From 19032c9b5354d295dceaa1ad284e20c89b7996ca Mon Sep 17 00:00:00 2001 From: Steven Gardiner Date: Tue, 25 Jul 2023 15:54:01 -0500 Subject: [PATCH 001/367] cherry-pick d7281db, fix merge conflict --- CMakeLists.txt | 1 + .../SBNEventWeight/Calculators/CMakeLists.txt | 2 +- .../Geant4/BetheBlochForG4ReweightValid.h | 145 +++++ .../Calculators/Geant4/CMakeLists.txt | 22 + .../Calculators/Geant4/Geant4WeightCalc.cxx | 524 ++++++++++++++++++ ups/product_deps | 11 +- 6 files changed, 699 insertions(+), 6 deletions(-) create mode 100644 sbncode/SBNEventWeight/Calculators/Geant4/BetheBlochForG4ReweightValid.h create mode 100644 sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt create mode 100644 sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index fc36b1322..d5b3927ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ find_package( CLHEP REQUIRED ) find_package( ROOT REQUIRED ) find_package( Geant4 REQUIRED ) find_package( Boost COMPONENTS system filesystem REQUIRED ) +find_package( geant4reweight REQUIRED ) # macros for dictionary and simple_plugin include(ArtDictionary) diff --git a/sbncode/SBNEventWeight/Calculators/CMakeLists.txt b/sbncode/SBNEventWeight/Calculators/CMakeLists.txt index e2080685f..383d41a3a 100644 --- a/sbncode/SBNEventWeight/Calculators/CMakeLists.txt +++ b/sbncode/SBNEventWeight/Calculators/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(CrossSections) add_subdirectory(BNBFlux) -#add_subdirectory(Geant4) +add_subdirectory(Geant4) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/BetheBlochForG4ReweightValid.h b/sbncode/SBNEventWeight/Calculators/Geant4/BetheBlochForG4ReweightValid.h new file mode 100644 index 000000000..58cfdc99e --- /dev/null +++ b/sbncode/SBNEventWeight/Calculators/Geant4/BetheBlochForG4ReweightValid.h @@ -0,0 +1,145 @@ + + +double BetheBloch(double energy, double mass){ + + //Need to make this configurable? Or delete... + double K = .307075; + double rho = 1.390; + double Z = 18; + double A = 40; + double I = 188E-6; + double me = .511; + //Need to make sure this is total energy, not KE + double gamma = energy/mass; + double beta = sqrt( 1. - (1. / (gamma*gamma)) ); + double Tmax = 2 * me * beta*beta * gamma*gamma; + + double first = K * (Z/A) * rho / (beta*beta); + double second = .5 * log(Tmax*Tmax/(I*I)) - beta*beta; + + double dEdX = first*second; + return dEdX; +} + +std::vector< std::pair > ThinSliceBetheBloch(G4ReweightTraj * theTraj, double res, double mass, bool isElastic){ + + std::vector< std::pair > result; + + //First slice position +// double sliceEdge = res; +// double lastPos = 0.; +// double nextPos = 0.; +// double px,py,pz; + int interactInSlice = 0; + + //Get total distance traveled in z +// double totalDeltaZ = 0.; + double disp = 0.; +// double oldDisp = 0.; +// int crossedSlices = 0; + + int currentSlice = 0; + int oldSlice = 0; + + double sliceEnergy = theTraj->GetEnergy(); + size_t nSteps = theTraj->GetNSteps(); + for(size_t is = 0; is < nSteps; ++is){ + auto theStep = theTraj->GetStep(is); + + disp += theStep->GetStepLength(); + currentSlice = floor(disp/res); + + std::string theProc = theStep->GetStepChosenProc(); + + //Check to see if in a new slice and it's not the end + if( oldSlice != currentSlice && is < nSteps - 1){ + + + //Save Interaction info of the prev slice + //and reset + result.push_back( std::make_pair(sliceEnergy, interactInSlice) ); + interactInSlice = 0; + + //Update the energy + sliceEnergy = sliceEnergy - res*BetheBloch(sliceEnergy, mass); + if( sliceEnergy - mass < 0.){ + //std::cout << "Warning! Negative energy " << sliceEnergy - mass << std::endl; + //std::cout << "Crossed " << oldSlice - currentSlice << std::endl; + sliceEnergy = 0.0001; + } + //If it's more than 1 slice, add in non-interacting slices + for(int ic = 1; ic < abs( oldSlice - currentSlice ); ++ic){ + //std::cout << ic << std::endl; + + result.push_back( std::make_pair(sliceEnergy, 0) ); + + //Update the energy again + sliceEnergy = sliceEnergy - res*BetheBloch(sliceEnergy, mass); + if( sliceEnergy - mass < 0.){ + //std::cout << "Warning! Negative energy " << sliceEnergy - mass << std::endl; + //std::cout << "Crossed " << oldSlice - currentSlice << std::endl; + sliceEnergy = 0.0001; + } + } + + if ((!isElastic && theProc.find(std::string("Inelastic")) != std::string::npos) || (isElastic && theProc.find(std::string("hadElastic")) != std::string::npos)) { + // std::cout << "found! " << theProc << '\n'; + interactInSlice = 1; + } + } + //It's crossed a slice and it's the last step. Save both info + else if( oldSlice != currentSlice && is == nSteps - 1 ){ + result.push_back( std::make_pair(sliceEnergy, interactInSlice) ); + interactInSlice = 0; + + //Update the energy + sliceEnergy = sliceEnergy - res*BetheBloch(sliceEnergy, mass); + if( sliceEnergy - mass < 0.){ + //std::cout << "Warning! Negative energy " << sliceEnergy - mass << std::endl; + //std::cout << "Crossed " << oldSlice - currentSlice << std::endl; + sliceEnergy = 0.0001; + } + //If it's more than 1 slice, add in non-interacting slices + for(int ic = 1; ic < abs( oldSlice - currentSlice ); ++ic){ + //std::cout << ic << std::endl; + + result.push_back( std::make_pair(sliceEnergy, 0) ); + + //Update the energy again + sliceEnergy = sliceEnergy - res*BetheBloch(sliceEnergy, mass); + if( sliceEnergy - mass < 0.){ + //std::cout << "Warning! Negative energy " << sliceEnergy - mass << std::endl; + //std::cout << "Crossed " << oldSlice - currentSlice << std::endl; + sliceEnergy = 0.0001; + } + } + + //Save the last slice + if ((!isElastic && theProc.find(std::string("Inelastic")) != std::string::npos) || (isElastic && theProc.find(std::string("hadElastic")) != std::string::npos)) { + // std::cout << "found! " << theProc << '\n'; + interactInSlice = 1; + } + result.push_back( std::make_pair(sliceEnergy, interactInSlice) ); + } + //It's the end, so just save this last info + else if( oldSlice == currentSlice && is == nSteps - 1 ){ + if ((!isElastic && theProc.find(std::string("Inelastic")) != std::string::npos) || (isElastic && theProc.find(std::string("hadElastic")) != std::string::npos)) { + // std::cout << "found! " << theProc << '\n'; + interactInSlice = 1; + } + result.push_back( std::make_pair(sliceEnergy, interactInSlice) ); + } + //Same slice, not the end. Check for interactions + else{ + if ((!isElastic && theProc.find(std::string("Inelastic")) != std::string::npos) || (isElastic && theProc.find(std::string("hadElastic")) != std::string::npos)) { + // std::cout << "found! " << theProc << '\n'; + interactInSlice = 1; + } + } + + //Update oldslice + oldSlice = currentSlice; + } + + return result; +} diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt new file mode 100644 index 000000000..e1289208d --- /dev/null +++ b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt @@ -0,0 +1,22 @@ +include_directories ( $ENV{GEANT4_FQ_DIR}/include ) +include_directories ( $ENV{GEANT4REWEIGHT_INC} ) + +art_make_library( + LIBRARY_NAME sbncode_SBNEventWeight_Calculators_Geant4 + LIBRARIES + sbncode_SBNEventWeight_Base + nusimdata::SimulationBase + nurandom::RandomUtils_NuRandomService_service + art::Framework_Principal + art::Framework_Services_Registry + art_root_io::TFileService_service + larcore::Geometry_Geometry_service + cetlib_except::cetlib_except + ReweightBaseLib + PropBaseLib +) + +install_headers() +install_fhicl() +install_source() + diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx new file mode 100644 index 000000000..f4ba26774 --- /dev/null +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -0,0 +1,524 @@ +/** + * \class evwgh::Geant4WeightCalc + * \brief Updated hadron reinteraction event reweighting, using geant4reweight + * \author K. Duffy , 2019/10 + * + * Reweight events based on hadron reinteraction probabilities. + */ + +#include +#include +#include "TDirectory.h" +#include "TFile.h" +#include "TH1D.h" +#include "TTree.h" +#include "Geant4/G4LossTableManager.hh" +#include "Geant4/G4ParticleTable.hh" +#include "Geant4/G4ParticleDefinition.hh" +#include "Geant4/G4Material.hh" +#include "Geant4/G4MaterialCutsCouple.hh" +#include "art_root_io/TFileService.h" +#include "art_root_io/TFileDirectory.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Persistency/Provenance/ModuleContext.h" +#include "art/Framework/Principal/Event.h" +#include "canvas/Persistency/Common/FindManyP.h" +#include "canvas/Persistency/Common/Ptr.h" +#include "nusimdata/SimulationBase/MCParticle.h" +#include "nusimdata/SimulationBase/MCTruth.h" +#include "CLHEP/Random/RandGaussQ.h" +#include "CLHEP/Units/PhysicalConstants.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "sbncode/SBNEventWeight/Base/WeightCalcCreator.h" +#include "sbncode/SBNEventWeight/Base/WeightCalc.h" +#include "larcore/Geometry/Geometry.h" +#include "geant4reweight/ReweightBase/G4ReweighterFactory.hh" +#include "geant4reweight/ReweightBase/G4Reweighter.hh" +#include "geant4reweight/ReweightBase/G4ReweightTraj.hh" +#include "geant4reweight/ReweightBase/G4ReweightStep.hh" +#include "geant4reweight/PropBase/G4ReweightParameterMaker.hh" + +// local include +#include "BetheBlochForG4ReweightValid.h" + +namespace sbn { + +namespace evwgh { + +class Geant4WeightCalc : public WeightCalc { +public: + Geant4WeightCalc() {} + + void Configure(fhicl::ParameterSet const& p, CLHEP::HepRandomEngine& engine); + + std::vector > GetWeight(art::Event& e); + +private: + std::string fMCParticleProducer; //!< Label for the MCParticle producer + std::string fMCTruthProducer; //!< Label for the MCTruth producer + CLHEP::RandGaussQ* fGaussRandom; //!< Random number generator + // std::map fParticles; //!< Particles to reweight + unsigned fNsims; //!< Number of multisims + int fPdg; //!< PDG value for particles that a given weight calculator should apply to. Note that for now this module can only handle weights for one particle species at a time. + // float fXSUncertainty; //!< Flat cross section uncertainty + G4ReweighterFactory RWFactory; //!< Base class to handle all Geant4Reweighters (right now "all" means pi+, pi-, p) + G4Reweighter *theReweighter; //!< Geant4Reweighter -- this is what provides the weights + G4ReweightParameterMaker *ParMaker; + std::vector> UniverseVals; //!< Vector of maps relating parameter name to value (defines parameter values that will be evaluated in universes). Each map should have one entry per parameter we are considering + + art::ServiceHandle < geo::Geometry > fGeometryService; + + bool fMakeOutputTrees; ///!< Fcl parameter to decide whether to save output tree (useful for validations but not necessary when running in production) + TTree *fOutTree_MCTruth; //!< Output tree for quick validations: on entry per MCTruth object + TTree *fOutTree_Particle; //!< Output tree for quick validations: one entry per neutrino-induced pi+, pi-, or proton + int event_num; //!< Variables for both output trees + int run_num; //!< Variables for both output trees + int subrun_num; //!< Variables for both output trees + double p_track_length; //!< Variables for by-particle output tree + int p_PDG; //!< Variables for by-particle output tree + std::string p_final_proc; //!< Variables for by-particle output tree + double p_init_momentum; //!< Variables for by-particle output tree + double p_final_momentum; //!< Variables for by-particle output tree + std::vector< double > p_energies_el; //!< Variables for by-particle output tree + std::vector< int > p_sliceInts_el; //!< Variables for by-particle output tree + std::vector< double > p_energies_inel; //!< Variables for by-particle output tree + std::vector< int > p_sliceInts_inel; //!< Variables for by-particle output tree + int p_nElasticScatters; //!< Variables for by-particle output tree + std::vector p_inel_weight; //!< Variables for by-particle output tree + std::vector p_elastic_weight; //!< Variables for by-particle output + std::vector > e_inel_weight; //!< Variables for by-event output tree + std::vector > e_elastic_weight; //!< Variables for by-event output tree + + bool fDebug; //!< print debug statements + + DECLARE_WEIGHTCALC(Geant4WeightCalc) +}; + + +void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, + CLHEP::HepRandomEngine& engine) +{ + std::cout << "Using Geant4WeightCalc for reinteraction weights" << std::endl; + + // Get configuration for this function + fhicl::ParameterSet const& pset = p.get(GetName()); + // std::cout << pset.GetName() << std::endl; + fMCParticleProducer = pset.get("MCParticleProducer", "largeant"); + fMCTruthProducer = pset.get("MCTruthProducer", "generator"); + fMakeOutputTrees = pset.get< bool >( "makeoutputtree", false ); + std::string mode = pset.get("mode"); + std::string FracsFileName = pset.get< std::string >( "fracsfile" ); + std::string XSecFileName = pset.get< std::string >( "xsecfile" ); + std::vector< fhicl::ParameterSet > FitParSets = pset.get< std::vector< fhicl::ParameterSet > >("parameters"); + fNsims = pset.get ("number_of_multisims", 0); + fPdg = pset.get ("pdg_to_reweight"); + fDebug = pset.get ("debug",false); + + // Prepare random generator + fGaussRandom = new CLHEP::RandGaussQ(engine); + + // Get input files + TFile FracsFile( FracsFileName.c_str(), "OPEN" ); + TFile XSecFile( XSecFileName.c_str(), "OPEN" ); + + // Configure G4Reweighter + bool totalonly = false; + if (fPdg==2212) totalonly = true; + ParMaker = new G4ReweightParameterMaker( FitParSets, totalonly ); + theReweighter = RWFactory.BuildReweighter(fPdg, &XSecFile, &FracsFile, ParMaker->GetFSHists(), ParMaker->GetElasticHist() ); + + // Make output trees to save things for quick and easy validation + art::ServiceHandle tfs; + + if (fMakeOutputTrees){ + fOutTree_Particle = tfs->make(Form("%s_%i","ByParticleValidTree",fPdg),""); + fOutTree_Particle->Branch("event_num",&event_num); + fOutTree_Particle->Branch("run_num",&run_num); + fOutTree_Particle->Branch("subrun_num",&subrun_num); + fOutTree_Particle->Branch("UniverseVals", &UniverseVals); + fOutTree_Particle->Branch("pdg_to_reweight",&fPdg); + fOutTree_Particle->Branch("inelastic_weight",&p_inel_weight); + fOutTree_Particle->Branch("elastic_weight",&p_elastic_weight); + fOutTree_Particle->Branch("track_length",&p_track_length); + fOutTree_Particle->Branch("PDG",&p_PDG); + fOutTree_Particle->Branch("final_proc",&p_final_proc); + fOutTree_Particle->Branch("init_momentum",&p_init_momentum); + fOutTree_Particle->Branch("final_momentum",&p_final_momentum); + fOutTree_Particle->Branch("energies_el",&p_energies_el); + fOutTree_Particle->Branch("sliceInts_el",&p_sliceInts_el); + fOutTree_Particle->Branch("energies_inel",&p_energies_inel); + fOutTree_Particle->Branch("sliceInts_inel",&p_sliceInts_inel); + fOutTree_Particle->Branch("nElasticScatters",&p_nElasticScatters); + + fOutTree_MCTruth = tfs->make(Form("%s_%i","ByMCTruthValidTree",fPdg),""); + fOutTree_MCTruth->Branch("event_num",&event_num); + fOutTree_MCTruth->Branch("run_num",&run_num); + fOutTree_MCTruth->Branch("subrun_num",&subrun_num); + fOutTree_MCTruth->Branch("UniverseVals", &UniverseVals); + fOutTree_MCTruth->Branch("pdg_to_reweight",&fPdg); + fOutTree_MCTruth->Branch("inelastic_weight",&e_inel_weight); + fOutTree_MCTruth->Branch("elastic_weight",&e_elastic_weight); + + } + + + // Read input parameter sets and set up universes + size_t n_parsets = FitParSets.size(); + std::vector FitParNames; + std::vector FitParNominals; + std::vector FitParSigmas; + std::map theNominals; + + for (size_t i_parset=0; i_parset("Name"); + double theNominal = theSet.get("Nominal",1.); + double theSigma = theSet.get("Sigma",0.); + + FitParNames.push_back(theName); + FitParNominals.push_back(theNominal); + FitParSigmas.push_back(theSigma); + + theNominals[theName] = theNominal; + } + + if (mode=="pm1sigma"){ + // pm1sigma mode: 0 = +1sigma, 1 = -1sigma of a single parameter. All other parameters at nominal + for (size_t i_parset=0; i_parset tmp_vals_p1sigma(theNominals); + std::map tmp_vals_m1sigma(theNominals); + // Now reset the +1sigma and -1sigma values for this parameter set only + tmp_vals_p1sigma[FitParNames.at(i_parset)] = FitParNominals.at(i_parset)+FitParSigmas.at(i_parset); + tmp_vals_m1sigma[FitParNames.at(i_parset)] = FitParNominals.at(i_parset)-FitParSigmas.at(i_parset); + + if (fDebug){ + std::cout << "Universe " << i_parset*2 << ": " << FitParNames.at(i_parset) << " = " << FitParNominals.at(i_parset)+FitParSigmas.at(i_parset) << std::endl; + std::cout << "Universe " << i_parset*2+1 << ": " << FitParNames.at(i_parset) << " = " << FitParNominals.at(i_parset)-FitParSigmas.at(i_parset) << std::endl; + } + + // Finally, add these universes into the vector + UniverseVals.push_back(tmp_vals_p1sigma); + UniverseVals.push_back(tmp_vals_m1sigma); + } // end loop over parsets (i) + } // pm1sigma + else if (mode=="multisim"){ + // multisim mode: parameter values sample within the given uncertainty for all parameters simultaneously + // Loop over universes j + for (unsigned j=0; j tmp_vals; + for (size_t i_parset=0; i_parsetfire(0.0,1.0); + tmp_vals[FitParNames.at(i_parset)] = FitParNominals.at(i_parset)+(FitParSigmas.at(i_parset)*r); + } // loop over parameters (i_parset) + // Now save this universe + UniverseVals.push_back(tmp_vals); + } // loop over Nsims (j) + } // multisim + else{ + // Anything else mode: Set parameters to user-defined nominal value + UniverseVals.push_back(theNominals); + } // any other mode + + fNsims = UniverseVals.size(); + if (fDebug) std::cout << "Running mode: " << mode <<". Nsims = " << fNsims << std::endl; +} + + +std::vector > +Geant4WeightCalc::GetWeight(art::Event& e) { + + // Get event/run/subrun numbers for output + run_num = e.run(); + subrun_num = e.subRun(); + event_num = e.id().event(); + + // Get MCParticles for each MCTruth in this event + art::Handle > truthHandle; + e.getByLabel(fMCTruthProducer, truthHandle); + const art::FindManyP truthParticles(truthHandle, e, fMCParticleProducer); + assert(truthParticles.isValid()); + + // Initialize the vector of event weights + std::vector > weight(truthHandle->size()); + // These two are just for saving to the output tree for fast validation + e_inel_weight.clear(); + e_inel_weight.resize(truthHandle->size()); + e_elastic_weight.clear(); + e_elastic_weight.resize(truthHandle->size()); + + // Loop over sets of MCTruth-associated particles + for (size_t itruth=0; itruth trajpoint_X; + std::vector trajpoint_Y; + std::vector trajpoint_Z; + std::vector trajpoint_PX; + std::vector trajpoint_PY; + std::vector trajpoint_PZ; + std::vector elastic_indices; + + //Get the list of processes from the true trajectory + const std::vector< std::pair< size_t, unsigned char > > & processes = p.Trajectory().TrajectoryProcesses(); + std::map< size_t, std::string > process_map; + for( auto it = processes.begin(); it != processes.end(); ++it ){ + process_map[ it->first ] = p.Trajectory().KeyToProcess( it->second ); + } + + for( size_t i = 0; i < p.NumberTrajectoryPoints(); ++i ){ + double X = p.Position(i).X(); + double Y = p.Position(i).Y(); + double Z = p.Position(i).Z(); + geo::Point_t testpoint1 { X, Y, Z }; + const TGeoMaterial* testmaterial1 = fGeometryService->Material( testpoint1 ); + //For now, just going to reweight the points within the LAr of the TPC + // TODO check if this is right + if ( !strcmp( testmaterial1->GetName(), "LAr" ) ){ + trajpoint_X.push_back( X ); + trajpoint_Y.push_back( Y ); + trajpoint_Z.push_back( Z ); + + trajpoint_PX.push_back( p.Px(i) ); + trajpoint_PY.push_back( p.Py(i) ); + trajpoint_PZ.push_back( p.Pz(i) ); + + auto itProc = process_map.find(i); + if( itProc != process_map.end() && itProc->second == "hadElastic" ){ + //Push back the index relative to the start of the reweightable steps + elastic_indices.push_back( trajpoint_X.size() - 1 ); + // if (fDebug) std::cout << "Elastic index: " << trajpoint_X.size() - 1 << std::endl; + } + + } + + } // end loop over trajectory points + + // Now find daughters of the MCP + std::vector daughter_PDGs; + std::vector daughter_IDs; + for( int i_mcp = 0; i_mcp < p.NumberDaughters(); i_mcp++ ){ + int daughterID = p.Daughter(i_mcp); + for (auto test_mcp : mcparticles){ + if (test_mcp->TrackId() == daughterID){ + int pid = test_mcp->PdgCode(); + daughter_PDGs.push_back(pid); + daughter_IDs.push_back( test_mcp->TrackId() ); + break; + } + } + } // end loop over daughters + + // --- Now that we have all the information about the track we need, here comes the reweighting part! --- // + + //Make a G4ReweightTraj -- This is the reweightable object + G4ReweightTraj theTraj(mcpID, p_PDG, 0, event_num, std::make_pair(0,0)); + + //Create its set of G4ReweightSteps and add them to the Traj (note: this needs to be done once per MCParticle but will be valid for all weight calculations) + std::vector< G4ReweightStep* > allSteps; + + size_t nSteps = trajpoint_PX.size(); + + if( nSteps < 2 ) continue; + + p_nElasticScatters = elastic_indices.size(); + for( size_t istep = 1; istep < nSteps; ++istep ){ + + // if( istep == trajpoint_PX.size() - 1 && std::find( elastic_indices.begin(), elastic_indices.end(), j ) != elastic_indices.end() ) + // std::cout << "Warning: last step an elastic process" << std::endl; + + std::string proc = "default"; + if( istep == trajpoint_PX.size() - 1 ) + proc = EndProcess; + else if( std::find( elastic_indices.begin(), elastic_indices.end(), istep ) != elastic_indices.end() ){ + proc = "hadElastic"; + } + + + double deltaX = ( trajpoint_X.at(istep) - trajpoint_X.at(istep-1) ); + double deltaY = ( trajpoint_Y.at(istep) - trajpoint_Y.at(istep-1) ); + double deltaZ = ( trajpoint_Z.at(istep) - trajpoint_Z.at(istep-1) ); + + double len = sqrt( + std::pow( deltaX, 2 ) + + std::pow( deltaY, 2 ) + + std::pow( deltaZ, 2 ) + ); + + double preStepP[3] = { + trajpoint_PX.at(istep-1)*1.e3, + trajpoint_PY.at(istep-1)*1.e3, + trajpoint_PZ.at(istep-1)*1.e3 + }; + + double postStepP[3] = { + trajpoint_PX.at(istep)*1.e3, + trajpoint_PY.at(istep)*1.e3, + trajpoint_PZ.at(istep)*1.e3 + }; + + if( istep == 1 ){ + theTraj.SetEnergy( sqrt( preStepP[0]*preStepP[0] + preStepP[1]*preStepP[1] + preStepP[2]*preStepP[2] + mass*mass ) ); + } + + G4ReweightStep * theStep = new G4ReweightStep( mcpID, p_PDG, 0, event_num, preStepP, postStepP, len, proc ); + theStep->SetDeltaX( deltaX ); + theStep->SetDeltaY( deltaY ); + theStep->SetDeltaZ( deltaZ ); + + theTraj.AddStep( theStep ); + + for( size_t k = 0; k < daughter_PDGs.size(); ++k ){ + theTraj.AddChild( new G4ReweightTraj(daughter_IDs[k], daughter_PDGs[k], mcpID, event_num, std::make_pair(0,0) ) ); + } + } // end loop over nSteps (istep) + p_track_length = theTraj.GetTotalLength(); + + p_init_momentum = sqrt( theTraj.GetEnergy()*theTraj.GetEnergy() - mass*mass ); + p_final_momentum = sqrt( + std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPx(), 2 ) + + std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPy(), 2 ) + + std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPz(), 2 ) + ); + + std::vector< std::pair< double, int > > thin_slice_inelastic = ThinSliceBetheBloch( &theTraj, .5, mass , false); + std::vector< std::pair< double, int > > thin_slice_elastic = ThinSliceBetheBloch( &theTraj, .5, mass , true); + + p_energies_inel.clear(); + p_sliceInts_inel.clear(); + for( size_t islice = 0; islice < thin_slice_inelastic.size(); ++islice ){ + p_energies_inel.push_back( thin_slice_inelastic[islice].first ); + p_sliceInts_inel.push_back( thin_slice_inelastic[islice].second ); + } + + p_energies_el.clear(); + p_sliceInts_el.clear(); + for( size_t islice = 0; islice < thin_slice_elastic.size(); ++islice ){ + p_energies_el.push_back( thin_slice_elastic[islice].first ); + p_sliceInts_el.push_back( thin_slice_elastic[islice].second ); + } + + // Loop through universes (j) + for (size_t j=0; jSetNewVals(UniverseVals.at(j)); + theReweighter->SetNewHists(ParMaker->GetFSHists()); + theReweighter->SetNewElasticHists(ParMaker->GetElasticHist()); + + //Get the weight from the G4ReweightTraj + w = theReweighter->GetWeight( &theTraj ); + // Total weight is the product of track weights in the event + weight[itruth][j] *= std::max((float)0.0, w); + + // Do the same for elastic weight (should be 1 unless set to non-nominal ) + el_w = theReweighter->GetElasticWeight( &theTraj ); + weight[itruth][j] *= std::max((float)0.0,el_w); + + // just for the output tree + p_inel_weight[j] = w; + p_elastic_weight[j] = el_w; + e_inel_weight[itruth][j] *= std::max((float)0.0,w); + e_elastic_weight[itruth][j] *= std::max((float)0.0,el_w); + + if (fDebug){ + std::cout << " Universe " << j << ": "; + // std::cout << UniverseVals.at(j) << std::endl; + std::cout << " w = " << w << ", el_w = " << el_w << std::endl; + } + + + } // loop through universes (j) + + if (fDebug){ + std::cout << "PDG = " << p_PDG << std::endl; + std::cout << "inel weights by particle: "; + for (unsigned int j=0; jFill(); + } // loop over mcparticles (i) + if (fMakeOutputTrees) fOutTree_MCTruth->Fill(); + } // loop over sets of MCtruth-associated particles (itruth) + +return weight; + +} + +REGISTER_WEIGHTCALC(Geant4WeightCalc) + +} // namespace evwgh + +} // namespace sbn diff --git a/ups/product_deps b/ups/product_deps index 9e0fd280d..9586bb584 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -261,6 +261,7 @@ sbndata v01_07 - sbnobj v09_19_04 - systematicstools v01_04_04 - nusystematics v1_05_01 - +geant4reweight v01_20_08 - cetmodules v3_24_01 - only_for_build end_product_list #################################### @@ -317,11 +318,11 @@ end_product_list # #################################### -qualifier larsoft sbnobj sbnanaobj sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics notes -c14:debug c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug -nq- -c14:prof c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof -nq- -e26:debug e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug -nq- -e26:prof e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof -nq- +qualifier larsoft sbnobj sbnanaobj sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics geant4reweight notes +c14:debug c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug c14:debug:s131 -nq- +c14:prof c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof c14:prof:s131 -nq- +e26:debug e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug e26:debug:s131 -nq- +e26:prof e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof e26:prof:s131 -nq- end_qualifier_list #################################### From 5ede08a2adf1cb827865607c45b64be348fa02d5 Mon Sep 17 00:00:00 2001 From: Steven Gardiner Date: Tue, 25 Jul 2023 17:25:52 -0500 Subject: [PATCH 002/367] Some tweaks to adjust for larsim EventWeight (used by uB) vs. SBNEventWeight differences. Also make some adjustments to get it to build against geant4reweight v01_00_03e -q e20:s120a:prof --- .../Calculators/Geant4/CMakeLists.txt | 1 + .../Calculators/Geant4/Geant4WeightCalc.cxx | 463 ++++++++---------- ups/product_deps | 2 +- 3 files changed, 216 insertions(+), 250 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt index e1289208d..f05f8d274 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt +++ b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt @@ -14,6 +14,7 @@ art_make_library( cetlib_except::cetlib_except ReweightBaseLib PropBaseLib + ROOT::Tree ) install_headers() diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index f4ba26774..8b4736aa0 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -52,7 +52,7 @@ class Geant4WeightCalc : public WeightCalc { void Configure(fhicl::ParameterSet const& p, CLHEP::HepRandomEngine& engine); - std::vector > GetWeight(art::Event& e); + std::vector GetWeight(art::Event& e, size_t inu); private: std::string fMCParticleProducer; //!< Label for the MCParticle producer @@ -87,17 +87,18 @@ class Geant4WeightCalc : public WeightCalc { int p_nElasticScatters; //!< Variables for by-particle output tree std::vector p_inel_weight; //!< Variables for by-particle output tree std::vector p_elastic_weight; //!< Variables for by-particle output - std::vector > e_inel_weight; //!< Variables for by-event output tree - std::vector > e_elastic_weight; //!< Variables for by-event output tree bool fDebug; //!< print debug statements DECLARE_WEIGHTCALC(Geant4WeightCalc) }; +} // namespace evwgh + +} // namespace sbn -void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, - CLHEP::HepRandomEngine& engine) +void sbn::evwgh::Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, + CLHEP::HepRandomEngine& engine) { std::cout << "Using Geant4WeightCalc for reinteraction weights" << std::endl; @@ -157,9 +158,6 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, fOutTree_MCTruth->Branch("subrun_num",&subrun_num); fOutTree_MCTruth->Branch("UniverseVals", &UniverseVals); fOutTree_MCTruth->Branch("pdg_to_reweight",&fPdg); - fOutTree_MCTruth->Branch("inelastic_weight",&e_inel_weight); - fOutTree_MCTruth->Branch("elastic_weight",&e_elastic_weight); - } @@ -227,8 +225,8 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, } -std::vector > -Geant4WeightCalc::GetWeight(art::Event& e) { +std::vector +sbn::evwgh::Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Get event/run/subrun numbers for output run_num = e.run(); @@ -242,283 +240,250 @@ Geant4WeightCalc::GetWeight(art::Event& e) { assert(truthParticles.isValid()); // Initialize the vector of event weights - std::vector > weight(truthHandle->size()); - // These two are just for saving to the output tree for fast validation - e_inel_weight.clear(); - e_inel_weight.resize(truthHandle->size()); - e_elastic_weight.clear(); - e_elastic_weight.resize(truthHandle->size()); + std::vector weight; - // Loop over sets of MCTruth-associated particles - for (size_t itruth=0; itruth trajpoint_X; - std::vector trajpoint_Y; - std::vector trajpoint_Z; - std::vector trajpoint_PX; - std::vector trajpoint_PY; - std::vector trajpoint_PZ; - std::vector elastic_indices; - - //Get the list of processes from the true trajectory - const std::vector< std::pair< size_t, unsigned char > > & processes = p.Trajectory().TrajectoryProcesses(); - std::map< size_t, std::string > process_map; - for( auto it = processes.begin(); it != processes.end(); ++it ){ - process_map[ it->first ] = p.Trajectory().KeyToProcess( it->second ); - } - - for( size_t i = 0; i < p.NumberTrajectoryPoints(); ++i ){ - double X = p.Position(i).X(); - double Y = p.Position(i).Y(); - double Z = p.Position(i).Z(); - geo::Point_t testpoint1 { X, Y, Z }; - const TGeoMaterial* testmaterial1 = fGeometryService->Material( testpoint1 ); - //For now, just going to reweight the points within the LAr of the TPC - // TODO check if this is right - if ( !strcmp( testmaterial1->GetName(), "LAr" ) ){ - trajpoint_X.push_back( X ); - trajpoint_Y.push_back( Y ); - trajpoint_Z.push_back( Z ); - - trajpoint_PX.push_back( p.Px(i) ); - trajpoint_PY.push_back( p.Py(i) ); - trajpoint_PZ.push_back( p.Pz(i) ); - - auto itProc = process_map.find(i); - if( itProc != process_map.end() && itProc->second == "hadElastic" ){ - //Push back the index relative to the start of the reweightable steps - elastic_indices.push_back( trajpoint_X.size() - 1 ); - // if (fDebug) std::cout << "Elastic index: " << trajpoint_X.size() - 1 << std::endl; - } + p_inel_weight.clear(); + p_inel_weight.resize(fNsims,1.0); + p_elastic_weight.clear(); + p_elastic_weight.resize(fNsims,1.0); + p_track_length=-9999; + p_PDG=-9999; + p_final_proc="dummy"; + p_init_momentum=-9999; + p_final_momentum=-9999; + p_energies_el.clear(); + p_sliceInts_el.clear(); + p_energies_inel.clear(); + p_sliceInts_inel.clear(); + p_nElasticScatters=-9999; + + + const simb::MCParticle& p = *mcparticles.at(i); + p_PDG = p.PdgCode(); + int mcpID = p.TrackId(); + std::string EndProcess = p.EndProcess(); + + double mass = 0.; + if( TMath::Abs(p_PDG) == 211 ) mass = 139.57; + else if( p_PDG == 2212 ) mass = 938.28; + + // We only want to record weights for one type of particle (defined by fPDG from the fcl file), so skip other particles + if (p_PDG == fPdg){ + // Get GEANT trajectory points: weighting will depend on position and momentum at each trajectory point so calculate those + std::vector trajpoint_X; + std::vector trajpoint_Y; + std::vector trajpoint_Z; + std::vector trajpoint_PX; + std::vector trajpoint_PY; + std::vector trajpoint_PZ; + std::vector elastic_indices; + + //Get the list of processes from the true trajectory + const std::vector< std::pair< size_t, unsigned char > > & processes = p.Trajectory().TrajectoryProcesses(); + std::map< size_t, std::string > process_map; + for( auto it = processes.begin(); it != processes.end(); ++it ){ + process_map[ it->first ] = p.Trajectory().KeyToProcess( it->second ); + } + for( size_t i = 0; i < p.NumberTrajectoryPoints(); ++i ){ + double X = p.Position(i).X(); + double Y = p.Position(i).Y(); + double Z = p.Position(i).Z(); + geo::Point_t testpoint1 { X, Y, Z }; + const TGeoMaterial* testmaterial1 = fGeometryService->Material( testpoint1 ); + //For now, just going to reweight the points within the LAr of the TPC + // TODO check if this is right + if ( !strcmp( testmaterial1->GetName(), "LAr" ) ){ + trajpoint_X.push_back( X ); + trajpoint_Y.push_back( Y ); + trajpoint_Z.push_back( Z ); + + trajpoint_PX.push_back( p.Px(i) ); + trajpoint_PY.push_back( p.Py(i) ); + trajpoint_PZ.push_back( p.Pz(i) ); + + auto itProc = process_map.find(i); + if( itProc != process_map.end() && itProc->second == "hadElastic" ){ + //Push back the index relative to the start of the reweightable steps + elastic_indices.push_back( trajpoint_X.size() - 1 ); + // if (fDebug) std::cout << "Elastic index: " << trajpoint_X.size() - 1 << std::endl; } - } // end loop over trajectory points - - // Now find daughters of the MCP - std::vector daughter_PDGs; - std::vector daughter_IDs; - for( int i_mcp = 0; i_mcp < p.NumberDaughters(); i_mcp++ ){ - int daughterID = p.Daughter(i_mcp); - for (auto test_mcp : mcparticles){ - if (test_mcp->TrackId() == daughterID){ - int pid = test_mcp->PdgCode(); - daughter_PDGs.push_back(pid); - daughter_IDs.push_back( test_mcp->TrackId() ); - break; - } + } + + } // end loop over trajectory points + + // Now find daughters of the MCP + std::vector daughter_PDGs; + std::vector daughter_IDs; + for( int i_mcp = 0; i_mcp < p.NumberDaughters(); i_mcp++ ){ + int daughterID = p.Daughter(i_mcp); + for (auto test_mcp : mcparticles){ + if (test_mcp->TrackId() == daughterID){ + int pid = test_mcp->PdgCode(); + daughter_PDGs.push_back(pid); + daughter_IDs.push_back( test_mcp->TrackId() ); + break; } - } // end loop over daughters + } + } // end loop over daughters - // --- Now that we have all the information about the track we need, here comes the reweighting part! --- // + // --- Now that we have all the information about the track we need, here comes the reweighting part! --- // - //Make a G4ReweightTraj -- This is the reweightable object - G4ReweightTraj theTraj(mcpID, p_PDG, 0, event_num, std::make_pair(0,0)); + //Make a G4ReweightTraj -- This is the reweightable object + G4ReweightTraj theTraj(mcpID, p_PDG, 0, event_num, std::make_pair(0,0)); - //Create its set of G4ReweightSteps and add them to the Traj (note: this needs to be done once per MCParticle but will be valid for all weight calculations) - std::vector< G4ReweightStep* > allSteps; + //Create its set of G4ReweightSteps and add them to the Traj (note: this needs to be done once per MCParticle but will be valid for all weight calculations) + std::vector< G4ReweightStep* > allSteps; - size_t nSteps = trajpoint_PX.size(); + size_t nSteps = trajpoint_PX.size(); - if( nSteps < 2 ) continue; + if( nSteps < 2 ) continue; - p_nElasticScatters = elastic_indices.size(); - for( size_t istep = 1; istep < nSteps; ++istep ){ + p_nElasticScatters = elastic_indices.size(); + for( size_t istep = 1; istep < nSteps; ++istep ){ - // if( istep == trajpoint_PX.size() - 1 && std::find( elastic_indices.begin(), elastic_indices.end(), j ) != elastic_indices.end() ) - // std::cout << "Warning: last step an elastic process" << std::endl; + // if( istep == trajpoint_PX.size() - 1 && std::find( elastic_indices.begin(), elastic_indices.end(), j ) != elastic_indices.end() ) + // std::cout << "Warning: last step an elastic process" << std::endl; - std::string proc = "default"; - if( istep == trajpoint_PX.size() - 1 ) - proc = EndProcess; - else if( std::find( elastic_indices.begin(), elastic_indices.end(), istep ) != elastic_indices.end() ){ - proc = "hadElastic"; - } + std::string proc = "default"; + if( istep == trajpoint_PX.size() - 1 ) + proc = EndProcess; + else if( std::find( elastic_indices.begin(), elastic_indices.end(), istep ) != elastic_indices.end() ){ + proc = "hadElastic"; + } - double deltaX = ( trajpoint_X.at(istep) - trajpoint_X.at(istep-1) ); - double deltaY = ( trajpoint_Y.at(istep) - trajpoint_Y.at(istep-1) ); - double deltaZ = ( trajpoint_Z.at(istep) - trajpoint_Z.at(istep-1) ); + double deltaX = ( trajpoint_X.at(istep) - trajpoint_X.at(istep-1) ); + double deltaY = ( trajpoint_Y.at(istep) - trajpoint_Y.at(istep-1) ); + double deltaZ = ( trajpoint_Z.at(istep) - trajpoint_Z.at(istep-1) ); - double len = sqrt( - std::pow( deltaX, 2 ) + - std::pow( deltaY, 2 ) + - std::pow( deltaZ, 2 ) - ); + double len = sqrt( + std::pow( deltaX, 2 ) + + std::pow( deltaY, 2 ) + + std::pow( deltaZ, 2 ) + ); - double preStepP[3] = { - trajpoint_PX.at(istep-1)*1.e3, - trajpoint_PY.at(istep-1)*1.e3, - trajpoint_PZ.at(istep-1)*1.e3 - }; + double preStepP[3] = { + trajpoint_PX.at(istep-1)*1.e3, + trajpoint_PY.at(istep-1)*1.e3, + trajpoint_PZ.at(istep-1)*1.e3 + }; - double postStepP[3] = { - trajpoint_PX.at(istep)*1.e3, - trajpoint_PY.at(istep)*1.e3, - trajpoint_PZ.at(istep)*1.e3 - }; + double postStepP[3] = { + trajpoint_PX.at(istep)*1.e3, + trajpoint_PY.at(istep)*1.e3, + trajpoint_PZ.at(istep)*1.e3 + }; - if( istep == 1 ){ - theTraj.SetEnergy( sqrt( preStepP[0]*preStepP[0] + preStepP[1]*preStepP[1] + preStepP[2]*preStepP[2] + mass*mass ) ); - } + if( istep == 1 ){ + theTraj.SetEnergy( sqrt( preStepP[0]*preStepP[0] + preStepP[1]*preStepP[1] + preStepP[2]*preStepP[2] + mass*mass ) ); + } - G4ReweightStep * theStep = new G4ReweightStep( mcpID, p_PDG, 0, event_num, preStepP, postStepP, len, proc ); - theStep->SetDeltaX( deltaX ); - theStep->SetDeltaY( deltaY ); - theStep->SetDeltaZ( deltaZ ); + G4ReweightStep * theStep = new G4ReweightStep( mcpID, p_PDG, 0, event_num, preStepP, postStepP, len, proc ); + theStep->SetDeltaX( deltaX ); + theStep->SetDeltaY( deltaY ); + theStep->SetDeltaZ( deltaZ ); - theTraj.AddStep( theStep ); + theTraj.AddStep( theStep ); - for( size_t k = 0; k < daughter_PDGs.size(); ++k ){ - theTraj.AddChild( new G4ReweightTraj(daughter_IDs[k], daughter_PDGs[k], mcpID, event_num, std::make_pair(0,0) ) ); - } - } // end loop over nSteps (istep) - p_track_length = theTraj.GetTotalLength(); - - p_init_momentum = sqrt( theTraj.GetEnergy()*theTraj.GetEnergy() - mass*mass ); - p_final_momentum = sqrt( - std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPx(), 2 ) + - std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPy(), 2 ) + - std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPz(), 2 ) - ); + for( size_t k = 0; k < daughter_PDGs.size(); ++k ){ + theTraj.AddChild( new G4ReweightTraj(daughter_IDs[k], daughter_PDGs[k], mcpID, event_num, std::make_pair(0,0) ) ); + } + } // end loop over nSteps (istep) + p_track_length = theTraj.GetTotalLength(); - std::vector< std::pair< double, int > > thin_slice_inelastic = ThinSliceBetheBloch( &theTraj, .5, mass , false); - std::vector< std::pair< double, int > > thin_slice_elastic = ThinSliceBetheBloch( &theTraj, .5, mass , true); + p_init_momentum = sqrt( theTraj.GetEnergy()*theTraj.GetEnergy() - mass*mass ); + p_final_momentum = sqrt( + std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPx(), 2 ) + + std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPy(), 2 ) + + std::pow( theTraj.GetStep( theTraj.GetNSteps() - 1 )->GetPreStepPz(), 2 ) + ); - p_energies_inel.clear(); - p_sliceInts_inel.clear(); - for( size_t islice = 0; islice < thin_slice_inelastic.size(); ++islice ){ - p_energies_inel.push_back( thin_slice_inelastic[islice].first ); - p_sliceInts_inel.push_back( thin_slice_inelastic[islice].second ); - } + std::vector< std::pair< double, int > > thin_slice_inelastic = ThinSliceBetheBloch( &theTraj, .5, mass , false); + std::vector< std::pair< double, int > > thin_slice_elastic = ThinSliceBetheBloch( &theTraj, .5, mass , true); - p_energies_el.clear(); - p_sliceInts_el.clear(); - for( size_t islice = 0; islice < thin_slice_elastic.size(); ++islice ){ - p_energies_el.push_back( thin_slice_elastic[islice].first ); - p_sliceInts_el.push_back( thin_slice_elastic[islice].second ); - } + p_energies_inel.clear(); + p_sliceInts_inel.clear(); + for( size_t islice = 0; islice < thin_slice_inelastic.size(); ++islice ){ + p_energies_inel.push_back( thin_slice_inelastic[islice].first ); + p_sliceInts_inel.push_back( thin_slice_inelastic[islice].second ); + } - // Loop through universes (j) - for (size_t j=0; jSetNewVals(UniverseVals.at(j)); - theReweighter->SetNewHists(ParMaker->GetFSHists()); - theReweighter->SetNewElasticHists(ParMaker->GetElasticHist()); - - //Get the weight from the G4ReweightTraj - w = theReweighter->GetWeight( &theTraj ); - // Total weight is the product of track weights in the event - weight[itruth][j] *= std::max((float)0.0, w); - - // Do the same for elastic weight (should be 1 unless set to non-nominal ) - el_w = theReweighter->GetElasticWeight( &theTraj ); - weight[itruth][j] *= std::max((float)0.0,el_w); - - // just for the output tree - p_inel_weight[j] = w; - p_elastic_weight[j] = el_w; - e_inel_weight[itruth][j] *= std::max((float)0.0,w); - e_elastic_weight[itruth][j] *= std::max((float)0.0,el_w); - - if (fDebug){ - std::cout << " Universe " << j << ": "; - // std::cout << UniverseVals.at(j) << std::endl; - std::cout << " w = " << w << ", el_w = " << el_w << std::endl; - } + p_energies_el.clear(); + p_sliceInts_el.clear(); + for( size_t islice = 0; islice < thin_slice_elastic.size(); ++islice ){ + p_energies_el.push_back( thin_slice_elastic[islice].first ); + p_sliceInts_el.push_back( thin_slice_elastic[islice].second ); + } + + // Loop through universes (j) + for (size_t j=0; jSetNewVals(UniverseVals.at(j)); + theReweighter->SetNewHists(ParMaker->GetFSHists()); + theReweighter->SetNewElasticHists(ParMaker->GetElasticHist()); + //Get the weight from the G4ReweightTraj + w = theReweighter->GetWeight( &theTraj ); + // Total weight is the product of track weights in the event + weight[j] *= std::max((float)0.0, w); - } // loop through universes (j) + // Do the same for elastic weight (should be 1 unless set to non-nominal ) + el_w = theReweighter->GetElasticWeight( &theTraj ); + weight[j] *= std::max((float)0.0,el_w); + + // just for the output tree + p_inel_weight[j] = w; + p_elastic_weight[j] = el_w; if (fDebug){ - std::cout << "PDG = " << p_PDG << std::endl; - std::cout << "inel weights by particle: "; - for (unsigned int j=0; jFill(); + } // loop over mcparticles (i) + if (fMakeOutputTrees) fOutTree_MCTruth->Fill(); -} // namespace evwgh +return weight; -} // namespace sbn +} + +REGISTER_WEIGHTCALC(sbn::evwgh::Geant4WeightCalc) diff --git a/ups/product_deps b/ups/product_deps index 9586bb584..b54043517 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -248,7 +248,7 @@ libdir fq_dir lib # cetmodules), an entry for cetmodules is required. # # * It is an error for more than one non-( == "-default-") -# entry to match for a given product. + entry to match for a given product. # #################################### product version qual flags From c30d8d153982f1476ec18e2183a3bbfa620ee64f Mon Sep 17 00:00:00 2001 From: Andrew Mastbaum Date: Wed, 26 Jul 2023 15:59:01 -0500 Subject: [PATCH 003/367] geant4reweight interface updates + generic sbn fcls --- sbncode/SBNEventWeight/App/CMakeLists.txt | 7 +- .../Calculators/Geant4/Geant4WeightCalc.cxx | 14 +-- sbncode/SBNEventWeight/jobs/CMakeLists.txt | 1 + .../SBNEventWeight/jobs/geant4/CMakeLists.txt | 6 ++ .../jobs/geant4/eventweight_g4rwt_reint.fcl | 99 +++++++++++++++++++ .../geant4/piminus_reweight_parameters.fcl | 66 +++++++++++++ .../geant4/piplus_reweight_parameters.fcl | 66 +++++++++++++ .../geant4/proton_reweight_parameters.fcl | 23 +++++ 8 files changed, 273 insertions(+), 9 deletions(-) create mode 100644 sbncode/SBNEventWeight/jobs/geant4/CMakeLists.txt create mode 100644 sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl create mode 100644 sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl create mode 100644 sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl create mode 100644 sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl diff --git a/sbncode/SBNEventWeight/App/CMakeLists.txt b/sbncode/SBNEventWeight/App/CMakeLists.txt index 2989659b7..335a19557 100644 --- a/sbncode/SBNEventWeight/App/CMakeLists.txt +++ b/sbncode/SBNEventWeight/App/CMakeLists.txt @@ -1,8 +1,11 @@ cet_build_plugin(SBNEventWeight art::module LIBRARIES - sbnobj::Common_SBNEventWeight sbncode_SBNEventWeight_Base + sbnobj::Common_SBNEventWeight + sbncode_SBNEventWeight_Base sbncode_SBNEventWeight_Calculators_CrossSection - sbncode_SBNEventWeight_Calculators_BNBFlux nusimdata::SimulationBase + sbncode_SBNEventWeight_Calculators_BNBFlux + sbncode_SBNEventWeight_Calculators_Geant4 + nusimdata::SimulationBase ROOT::Geom) cet_build_plugin(SystToolsEventWeight art::module diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 8b4736aa0..0ed593b04 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -93,11 +93,8 @@ class Geant4WeightCalc : public WeightCalc { DECLARE_WEIGHTCALC(Geant4WeightCalc) }; -} // namespace evwgh - -} // namespace sbn -void sbn::evwgh::Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, +void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, CLHEP::HepRandomEngine& engine) { std::cout << "Using Geant4WeightCalc for reinteraction weights" << std::endl; @@ -225,8 +222,7 @@ void sbn::evwgh::Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, } -std::vector -sbn::evwgh::Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { +std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Get event/run/subrun numbers for output run_num = e.run(); @@ -486,4 +482,8 @@ return weight; } -REGISTER_WEIGHTCALC(sbn::evwgh::Geant4WeightCalc) +REGISTER_WEIGHTCALC(Geant4WeightCalc) + +} // namespace evwgh + +} // namespace sbn diff --git a/sbncode/SBNEventWeight/jobs/CMakeLists.txt b/sbncode/SBNEventWeight/jobs/CMakeLists.txt index e36b8b0cc..b5aae6724 100644 --- a/sbncode/SBNEventWeight/jobs/CMakeLists.txt +++ b/sbncode/SBNEventWeight/jobs/CMakeLists.txt @@ -5,4 +5,5 @@ install_source() add_subdirectory(SystTools) add_subdirectory(genie) add_subdirectory(flux) +add_subdirectory(geant4) diff --git a/sbncode/SBNEventWeight/jobs/geant4/CMakeLists.txt b/sbncode/SBNEventWeight/jobs/geant4/CMakeLists.txt new file mode 100644 index 000000000..589bc695a --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/CMakeLists.txt @@ -0,0 +1,6 @@ +install_fhicl() + +FILE(GLOB fcl_files *.fcl) + +install_source( EXTRAS ${fcl_files} ) + diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl new file mode 100644 index 000000000..d08990c2c --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl @@ -0,0 +1,99 @@ +########################################################## +## Hadron reinteraction uncertainties +## +## References: +## +## * K. Duffy, Pion Secondary Interaction Systematics (from GEANTReweight), DocDB 25379 +## * J. Calcutt, GEANTReweight documentation DocDB 25084, repository https://cdcvs.fnal.gov/redmine/projects/geant4reweight/repository +## +## From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 +## (uBooNE author: Kirsty Duffy (kduffy@fnal.gov)) +## +########################################################## + +#include "piplus_reweight_parameters.fcl" +#include "piminus_reweight_parameters.fcl" +#include "proton_reweight_parameters.fcl" + +geant4weight_sbn: { + module_type: "SBNEventWeight" + AllowMissingTruth: true + min_weight: 0.0 + max_weight: 100 + + weight_functions_reint: [ reinteractions_piplus, reinteractions_piminus, reinteractions_proton ] + + reinteractions_piplus: { + type: Geant4 + random_seed: 58 + parameters: @local::PiPlusParameters + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piplus.root" + xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_piplus.root" + makeoutputtree: false + pdg_to_reweight: 211 + debug: false + } + + reinteractions_piminus: { + type: Geant4 + random_seed: 59 + parameters: @local::PiMinusParameters + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piminus.root" + xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_piminus.root" + makeoutputtree: false + pdg_to_reweight: -211 + debug: false + } + + reinteractions_proton: { + type: Geant4 + random_seed: 60 + parameters: @local::ProtonParameters + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_proton.root" + makeoutputtree: false + pdg_to_reweight: 2212 + debug: false + } +} + +### +# Reweighting parameters should be defined as +# +# TheParameters: [ +# { +# Cut: "reac" +# Name: "fReacLow" +# Range: [10., 200.] +# Nominal: 1.0 +# Sigma: 0.3 +# }, +# {...} +# ] +# +# - Range defines the energy range over which that parameter has an effect (MeV) +# - Nominal is not used in "multisim" mode. In "pm1sigma" mode it defines the +# nominal (around which you calculate +/- 1 sigma variations). In any other +# mode, the parameter is set to the value under Nominal (so it's not really a +# "nominal" value in that case, just the set value) +# - Sigma defines the 1-sigma range for multisims and unisims. Currently the +# code can only accept a single value for sigma, giving symmetric +# uncertainty bounds: nominal-sigma and nominal+sigma +# - Cut must be one of the following: +# "reac" <- total inelastic scattering cross section +# "abs" <- absorption cross section (pi+ and pi- only at the moment -- Oct 2019) +# "cex" <- charge exchange cross section (pi+ and pi- only at the moment -- Oct 2019) +# "dcex" <- double charge exchange cross section (pi+ and pi- only at the moment -- Oct 2019) +# "prod" <- pion production cross section (pi+ and pi- only at the moment -- Oct 2019) +# "inel" <- quasi-elastic inelastic scattering cross section (pi+ and pi- only at the moment -- Oct 2019) +# "elast" <- total elastic scattering cross section +# - Name can be anything you like (but should uniquely identify that parameter/ +# variation) +### + diff --git a/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl new file mode 100644 index 000000000..b64756415 --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl @@ -0,0 +1,66 @@ +BEGIN_PROLOG + +# From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 + +PiMinusParameters: [ + { + Name: "fPiMinusReacLow" + Cut: "reac" + Range: [10., 200.] + Nominal: 1 + Sigma: 0.2 + } , + { + Name: "fPiMinusReacHigh" + Cut: "reac" + Range: [700., 2005.] + Nominal: 1.0 + Sigma: 0.2 + } , + + { + Name: "fPiMinusAbs" + Cut: "abs" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiMinusCex" + Cut: "cex" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiMinusDCex" + Cut: "dcex" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiMinusPiProd" + Cut: "prod" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiMinusElast" + Cut: "elast" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + } +] + +END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl new file mode 100644 index 000000000..c9cfc3e23 --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl @@ -0,0 +1,66 @@ +BEGIN_PROLOG + +# From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 + +PiPlusParameters: [ + { + Name: "fPiPlusReacLow" + Cut: "reac" + Range: [10., 200.] + Nominal: 1 + Sigma: 0.2 + } , + { + Name: "fPiPlusReacHigh" + Cut: "reac" + Range: [700., 2005.] + Nominal: 1.0 + Sigma: 0.2 + } , + + { + Name: "fPiPlusAbs" + Cut: "abs" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiPlusCex" + Cut: "cex" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiPlusDCex" + Cut: "dcex" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiPlusPiProd" + Cut: "prod" + # Range: [200.0, 700.00] + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + }, + + { + Name: "fPiPlusElast" + Cut: "elast" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + } +] + +END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl new file mode 100644 index 000000000..13113db75 --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl @@ -0,0 +1,23 @@ +BEGIN_PROLOG + +# From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 + +ProtonParameters: [ + { + Name: "fProtonReac" + Cut: "reac" + Range: [10., 2005.] + Nominal: 1 + Sigma: 0.2 + }, + + { + Name: "fProtonElast" + Cut: "elast" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + } +] + +END_PROLOG From 82c781cbdeb59c339d4b0d615d74e0c9581f1cfc Mon Sep 17 00:00:00 2001 From: Andrew Mastbaum Date: Thu, 27 Jul 2023 13:40:59 -0500 Subject: [PATCH 004/367] g4reweight bugfix and temporary parameter storage * Placeholder for sampled parameter storage, for CAF compatibility. * Renamed fcl for consistency --- fcl/caf/cafmaker_common_defs.fcl | 2 ++ .../SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx | 7 +++++-- ...ntweight_g4rwt_reint.fcl => eventweight_geant4_sbn.fcl} | 6 +++++- 3 files changed, 12 insertions(+), 3 deletions(-) rename sbncode/SBNEventWeight/jobs/geant4/{eventweight_g4rwt_reint.fcl => eventweight_geant4_sbn.fcl} (98%) diff --git a/fcl/caf/cafmaker_common_defs.fcl b/fcl/caf/cafmaker_common_defs.fcl index 66fcdf7ab..b4d45abbf 100644 --- a/fcl/caf/cafmaker_common_defs.fcl +++ b/fcl/caf/cafmaker_common_defs.fcl @@ -1,3 +1,4 @@ +#include "eventweight_geant4_sbn.fcl" #include "eventweight_genie_sbn.fcl" #include "eventweight_flux_sbn.fcl" @@ -15,6 +16,7 @@ cafmaker_common_producers: { rns: { module_type: "RandomNumberSaver" } genieweight: @local::sbn_eventweight_genie fluxweight: @local::sbn_eventweight_flux + geant4weight: @local::sbn_eventweight_geant4 } END_PROLOG diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 0ed593b04..de2dda819 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -165,6 +165,8 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, std::vector FitParSigmas; std::map theNominals; + fParameterSet.Configure(GetFullName(), mode, fNsims); + for (size_t i_parset=0; i_parset("Name"); @@ -176,6 +178,8 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, FitParSigmas.push_back(theSigma); theNominals[theName] = theNominal; + + fParameterSet.AddParameter(theName, theSigma); } if (mode=="pm1sigma"){ @@ -240,7 +244,7 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Initialize weight vector for this MCTruth weight.clear(); - weight.resize(1.0); + weight.resize(fNsims, 1.0); // Loop over MCParticles in the event auto const& mcparticles = truthParticles.at(itruth); @@ -431,7 +435,6 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { ParMaker->SetNewVals(UniverseVals.at(j)); theReweighter->SetNewHists(ParMaker->GetFSHists()); theReweighter->SetNewElasticHists(ParMaker->GetElasticHist()); - //Get the weight from the G4ReweightTraj w = theReweighter->GetWeight( &theTraj ); // Total weight is the product of track weights in the event diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl similarity index 98% rename from sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl rename to sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index d08990c2c..e45065880 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_g4rwt_reint.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -15,7 +15,9 @@ #include "piminus_reweight_parameters.fcl" #include "proton_reweight_parameters.fcl" -geant4weight_sbn: { +BEGIN_PROLOG + +sbn_eventweight_geant4: { module_type: "SBNEventWeight" AllowMissingTruth: true min_weight: 0.0 @@ -97,3 +99,5 @@ geant4weight_sbn: { # variation) ### +END_PROLOG + From 47810c44af32287061351cf050ca067b3dbf803d Mon Sep 17 00:00:00 2001 From: gputnam Date: Sat, 21 Oct 2023 20:50:57 -0500 Subject: [PATCH 005/367] Include Geant4 libraries for buiding --- sbncode/SBNEventWeight/CMakeLists.txt | 3 +++ sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt | 1 + 2 files changed, 4 insertions(+) diff --git a/sbncode/SBNEventWeight/CMakeLists.txt b/sbncode/SBNEventWeight/CMakeLists.txt index de59387f6..9f4018c28 100644 --- a/sbncode/SBNEventWeight/CMakeLists.txt +++ b/sbncode/SBNEventWeight/CMakeLists.txt @@ -1,3 +1,6 @@ +include_directories ( $ENV{GEANT4REWEIGHT_INC} ) +link_directories ( $ENV{GEANT4REWEIGHT_LIB} ) + add_subdirectory(Base) add_subdirectory(Calculators) add_subdirectory(App) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt index f05f8d274..568ecc7f6 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt +++ b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt @@ -1,5 +1,6 @@ include_directories ( $ENV{GEANT4_FQ_DIR}/include ) include_directories ( $ENV{GEANT4REWEIGHT_INC} ) +link_directories ( $ENV{GEANT4REWEIGHT_LIB} ) art_make_library( LIBRARY_NAME sbncode_SBNEventWeight_Calculators_Geant4 From 0509def6c3c4ca29537c21364e96c7cfc82d03eb Mon Sep 17 00:00:00 2001 From: Jack Smedley Date: Tue, 23 Jul 2024 19:40:50 -0500 Subject: [PATCH 006/367] Added G4ReweightManager and collapsed elastic and inelastic weights into one, successfully compiled --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index de2dda819..401c08896 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -33,6 +33,7 @@ #include "sbncode/SBNEventWeight/Base/WeightCalcCreator.h" #include "sbncode/SBNEventWeight/Base/WeightCalc.h" #include "larcore/Geometry/Geometry.h" +#include "geant4reweight/ReweightBase/G4ReweightManager.hh" #include "geant4reweight/ReweightBase/G4ReweighterFactory.hh" #include "geant4reweight/ReweightBase/G4Reweighter.hh" #include "geant4reweight/ReweightBase/G4ReweightTraj.hh" @@ -62,7 +63,8 @@ class Geant4WeightCalc : public WeightCalc { unsigned fNsims; //!< Number of multisims int fPdg; //!< PDG value for particles that a given weight calculator should apply to. Note that for now this module can only handle weights for one particle species at a time. // float fXSUncertainty; //!< Flat cross section uncertainty - G4ReweighterFactory RWFactory; //!< Base class to handle all Geant4Reweighters (right now "all" means pi+, pi-, p) + G4ReweightManager *RWManager; //!< "holds the run manager and creates the detector" according to the commit message (?) + G4ReweighterFactory RWFactory; //!< Base class to handle all Geant4Reweighters G4Reweighter *theReweighter; //!< Geant4Reweighter -- this is what provides the weights G4ReweightParameterMaker *ParMaker; std::vector> UniverseVals; //!< Vector of maps relating parameter name to value (defines parameter values that will be evaluated in universes). Each map should have one entry per parameter we are considering @@ -85,8 +87,12 @@ class Geant4WeightCalc : public WeightCalc { std::vector< double > p_energies_inel; //!< Variables for by-particle output tree std::vector< int > p_sliceInts_inel; //!< Variables for by-particle output tree int p_nElasticScatters; //!< Variables for by-particle output tree - std::vector p_inel_weight; //!< Variables for by-particle output tree - std::vector p_elastic_weight; //!< Variables for by-particle output + std::vector p_weight; //!< Variables for by-particle output tree + + + // **IF** I understand correctly, then after commit 11077f2 (el_weight*inel_weight) is returned by GetWeight() + //std::vector p_inel_weight; //!< Variables for by-particle output tree + //std::vector p_elastic_weight; //!< Variables for by-particle output bool fDebug; //!< print debug statements @@ -121,10 +127,9 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, TFile XSecFile( XSecFileName.c_str(), "OPEN" ); // Configure G4Reweighter - bool totalonly = false; - if (fPdg==2212) totalonly = true; - ParMaker = new G4ReweightParameterMaker( FitParSets, totalonly ); - theReweighter = RWFactory.BuildReweighter(fPdg, &XSecFile, &FracsFile, ParMaker->GetFSHists(), ParMaker->GetElasticHist() ); + ParMaker = new G4ReweightParameterMaker( FitParSets, true , fPdg ); //TODO:Do we want check_overlap? Maybe a fcl switch? + RWManager = new G4ReweightManager( FitParSets ); + theReweighter = RWFactory.BuildReweighter(fPdg, &FracsFile, ParMaker->GetFSHists(), pset, RWManager, ParMaker->GetElasticHist() ); // Make output trees to save things for quick and easy validation art::ServiceHandle tfs; @@ -136,8 +141,10 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, fOutTree_Particle->Branch("subrun_num",&subrun_num); fOutTree_Particle->Branch("UniverseVals", &UniverseVals); fOutTree_Particle->Branch("pdg_to_reweight",&fPdg); - fOutTree_Particle->Branch("inelastic_weight",&p_inel_weight); - fOutTree_Particle->Branch("elastic_weight",&p_elastic_weight); + + fOutTree_Particle->Branch("weight",&p_weight); + //fOutTree_Particle->Branch("inelastic_weight",&p_inel_weight); + //fOutTree_Particle->Branch("elastic_weight",&p_elastic_weight); fOutTree_Particle->Branch("track_length",&p_track_length); fOutTree_Particle->Branch("PDG",&p_PDG); fOutTree_Particle->Branch("final_proc",&p_final_proc); @@ -252,10 +259,12 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { for (size_t i=0; i Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Loop through universes (j) for (size_t j=0; jSetNewVals(UniverseVals.at(j)); @@ -440,6 +449,10 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Total weight is the product of track weights in the event weight[j] *= std::max((float)0.0, w); + // just for the output tree + p_weight[j] = w; + +/* // Do the same for elastic weight (should be 1 unless set to non-nominal ) el_w = theReweighter->GetElasticWeight( &theTraj ); weight[j] *= std::max((float)0.0,el_w); @@ -453,12 +466,13 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // std::cout << UniverseVals.at(j) << std::endl; std::cout << " w = " << w << ", el_w = " << el_w << std::endl; } - +*/ } // loop through universes (j) if (fDebug){ std::cout << "PDG = " << p_PDG << std::endl; +/* std::cout << "inel weights by particle: "; for (unsigned int j=0; j Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { for (unsigned int j=0; j Date: Thu, 25 Jul 2024 20:16:24 -0500 Subject: [PATCH 007/367] Add material input; This build ~works~ as long as you only run one particle type at time --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 26 ++++++++++--------- .../jobs/geant4/eventweight_geant4_sbn.fcl | 20 +++++++++----- .../jobs/geant4/material_parameters.fcl | 18 +++++++++++++ 3 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 sbncode/SBNEventWeight/jobs/geant4/material_parameters.fcl diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 401c08896..dd200f14c 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -59,14 +59,15 @@ class Geant4WeightCalc : public WeightCalc { std::string fMCParticleProducer; //!< Label for the MCParticle producer std::string fMCTruthProducer; //!< Label for the MCTruth producer CLHEP::RandGaussQ* fGaussRandom; //!< Random number generator + fhicl::ParameterSet fMaterial; //!< Detector material, i.e. LAr // std::map fParticles; //!< Particles to reweight unsigned fNsims; //!< Number of multisims int fPdg; //!< PDG value for particles that a given weight calculator should apply to. Note that for now this module can only handle weights for one particle species at a time. // float fXSUncertainty; //!< Flat cross section uncertainty - G4ReweightManager *RWManager; //!< "holds the run manager and creates the detector" according to the commit message (?) - G4ReweighterFactory RWFactory; //!< Base class to handle all Geant4Reweighters - G4Reweighter *theReweighter; //!< Geant4Reweighter -- this is what provides the weights - G4ReweightParameterMaker *ParMaker; + G4ReweightManager *fRWManager; //!< "holds the run manager and creates the detector" according to the commit message (?) + G4ReweighterFactory fRWFactory; //!< Base class to handle all Geant4Reweighters + G4Reweighter *fReweighter; //!< Geant4Reweighter -- this is what provides the weights + G4ReweightParameterMaker *fParMaker; std::vector> UniverseVals; //!< Vector of maps relating parameter name to value (defines parameter values that will be evaluated in universes). Each map should have one entry per parameter we are considering art::ServiceHandle < geo::Geometry > fGeometryService; @@ -117,6 +118,7 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, std::vector< fhicl::ParameterSet > FitParSets = pset.get< std::vector< fhicl::ParameterSet > >("parameters"); fNsims = pset.get ("number_of_multisims", 0); fPdg = pset.get ("pdg_to_reweight"); + fMaterial = pset.get ("material"); fDebug = pset.get ("debug",false); // Prepare random generator @@ -127,9 +129,9 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, TFile XSecFile( XSecFileName.c_str(), "OPEN" ); // Configure G4Reweighter - ParMaker = new G4ReweightParameterMaker( FitParSets, true , fPdg ); //TODO:Do we want check_overlap? Maybe a fcl switch? - RWManager = new G4ReweightManager( FitParSets ); - theReweighter = RWFactory.BuildReweighter(fPdg, &FracsFile, ParMaker->GetFSHists(), pset, RWManager, ParMaker->GetElasticHist() ); + fParMaker = new G4ReweightParameterMaker( FitParSets, true , fPdg ); //TODO:Do we want check_overlap? Maybe a fcl switch? + fRWManager = new G4ReweightManager( {fMaterial} ); //Constructor asks for a vector, but SBN only cares about one material + fReweighter = fRWFactory.BuildReweighter(fPdg, &FracsFile, fParMaker->GetFSHists(), fMaterial, fRWManager, fParMaker->GetElasticHist() ); // Make output trees to save things for quick and easy validation art::ServiceHandle tfs; @@ -441,11 +443,11 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { float w/*, el_w*/; // I think this is the only bit that needs to change for different universes -- all the above is jut about the track, which doesn't change based on universe - ParMaker->SetNewVals(UniverseVals.at(j)); - theReweighter->SetNewHists(ParMaker->GetFSHists()); - theReweighter->SetNewElasticHists(ParMaker->GetElasticHist()); + fParMaker->SetNewVals(UniverseVals.at(j)); + fReweighter->SetNewHists(fParMaker->GetFSHists()); + fReweighter->SetNewElasticHists(fParMaker->GetElasticHist()); //Get the weight from the G4ReweightTraj - w = theReweighter->GetWeight( &theTraj ); + w = fReweighter->GetWeight( &theTraj ); // Total weight is the product of track weights in the event weight[j] *= std::max((float)0.0, w); @@ -454,7 +456,7 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { /* // Do the same for elastic weight (should be 1 unless set to non-nominal ) - el_w = theReweighter->GetElasticWeight( &theTraj ); + el_w = fReweighter->GetElasticWeight( &theTraj ); weight[j] *= std::max((float)0.0,el_w); // just for the output tree diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index e45065880..997b40157 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -14,6 +14,7 @@ #include "piplus_reweight_parameters.fcl" #include "piminus_reweight_parameters.fcl" #include "proton_reweight_parameters.fcl" +#include "material_parameters.fcl" BEGIN_PROLOG @@ -23,48 +24,53 @@ sbn_eventweight_geant4: { min_weight: 0.0 max_weight: 100 - weight_functions_reint: [ reinteractions_piplus, reinteractions_piminus, reinteractions_proton ] + weight_functions_reint: [ reinteractions_piplus] #, reinteractions_piminus, reinteractions_proton ] reinteractions_piplus: { type: Geant4 + material: @local::LAr random_seed: 58 parameters: @local::PiPlusParameters mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piplus.root" xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_piplus.root" - makeoutputtree: false + makeoutputtree: true pdg_to_reweight: 211 - debug: false + debug: true } reinteractions_piminus: { type: Geant4 + material: @local::LAr random_seed: 59 parameters: @local::PiMinusParameters mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piminus.root" xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_piminus.root" - makeoutputtree: false + makeoutputtree: true pdg_to_reweight: -211 - debug: false + debug: true } reinteractions_proton: { type: Geant4 + material: @local::LAr random_seed: 60 parameters: @local::ProtonParameters mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_proton.root" - makeoutputtree: false + makeoutputtree: true pdg_to_reweight: 2212 - debug: false + debug: true } } +# reinteractions_neutron + ### # Reweighting parameters should be defined as # diff --git a/sbncode/SBNEventWeight/jobs/geant4/material_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/material_parameters.fcl new file mode 100644 index 000000000..ed735621f --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/material_parameters.fcl @@ -0,0 +1,18 @@ +BEGIN_PROLOG + +# LAr parameters for geant4reweight, stolen out of the ND-Lar 2x2 implementation +# A more complete solution would be to get this info out of the geometry instead... + +LAr: { + Name: "liquidArgon" + Density: 1.390 + Components: [ + { + Z: 18 + Mass: 39.95 + Fraction: 1. + } + ] +} + +END_PROLOG From 5a02db64b0da60edc07af46ade92db2f82b9471a Mon Sep 17 00:00:00 2001 From: Jack Smedley Date: Fri, 26 Jul 2024 19:37:13 -0500 Subject: [PATCH 008/367] Iitialize G4ReweightManager as static so only one G4RunManager is started --- .../SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx | 5 ++--- .../SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index dd200f14c..ebb5ad44d 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -64,7 +64,6 @@ class Geant4WeightCalc : public WeightCalc { unsigned fNsims; //!< Number of multisims int fPdg; //!< PDG value for particles that a given weight calculator should apply to. Note that for now this module can only handle weights for one particle species at a time. // float fXSUncertainty; //!< Flat cross section uncertainty - G4ReweightManager *fRWManager; //!< "holds the run manager and creates the detector" according to the commit message (?) G4ReweighterFactory fRWFactory; //!< Base class to handle all Geant4Reweighters G4Reweighter *fReweighter; //!< Geant4Reweighter -- this is what provides the weights G4ReweightParameterMaker *fParMaker; @@ -130,8 +129,8 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, // Configure G4Reweighter fParMaker = new G4ReweightParameterMaker( FitParSets, true , fPdg ); //TODO:Do we want check_overlap? Maybe a fcl switch? - fRWManager = new G4ReweightManager( {fMaterial} ); //Constructor asks for a vector, but SBN only cares about one material - fReweighter = fRWFactory.BuildReweighter(fPdg, &FracsFile, fParMaker->GetFSHists(), fMaterial, fRWManager, fParMaker->GetElasticHist() ); + static G4ReweightManager* RWManager = new G4ReweightManager( {fMaterial} ); //Constructor asks for a vector, but SBN only cares about one material + fReweighter = fRWFactory.BuildReweighter(fPdg, &FracsFile, fParMaker->GetFSHists(), fMaterial, RWManager, fParMaker->GetElasticHist() ); // Make output trees to save things for quick and easy validation art::ServiceHandle tfs; diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index 997b40157..aa565bf9e 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -24,7 +24,7 @@ sbn_eventweight_geant4: { min_weight: 0.0 max_weight: 100 - weight_functions_reint: [ reinteractions_piplus] #, reinteractions_piminus, reinteractions_proton ] + weight_functions_reint: [ reinteractions_piplus , reinteractions_piminus, reinteractions_proton ] reinteractions_piplus: { type: Geant4 From afc823dc080b4e2eea40f995bfc72d39f629bebb Mon Sep 17 00:00:00 2001 From: Jack Smedley Date: Thu, 1 Aug 2024 15:23:14 -0500 Subject: [PATCH 009/367] Add neutron and kaon parameters, remove dependence on input XS file --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 4 +- .../jobs/geant4/eventweight_geant4_sbn.fcl | 49 +++++++++++++++++-- .../geant4/kminus_reweight_parameters.fcl | 21 ++++++++ .../jobs/geant4/kplus_reweight_parameters.fcl | 21 ++++++++ .../geant4/neutron_reweight_parameters.fcl | 21 ++++++++ 5 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl create mode 100644 sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl create mode 100644 sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index ebb5ad44d..16d684f72 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -113,7 +113,6 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, fMakeOutputTrees = pset.get< bool >( "makeoutputtree", false ); std::string mode = pset.get("mode"); std::string FracsFileName = pset.get< std::string >( "fracsfile" ); - std::string XSecFileName = pset.get< std::string >( "xsecfile" ); std::vector< fhicl::ParameterSet > FitParSets = pset.get< std::vector< fhicl::ParameterSet > >("parameters"); fNsims = pset.get ("number_of_multisims", 0); fPdg = pset.get ("pdg_to_reweight"); @@ -123,9 +122,8 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, // Prepare random generator fGaussRandom = new CLHEP::RandGaussQ(engine); - // Get input files + // Get input file TFile FracsFile( FracsFileName.c_str(), "OPEN" ); - TFile XSecFile( XSecFileName.c_str(), "OPEN" ); // Configure G4Reweighter fParMaker = new G4ReweightParameterMaker( FitParSets, true , fPdg ); //TODO:Do we want check_overlap? Maybe a fcl switch? diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index aa565bf9e..6711f56d5 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -14,6 +14,10 @@ #include "piplus_reweight_parameters.fcl" #include "piminus_reweight_parameters.fcl" #include "proton_reweight_parameters.fcl" +#include "neutron_reweight_parameters.fcl" +#include "kplus_reweight_parameters.fcl" +#include "kminus_reweight_parameters.fcl" + #include "material_parameters.fcl" BEGIN_PROLOG @@ -24,7 +28,7 @@ sbn_eventweight_geant4: { min_weight: 0.0 max_weight: 100 - weight_functions_reint: [ reinteractions_piplus , reinteractions_piminus, reinteractions_proton ] + weight_functions_reint: [ reinteractions_piplus , reinteractions_piminus, reinteractions_proton , reinteractions_neutron , reinteractions_kplus , reinteractions_kminus ] reinteractions_piplus: { type: Geant4 @@ -34,7 +38,6 @@ sbn_eventweight_geant4: { mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piplus.root" - xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_piplus.root" makeoutputtree: true pdg_to_reweight: 211 debug: true @@ -48,7 +51,6 @@ sbn_eventweight_geant4: { mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piminus.root" - xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_piminus.root" makeoutputtree: true pdg_to_reweight: -211 debug: true @@ -62,11 +64,50 @@ sbn_eventweight_geant4: { mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" - xsecfile: "$SBNDATA_DIR/systematics/reint/g4_cross_section_proton.root" makeoutputtree: true pdg_to_reweight: 2212 debug: true } + + reinteractions_neutron: { + type: Geant4 + material: @local::LAr + random_seed: 60 + parameters: @local::NeutronParameters + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + makeoutputtree: true + pdg_to_reweight: 2112 + debug: true + } + + reinteractions_kplus: { + type: Geant4 + material: @local::LAr + random_seed: 60 + parameters: @local::KPlusParameters + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + makeoutputtree: true + pdg_to_reweight: 321 + debug: true + } + + reinteractions_kminus: { + type: Geant4 + material: @local::LAr + random_seed: 60 + parameters: @local::KMinusParameters + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + makeoutputtree: true + pdg_to_reweight: -321 + debug: true + } + } # reinteractions_neutron diff --git a/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl new file mode 100644 index 000000000..3713f0183 --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl @@ -0,0 +1,21 @@ +BEGIN_PROLOG + +KMinusParameters: [ + { + Name: "fKMinusReac" + Cut: "reac" + Range: [10., 2005.] + Nominal: 1 + Sigma: 0.2 + }, + + { + Name: "fKMinusElast" + Cut: "elast" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + } +] + +END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl new file mode 100644 index 000000000..b426eb6bd --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl @@ -0,0 +1,21 @@ +BEGIN_PROLOG + +KPlusParameters: [ + { + Name: "fKPlusReac" + Cut: "reac" + Range: [10., 2005.] + Nominal: 1 + Sigma: 0.2 + }, + + { + Name: "fKPlusElast" + Cut: "elast" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + } +] + +END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl new file mode 100644 index 000000000..a5c462d84 --- /dev/null +++ b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl @@ -0,0 +1,21 @@ +BEGIN_PROLOG + +NeutronParameters: [ + { + Name: "fNeutronReac" + Cut: "reac" + Range: [10., 2005.] + Nominal: 1 + Sigma: 0.2 + }, + + { + Name: "fNeutronElast" + Cut: "elast" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 + } +] + +END_PROLOG From 1df323461441deb1801aeff852b0c2addbedbc9c Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Wed, 9 Oct 2024 14:50:43 -0500 Subject: [PATCH 010/367] initial commit --- .../BNBRetriever/SBNDBNBDefaults.fcl | 22 + .../BNBRetriever/SBNDBNB_module.cc | 601 ++++++++++++++++++ .../BNBRetriever/runbnb.fcl | 31 + 3 files changed, 654 insertions(+) create mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc create mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl new file mode 100644 index 000000000..9ee036aac --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl @@ -0,0 +1,22 @@ +BEGIN_PROLOG + +SBNDBNBDefaults: { + module_type: SBNDBNB + InputLabel: "bnb" + InputContainerInstance: "ContainerBNB" + InputNonContainerInstance: "BNB" + OutputInstance: "" + DebugLevel: 0 + TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away + URL: "" #https://dbdata3vm.fnal.gov:9443/ifbeam + Bundle: "BoosterNeutrinoBeam_read" + MultiWireBundle: "BNBMultiWire" + TimeWindow: "700" #seconds + MWR_TimeWindow: "3601" #seconds + RawDataLabel: "ptbdecoder" + DeviceUsedForTiming: "E:TOR860" + TriggerDatabaseFile: "triggerDatabase/icarus_triggers.db" +} + +END_PROLOG + diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc new file mode 100644 index 000000000..934065d73 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc @@ -0,0 +1,601 @@ +//////////////////////////////////////////////////////////////////////// +// Class: SBNDBNB +// Plugin Type: producer +// File: SBNDBNB_module.cc +// +//////////////////////////////////////////////////////////////////////// + +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +#include +#include +#include + +#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" +#include "artdaq-core/Data/ContainerFragment.hh" +#include "sbndcode/Decoders/PTB/sbndptb.h" +#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" + +#include "ifdh_art/IFBeamService/IFBeam_service.h" +#include "ifbeam_c.h" +#include "MWRData.h" + +#include "larcorealg/CoreUtils/counter.h" + +class SBNDBNB : public art::EDProducer { +public: + explicit SBNDBNB(fhicl::ParameterSet const & params); + + // Plugins should not be copied or assigned. + SBNDBNB(SBNDBNB const &) = delete; + SBNDBNB(SBNDBNB &&) = delete; + SBNDBNB & operator = (SBNDBNB const &) = delete; + SBNDBNB & operator = (SBNDBNB &&) = delete; + + // Required functions. + void produce(art::Event & e) override; + void beginSubRun(art::SubRun& sr) override; + void endSubRun(art::SubRun& sr) override; + +private: + // Declare member data here. + std::vector< sbn::BNBSpillInfo > fOutbeamInfos; + double fTimePad; + std::string fInputLabel; + std::string fInputNonContainerInstance; + std::string fDeviceUsedForTiming; + std::string fOutputInstance; + std::string raw_data_label; + int fDebugLevel; + sbn::MWRData mwrdata; + art::ServiceHandle ifbeam_handle; + std::unique_ptr bfp; + std::unique_ptr bfp_mwr; + + struct TriggerInfo_t { + int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI + double t_current_event = 0; + double t_previous_event = 0; + unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type + std::int64_t WR_to_Spill_conversion = 0; + }; + + struct MWRdata_t { + std::vector< std::vector > MWR_times; + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + }; + + static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] + + TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; + int matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos + ) const; + + sbn::BNBSpillInfo makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; +}; + +SBNDBNB::SBNDBNB(fhicl::ParameterSet const & params) + : EDProducer{params} { + raw_data_label = params.get("RawDataLabel", "ptbdecoder"); + fInputLabel = params.get("InputLabel"); + fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); + fTimePad = params.get("TimePadding"); + fInputNonContainerInstance = params.get("InputNonContainerInstance"); + fOutputInstance = params.get("OutputInstance"); + fDebugLevel = params.get("DebugLevel",0); + bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); + bfp->set_epsilon(0.05); + bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); + bfp_mwr->set_epsilon(0.5); + bfp_mwr->setValidWindow(3605); +} + +int eventNum =0; +int _run; +int _subrun; +int _event; + +void SBNDBNB::produce(art::Event & e) +{ + + // If this is the first event in the run, then ignore it + // We do not currently have the ability to figure out the first + // spill that the DAQ was sensitive to, so don't try to save any + // spill information + +/* + art::InputTag ptb_tag { "ptbdecoder" }; + auto const& ptb_handle = e.getValidHandle< std::vector >(ptb_tag); + auto const& ptb_vec(*ptb_handle); + int ptb_size = ptb_vec.size(); + int NHL_trig; + if(ptb_size > 0){ + for (int j = 0; j < ptb_size; j++){ + if(ptb_vec.at(j).GetNHLTriggers() > 0){ + NHL_trig = ptb_vec.at(j).GetNHLTriggers(); + for(int k = 0; k < NHL_trig; k++){ + ULong64_t trig_time = ptb_vec.at(j).GetHLTrigger(k).timestamp; + if(ptb_vec.at(j).GetHLTrigger(k).trigger_word != 1048576){ + ULong64_t curr_min = 1e19; + //int curr_min_ind; + std::cout << "Zero Bias Trigger" << std::endl; + try{ + //auto vec_temp = bfp_mwr->GetNamedVector(trig_time/1e9,"E:M875BB{4440:888}.RAW"); + auto vec_temp = bfp->GetNamedVector(trig_time/1e9,"E:TOR875"); + //std::vector times = bfp->GetTimeList("E:M875BB"); + std::vector times = bfp->GetTimeList("E:TOR875"); + int times_size = times.size(); + for (int i = 0; i < times_size; i++) { + if(times[i] < trig_time/1e9){ + if(trig_time/1e9 - times[i] < curr_min){ + curr_min = trig_time - times[i]; + std::cout << "trig_time: " << trig_time << std::endl; + //curr_min_ind = i; + } + } + } + }catch(WebAPIException &we){std::cout << "Failed GetNamedVector" << std::endl;} + } + else{ + std::cout << "CRT Reset Trigger" << std::endl; + } + } + } + } + } +*/ + //sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); + //fOutbeamInfos.push_back(std::move(spillInfo)); + + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + + std::cout << "Gate Type: " << triggerInfo.gate_type << std::endl; + + MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); + + int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); + + if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) + mf::LogDebug("BNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; + else + mf::LogDebug("BNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; +} + +SBNDBNB::TriggerInfo_t SBNDBNB::extractTriggerInfo(art::Event const& e) const { + //Here we read in the artdaq Fragments and extract three pieces of information: + // 1. The time of the current event, t_current_event + // 2. the time of the previously triggered event, t_previous_event (NOTE: Events are non-sequential!) + // 3. the number of beam spills since the previously triggered event, number_of_gates_since_previous_event + auto const & raw_data = e.getProduct< std::vector >({ "ptbdecoder", "" }); + TriggerInfo_t triggerInfo; + /// Correction added to the White Rabbit time to get the trigger time. + triggerInfo.WR_to_Spill_conversion = 0; + triggerInfo.gate_type = 1; + + int raw_data_size = raw_data.size(); + if(raw_data_size > 0){ + for (int j = 0; j < raw_data_size; j++){ + if(raw_data.at(j).GetNHLTriggers() > 0){ + int NHL_trig = raw_data.at(j).GetNHLTriggers(); + for(int k = 0; k < NHL_trig; k++){ + ULong64_t trig_time = raw_data.at(j).GetHLTrigger(k).timestamp; + if(raw_data.at(j).GetHLTrigger(k).trigger_word != 1048576){ + std::cout << "Zero Bias Trigger" << std::endl; + triggerInfo.t_current_event = trig_time/1e9; + triggerInfo.t_previous_event = trig_time/1e9 - 10; + + triggerInfo.number_of_gates_since_previous_event = 100; + } + else{ + std::cout << "CRT Reset Trigger" << std::endl; + } + } + } + } + } + return triggerInfo; +} + +SBNDBNB::MWRdata_t SBNDBNB::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { + + // These lines get everything primed within the IFBeamDB + // They seem redundant but they are needed + try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} + try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {std::cout << "caught 2" << std::endl;} + + //The multiwire chambers provide their + // data in a vector format but we'll have + // to sort through it in std::string format + // to correctly unpack it + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + std::vector< std::vector< double> > MWR_times; + unpacked_MWR.resize(3); + MWR_times.resize(3); + std::string packed_data_str; + + //Create a list of all the MWR devices with their different + // memory buffer increments + // generally in the format: "E:.{Memory Block}" + std::vector vars = bfp_mwr->GetDeviceList(); + mf::LogDebug("BNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; + // Tracking the time from the IFBeamDB + double time_for_mwr; + + // this is an iterator to track which of the + // three devices we will be working with + int dev = 0; + + // The MWR devices are annoying and have confusing buffer + // what we'll do is sort through all of them first and then + // match them to the closest spills in time + // + + // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; + int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; + mf::LogDebug("BNBRetriever") << " t_steps " << t_steps << std::endl; + + for(int t = 0; t < t_steps; t++){//Iterate through time increments + for (std::string const& var : vars) {// Iterate through the devices + + //Make sure we have a device + if(var.empty()){ + //mf::LogDebug("BNBRetriever") << " NO MWR DEVICES?!" << std::endl; + continue; + } + /// Check the device name and interate the double-vector index + if(var.find("M875BB") != std::string::npos ) dev = 0; + else if(var.find("M876BB") != std::string::npos ) dev = 1; + else if(var.find("MMBTBB") != std::string::npos ) dev = 2; + else{ + //mf::LogDebug("BNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; + continue;} + + time_for_mwr = 0; + + try{ + + //Pull the MWR data for the device + // these data are "packed" + std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); + + //We'll convert this into a format + // that we can unpack doubles >> strings + // + packed_data_str.clear(); + packed_data_str += std::to_string(int(time_for_mwr)); + packed_data_str.append(","); + packed_data_str.append(var); + packed_data_str.append(",,"); + + /* for(auto const value: packed_MWR){ + packed_data_str += ','; + packed_data_str += std::to_string(int(value)); + }*/ + for(int j = 0; j < int(packed_MWR.size()); j++){ + packed_data_str += std::to_string(int(packed_MWR[j])); + if(j < int(packed_MWR.size())-1) + packed_data_str.append(","); + } + + // Use Zarko's unpacking function to turn this into consumeable data + std::vector MWR_times_temp; + + // There is a 35 ms offset between the toriod and the MWR times + // we'll just remove that here to match to the spill times + std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); + + //There are four events that are packed into one MWR IFBeam entry + for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ + + // If this entry has a unique time them store it for later + if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ + unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); + MWR_times[dev].push_back(MWR_times_temp[s]); + }//check for unique time + }//Iterate through the unpacked events + }//try + catch (WebAPIException &we) { + //Ignore when we can't find the MWR devices + // they don't always report and the timing of them can be annoying + }//catch + }// Iterate over all the multiwire devices + }// Iterate over all times + + mf::LogDebug("BNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; + mf::LogDebug("BNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; + mf::LogDebug("BNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; + mf::LogDebug("BNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; + mf::LogDebug("BNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; + mf::LogDebug("BNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; + + return { std::move(MWR_times), std::move(unpacked_MWR) }; +} + +int SBNDBNB::matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos +) const { + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + //Here we will start collecting all the other beamline devices + // First we get the times that the beamline device fired + // we have to pick a specific variable to use + std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); + + mf::LogDebug("BNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; + + // We'll keep track of how many of these spills match to our + // DAQ trigger times + int spill_count = 0; + int spills_removed = 0; + std::vector matched_MWR; + matched_MWR.resize(3); + + std::cout << std::setprecision(19) << "t_current_event: " << triggerInfo.t_current_event << std::endl; + // NOTE: for now, this is dead code because we don't + // do anything for the first event in a run. We may want to revisit + // this later to understand if there is a way we can do the POT + // accounting in the first event. + // + // Need to handle the first event in a run differently + if(isFirstEventInRun){ + + //We'll remove the spills after our event + int spills_after_our_target = 0; + // iterate through all the spills to find the + // spills that are after our triggered event + for (size_t i = 0; i < times_temps.size(); i++) { + if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ + spills_after_our_target++; + } + }//end loop through spill times + + // Remove the spills after our trigger + times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); + + // Remove the spills before the start of our Run + times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); + + }//end fix for "first event" + + ///reject time_stamps which have a trigger_type == 1 from data-base + //To-Do + + // mf::LogDebug("BNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; + // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; + // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; + + // Iterating through each of the beamline times + for (size_t i = 0; i < times_temps.size(); i++) { + + // Only continue if these times are matched to our DAQ time + //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; + + std::cout << std::setprecision(19) << "times_temps[i]: " << times_temps[i] << std::endl; + if(!isFirstEventInRun){//We already addressed the "first event" above + if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ + //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + spills_removed++; + continue;} + if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ + spills_removed++; + //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + continue;} + } + + //check if this spill is is minbias + /* + 40 ms was selected to be close to but outside the 66 ms + time of the next spill (when the beam is running at 15 Hz) + DocDB 33155 provides documentation of this + */ + + // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; + + // if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ + // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; + + // continue; + //} + + //Great we found a matched spill! Let's count it + spill_count++; + + //Loop through the multiwire devices: + + for(int dev = 0; dev < int(MWR_times.size()); dev++){ + + //Loop through the multiwire times: + double Tdiff = 1000000000.; + matched_MWR[dev] = 0; + + for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ + + //found a candidate match! + if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} + + bool best_match = true; + + //Check for a better match... + for (size_t j = 0; j < times_temps.size(); j++) { + if( j == i) continue; + if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} + if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} + + //is there a better match later in the spill sequence + if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < + fabs((MWR_times[dev][mwrt] - times_temps[i]))){ + //we can have patience... + best_match = false; + break; + } + }//end better match check + + //Verified best match! + if(best_match == true){ + matched_MWR[dev] = mwrt; + Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); + } + + }//end loop over MWR times + + }//end loop over MWR devices + + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); + + beamInfos.push_back(std::move(spillInfo)); + + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + }//end iteration over beam device times + + // mf::LogDebug("BNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; + + return spill_count; +} + +sbn::BNBSpillInfo SBNDBNB::makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const +{ + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + // initializing all of our device carriers + // device definitions can be found in BNBSpillInfo.h + + double TOR860 = 0; // units e12 protons + double TOR875 = 0; // units e12 protons + double LM875A = 0; // units R/s + double LM875B = 0; // units R/s + double LM875C = 0; // units R/s + double HP875 = 0; // units mm + double VP875 = 0; // units mm + double HPTG1 = 0; // units mm + double VPTG1 = 0; // units mm + double HPTG2 = 0; // units mm + double VPTG2 = 0; // units mm + double BTJT2 = 0; // units Deg C + double THCURR = 0; // units kiloAmps + + double TOR860_time = 0; // units s + + // Here we request all the devices + // since sometimes devices fail to report we'll + // allow each to throw an exception but still move forward + // interpreting these failures will be part of the beam quality analyses + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + //crunch the times + unsigned long int time_closest_int = (int) TOR860_time; + double time_closest_ns = (TOR860_time - time_closest_int)*1e9; + + //Store everything in our data-product + sbn::BNBSpillInfo beamInfo; + beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.LM875A = LM875A; + beamInfo.LM875B = LM875B; + beamInfo.LM875C = LM875C; + beamInfo.HP875 = HP875; + beamInfo.VP875 = VP875; + beamInfo.HPTG1 = HPTG1; + beamInfo.VPTG1 = VPTG1; + beamInfo.HPTG2 = HPTG2; + beamInfo.VPTG2 = VPTG2; + beamInfo.BTJT2 = BTJT2; + beamInfo.THCURR = THCURR; + beamInfo.spill_time_s = time_closest_int; + beamInfo.spill_time_ns = time_closest_ns; + + std::cout << "TOR860: " << TOR860 << std::endl; + + for(auto const& MWRdata: unpacked_MWR){ + std::ignore = MWRdata; + assert(!MWRdata.empty()); + } + + if(unpacked_MWR[0].empty()){ + beamInfo.M875BB.clear(); + beamInfo.M875BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; + beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); + } + + if(unpacked_MWR[1].empty()){ + beamInfo.M876BB.clear(); + beamInfo.M876BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; + beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); + } + + if(unpacked_MWR[2].empty()){ + beamInfo.MMBTBB.clear(); + beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; + beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); + } + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun + + return beamInfo; +} + +void SBNDBNB::beginSubRun(art::SubRun& sr) +{ + return; +} + +void SBNDBNB::endSubRun(art::SubRun& sr) +{ + //mf::LogDebug("BNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; + //mf::LogDebug("BNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; + + //auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); + //std::swap(*p, fOutbeamInfos); + + //sr.put(std::move(p), art::subRunFragment()); + + return; +} + +DEFINE_ART_MODULE(SBNDBNB) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl b/sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl new file mode 100644 index 000000000..780b32bb3 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl @@ -0,0 +1,31 @@ +#include "SBNDBNBDefaults.fcl" + +services:{ + IFBeam:{} +} + +physics: +{ + producers: + { + bnb: @local::SBNDBNBDefaults + } + + analyzers: {} + + my_producer_modules: [bnb] + trigger_paths: [my_producer_modules] + a: [rootout] + end_paths: [a] +} + +source: {} + +outputs: { + rootout: { + module_type: "RootOutput" + fileName: "BNB_out.root" + } +} + +process_name: BNBTEST From 357c6e577630060c18f1ebc0f828de19cb91602b Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Thu, 10 Oct 2024 15:37:00 -0500 Subject: [PATCH 011/367] Develop change not in release 09_91_02_02 --- sbncode/CAFMaker/FillReco.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index a478bc840..0c35b8a59 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -119,8 +119,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Ts1(); - srspacepoint.time_err = spacepoint.Ts1Err(); + srspacepoint.time = spacepoint.Time(); + srspacepoint.time_err = spacepoint.TimeErr(); srspacepoint.complete = spacepoint.Complete(); } @@ -131,8 +131,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Ts1(); - srsbndcrttrack.time_err = track.Ts1Err(); + srsbndcrttrack.time = track.Time(); + srsbndcrttrack.time_err = track.TimeErr(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From b205ea95d76819e3d1bf3609c5eab5dfdc72ee9c Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Tue, 15 Oct 2024 13:50:05 -0500 Subject: [PATCH 012/367] Builds and runs --- .../BNBRetriever/CMakeLists.txt | 21 +++ .../BNBRetriever/SBNDBNBDefaults.fcl | 7 +- ...B_module.cc => SBNDBNBRetriever_module.cc} | 169 +++++++++--------- 3 files changed, 110 insertions(+), 87 deletions(-) rename sbncode/BeamSpillInfoRetriever/BNBRetriever/{SBNDBNB_module.cc => SBNDBNBRetriever_module.cc} (70%) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt index a34b60d6a..1f0dab80a 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt @@ -28,6 +28,27 @@ cet_build_plugin(BNBRetriever art::module larcorealg::CoreUtils ) +cet_build_plugin(SBNDBNBRetriever art::module + LIBRARIES + art::Persistency_Common + art::Utilities canvas::canvas + cetlib::cetlib cetlib_except::cetlib_except + ROOT::X3d + Boost::system + messagefacility::MF_MessageLogger + ifbeam::ifbeam + ifdh_art::IFBeam_service + SQLite::SQLite3 + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND + artdaq_core::artdaq-core_Utilities + sbn_BNBSpillInfoRetriever_MWRData + sbnobj::Common_POTAccounting + larcorealg::CoreUtils +) + install_headers() install_fhicl() install_source() diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl index 9ee036aac..03e3cdc87 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl @@ -1,21 +1,20 @@ BEGIN_PROLOG SBNDBNBDefaults: { - module_type: SBNDBNB + module_type: SBNDBNBRetriever InputLabel: "bnb" InputContainerInstance: "ContainerBNB" InputNonContainerInstance: "BNB" OutputInstance: "" DebugLevel: 0 TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - URL: "" #https://dbdata3vm.fnal.gov:9443/ifbeam + URL: "" Bundle: "BoosterNeutrinoBeam_read" MultiWireBundle: "BNBMultiWire" TimeWindow: "700" #seconds MWR_TimeWindow: "3601" #seconds - RawDataLabel: "ptbdecoder" + raw_data_label: "daq" DeviceUsedForTiming: "E:TOR860" - TriggerDatabaseFile: "triggerDatabase/icarus_triggers.db" } END_PROLOG diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc similarity index 70% rename from sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc rename to sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 934065d73..2ceaf32bc 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNB_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////// -// Class: SBNDBNB +// Class: SBNDBNBRetriever // Plugin Type: producer -// File: SBNDBNB_module.cc +// File: SBNDBNBRetriever_module.cc // //////////////////////////////////////////////////////////////////////// @@ -21,7 +21,7 @@ #include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" #include "artdaq-core/Data/ContainerFragment.hh" -#include "sbndcode/Decoders/PTB/sbndptb.h" +//#include "sbndcode/Decoders/PTB/sbndptb.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" #include "ifdh_art/IFBeamService/IFBeam_service.h" @@ -30,15 +30,15 @@ #include "larcorealg/CoreUtils/counter.h" -class SBNDBNB : public art::EDProducer { +class SBNDBNBRetriever : public art::EDProducer { public: - explicit SBNDBNB(fhicl::ParameterSet const & params); + explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); // Plugins should not be copied or assigned. - SBNDBNB(SBNDBNB const &) = delete; - SBNDBNB(SBNDBNB &&) = delete; - SBNDBNB & operator = (SBNDBNB const &) = delete; - SBNDBNB & operator = (SBNDBNB &&) = delete; + SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; // Required functions. void produce(art::Event & e) override; @@ -61,11 +61,9 @@ class SBNDBNB : public art::EDProducer { std::unique_ptr bfp_mwr; struct TriggerInfo_t { - int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI double t_current_event = 0; double t_previous_event = 0; unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - std::int64_t WR_to_Spill_conversion = 0; }; struct MWRdata_t { @@ -88,9 +86,9 @@ class SBNDBNB : public art::EDProducer { (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; }; -SBNDBNB::SBNDBNB(fhicl::ParameterSet const & params) +SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) : EDProducer{params} { - raw_data_label = params.get("RawDataLabel", "ptbdecoder"); + raw_data_label = params.get("raw_data_label", "daq"); fInputLabel = params.get("InputLabel"); fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); fTimePad = params.get("TimePadding"); @@ -109,7 +107,7 @@ int _run; int _subrun; int _event; -void SBNDBNB::produce(art::Event & e) +void SBNDBNBRetriever::produce(art::Event & e) { // If this is the first event in the run, then ignore it @@ -170,47 +168,52 @@ void SBNDBNB::produce(art::Event & e) int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) - mf::LogDebug("BNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; + mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; else - mf::LogDebug("BNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; + mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; } -SBNDBNB::TriggerInfo_t SBNDBNB::extractTriggerInfo(art::Event const& e) const { +SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { //Here we read in the artdaq Fragments and extract three pieces of information: // 1. The time of the current event, t_current_event // 2. the time of the previously triggered event, t_previous_event (NOTE: Events are non-sequential!) // 3. the number of beam spills since the previously triggered event, number_of_gates_since_previous_event - auto const & raw_data = e.getProduct< std::vector >({ "ptbdecoder", "" }); + auto const & raw_data = e.getProduct< std::vector >({ raw_data_label, "ContainerTDCTIMESTAMP" }); TriggerInfo_t triggerInfo; /// Correction added to the White Rabbit time to get the trigger time. - triggerInfo.WR_to_Spill_conversion = 0; - triggerInfo.gate_type = 1; - - int raw_data_size = raw_data.size(); - if(raw_data_size > 0){ - for (int j = 0; j < raw_data_size; j++){ - if(raw_data.at(j).GetNHLTriggers() > 0){ - int NHL_trig = raw_data.at(j).GetNHLTriggers(); - for(int k = 0; k < NHL_trig; k++){ - ULong64_t trig_time = raw_data.at(j).GetHLTrigger(k).timestamp; - if(raw_data.at(j).GetHLTrigger(k).trigger_word != 1048576){ - std::cout << "Zero Bias Trigger" << std::endl; - triggerInfo.t_current_event = trig_time/1e9; - triggerInfo.t_previous_event = trig_time/1e9 - 10; + for(auto raw_datum : raw_data){ + + uint64_t artdaq_ts = raw_datum.timestamp(); + //icarus::ICARUSTriggerV3Fragment frag(raw_datum); + //std::string data = frag.GetDataString(); + //char *buffer = const_cast(data.c_str()); + //icarus::ICARUSTriggerInfo datastream_info = icarus::parse_ICARUSTriggerV3String(buffer); + //triggerInfo.gate_type = datastream_info.gate_type; + //triggerInfo.number_of_gates_since_previous_event = frag.getDeltaGatesBNBMaj(); + triggerInfo.number_of_gates_since_previous_event = 1; + + /* + The DAQ trigger time is issued at the Beam Extraction Signal (BES) which is issued + 36 ms *after* the $1D of the BNB, which is what is used in the IFBeam database + + We subtract 36ms from the Trigger time to match our triggers to the spills in the + IFBeam database + + */ - triggerInfo.number_of_gates_since_previous_event = 100; - } - else{ - std::cout << "CRT Reset Trigger" << std::endl; - } - } - } - } + triggerInfo.t_current_event = static_cast(artdaq_ts-3.6e7)/(1000000000.0); //check this offset... + if(triggerInfo.gate_type == 1) + triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); + else + triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(frag.getLastTimestampOther()-3.6e7))/(1000000000.0); + } + + mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Previous : " << triggerInfo.t_previous_event << ", Current : " << triggerInfo.t_current_event << ", Spill Count " << triggerInfo.number_of_gates_since_previous_event << std::endl; return triggerInfo; } -SBNDBNB::MWRdata_t SBNDBNB::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { +SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { // These lines get everything primed within the IFBeamDB // They seem redundant but they are needed @@ -231,7 +234,7 @@ SBNDBNB::MWRdata_t SBNDBNB::extractSpillTimes(TriggerInfo_t const& triggerInfo) // memory buffer increments // generally in the format: "E:.{Memory Block}" std::vector vars = bfp_mwr->GetDeviceList(); - mf::LogDebug("BNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; // Tracking the time from the IFBeamDB double time_for_mwr; @@ -246,14 +249,14 @@ SBNDBNB::MWRdata_t SBNDBNB::extractSpillTimes(TriggerInfo_t const& triggerInfo) // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; - mf::LogDebug("BNBRetriever") << " t_steps " << t_steps << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " t_steps " << t_steps << std::endl; for(int t = 0; t < t_steps; t++){//Iterate through time increments for (std::string const& var : vars) {// Iterate through the devices //Make sure we have a device if(var.empty()){ - //mf::LogDebug("BNBRetriever") << " NO MWR DEVICES?!" << std::endl; + //mf::LogDebug("SBNDBNBRetriever") << " NO MWR DEVICES?!" << std::endl; continue; } /// Check the device name and interate the double-vector index @@ -261,7 +264,7 @@ SBNDBNB::MWRdata_t SBNDBNB::extractSpillTimes(TriggerInfo_t const& triggerInfo) else if(var.find("M876BB") != std::string::npos ) dev = 1; else if(var.find("MMBTBB") != std::string::npos ) dev = 2; else{ - //mf::LogDebug("BNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; + //mf::LogDebug("SBNDBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; continue;} time_for_mwr = 0; @@ -315,17 +318,17 @@ SBNDBNB::MWRdata_t SBNDBNB::extractSpillTimes(TriggerInfo_t const& triggerInfo) }// Iterate over all the multiwire devices }// Iterate over all times - mf::LogDebug("BNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; return { std::move(MWR_times), std::move(unpacked_MWR) }; } -int SBNDBNB::matchMultiWireData( +int SBNDBNBRetriever::matchMultiWireData( art::EventID const& eventID, TriggerInfo_t const& triggerInfo, MWRdata_t const& MWRdata, bool isFirstEventInRun, @@ -339,7 +342,7 @@ int SBNDBNB::matchMultiWireData( // we have to pick a specific variable to use std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); - mf::LogDebug("BNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; // We'll keep track of how many of these spills match to our // DAQ trigger times @@ -378,25 +381,25 @@ int SBNDBNB::matchMultiWireData( ///reject time_stamps which have a trigger_type == 1 from data-base //To-Do - // mf::LogDebug("BNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; - // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; - // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; // Iterating through each of the beamline times for (size_t i = 0; i < times_temps.size(); i++) { // Only continue if these times are matched to our DAQ time - //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; + //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; - std::cout << std::setprecision(19) << "times_temps[i]: " << times_temps[i] << std::endl; + //std::cout << std::setprecision(19) << "times_temps[i]: " << times_temps[i] << std::endl; if(!isFirstEventInRun){//We already addressed the "first event" above if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ - //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; spills_removed++; continue;} if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ spills_removed++; - //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; continue;} } @@ -407,10 +410,10 @@ int SBNDBNB::matchMultiWireData( DocDB 33155 provides documentation of this */ - // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; // if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ - // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; // continue; //} @@ -468,12 +471,12 @@ int SBNDBNB::matchMultiWireData( }//end iteration over beam device times - // mf::LogDebug("BNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; return spill_count; } -sbn::BNBSpillInfo SBNDBNB::makeBNBSpillInfo +sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const { @@ -502,19 +505,19 @@ sbn::BNBSpillInfo SBNDBNB::makeBNBSpillInfo // since sometimes devices fail to report we'll // allow each to throw an exception but still move forward // interpreting these failures will be part of the beam quality analyses - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} //crunch the times unsigned long int time_closest_int = (int) TOR860_time; @@ -538,7 +541,7 @@ sbn::BNBSpillInfo SBNDBNB::makeBNBSpillInfo beamInfo.spill_time_s = time_closest_int; beamInfo.spill_time_ns = time_closest_ns; - std::cout << "TOR860: " << TOR860 << std::endl; + // std::cout << "TOR860: " << TOR860 << std::endl; for(auto const& MWRdata: unpacked_MWR){ std::ignore = MWRdata; @@ -580,15 +583,15 @@ sbn::BNBSpillInfo SBNDBNB::makeBNBSpillInfo return beamInfo; } -void SBNDBNB::beginSubRun(art::SubRun& sr) +void SBNDBNBRetriever::beginSubRun(art::SubRun& sr) { return; } -void SBNDBNB::endSubRun(art::SubRun& sr) +void SBNDBNBRetriever::endSubRun(art::SubRun& sr) { - //mf::LogDebug("BNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; - //mf::LogDebug("BNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; + //mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; + //mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; //auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); //std::swap(*p, fOutbeamInfos); @@ -598,4 +601,4 @@ void SBNDBNB::endSubRun(art::SubRun& sr) return; } -DEFINE_ART_MODULE(SBNDBNB) +DEFINE_ART_MODULE(SBNDBNBRetriever) From 225eaf9ce98265eb81a42fb4e871800f9fc8f36d Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Mon, 21 Oct 2024 15:21:13 -0500 Subject: [PATCH 013/367] debug and cache changes --- .../BNBRetriever/BNBRetriever_module.cc | 2 +- .../BNBRetriever/SBNDBNBRetriever_module.cc | 47 ++++++++++++------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc index 2265d0e2c..e8a20cb0e 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc @@ -388,7 +388,7 @@ sbn::BNBRetriever::MWRdata_t sbn::BNBRetriever::extractSpillTimes(TriggerInfo_t // These lines get everything primed within the IFBeamDB // They seem redundant but they are needed - // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_previous_event)-fTimePad,"E:THCURR");} catch (WebAPIException &we) {} + //try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_previous_event)-fTimePad,"E:THCURR");} catch (WebAPIException &we) {} try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {} try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {} diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 2ceaf32bc..1ed19a34d 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" #include "artdaq-core/Data/ContainerFragment.hh" @@ -96,6 +97,7 @@ SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) fOutputInstance = params.get("OutputInstance"); fDebugLevel = params.get("DebugLevel",0); bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); + //bfp->set_epsilon(0.02); bfp->set_epsilon(0.05); bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); bfp_mwr->set_epsilon(0.5); @@ -161,10 +163,9 @@ void SBNDBNBRetriever::produce(art::Event & e) TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - std::cout << "Gate Type: " << triggerInfo.gate_type << std::endl; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); + //std::cout << "event: " << e.event() << std::endl; int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) @@ -188,7 +189,6 @@ SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event //std::string data = frag.GetDataString(); //char *buffer = const_cast(data.c_str()); //icarus::ICARUSTriggerInfo datastream_info = icarus::parse_ICARUSTriggerV3String(buffer); - //triggerInfo.gate_type = datastream_info.gate_type; //triggerInfo.number_of_gates_since_previous_event = frag.getDeltaGatesBNBMaj(); triggerInfo.number_of_gates_since_previous_event = 1; @@ -202,11 +202,7 @@ SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event */ triggerInfo.t_current_event = static_cast(artdaq_ts-3.6e7)/(1000000000.0); //check this offset... - if(triggerInfo.gate_type == 1) - triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); - else - triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(frag.getLastTimestampOther()-3.6e7))/(1000000000.0); - + triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); } mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Previous : " << triggerInfo.t_previous_event << ", Current : " << triggerInfo.t_current_event << ", Spill Count " << triggerInfo.number_of_gates_since_previous_event << std::endl; @@ -217,9 +213,11 @@ SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t co // These lines get everything primed within the IFBeamDB // They seem redundant but they are needed - try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} - try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {std::cout << "caught 2" << std::endl;} - + // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_previous_event)-fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} + // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} + try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {} + try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} + try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {} //The multiwire chambers provide their // data in a vector format but we'll have // to sort through it in std::string format @@ -341,7 +339,7 @@ int SBNDBNBRetriever::matchMultiWireData( // First we get the times that the beamline device fired // we have to pick a specific variable to use std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); - + mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; // We'll keep track of how many of these spills match to our @@ -351,6 +349,7 @@ int SBNDBNBRetriever::matchMultiWireData( std::vector matched_MWR; matched_MWR.resize(3); + std::cout << std::setprecision(19) << "t_previous_event: " << triggerInfo.t_previous_event << std::endl; std::cout << std::setprecision(19) << "t_current_event: " << triggerInfo.t_current_event << std::endl; // NOTE: for now, this is dead code because we don't // do anything for the first event in a run. We may want to revisit @@ -359,7 +358,6 @@ int SBNDBNBRetriever::matchMultiWireData( // // Need to handle the first event in a run differently if(isFirstEventInRun){ - //We'll remove the spills after our event int spills_after_our_target = 0; // iterate through all the spills to find the @@ -389,9 +387,8 @@ int SBNDBNBRetriever::matchMultiWireData( for (size_t i = 0; i < times_temps.size(); i++) { // Only continue if these times are matched to our DAQ time - //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; - //std::cout << std::setprecision(19) << "times_temps[i]: " << times_temps[i] << std::endl; if(!isFirstEventInRun){//We already addressed the "first event" above if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; @@ -505,6 +502,7 @@ sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo // since sometimes devices fail to report we'll // allow each to throw an exception but still move forward // interpreting these failures will be part of the beam quality analyses + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -518,7 +516,24 @@ sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - + + std::cout << std::setprecision(19) << "spill_time: " << TOR860_time << std::endl; + +/* + std::cout << std::setprecision(13) << "TOR860: " << TOR860 << std::endl; + std::cout << std::setprecision(13) << "TOR875: " << TOR875 << std::endl; + std::cout << std::setprecision(13) << "LM875A: " << LM875A << std::endl; + std::cout << std::setprecision(13) << "LM875B: " << LM875B << std::endl; + std::cout << std::setprecision(13) << "LM875C: " << LM875C << std::endl; + std::cout << std::setprecision(13) << "HP875: " << HP875 << std::endl; + std::cout << std::setprecision(13) << "VP875: " << VP875 << std::endl; + std::cout << std::setprecision(13) << "HPTG1: " << HPTG1 << std::endl; + std::cout << std::setprecision(13) << "VPTG1: " << VPTG1 << std::endl; + std::cout << std::setprecision(13) << "HPTG2: " << HPTG2 << std::endl; + std::cout << std::setprecision(13) << "VPTG2: " << VPTG2 << std::endl; + std::cout << std::setprecision(13) << "BTJT2: " << BTJT2 << std::endl; + std::cout << std::setprecision(13) << "THCURR: " << THCURR << std::endl; +*/ //crunch the times unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; From 030248d8b22a895ccaa807116903734860dc337b Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Fri, 25 Oct 2024 09:26:53 -0500 Subject: [PATCH 014/367] Fill cache --- .../BNBRetriever/SBNDBNBRetriever_module.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 1ed19a34d..c09d7c878 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -214,9 +214,11 @@ SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t co // These lines get everything primed within the IFBeamDB // They seem redundant but they are needed // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_previous_event)-fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} - // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} - try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {} + // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} + try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {} try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} + //std::cout << std::setprecision(19) << "bfp->GetCacheStartTime()" << bfp->GetCacheStartTime() << std::endl; + //std::cout << std::setprecision(19) << "bfp->GetCacheEndTime()" << bfp->GetCacheEndTime() << std::endl; try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {} //The multiwire chambers provide their // data in a vector format but we'll have @@ -519,7 +521,7 @@ sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo std::cout << std::setprecision(19) << "spill_time: " << TOR860_time << std::endl; -/* + std::cout << std::setprecision(13) << "TOR860: " << TOR860 << std::endl; std::cout << std::setprecision(13) << "TOR875: " << TOR875 << std::endl; std::cout << std::setprecision(13) << "LM875A: " << LM875A << std::endl; @@ -533,7 +535,7 @@ sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo std::cout << std::setprecision(13) << "VPTG2: " << VPTG2 << std::endl; std::cout << std::setprecision(13) << "BTJT2: " << BTJT2 << std::endl; std::cout << std::setprecision(13) << "THCURR: " << THCURR << std::endl; -*/ + //crunch the times unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; From 076033d70e5e6c4aaad13cc017aa5e2226331065 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Mon, 28 Oct 2024 10:18:37 -0500 Subject: [PATCH 015/367] Get timestamp from PTB --- .../BNBRetriever/SBNDBNBRetriever_module.cc | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index c09d7c878..84689ea43 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -175,37 +175,43 @@ void SBNDBNBRetriever::produce(art::Event & e) } SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { - //Here we read in the artdaq Fragments and extract three pieces of information: - // 1. The time of the current event, t_current_event - // 2. the time of the previously triggered event, t_previous_event (NOTE: Events are non-sequential!) - // 3. the number of beam spills since the previously triggered event, number_of_gates_since_previous_event - auto const & raw_data = e.getProduct< std::vector >({ raw_data_label, "ContainerTDCTIMESTAMP" }); + art::InputTag itag("daq", "ContainerPTB"); + auto cont_frags = e.getHandle(itag); + int numcont = 0; TriggerInfo_t triggerInfo; - /// Correction added to the White Rabbit time to get the trigger time. - for(auto raw_datum : raw_data){ - - uint64_t artdaq_ts = raw_datum.timestamp(); - //icarus::ICARUSTriggerV3Fragment frag(raw_datum); - //std::string data = frag.GetDataString(); - //char *buffer = const_cast(data.c_str()); - //icarus::ICARUSTriggerInfo datastream_info = icarus::parse_ICARUSTriggerV3String(buffer); - //triggerInfo.number_of_gates_since_previous_event = frag.getDeltaGatesBNBMaj(); - triggerInfo.number_of_gates_since_previous_event = 1; - - /* - The DAQ trigger time is issued at the Beam Extraction Signal (BES) which is issued - 36 ms *after* the $1D of the BNB, which is what is used in the IFBeam database - - We subtract 36ms from the Trigger time to match our triggers to the spills in the - IFBeam database - - */ - triggerInfo.t_current_event = static_cast(artdaq_ts-3.6e7)/(1000000000.0); //check this offset... - triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); - } - - mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Previous : " << triggerInfo.t_previous_event << ", Current : " << triggerInfo.t_current_event << ", Spill Count " << triggerInfo.number_of_gates_since_previous_event << std::endl; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag =0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) + { + if(ctb_frag.Trigger(word_i)){ + uint32_t wt = 0; + uint32_t word_type = ctb_frag.Word(word_i)->word_type; + wt = word_type; + uint64_t NR_trigger_word = ctb_frag.Trigger(word_i)->trigger_word & 0x1FFFFFFFFFFFFFFF; //& 0x1FFFFFFFFFFF extracts the 61 bit payload + uint64_t NR_timestamp = ctb_frag.Trigger(word_i)->timestamp * 20; + if (wt == 2) + { + std::cout << "PTB Word type [" << std::bitset<3>(ctb_frag.Word(word_i)->word_type) << "] "; + std::cout << std::bitset<32>(NR_trigger_word) << " HLT Timestamp: " << std::bitset<64>(NR_timestamp/20) <(NR_timestamp/20).to_ullong()/50e6; + triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(ctb_frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); + std::cout << std::setprecision(19) << "triggerInfo.t_current_event: " << triggerInfo.t_current_event << std::endl; + std::cout << std::setprecision(19) << "triggerInfo.t_previous_event: " << triggerInfo.t_previous_event << std::endl; + } + } + } //End of loop over the number of trigger words + } //End of loop over the number of fragments per container + } //End of loop over the number of containers return triggerInfo; } From 8b5216d6738b2356c2dcf22069a8949b89065376 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Mon, 28 Oct 2024 13:19:05 -0500 Subject: [PATCH 016/367] Refactor PTB ts extraction --- .../BNBRetriever/SBNDBNBRetriever_module.cc | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 84689ea43..856747f2e 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -75,6 +75,7 @@ class SBNDBNBRetriever : public art::EDProducer { static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + double extractPTBTimeStamp(art::Handle > cont_frags) const; MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; int matchMultiWireData( art::EventID const& eventID, @@ -174,17 +175,15 @@ void SBNDBNBRetriever::produce(art::Event & e) mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; } -SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { - art::InputTag itag("daq", "ContainerPTB"); - auto cont_frags = e.getHandle(itag); +double SBNDBNBRetriever::extractPTBTimeStamp(art::Handle > cont_frags) const { int numcont = 0; - TriggerInfo_t triggerInfo; - + uint64_t PTBTimeStamp = 0; + uint64_t PTBTriggerWord; for (auto const& cont : *cont_frags) - { + { artdaq::ContainerFragment cont_frag(cont); numcont++; - int numfrag =0; + int numfrag = 0; for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) { numfrag++; @@ -196,22 +195,35 @@ SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event uint32_t wt = 0; uint32_t word_type = ctb_frag.Word(word_i)->word_type; wt = word_type; - uint64_t NR_trigger_word = ctb_frag.Trigger(word_i)->trigger_word & 0x1FFFFFFFFFFFFFFF; //& 0x1FFFFFFFFFFF extracts the 61 bit payload - uint64_t NR_timestamp = ctb_frag.Trigger(word_i)->timestamp * 20; - if (wt == 2) + PTBTriggerWord = ctb_frag.Trigger(word_i)->trigger_word & 0x1FFFFFFFFFFFFFFF; //& 0x1FFFFFFFFFFF extracts the 61 bit payload + std::bitset<32> desired_word{"00000000000000000000000000000010"};// Only use timestamp from specific HLT trigger word + if (wt == 2 && std::bitset<32>(PTBTriggerWord) == desired_word) { + PTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; std::cout << "PTB Word type [" << std::bitset<3>(ctb_frag.Word(word_i)->word_type) << "] "; - std::cout << std::bitset<32>(NR_trigger_word) << " HLT Timestamp: " << std::bitset<64>(NR_timestamp/20) <(NR_timestamp/20).to_ullong()/50e6; - triggerInfo.t_previous_event = triggerInfo.t_current_event - 10;//(static_cast(ctb_frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); - std::cout << std::setprecision(19) << "triggerInfo.t_current_event: " << triggerInfo.t_current_event << std::endl; - std::cout << std::setprecision(19) << "triggerInfo.t_previous_event: " << triggerInfo.t_previous_event << std::endl; + std::cout << std::bitset<32>(PTBTriggerWord) << " HLT Timestamp: " << std::bitset<64>(PTBTimeStamp/20) <(PTBTimeStamp/20).to_ullong()/50e6; +} + +SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { + art::InputTag itag("daq", "ContainerPTB"); + auto cont_frags = e.getHandle(itag); + + TriggerInfo_t triggerInfo; + double PTBTimeStamp = extractPTBTimeStamp(cont_frags); + + triggerInfo.t_current_event = PTBTimeStamp; + triggerInfo.t_previous_event = PTBTimeStamp-10; + triggerInfo.number_of_gates_since_previous_event = 1; + + std::cout << std::setprecision(19) << "triggerInfo.t_current_event: " << triggerInfo.t_current_event << std::endl; + std::cout << std::setprecision(19) << "triggerInfo.t_previous_event: " << triggerInfo.t_previous_event << std::endl; + return triggerInfo; } From 574348ae922ab6f0af237323e58fe87994172cf8 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Fri, 1 Nov 2024 17:41:54 -0500 Subject: [PATCH 017/367] Add TDC Timestamp func --- .../BNBRetriever/SBNDBNBRetriever_module.cc | 83 ++++++++----------- 1 file changed, 34 insertions(+), 49 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 856747f2e..0ba84d7c3 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -21,6 +21,7 @@ #include #include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" +#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" #include "artdaq-core/Data/ContainerFragment.hh" //#include "sbndcode/Decoders/PTB/sbndptb.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" @@ -76,6 +77,7 @@ class SBNDBNBRetriever : public art::EDProducer { TriggerInfo_t extractTriggerInfo(art::Event const& e) const; double extractPTBTimeStamp(art::Handle > cont_frags) const; + double extractTDCTimeStamp(art::Handle > cont_frags) const; MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; int matchMultiWireData( art::EventID const& eventID, @@ -118,50 +120,6 @@ void SBNDBNBRetriever::produce(art::Event & e) // spill that the DAQ was sensitive to, so don't try to save any // spill information -/* - art::InputTag ptb_tag { "ptbdecoder" }; - auto const& ptb_handle = e.getValidHandle< std::vector >(ptb_tag); - auto const& ptb_vec(*ptb_handle); - int ptb_size = ptb_vec.size(); - int NHL_trig; - if(ptb_size > 0){ - for (int j = 0; j < ptb_size; j++){ - if(ptb_vec.at(j).GetNHLTriggers() > 0){ - NHL_trig = ptb_vec.at(j).GetNHLTriggers(); - for(int k = 0; k < NHL_trig; k++){ - ULong64_t trig_time = ptb_vec.at(j).GetHLTrigger(k).timestamp; - if(ptb_vec.at(j).GetHLTrigger(k).trigger_word != 1048576){ - ULong64_t curr_min = 1e19; - //int curr_min_ind; - std::cout << "Zero Bias Trigger" << std::endl; - try{ - //auto vec_temp = bfp_mwr->GetNamedVector(trig_time/1e9,"E:M875BB{4440:888}.RAW"); - auto vec_temp = bfp->GetNamedVector(trig_time/1e9,"E:TOR875"); - //std::vector times = bfp->GetTimeList("E:M875BB"); - std::vector times = bfp->GetTimeList("E:TOR875"); - int times_size = times.size(); - for (int i = 0; i < times_size; i++) { - if(times[i] < trig_time/1e9){ - if(trig_time/1e9 - times[i] < curr_min){ - curr_min = trig_time - times[i]; - std::cout << "trig_time: " << trig_time << std::endl; - //curr_min_ind = i; - } - } - } - }catch(WebAPIException &we){std::cout << "Failed GetNamedVector" << std::endl;} - } - else{ - std::cout << "CRT Reset Trigger" << std::endl; - } - } - } - } - } -*/ - //sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); - //fOutbeamInfos.push_back(std::move(spillInfo)); - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); @@ -210,15 +168,42 @@ double SBNDBNBRetriever::extractPTBTimeStamp(art::Handle(PTBTimeStamp/20).to_ullong()/50e6; } +double SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { + int numcont = 0; + uint64_t TDCTimeStamp = 0; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::TDCTimestampFragment tdc_frag(frag); + TDCTimeStamp = tdc_frag.getTDCTimestamp()->timestamp_ns()/1e9; + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return TDCTimeStamp; +} + SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { - art::InputTag itag("daq", "ContainerPTB"); - auto cont_frags = e.getHandle(itag); + // Using TDC for current event, but PTB for previous event + art::InputTag PTB_itag("daq", "ContainerPTB"); + auto PTB_cont_frags = e.getHandle(PTB_itag); + + art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); + auto TDC_cont_frags = e.getHandle(TDC_itag); TriggerInfo_t triggerInfo; - double PTBTimeStamp = extractPTBTimeStamp(cont_frags); + double PTBTimeStamp = extractPTBTimeStamp(PTB_cont_frags); + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + + std::cout << "PTBTimeStamp: " << PTBTimeStamp << std::endl; + std::cout << "TDCTimeStamp: " << TDCTimeStamp << std::endl; - triggerInfo.t_current_event = PTBTimeStamp; - triggerInfo.t_previous_event = PTBTimeStamp-10; + triggerInfo.t_current_event = TDCTimeStamp; + triggerInfo.t_previous_event = TDCTimeStamp-10; triggerInfo.number_of_gates_since_previous_event = 1; std::cout << std::setprecision(19) << "triggerInfo.t_current_event: " << triggerInfo.t_current_event << std::endl; From fc0776af32f9a95eda2e61c7b34161595d729c3b Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Sun, 10 Nov 2024 19:32:03 -0600 Subject: [PATCH 018/367] Add prev ptb timestamp --- Module.txt | 1 + .../BNBRetriever/BNBRetriever_module.cc | 5 ++--- .../BNBRetriever/SBNDBNBRetriever_module.cc | 14 ++++---------- 3 files changed, 7 insertions(+), 13 deletions(-) create mode 100644 Module.txt diff --git a/Module.txt b/Module.txt new file mode 100644 index 000000000..16f27c055 --- /dev/null +++ b/Module.txt @@ -0,0 +1 @@ +Art has completed and will exit with status 90. diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc index e8a20cb0e..88c20b40d 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc @@ -388,9 +388,8 @@ sbn::BNBRetriever::MWRdata_t sbn::BNBRetriever::extractSpillTimes(TriggerInfo_t // These lines get everything primed within the IFBeamDB // They seem redundant but they are needed - //try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_previous_event)-fTimePad,"E:THCURR");} catch (WebAPIException &we) {} - try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {} - try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {} + try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} + try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} //The multiwire chambers provide their // data in a vector format but we'll have diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 0ba84d7c3..54bd2f29c 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -157,7 +157,7 @@ double SBNDBNBRetriever::extractPTBTimeStamp(art::Handle desired_word{"00000000000000000000000000000010"};// Only use timestamp from specific HLT trigger word if (wt == 2 && std::bitset<32>(PTBTriggerWord) == desired_word) { - PTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; + PTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; std::cout << "PTB Word type [" << std::bitset<3>(ctb_frag.Word(word_i)->word_type) << "] "; std::cout << std::bitset<32>(PTBTriggerWord) << " HLT Timestamp: " << std::bitset<64>(PTBTimeStamp/20) <(PTB_itag); - art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); - auto TDC_cont_frags = e.getHandle(TDC_itag); + // art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); + // auto TDC_cont_frags = e.getHandle(TDC_itag); TriggerInfo_t triggerInfo; double PTBTimeStamp = extractPTBTimeStamp(PTB_cont_frags); double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - std::cout << "PTBTimeStamp: " << PTBTimeStamp << std::endl; - std::cout << "TDCTimeStamp: " << TDCTimeStamp << std::endl; - triggerInfo.t_current_event = TDCTimeStamp; - triggerInfo.t_previous_event = TDCTimeStamp-10; + triggerInfo.t_previous_event = PTBTimeStamp-10; triggerInfo.number_of_gates_since_previous_event = 1; - std::cout << std::setprecision(19) << "triggerInfo.t_current_event: " << triggerInfo.t_current_event << std::endl; - std::cout << std::setprecision(19) << "triggerInfo.t_previous_event: " << triggerInfo.t_previous_event << std::endl; - return triggerInfo; } From c5aaeb9fb55e3a4cd5f37e4e1f13d38fad9de02f Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Sun, 10 Nov 2024 19:52:48 -0600 Subject: [PATCH 019/367] Cleaning print statements --- .../BNBRetriever/SBNDBNBRetriever_module.cc | 70 ++++++------------- 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 54bd2f29c..91b1694c2 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -100,8 +100,7 @@ SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) fOutputInstance = params.get("OutputInstance"); fDebugLevel = params.get("DebugLevel",0); bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); - //bfp->set_epsilon(0.02); - bfp->set_epsilon(0.05); + bfp->set_epsilon(0.02); bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); @@ -124,7 +123,6 @@ void SBNDBNBRetriever::produce(art::Event & e) MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); - //std::cout << "event: " << e.event() << std::endl; int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) @@ -133,9 +131,9 @@ void SBNDBNBRetriever::produce(art::Event & e) mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; } -double SBNDBNBRetriever::extractPTBTimeStamp(art::Handle > cont_frags) const { +double SBNDBNBRetriever::extractprevPTBTimeStamp(art::Handle > cont_frags) const { int numcont = 0; - uint64_t PTBTimeStamp = 0; + uint64_t prevPTBTimeStamp = 0; uint64_t PTBTriggerWord; for (auto const& cont : *cont_frags) { @@ -157,15 +155,13 @@ double SBNDBNBRetriever::extractPTBTimeStamp(art::Handle desired_word{"00000000000000000000000000000010"};// Only use timestamp from specific HLT trigger word if (wt == 2 && std::bitset<32>(PTBTriggerWord) == desired_word) { - PTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; - std::cout << "PTB Word type [" << std::bitset<3>(ctb_frag.Word(word_i)->word_type) << "] "; - std::cout << std::bitset<32>(PTBTriggerWord) << " HLT Timestamp: " << std::bitset<64>(PTBTimeStamp/20) <prevTS * 20; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers - return std::bitset<64>(PTBTimeStamp/20).to_ullong()/50e6; + return std::bitset<64>(prevPTBTimeStamp/20).to_ullong()/50e6; } double SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { @@ -192,32 +188,29 @@ SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event art::InputTag PTB_itag("daq", "ContainerPTB"); auto PTB_cont_frags = e.getHandle(PTB_itag); - // art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); - // auto TDC_cont_frags = e.getHandle(TDC_itag); + art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); + auto TDC_cont_frags = e.getHandle(TDC_itag); TriggerInfo_t triggerInfo; - double PTBTimeStamp = extractPTBTimeStamp(PTB_cont_frags); + double prevPTBTimeStamp = extractprevPTBTimeStamp(PTB_cont_frags); double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); triggerInfo.t_current_event = TDCTimeStamp; - triggerInfo.t_previous_event = PTBTimeStamp-10; - triggerInfo.number_of_gates_since_previous_event = 1; + triggerInfo.t_previous_event = prevPTBTimeStamp; + triggerInfo.number_of_gates_since_previous_event = -999; return triggerInfo; } SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { - // These lines get everything primed within the IFBeamDB - // They seem redundant but they are needed - // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_previous_event)-fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} - // try{auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:THCURR");} catch (WebAPIException &we) {std::cout << "caught 1" << std::endl;} + // These lines get everything primed within the IFBeamDB. try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {} try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} - //std::cout << std::setprecision(19) << "bfp->GetCacheStartTime()" << bfp->GetCacheStartTime() << std::endl; - //std::cout << std::setprecision(19) << "bfp->GetCacheEndTime()" << bfp->GetCacheEndTime() << std::endl; - try{auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.t_current_event)+fTimePad,"E:M875BB{4440:888}.RAW");} catch (WebAPIException &we) {} - //The multiwire chambers provide their + try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad)} catch (WebAPIException &we) {} + try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad)} catch (WebAPIException &we) {} + + // The multiwire chambers provide their // data in a vector format but we'll have // to sort through it in std::string format // to correctly unpack it @@ -227,7 +220,7 @@ SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t co MWR_times.resize(3); std::string packed_data_str; - //Create a list of all the MWR devices with their different + // Create a list of all the MWR devices with their different // memory buffer increments // generally in the format: "E:.{Memory Block}" std::vector vars = bfp_mwr->GetDeviceList(); @@ -348,8 +341,6 @@ int SBNDBNBRetriever::matchMultiWireData( std::vector matched_MWR; matched_MWR.resize(3); - std::cout << std::setprecision(19) << "t_previous_event: " << triggerInfo.t_previous_event << std::endl; - std::cout << std::setprecision(19) << "t_current_event: " << triggerInfo.t_current_event << std::endl; // NOTE: for now, this is dead code because we don't // do anything for the first event in a run. We may want to revisit // this later to understand if there is a way we can do the POT @@ -516,23 +507,6 @@ sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - std::cout << std::setprecision(19) << "spill_time: " << TOR860_time << std::endl; - - - std::cout << std::setprecision(13) << "TOR860: " << TOR860 << std::endl; - std::cout << std::setprecision(13) << "TOR875: " << TOR875 << std::endl; - std::cout << std::setprecision(13) << "LM875A: " << LM875A << std::endl; - std::cout << std::setprecision(13) << "LM875B: " << LM875B << std::endl; - std::cout << std::setprecision(13) << "LM875C: " << LM875C << std::endl; - std::cout << std::setprecision(13) << "HP875: " << HP875 << std::endl; - std::cout << std::setprecision(13) << "VP875: " << VP875 << std::endl; - std::cout << std::setprecision(13) << "HPTG1: " << HPTG1 << std::endl; - std::cout << std::setprecision(13) << "VPTG1: " << VPTG1 << std::endl; - std::cout << std::setprecision(13) << "HPTG2: " << HPTG2 << std::endl; - std::cout << std::setprecision(13) << "VPTG2: " << VPTG2 << std::endl; - std::cout << std::setprecision(13) << "BTJT2: " << BTJT2 << std::endl; - std::cout << std::setprecision(13) << "THCURR: " << THCURR << std::endl; - //crunch the times unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; @@ -555,8 +529,6 @@ sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo beamInfo.spill_time_s = time_closest_int; beamInfo.spill_time_ns = time_closest_ns; - // std::cout << "TOR860: " << TOR860 << std::endl; - for(auto const& MWRdata: unpacked_MWR){ std::ignore = MWRdata; assert(!MWRdata.empty()); @@ -604,13 +576,13 @@ void SBNDBNBRetriever::beginSubRun(art::SubRun& sr) void SBNDBNBRetriever::endSubRun(art::SubRun& sr) { - //mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; - //mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; + mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; + mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; - //auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); - //std::swap(*p, fOutbeamInfos); + auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); + std::swap(*p, fOutbeamInfos); - //sr.put(std::move(p), art::subRunFragment()); + sr.put(std::move(p), art::subRunFragment()); return; } From f5288577bee1902a8b667689f8b430b167ff2175 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Sun, 10 Nov 2024 19:56:00 -0600 Subject: [PATCH 020/367] Undo build fix, get rid of junk --- Module.txt | 1 - sbncode/CAFMaker/FillReco.cxx | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 Module.txt diff --git a/Module.txt b/Module.txt deleted file mode 100644 index 16f27c055..000000000 --- a/Module.txt +++ /dev/null @@ -1 +0,0 @@ -Art has completed and will exit with status 90. diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 0c35b8a59..a478bc840 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -119,8 +119,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Time(); - srspacepoint.time_err = spacepoint.TimeErr(); + srspacepoint.time = spacepoint.Ts1(); + srspacepoint.time_err = spacepoint.Ts1Err(); srspacepoint.complete = spacepoint.Complete(); } @@ -131,8 +131,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Time(); - srsbndcrttrack.time_err = track.TimeErr(); + srsbndcrttrack.time = track.Ts1(); + srsbndcrttrack.time_err = track.Ts1Err(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From 73137062c84324df3537b914639de94822e90e7b Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Fri, 8 Nov 2024 14:50:17 -0600 Subject: [PATCH 021/367] reassign CRT-PMT MatchID while filling CAFs --- sbncode/CAFMaker/CAFMaker_module.cc | 12 +++++------- sbncode/CAFMaker/FillReco.cxx | 12 ++++++++++-- sbncode/CAFMaker/FillReco.h | 5 +++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 4d70d098e..35f4d1347 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1471,22 +1471,20 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } - // Get all of the CRTPMT Matches .. + // Get all of the CRTPMT Matches std::vector srcrtpmtmatches; - std::cout << "srcrtpmtmatches.size = " << srcrtpmtmatches.size() << "\n"; art::Handle> crtpmtmatch_handle; GetByLabelStrict(evt, fParams.CRTPMTLabel(), crtpmtmatch_handle); if(crtpmtmatch_handle.isValid()){ - std::cout << "valid handle! label: " << fParams.CRTPMTLabel() << "\n"; const std::vector &crtpmtmatches = *crtpmtmatch_handle; for (unsigned i = 0; i < crtpmtmatches.size(); i++) { + int topen = 0, topex = 0, sideen = 0, sideex = 0; srcrtpmtmatches.emplace_back(); - FillCRTPMTMatch(crtpmtmatches[i],srcrtpmtmatches.back()); + FillCRTPMTMatch(crtpmtmatches[i], + topen, topex, sideen, sideex, + srcrtpmtmatches.back()); } } - else{ - std::cout << "crtpmtmatch_handle.isNOTValid!\n"; - } // Get all of the OpFlashes std::vector srflashes; diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 0daa7d309..38b72e79b 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -138,6 +138,7 @@ namespace caf } void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, + int &topen, int &topex, int &sideen, int &sideex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty){ // allowEmpty does not (yet) matter here @@ -154,17 +155,24 @@ namespace caf srmatch.flashPosition = SRVector3D (match.flashPosition.X(), match.flashPosition.Y(), match.flashPosition.Z()); srmatch.flashYWidth = match.flashYWidth; srmatch.flashZWidth = match.flashZWidth; - srmatch.flashClassification = static_cast(match.flashClassification); for(const auto& matchedCRTHit : match.matchedCRTHits){ - std::cout << "CRTPMTTimeDiff = "<< matchedCRTHit.PMTTimeDiff << "\n"; caf::SRMatchedCRT matchedCRT; matchedCRT.PMTTimeDiff = matchedCRTHit.PMTTimeDiff; matchedCRT.time = matchedCRTHit.time; matchedCRT.sys = matchedCRTHit.sys; matchedCRT.region = matchedCRTHit.region; matchedCRT.position = SRVector3D(matchedCRTHit.position.X(), matchedCRTHit.position.Y(), matchedCRTHit.position.Z()); + if(matchedCRTHit.PMTTimeDiff < 0){ + if(matchedCRTHit.sys == 0) topen++; + else if(matchedCRTHit.sys == 1) sideen++; + } + else if(matchedCRTHit.PMTTimeDiff >= 0){ + if(matchedCRTHit.sys == 0) topex++; + else if(matchedCRTHit.sys == 1) sideex++; + } srmatch.matchedCRTHits.push_back(matchedCRT); } + srmatch.flashClassification = static_cast(sbn::crt::assignFlashClassification(topen, topex, sideen, sideex, 0, 0)); } diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index fb40df775..044aacddc 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -225,8 +225,9 @@ namespace caf caf::SROpFlash &srflash, bool allowEmpty = false); void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, - caf::SRCRTPMTMatch &srmatch, - bool allowEmpty = false); + int &topen, int &topex, int &sideen, int &sidex, + caf::SRCRTPMTMatch &srmatch, + bool allowEmpty = false); void FillTPCPMTBarycenterMatch(const sbn::TPCPMTBarycenterMatch *matchInfo, caf::SRSlice& slice); From 8a7fbf8e151ddc25613d94e082a9743393b8624a Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Mon, 11 Nov 2024 18:26:25 -0600 Subject: [PATCH 022/367] Moving fcls to jobs --- .../BNBRetriever/SBNDBNBRetriever_module.cc | 42 +++++++++-------- .../BNBRetriever/runbnb.fcl | 31 ------------- .../job/run_sbndbnbinfo_sbn.fcl | 45 +++++++++++++++++++ .../sbndbnbspillinfo.fcl} | 2 +- sbncode/CAFMaker/FillReco.cxx | 8 ++-- 5 files changed, 74 insertions(+), 54 deletions(-) delete mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl rename sbncode/BeamSpillInfoRetriever/{BNBRetriever/SBNDBNBDefaults.fcl => job/sbndbnbspillinfo.fcl} (96%) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc index 91b1694c2..bb970c366 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc @@ -62,6 +62,11 @@ class SBNDBNBRetriever : public art::EDProducer { std::unique_ptr bfp; std::unique_ptr bfp_mwr; + struct PTBInfo_t { + double prevPTBTimeStamp = 0; + unsigned int GateCounter = 0; // FIXME needs to be integral type + }; + struct TriggerInfo_t { double t_current_event = 0; double t_previous_event = 0; @@ -76,7 +81,7 @@ class SBNDBNBRetriever : public art::EDProducer { static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - double extractPTBTimeStamp(art::Handle > cont_frags) const; + PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; double extractTDCTimeStamp(art::Handle > cont_frags) const; MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; int matchMultiWireData( @@ -85,7 +90,7 @@ class SBNDBNBRetriever : public art::EDProducer { MWRdata_t const& MWRdata, bool isFirstEventInRun, std::vector< sbn::BNBSpillInfo >& beamInfos ) const; - + unsigned int TotalBeamSpills; sbn::BNBSpillInfo makeBNBSpillInfo (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; }; @@ -104,6 +109,7 @@ SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); + TotalBeamSpills = 0; } int eventNum =0; @@ -120,7 +126,7 @@ void SBNDBNBRetriever::produce(art::Event & e) // spill information TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - + TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); @@ -131,10 +137,9 @@ void SBNDBNBRetriever::produce(art::Event & e) mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; } -double SBNDBNBRetriever::extractprevPTBTimeStamp(art::Handle > cont_frags) const { +SBNDBNBRetriever::PTBInfo_t SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { int numcont = 0; - uint64_t prevPTBTimeStamp = 0; - uint64_t PTBTriggerWord; + PTBInfo_t PTBInfo; for (auto const& cont : *cont_frags) { artdaq::ContainerFragment cont_frag(cont); @@ -151,17 +156,17 @@ double SBNDBNBRetriever::extractprevPTBTimeStamp(art::Handleword_type; wt = word_type; - PTBTriggerWord = ctb_frag.Trigger(word_i)->trigger_word & 0x1FFFFFFFFFFFFFFF; //& 0x1FFFFFFFFFFF extracts the 61 bit payload - std::bitset<32> desired_word{"00000000000000000000000000000010"};// Only use timestamp from specific HLT trigger word - if (wt == 2 && std::bitset<32>(PTBTriggerWord) == desired_word) + if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) { - prevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers - return std::bitset<64>(prevPTBTimeStamp/20).to_ullong()/50e6; + return PTBInfo; } double SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { @@ -191,13 +196,14 @@ SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); auto TDC_cont_frags = e.getHandle(TDC_itag); + PTBInfo_t PTBInfo; TriggerInfo_t triggerInfo; - double prevPTBTimeStamp = extractprevPTBTimeStamp(PTB_cont_frags); + PTBInfo = extractPTBInfo(PTB_cont_frags); double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); triggerInfo.t_current_event = TDCTimeStamp; - triggerInfo.t_previous_event = prevPTBTimeStamp; - triggerInfo.number_of_gates_since_previous_event = -999; + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; + triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; return triggerInfo; } @@ -205,10 +211,10 @@ SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { // These lines get everything primed within the IFBeamDB. - try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {} - try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} - try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad)} catch (WebAPIException &we) {} - try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad)} catch (WebAPIException &we) {} + try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; + try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; // The multiwire chambers provide their // data in a vector format but we'll have diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl b/sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl deleted file mode 100644 index 780b32bb3..000000000 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/runbnb.fcl +++ /dev/null @@ -1,31 +0,0 @@ -#include "SBNDBNBDefaults.fcl" - -services:{ - IFBeam:{} -} - -physics: -{ - producers: - { - bnb: @local::SBNDBNBDefaults - } - - analyzers: {} - - my_producer_modules: [bnb] - trigger_paths: [my_producer_modules] - a: [rootout] - end_paths: [a] -} - -source: {} - -outputs: { - rootout: { - module_type: "RootOutput" - fileName: "BNB_out.root" - } -} - -process_name: BNBTEST diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl new file mode 100644 index 000000000..b14918934 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl @@ -0,0 +1,45 @@ +#include "sbndbnbspillinfo.fcl" + +process_name: SBNDBNBInfoGen + +services:{ + + message: { + debugModules: [ "*" ] + destinations: { + LogDebugFile:{ + type: "file" + filename: "debug.log" + append: false + threshold: "DEBUG" + categories: { + default: {} + } + } + } + } + IFBeam:{} +} + + +source: { + +} + +physics: { + producers: { + sbndbnbinfo: @local::sbndbnbspillinfo + } + + simulate: [sbndbnbinfo ] + stream1: [ out1 ] +} + +outputs: { + out1: { + module_type: RootOutput + fileName: "%ifb_%tc_sbndbnbinfo.root" + dataTier: "raw" + compressionLevel: 1 + } +} diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl similarity index 96% rename from sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl rename to sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl index 03e3cdc87..2bf598456 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBDefaults.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl @@ -1,6 +1,6 @@ BEGIN_PROLOG -SBNDBNBDefaults: { +sbndbnbspillinfo: { module_type: SBNDBNBRetriever InputLabel: "bnb" InputContainerInstance: "ContainerBNB" diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index a478bc840..0c35b8a59 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -119,8 +119,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Ts1(); - srspacepoint.time_err = spacepoint.Ts1Err(); + srspacepoint.time = spacepoint.Time(); + srspacepoint.time_err = spacepoint.TimeErr(); srspacepoint.complete = spacepoint.Complete(); } @@ -131,8 +131,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Ts1(); - srsbndcrttrack.time_err = track.Ts1Err(); + srsbndcrttrack.time = track.Time(); + srsbndcrttrack.time_err = track.TimeErr(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From 12b93b444c10ca13cb094df289bb1941f00e1a0c Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Tue, 12 Nov 2024 14:04:22 -0600 Subject: [PATCH 023/367] Rename ICARUS module --- .../BNBRetriever/BNBRetriever_module.cc | 780 ------------------ .../BNBRetriever/CMakeLists.txt | 55 -- .../BNBRetriever/MWRData.cpp | 71 -- .../BNBRetriever/MWRData.h | 39 - .../BNBRetriever/SBNDBNBRetriever_module.cc | 596 ------------- sbncode/BeamSpillInfoRetriever/CMakeLists.txt | 3 +- .../job/bnbspillinfo.fcl | 17 - .../job/run_bnbinfo_sbn.fcl | 46 -- 8 files changed, 2 insertions(+), 1605 deletions(-) delete mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc delete mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt delete mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/MWRData.cpp delete mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/MWRData.h delete mode 100644 sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc delete mode 100644 sbncode/BeamSpillInfoRetriever/job/bnbspillinfo.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/run_bnbinfo_sbn.fcl diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc deleted file mode 100644 index 88c20b40d..000000000 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc +++ /dev/null @@ -1,780 +0,0 @@ -/** ******************************************************************** - * @file BNBRetriever_module.cc - * @date Wed April 9 2021 - * @author J. Zennamo (FNAL) - * - * Based heavily on code by Z. Pavlovic written for MicroBooNE - * Based heavily on code by NOvA collaboration (Thanks NOvA!): - * https://cdcvs.fnal.gov/redmine/projects/novaart/repository/entry/trunk/IFDBSpillInfo/BNBInfo_module.cc - * Database implementation by Justin Mueller - */ - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -#include "canvas/Utilities/InputTag.h" -#include "fhiclcpp/types/Atom.h" -#include "messagefacility/MessageLogger/MessageLogger.h" -#include "larcorealg/CoreUtils/counter.h" - -#include "artdaq-core/Data/Fragment.hh" -#include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV3Fragment.hh" -#include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" - -#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" - -#include "ifdh_art/IFBeamService/IFBeam_service.h" -#include "ifbeam_c.h" -#include "MWRData.h" - -#include -#include -#include - -#include -#include -#include - -namespace sbn { - class BNBRetriever; -} - -class sbn::BNBRetriever : public art::EDProducer { -public: - - struct Config { - - using Name = fhicl::Name; - using Comment = fhicl::Comment; - - fhicl::Atom TimePadding { - Name{ "TimePadding" }, - Comment{ "extension to the time window considered when collecting spills [seconds]" }, - 0.0333 // default - }; - - fhicl::Atom RawDataLabel { - Name{ "raw_data_label" }, - Comment{ "art data product instance name for trigger information (product label is 'daq')" } - }; - - fhicl::Atom DeviceUsedForTiming { - Name{ "DeviceUsedForTiming" }, - Comment{ "name in the IFBeam database of the device used to extract spill times" } - }; - - fhicl::Atom URL { - Name{ "URL" }, - Comment{ "IFBeam database access URL" } - }; - - fhicl::Atom Bundle { - Name{ "Bundle" }, - Comment{ "" } // explain what this is and which database/table it's looking for - }; - - fhicl::Atom TimeWindow { - Name{ "TimeWindow" }, - Comment{ "" } // explain what this is, what's for and its unit - }; - - fhicl::Atom MultiWireBundle { - Name{ "MultiWireBundle" }, - Comment{ "" } // explain what this is and which database/table it's looking for - }; - - fhicl::Atom MWR_TimeWindow { - Name{ "MWR_TimeWindow" }, - Comment{ "" } // explain what this is, what's for and its unit - }; - - fhicl::Atom TriggerDatabaseFile { - Name{ "TriggerDatabaseFile" }, - Comment{ "" } // explain what this is, what's for and its unit - }; - - - }; // Config - - using Parameters = art::EDProducer::Table; - - - explicit BNBRetriever(Parameters const& params); - // The compiler-generated destructor is fine for non-base - // classes without bare pointers or other resource use. - - // Plugins should not be copied or assigned. - BNBRetriever(BNBRetriever const&) = delete; - BNBRetriever(BNBRetriever&&) = delete; - BNBRetriever& operator=(BNBRetriever const&) = delete; - BNBRetriever& operator=(BNBRetriever&&) = delete; - - // Required functions. - void produce(art::Event& e) override; - void beginSubRun(art::SubRun& sr) override; - void endSubRun(art::SubRun& sr) override; - -private: - // input labels - std::vector< sbn::BNBSpillInfo > fOutbeamInfos; - double fTimePad; - std::string fURL; - MWRData mwrdata; - int run_number; - std::string raw_data_label; - std::string fDeviceUsedForTiming; - unsigned int TotalBeamSpills; - // - art::ServiceHandle ifbeam_handle; - std::unique_ptr bfp; - std::unique_ptr bfp_mwr; - - // - std::string fTriggerDatabaseFile; - sqlite3 *db; - int rc; - - struct TriggerInfo_t { - int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI - double t_current_event = 0; - double t_previous_event = 0; - unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - std::int64_t WR_to_Spill_conversion = 0; - }; - - struct MWRdata_t { - std::vector< std::vector > MWR_times; - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - }; - - - static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] - - /// Returns the information of the trigger in the current event. - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - - /** - * @brief Determines spill times and extracts data based on multiwire devices. - * @param triggerInfo information from the trigger of this event - * @return times and unpacked data, per device (`"M875BB"`, `"M876BB"`, `"MMBTBB"`) - */ - MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; - - /** - * @brief Matches spill times with multiwire chamber data from the database. - * @param eventID ID of the event the information is associated to - * @param triggerInfo information from the trigger of this event - * @param MWRdata data from multiwire chambers - * @param isFirstEventInRun whether we are processing the first event of the run - * @param[out] beamInfos container to _add_ spill information records to - * @return count of matched spills - */ - int matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos - ) const; - - /** - * @brief Assembles and returns a spill information record. - * @param eventID ID of the event the information is associated to - * @param time time of the spill - * @param MWRdata all extracted data from multiwire chambers - * @param matched_MWR data from multiwire chambers matched with the time - * @return a `sbn::BNBSpillInfo` object with information on the spill at `time` - */ - sbn::BNBSpillInfo makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; - -/** - * @brief SQLite callback function for retrieving trigger_type from a query. - * @param data Pointer to the integer where the trigger type will be stored. - * @param argc Count of the number of columns returned by the query. - * @param argv Array of c-strings containing the column data of the query. - * @param columns Array of c-strings listing the names of the columns. - * @return 0 if successful. - */ -// int callback_trigger_type(void *data, -// int argc, -// char **argv, -// char **columns); - -/** - * @brief Queries the trigger database and finds the trigger_type of the matching trigger (if any). - * @param db The pointer to the SQLite database instance. - * @param run The run number of the current event (helps with queries). - * @param gate_time The time in milliseconds of the gate. - * @param threshold The required absolute time difference between gate and trigger. - * @return trigger_type -1: No matching trigger, 0: Majority, 1: MinBias - */ - int get_trigger_type_matching_gate(sqlite3 *db, - int func(void*,int,char**,char**), - int run, - long long int gate_time, - float threshold) const; - -}; - -int callback_trigger_type(void *data, int argc, char **argv, char **columns) -{ - int *result = static_cast(data); - // Does this query return non-NULL values? - if(argc > 0 && argv[0]) - *result = std::stoi(argv[0]); - else - *result = -1; - - return 0; -} - -int sbn::BNBRetriever::get_trigger_type_matching_gate(sqlite3 *db, int func(void*,int,char**,char**), int run, long long int gate_time, float threshold) const -{ - int trigger_type(-1), query_status; - std::stringstream query; - query << "SELECT trigger_type FROM triggerdata WHERE gate_type=1 AND run_number =" - << run - << " AND ABS(1000000000*wr_seconds + wr_nanoseconds - " - << std::fixed << gate_time - << ") < " - << threshold*1000000 - << " ORDER BY ABS(1000000000*wr_seconds + wr_nanoseconds - " - << std::fixed << gate_time - << ") LIMIT 1;"; - - query_status = sqlite3_exec(db, query.str().c_str(), func, &trigger_type, NULL); - if (query_status != SQLITE_OK) - { - mf::LogError("BNBEXTRetriever") << "SQL error: " << sqlite3_errmsg(db); - trigger_type = -1; - } - return trigger_type; -} - -sbn::BNBRetriever::BNBRetriever(Parameters const& params) - : EDProducer{params}, - fTimePad(params().TimePadding()), - raw_data_label(params().RawDataLabel()), - fDeviceUsedForTiming(params().DeviceUsedForTiming()), - bfp( ifbeam_handle->getBeamFolder(params().Bundle(), params().URL(), params().TimeWindow())), - bfp_mwr( ifbeam_handle->getBeamFolder(params().MultiWireBundle(), params().URL(), params().MWR_TimeWindow())), - fTriggerDatabaseFile(params().TriggerDatabaseFile()) -{ - - // Check fTimePad is positive - if (fTimePad < 0) { - throw art::Exception(art::errors::Configuration) - << "Parameter `TimePadding` must be non-negative (" << fTimePad << " was specified).\n"; - }//End Time check - - // how close in time does the spill time have to be from the DAQ time (in seconds). - // If these are too large then it fails to capture the device - // If these are too small then the time jitter in devices means we miss good data - // - // These values should likely not be changed unless authors of the IFBeam API are consulted - // - bfp->set_epsilon(0.02); //20 ms, this was tuned by hand and compared to IFBeamDB times - bfp_mwr->set_epsilon(0.5); - - //bfp_mwr->setValidWindow(86400); - bfp_mwr->setValidWindow(3605); - produces< std::vector< sbn::BNBSpillInfo >, art::InSubRun >(); - TotalBeamSpills = 0; - - cet::search_path sp("FW_SEARCH_PATH"); - std::string trigDB_path = sp.find_file(fTriggerDatabaseFile.c_str()); - - rc = sqlite3_open(trigDB_path.c_str(), &db); - if(rc) - { - fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); - throw art::Exception(art::errors::NotFound) - << "Can't open database: " << sqlite3_errmsg(db); - } - -} - - -void sbn::BNBRetriever::produce(art::Event& e) -{ - - // If this is the first event in the run, then ignore it - // We do not currently have the ability to figure out the first - // spill that the DAQ was sensitive to, so don't try to save any - // spill information - // - // TODO: long-term goal -- can we fix this? - // FIXME This is wrong.... - // Need to use: ICARUSTriggerV3Fragment long getTotalTriggerBNBMaj() const - - if (e.event() == 1) return; - - run_number = e.id().run(); - - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - - //We only want to process BNB gates, i.e. type 1 - if(triggerInfo.gate_type != 1) return; - // Keep track of the number of beam gates the DAQ thinks - // are in this job - TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - - - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); - - - int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); - - - if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) - mf::LogDebug("BNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; - else - mf::LogDebug("BNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; - -}//end iteration over art::Events - - -sbn::BNBRetriever::TriggerInfo_t sbn::BNBRetriever::extractTriggerInfo(art::Event const& e) const { - - //Here we read in the artdaq Fragments and extract three pieces of information: - // 1. The time of the current event, t_current_event - // 2. the time of the previously triggered event, t_previous_event (NOTE: Events are non-sequential!) - // 3. the number of beam spills since the previously triggered event, number_of_gates_since_previous_event - - auto const & raw_data = e.getProduct< std::vector >({ raw_data_label, "ICARUSTriggerV3" }); - auto const & extraTrigInfo = e.getProduct< sbn::ExtraTriggerInfo >("daqTrigger"); - - TriggerInfo_t triggerInfo; - - triggerInfo.WR_to_Spill_conversion = extraTrigInfo.WRtimeToTriggerTime; - - for(auto raw_datum : raw_data){ - - uint64_t artdaq_ts = raw_datum.timestamp(); - icarus::ICARUSTriggerV3Fragment frag(raw_datum); - std::string data = frag.GetDataString(); - char *buffer = const_cast(data.c_str()); - icarus::ICARUSTriggerInfo datastream_info = icarus::parse_ICARUSTriggerV3String(buffer); - triggerInfo.gate_type = datastream_info.gate_type; - triggerInfo.number_of_gates_since_previous_event = frag.getDeltaGatesBNBMaj(); - - /* - The DAQ trigger time is issued at the Beam Extraction Signal (BES) which is issued - 36 ms *after* the $1D of the BNB, which is what is used in the IFBeam database - - We subtract 36ms from the Trigger time to match our triggers to the spills in the - IFBeam database - - */ - - triggerInfo.t_current_event = static_cast(artdaq_ts-3.6e7)/(1000000000.0); //check this offset... - if(triggerInfo.gate_type == 1) - triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); - else - triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampOther()-3.6e7))/(1000000000.0); - - } - - mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Previous : " << triggerInfo.t_previous_event << ", Current : " << triggerInfo.t_current_event << ", Spill Count " << triggerInfo.number_of_gates_since_previous_event << std::endl; - - return triggerInfo; -} - - -sbn::BNBRetriever::MWRdata_t sbn::BNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { - - // These lines get everything primed within the IFBeamDB - // They seem redundant but they are needed - try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} - try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} - - //The multiwire chambers provide their - // data in a vector format but we'll have - // to sort through it in std::string format - // to correctly unpack it - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - std::vector< std::vector< double> > MWR_times; - unpacked_MWR.resize(3); - MWR_times.resize(3); - std::string packed_data_str; - - //Create a list of all the MWR devices with their different - // memory buffer increments - // generally in the format: "E:.{Memory Block}" - std::vector vars = bfp_mwr->GetDeviceList(); - mf::LogDebug("BNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; - // Tracking the time from the IFBeamDB - double time_for_mwr; - - // this is an iterator to track which of the - // three devices we will be working with - int dev = 0; - - // The MWR devices are annoying and have confusing buffer - // what we'll do is sort through all of them first and then - // match them to the closest spills in time - // - - // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; - int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; - mf::LogDebug("BNBRetriever") << " t_steps " << t_steps << std::endl; - - for(int t = 0; t < t_steps; t++){//Iterate through time increments - for (std::string const& var : vars) {// Iterate through the devices - - //Make sure we have a device - if(var.empty()){ - //mf::LogDebug("BNBRetriever") << " NO MWR DEVICES?!" << std::endl; - continue; - } - /// Check the device name and interate the double-vector index - if(var.find("M875BB") != std::string::npos ) dev = 0; - else if(var.find("M876BB") != std::string::npos ) dev = 1; - else if(var.find("MMBTBB") != std::string::npos ) dev = 2; - else{ - //mf::LogDebug("BNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; - continue;} - - time_for_mwr = 0; - - try{ - //Pull the MWR data for the device - // these data are "packed" - std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); - - //We'll convert this into a format - // that we can unpack doubles >> strings - // - packed_data_str.clear(); - packed_data_str += std::to_string(int(time_for_mwr)); - packed_data_str.append(","); - packed_data_str.append(var); - packed_data_str.append(",,"); - - /* for(auto const value: packed_MWR){ - packed_data_str += ','; - packed_data_str += std::to_string(int(value)); - }*/ - for(int j = 0; j < int(packed_MWR.size()); j++){ - packed_data_str += std::to_string(int(packed_MWR[j])); - if(j < int(packed_MWR.size())-1) - packed_data_str.append(","); - } - - // Use Zarko's unpacking function to turn this into consumeable data - std::vector MWR_times_temp; - - // There is a 35 ms offset between the toriod and the MWR times - // we'll just remove that here to match to the spill times - std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); - - //There are four events that are packed into one MWR IFBeam entry - for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ - - // If this entry has a unique time them store it for later - if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ - unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); - MWR_times[dev].push_back(MWR_times_temp[s]); - }//check for unique time - }//Iterate through the unpacked events - }//try - catch (WebAPIException &we) { - //Ignore when we can't find the MWR devices - // they don't always report and the timing of them can be annoying - - }//catch - }// Iterate over all the multiwire devices - }// Iterate over all times - - mf::LogDebug("BNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; - mf::LogDebug("BNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; - - return { std::move(MWR_times), std::move(unpacked_MWR) }; -} - - -int sbn::BNBRetriever::matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos -) const { - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - //Here we will start collecting all the other beamline devices - // First we get the times that the beamline device fired - // we have to pick a specific variable to use - std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); - - mf::LogDebug("BNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; - - // We'll keep track of how many of these spills match to our - // DAQ trigger times - int spill_count = 0; - int spills_removed = 0; - std::vector matched_MWR; - matched_MWR.resize(3); - - - // NOTE: for now, this is dead code because we don't - // do anything for the first event in a run. We may want to revisit - // this later to understand if there is a way we can do the POT - // accounting in the first event. - // - // Need to handle the first event in a run differently - if(isFirstEventInRun){ - - //We'll remove the spills after our event - int spills_after_our_target = 0; - // iterate through all the spills to find the - // spills that are after our triggered event - for (size_t i = 0; i < times_temps.size(); i++) { - if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ - spills_after_our_target++; - } - }//end loop through spill times - - // Remove the spills after our trigger - times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); - - // Remove the spills before the start of our Run - times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); - - }//end fix for "first event" - - ///reject time_stamps which have a trigger_type == 1 from data-base - //To-Do - - // mf::LogDebug("BNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; - // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; - // mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; - - // Iterating through each of the beamline times - for (size_t i = 0; i < times_temps.size(); i++) { - - // Only continue if these times are matched to our DAQ time - //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; - - if(!isFirstEventInRun){//We already addressed the "first event" above - if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ - //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - spills_removed++; - continue;} - if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ - spills_removed++; - //mf::LogDebug("BNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - continue;} - } - - //check if this spill is is minbias - /* - 40 ms was selected to be close to but outside the 66 ms - time of the next spill (when the beam is running at 15 Hz) - DocDB 33155 provides documentation of this - */ - - mf::LogDebug("BNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; - - if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ - mf::LogDebug("BNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; - - continue; - } - - //Great we found a matched spill! Let's count it - spill_count++; - - //Loop through the multiwire devices: - - for(int dev = 0; dev < int(MWR_times.size()); dev++){ - - //Loop through the multiwire times: - double Tdiff = 1000000000.; - matched_MWR[dev] = 0; - - for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ - - //found a candidate match! - if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} - - bool best_match = true; - - //Check for a better match... - for (size_t j = 0; j < times_temps.size(); j++) { - if( j == i) continue; - if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} - if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} - - //is there a better match later in the spill sequence - if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < - fabs((MWR_times[dev][mwrt] - times_temps[i]))){ - //we can have patience... - best_match = false; - break; - } - }//end better match check - - //Verified best match! - if(best_match == true){ - matched_MWR[dev] = mwrt; - Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); - } - - }//end loop over MWR times - - }//end loop over MWR devices - - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); - - beamInfos.push_back(std::move(spillInfo)); - - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - }//end iteration over beam device times - - // mf::LogDebug("BNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; - - return spill_count; -} - - -sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const -{ - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - // initializing all of our device carriers - // device definitions can be found in BNBSpillInfo.h - - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps - - double TOR860_time = 0; // units s - - // Here we request all the devices - // since sometimes devices fail to report we'll - // allow each to throw an exception but still move forward - // interpreting these failures will be part of the beam quality analyses - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - - //crunch the times - unsigned long int time_closest_int = (int) TOR860_time; - double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - - //Store everything in our data-product - sbn::BNBSpillInfo beamInfo; - beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.LM875A = LM875A; - beamInfo.LM875B = LM875B; - beamInfo.LM875C = LM875C; - beamInfo.HP875 = HP875; - beamInfo.VP875 = VP875; - beamInfo.HPTG1 = HPTG1; - beamInfo.VPTG1 = VPTG1; - beamInfo.HPTG2 = HPTG2; - beamInfo.VPTG2 = VPTG2; - beamInfo.BTJT2 = BTJT2; - beamInfo.THCURR = THCURR; - beamInfo.spill_time_s = time_closest_int; - beamInfo.spill_time_ns = time_closest_ns; - - for(auto const& MWRdata: unpacked_MWR){ - std::ignore = MWRdata; - assert(!MWRdata.empty()); - } - - if(unpacked_MWR[0].empty()){ - beamInfo.M875BB.clear(); - beamInfo.M875BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; - beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); - } - - if(unpacked_MWR[1].empty()){ - beamInfo.M876BB.clear(); - beamInfo.M876BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; - beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); - } - - if(unpacked_MWR[2].empty()){ - beamInfo.MMBTBB.clear(); - beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; - beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); - } - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun - - return beamInfo; -} - - -void sbn::BNBRetriever::beginSubRun(art::SubRun& sr) -{ - return; -} - -//____________________________________________________________________________ -void sbn::BNBRetriever::endSubRun(art::SubRun& sr) -{ - // We will add all of the BNBSpillInfo data-products to the - // art::SubRun so it persists - // currently this is ~2.7 kB/event or ~0.07 kB/spill - -mf::LogDebug("BNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; -mf::LogDebug("BNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; - - auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); - std::swap(*p, fOutbeamInfos); - - sr.put(std::move(p), art::subRunFragment()); - - return; -} - -DEFINE_ART_MODULE(sbn::BNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt deleted file mode 100644 index 1f0dab80a..000000000 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/CMakeLists.txt +++ /dev/null @@ -1,55 +0,0 @@ -find_package(ifbeam) -find_package(ifdh_art) - - -art_make_library(LIBRARIES Boost::system - LIBRARY_NAME sbn_BNBSpillInfoRetriever_MWRData - SOURCE MWRData.cpp -) - - -cet_build_plugin(BNBRetriever art::module - LIBRARIES - art::Persistency_Common - art::Utilities canvas::canvas - cetlib::cetlib cetlib_except::cetlib_except - ROOT::X3d - Boost::system - messagefacility::MF_MessageLogger - ifbeam::ifbeam - ifdh_art::IFBeam_service - SQLite::SQLite3 - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS - artdaq_core::artdaq-core_Utilities - sbn_BNBSpillInfoRetriever_MWRData - sbnobj::Common_POTAccounting - larcorealg::CoreUtils -) - -cet_build_plugin(SBNDBNBRetriever art::module - LIBRARIES - art::Persistency_Common - art::Utilities canvas::canvas - cetlib::cetlib cetlib_except::cetlib_except - ROOT::X3d - Boost::system - messagefacility::MF_MessageLogger - ifbeam::ifbeam - ifdh_art::IFBeam_service - SQLite::SQLite3 - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND - artdaq_core::artdaq-core_Utilities - sbn_BNBSpillInfoRetriever_MWRData - sbnobj::Common_POTAccounting - larcorealg::CoreUtils -) - -install_headers() -install_fhicl() -install_source() - diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/BNBRetriever/MWRData.cpp deleted file mode 100644 index 48d0bda3f..000000000 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/MWRData.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "MWRData.h" - -using namespace std; - -namespace sbn{ - - std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const -{ - - std::vector > unpacked_data; - unpacked_data.resize(4); - short data[444]; - - std::vector row(0); - boost::split(row, packed_data, boost::is_any_of(",")); - if (row.size()==447) { - for (int i=3;i<447;i++) { - data[i-3]=atoi(row[i].c_str()); - } - string devname=row[1].substr(0,8); - for (int idev=0;idev<4;idev++) { - mwrpulse_t mwr=getMWRdata(data,idev); - time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.hor[ich]); - } - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.ver[ich]); - } - } - } else { - cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< -namespace sbn{ -class MWRData -{ - typedef struct swicheader_t { - long timesec; - long timensec; - long gpstime1; - long gpstime2; - short boosterevent; - short mievent; - short hz15micnt; - long delta1f; - short pulsemi; - short pulsesc; - } swicheader_t; - - typedef struct mwrpulse_t { - short hor[48]; - short ver[48]; - swicheader_t sheader; - } mwrpulse_t; - - static long flipByte(long data) - { - return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); - } - - mwrpulse_t getMWRdata(short* data, int nblock) const; - - public: - std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; -}; -} - -#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc deleted file mode 100644 index bb970c366..000000000 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/SBNDBNBRetriever_module.cc +++ /dev/null @@ -1,596 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Class: SBNDBNBRetriever -// Plugin Type: producer -// File: SBNDBNBRetriever_module.cc -// -//////////////////////////////////////////////////////////////////////// - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -#include "canvas/Utilities/InputTag.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include -#include -#include -#include - -#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" -#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" -#include "artdaq-core/Data/ContainerFragment.hh" -//#include "sbndcode/Decoders/PTB/sbndptb.h" -#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" - -#include "ifdh_art/IFBeamService/IFBeam_service.h" -#include "ifbeam_c.h" -#include "MWRData.h" - -#include "larcorealg/CoreUtils/counter.h" - -class SBNDBNBRetriever : public art::EDProducer { -public: - explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); - - // Plugins should not be copied or assigned. - SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; - - // Required functions. - void produce(art::Event & e) override; - void beginSubRun(art::SubRun& sr) override; - void endSubRun(art::SubRun& sr) override; - -private: - // Declare member data here. - std::vector< sbn::BNBSpillInfo > fOutbeamInfos; - double fTimePad; - std::string fInputLabel; - std::string fInputNonContainerInstance; - std::string fDeviceUsedForTiming; - std::string fOutputInstance; - std::string raw_data_label; - int fDebugLevel; - sbn::MWRData mwrdata; - art::ServiceHandle ifbeam_handle; - std::unique_ptr bfp; - std::unique_ptr bfp_mwr; - - struct PTBInfo_t { - double prevPTBTimeStamp = 0; - unsigned int GateCounter = 0; // FIXME needs to be integral type - }; - - struct TriggerInfo_t { - double t_current_event = 0; - double t_previous_event = 0; - unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - }; - - struct MWRdata_t { - std::vector< std::vector > MWR_times; - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - }; - - static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] - - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; - double extractTDCTimeStamp(art::Handle > cont_frags) const; - MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; - int matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos - ) const; - unsigned int TotalBeamSpills; - sbn::BNBSpillInfo makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; -}; - -SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) - : EDProducer{params} { - raw_data_label = params.get("raw_data_label", "daq"); - fInputLabel = params.get("InputLabel"); - fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); - fTimePad = params.get("TimePadding"); - fInputNonContainerInstance = params.get("InputNonContainerInstance"); - fOutputInstance = params.get("OutputInstance"); - fDebugLevel = params.get("DebugLevel",0); - bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); - bfp->set_epsilon(0.02); - bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); - bfp_mwr->set_epsilon(0.5); - bfp_mwr->setValidWindow(3605); - TotalBeamSpills = 0; -} - -int eventNum =0; -int _run; -int _subrun; -int _event; - -void SBNDBNBRetriever::produce(art::Event & e) -{ - - // If this is the first event in the run, then ignore it - // We do not currently have the ability to figure out the first - // spill that the DAQ was sensitive to, so don't try to save any - // spill information - - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); - - int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); - - if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) - mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; - else - mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; -} - -SBNDBNBRetriever::PTBInfo_t SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { - int numcont = 0; - PTBInfo_t PTBInfo; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck - for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) - { - if(ctb_frag.Trigger(word_i)){ - uint32_t wt = 0; - uint32_t word_type = ctb_frag.Word(word_i)->word_type; - wt = word_type; - if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) - { - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; - } - } - } //End of loop over the number of trigger words - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - return PTBInfo; -} - -double SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { - int numcont = 0; - uint64_t TDCTimeStamp = 0; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::TDCTimestampFragment tdc_frag(frag); - TDCTimeStamp = tdc_frag.getTDCTimestamp()->timestamp_ns()/1e9; - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - return TDCTimeStamp; -} - -SBNDBNBRetriever::TriggerInfo_t SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { - // Using TDC for current event, but PTB for previous event - art::InputTag PTB_itag("daq", "ContainerPTB"); - auto PTB_cont_frags = e.getHandle(PTB_itag); - - art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); - auto TDC_cont_frags = e.getHandle(TDC_itag); - - PTBInfo_t PTBInfo; - TriggerInfo_t triggerInfo; - PTBInfo = extractPTBInfo(PTB_cont_frags); - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - - triggerInfo.t_current_event = TDCTimeStamp; - triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; - triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - - return triggerInfo; -} - -SBNDBNBRetriever::MWRdata_t SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { - - // These lines get everything primed within the IFBeamDB. - try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; - try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; - - // The multiwire chambers provide their - // data in a vector format but we'll have - // to sort through it in std::string format - // to correctly unpack it - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - std::vector< std::vector< double> > MWR_times; - unpacked_MWR.resize(3); - MWR_times.resize(3); - std::string packed_data_str; - - // Create a list of all the MWR devices with their different - // memory buffer increments - // generally in the format: "E:.{Memory Block}" - std::vector vars = bfp_mwr->GetDeviceList(); - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; - // Tracking the time from the IFBeamDB - double time_for_mwr; - - // this is an iterator to track which of the - // three devices we will be working with - int dev = 0; - - // The MWR devices are annoying and have confusing buffer - // what we'll do is sort through all of them first and then - // match them to the closest spills in time - // - - // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; - int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; - mf::LogDebug("SBNDBNBRetriever") << " t_steps " << t_steps << std::endl; - - for(int t = 0; t < t_steps; t++){//Iterate through time increments - for (std::string const& var : vars) {// Iterate through the devices - - //Make sure we have a device - if(var.empty()){ - //mf::LogDebug("SBNDBNBRetriever") << " NO MWR DEVICES?!" << std::endl; - continue; - } - /// Check the device name and interate the double-vector index - if(var.find("M875BB") != std::string::npos ) dev = 0; - else if(var.find("M876BB") != std::string::npos ) dev = 1; - else if(var.find("MMBTBB") != std::string::npos ) dev = 2; - else{ - //mf::LogDebug("SBNDBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; - continue;} - - time_for_mwr = 0; - - try{ - - //Pull the MWR data for the device - // these data are "packed" - std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); - - //We'll convert this into a format - // that we can unpack doubles >> strings - // - packed_data_str.clear(); - packed_data_str += std::to_string(int(time_for_mwr)); - packed_data_str.append(","); - packed_data_str.append(var); - packed_data_str.append(",,"); - - /* for(auto const value: packed_MWR){ - packed_data_str += ','; - packed_data_str += std::to_string(int(value)); - }*/ - for(int j = 0; j < int(packed_MWR.size()); j++){ - packed_data_str += std::to_string(int(packed_MWR[j])); - if(j < int(packed_MWR.size())-1) - packed_data_str.append(","); - } - - // Use Zarko's unpacking function to turn this into consumeable data - std::vector MWR_times_temp; - - // There is a 35 ms offset between the toriod and the MWR times - // we'll just remove that here to match to the spill times - std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); - - //There are four events that are packed into one MWR IFBeam entry - for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ - - // If this entry has a unique time them store it for later - if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ - unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); - MWR_times[dev].push_back(MWR_times_temp[s]); - }//check for unique time - }//Iterate through the unpacked events - }//try - catch (WebAPIException &we) { - //Ignore when we can't find the MWR devices - // they don't always report and the timing of them can be annoying - }//catch - }// Iterate over all the multiwire devices - }// Iterate over all times - - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; - - return { std::move(MWR_times), std::move(unpacked_MWR) }; -} - -int SBNDBNBRetriever::matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos -) const { - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - //Here we will start collecting all the other beamline devices - // First we get the times that the beamline device fired - // we have to pick a specific variable to use - std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); - - mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; - - // We'll keep track of how many of these spills match to our - // DAQ trigger times - int spill_count = 0; - int spills_removed = 0; - std::vector matched_MWR; - matched_MWR.resize(3); - - // NOTE: for now, this is dead code because we don't - // do anything for the first event in a run. We may want to revisit - // this later to understand if there is a way we can do the POT - // accounting in the first event. - // - // Need to handle the first event in a run differently - if(isFirstEventInRun){ - //We'll remove the spills after our event - int spills_after_our_target = 0; - // iterate through all the spills to find the - // spills that are after our triggered event - for (size_t i = 0; i < times_temps.size(); i++) { - if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ - spills_after_our_target++; - } - }//end loop through spill times - - // Remove the spills after our trigger - times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); - - // Remove the spills before the start of our Run - times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); - - }//end fix for "first event" - - ///reject time_stamps which have a trigger_type == 1 from data-base - //To-Do - - // mf::LogDebug("SBNDBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; - - // Iterating through each of the beamline times - for (size_t i = 0; i < times_temps.size(); i++) { - - // Only continue if these times are matched to our DAQ time - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; - - if(!isFirstEventInRun){//We already addressed the "first event" above - if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ - //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - spills_removed++; - continue;} - if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ - spills_removed++; - //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - continue;} - } - - //check if this spill is is minbias - /* - 40 ms was selected to be close to but outside the 66 ms - time of the next spill (when the beam is running at 15 Hz) - DocDB 33155 provides documentation of this - */ - - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; - - // if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; - - // continue; - //} - - //Great we found a matched spill! Let's count it - spill_count++; - - //Loop through the multiwire devices: - - for(int dev = 0; dev < int(MWR_times.size()); dev++){ - - //Loop through the multiwire times: - double Tdiff = 1000000000.; - matched_MWR[dev] = 0; - - for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ - - //found a candidate match! - if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} - - bool best_match = true; - - //Check for a better match... - for (size_t j = 0; j < times_temps.size(); j++) { - if( j == i) continue; - if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} - if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} - - //is there a better match later in the spill sequence - if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < - fabs((MWR_times[dev][mwrt] - times_temps[i]))){ - //we can have patience... - best_match = false; - break; - } - }//end better match check - - //Verified best match! - if(best_match == true){ - matched_MWR[dev] = mwrt; - Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); - } - - }//end loop over MWR times - - }//end loop over MWR devices - - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); - - beamInfos.push_back(std::move(spillInfo)); - - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - }//end iteration over beam device times - - // mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; - - return spill_count; -} - -sbn::BNBSpillInfo SBNDBNBRetriever::makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const -{ - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - // initializing all of our device carriers - // device definitions can be found in BNBSpillInfo.h - - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps - - double TOR860_time = 0; // units s - - // Here we request all the devices - // since sometimes devices fail to report we'll - // allow each to throw an exception but still move forward - // interpreting these failures will be part of the beam quality analyses - - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - - //crunch the times - unsigned long int time_closest_int = (int) TOR860_time; - double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - - //Store everything in our data-product - sbn::BNBSpillInfo beamInfo; - beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.LM875A = LM875A; - beamInfo.LM875B = LM875B; - beamInfo.LM875C = LM875C; - beamInfo.HP875 = HP875; - beamInfo.VP875 = VP875; - beamInfo.HPTG1 = HPTG1; - beamInfo.VPTG1 = VPTG1; - beamInfo.HPTG2 = HPTG2; - beamInfo.VPTG2 = VPTG2; - beamInfo.BTJT2 = BTJT2; - beamInfo.THCURR = THCURR; - beamInfo.spill_time_s = time_closest_int; - beamInfo.spill_time_ns = time_closest_ns; - - for(auto const& MWRdata: unpacked_MWR){ - std::ignore = MWRdata; - assert(!MWRdata.empty()); - } - - if(unpacked_MWR[0].empty()){ - beamInfo.M875BB.clear(); - beamInfo.M875BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; - beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); - } - - if(unpacked_MWR[1].empty()){ - beamInfo.M876BB.clear(); - beamInfo.M876BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; - beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); - } - - if(unpacked_MWR[2].empty()){ - beamInfo.MMBTBB.clear(); - beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; - beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); - } - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun - - return beamInfo; -} - -void SBNDBNBRetriever::beginSubRun(art::SubRun& sr) -{ - return; -} - -void SBNDBNBRetriever::endSubRun(art::SubRun& sr) -{ - mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; - mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; - - auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); - std::swap(*p, fOutbeamInfos); - - sr.put(std::move(p), art::subRunFragment()); - - return; -} - -DEFINE_ART_MODULE(SBNDBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt index 0caadf2a5..b99d4dcfa 100644 --- a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt @@ -1,4 +1,5 @@ -add_subdirectory(BNBRetriever) +add_subdirectory(ICARUSBNBRetriever) +add_subdirectory(SBNDBNBRetriever) add_subdirectory(NuMIRetriever) add_subdirectory(BNBEXTRetriever) add_subdirectory(NuMIEXTRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/job/bnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/bnbspillinfo.fcl deleted file mode 100644 index 3aece8658..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/bnbspillinfo.fcl +++ /dev/null @@ -1,17 +0,0 @@ - -BEGIN_PROLOG - -bnbspillinfo: { - - module_type: "BNBRetriever" - TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - URL: "" #keep this blank and we're good - Bundle: "BoosterNeutrinoBeam_read" - MultiWireBundle: "BNBMultiWire" - TimeWindow: "700" #seconds - MWR_TimeWindow: "3601" #seconds - raw_data_label: "daq" - DeviceUsedForTiming: "E:TOR860" - TriggerDatabaseFile: "triggerDatabase/icarus_triggers.db" -} -END_PROLOG diff --git a/sbncode/BeamSpillInfoRetriever/job/run_bnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_bnbinfo_sbn.fcl deleted file mode 100644 index 34f8f689d..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/run_bnbinfo_sbn.fcl +++ /dev/null @@ -1,46 +0,0 @@ -#include "bnbspillinfo.fcl" - -process_name: BNBInfoGen - -services:{ - - message: { - debugModules: [ "*" ] - destinations: { - LogDebugFile:{ - type: "file" - filename: "debug.log" - append: false - threshold: "DEBUG" - categories: { - default: {} - } - } - } - } - IFBeam:{} -} - - -source: { - -} - -physics: { - producers: { - bnbinfo: @local::bnbspillinfo - } - - simulate: [bnbinfo ] - stream1: [ out1 ] -} - -outputs: { - out1: { - module_type: RootOutput - fileName: "%ifb_%tc_bnbinfo.root" - dataTier: "raw" - compressionLevel: 1 - } -} - From 3742907492ba3f2219e45f7682e866a8405afa10 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Tue, 12 Nov 2024 14:10:13 -0600 Subject: [PATCH 024/367] Build issues returned to match branch --- .../ICARUSBNBRetriever/CMakeLists.txt | 34 + .../ICARUSBNBRetriever_module.cc | 780 ++++++++++++++++++ .../ICARUSBNBRetriever/MWRData.cpp | 71 ++ .../ICARUSBNBRetriever/MWRData.h | 39 + .../SBNDBNBRetriever/CMakeLists.txt | 34 + .../SBNDBNBRetriever/MWRData.cpp | 71 ++ .../SBNDBNBRetriever/MWRData.h | 39 + .../SBNDBNBRetriever_module.cc | 600 ++++++++++++++ .../job/icarusspillinfo.fcl | 17 + .../job/run_icarusbnbinfo_sbn.fcl | 46 ++ sbncode/CAFMaker/FillReco.cxx | 8 +- 11 files changed, 1735 insertions(+), 4 deletions(-) create mode 100644 sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt create mode 100644 sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc create mode 100644 sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp create mode 100644 sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.h create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.h create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc create mode 100644 sbncode/BeamSpillInfoRetriever/job/icarusspillinfo.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt new file mode 100644 index 000000000..2668311a3 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt @@ -0,0 +1,34 @@ +find_package(ifbeam) +find_package(ifdh_art) + + +art_make_library(LIBRARIES Boost::system + LIBRARY_NAME sbn_ICARUSBNBSpillInfoRetriever_MWRData + SOURCE MWRData.cpp +) + + +cet_build_plugin(ICARUSBNBRetriever art::module + LIBRARIES + art::Persistency_Common + art::Utilities canvas::canvas + cetlib::cetlib cetlib_except::cetlib_except + ROOT::X3d + Boost::system + messagefacility::MF_MessageLogger + ifbeam::ifbeam + ifdh_art::IFBeam_service + SQLite::SQLite3 + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS + artdaq_core::artdaq-core_Utilities + sbn_ICARUSBNBSpillInfoRetriever_MWRData + sbnobj::Common_POTAccounting + larcorealg::CoreUtils +) + +install_headers() +install_fhicl() +install_source() + diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc new file mode 100644 index 000000000..f559c1df8 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -0,0 +1,780 @@ +/** ******************************************************************** + * @file ICARUSBNBRetriever_module.cc + * @date Wed April 9 2021 + * @author J. Zennamo (FNAL) + * + * Based heavily on code by Z. Pavlovic written for MicroBooNE + * Based heavily on code by NOvA collaboration (Thanks NOvA!): + * https://cdcvs.fnal.gov/redmine/projects/novaart/repository/entry/trunk/IFDBSpillInfo/BNBInfo_module.cc + * Database implementation by Justin Mueller + */ + +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/types/Atom.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "larcorealg/CoreUtils/counter.h" + +#include "artdaq-core/Data/Fragment.hh" +#include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV3Fragment.hh" +#include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" + +#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" + +#include "ifdh_art/IFBeamService/IFBeam_service.h" +#include "ifbeam_c.h" +#include "MWRData.h" + +#include +#include +#include + +#include +#include +#include + +namespace sbn { + class ICARUSBNBRetriever; +} + +class sbn::ICARUSBNBRetriever : public art::EDProducer { +public: + + struct Config { + + using Name = fhicl::Name; + using Comment = fhicl::Comment; + + fhicl::Atom TimePadding { + Name{ "TimePadding" }, + Comment{ "extension to the time window considered when collecting spills [seconds]" }, + 0.0333 // default + }; + + fhicl::Atom RawDataLabel { + Name{ "raw_data_label" }, + Comment{ "art data product instance name for trigger information (product label is 'daq')" } + }; + + fhicl::Atom DeviceUsedForTiming { + Name{ "DeviceUsedForTiming" }, + Comment{ "name in the IFBeam database of the device used to extract spill times" } + }; + + fhicl::Atom URL { + Name{ "URL" }, + Comment{ "IFBeam database access URL" } + }; + + fhicl::Atom Bundle { + Name{ "Bundle" }, + Comment{ "" } // explain what this is and which database/table it's looking for + }; + + fhicl::Atom TimeWindow { + Name{ "TimeWindow" }, + Comment{ "" } // explain what this is, what's for and its unit + }; + + fhicl::Atom MultiWireBundle { + Name{ "MultiWireBundle" }, + Comment{ "" } // explain what this is and which database/table it's looking for + }; + + fhicl::Atom MWR_TimeWindow { + Name{ "MWR_TimeWindow" }, + Comment{ "" } // explain what this is, what's for and its unit + }; + + fhicl::Atom TriggerDatabaseFile { + Name{ "TriggerDatabaseFile" }, + Comment{ "" } // explain what this is, what's for and its unit + }; + + + }; // Config + + using Parameters = art::EDProducer::Table; + + + explicit ICARUSBNBRetriever(Parameters const& params); + // The compiler-generated destructor is fine for non-base + // classes without bare pointers or other resource use. + + // Plugins should not be copied or assigned. + ICARUSBNBRetriever(ICARUSBNBRetriever const&) = delete; + ICARUSBNBRetriever(ICARUSBNBRetriever&&) = delete; + ICARUSBNBRetriever& operator=(ICARUSBNBRetriever const&) = delete; + ICARUSBNBRetriever& operator=(ICARUSBNBRetriever&&) = delete; + + // Required functions. + void produce(art::Event& e) override; + void beginSubRun(art::SubRun& sr) override; + void endSubRun(art::SubRun& sr) override; + +private: + // input labels + std::vector< sbn::BNBSpillInfo > fOutbeamInfos; + double fTimePad; + std::string fURL; + MWRData mwrdata; + int run_number; + std::string raw_data_label; + std::string fDeviceUsedForTiming; + unsigned int TotalBeamSpills; + // + art::ServiceHandle ifbeam_handle; + std::unique_ptr bfp; + std::unique_ptr bfp_mwr; + + // + std::string fTriggerDatabaseFile; + sqlite3 *db; + int rc; + + struct TriggerInfo_t { + int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI + double t_current_event = 0; + double t_previous_event = 0; + unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type + std::int64_t WR_to_Spill_conversion = 0; + }; + + struct MWRdata_t { + std::vector< std::vector > MWR_times; + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + }; + + + static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] + + /// Returns the information of the trigger in the current event. + TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + + /** + * @brief Determines spill times and extracts data based on multiwire devices. + * @param triggerInfo information from the trigger of this event + * @return times and unpacked data, per device (`"M875BB"`, `"M876BB"`, `"MMBTBB"`) + */ + MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; + + /** + * @brief Matches spill times with multiwire chamber data from the database. + * @param eventID ID of the event the information is associated to + * @param triggerInfo information from the trigger of this event + * @param MWRdata data from multiwire chambers + * @param isFirstEventInRun whether we are processing the first event of the run + * @param[out] beamInfos container to _add_ spill information records to + * @return count of matched spills + */ + int matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos + ) const; + + /** + * @brief Assembles and returns a spill information record. + * @param eventID ID of the event the information is associated to + * @param time time of the spill + * @param MWRdata all extracted data from multiwire chambers + * @param matched_MWR data from multiwire chambers matched with the time + * @return a `sbn::BNBSpillInfo` object with information on the spill at `time` + */ + sbn::BNBSpillInfo makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; + +/** + * @brief SQLite callback function for retrieving trigger_type from a query. + * @param data Pointer to the integer where the trigger type will be stored. + * @param argc Count of the number of columns returned by the query. + * @param argv Array of c-strings containing the column data of the query. + * @param columns Array of c-strings listing the names of the columns. + * @return 0 if successful. + */ +// int callback_trigger_type(void *data, +// int argc, +// char **argv, +// char **columns); + +/** + * @brief Queries the trigger database and finds the trigger_type of the matching trigger (if any). + * @param db The pointer to the SQLite database instance. + * @param run The run number of the current event (helps with queries). + * @param gate_time The time in milliseconds of the gate. + * @param threshold The required absolute time difference between gate and trigger. + * @return trigger_type -1: No matching trigger, 0: Majority, 1: MinBias + */ + int get_trigger_type_matching_gate(sqlite3 *db, + int func(void*,int,char**,char**), + int run, + long long int gate_time, + float threshold) const; + +}; + +int callback_trigger_type(void *data, int argc, char **argv, char **columns) +{ + int *result = static_cast(data); + // Does this query return non-NULL values? + if(argc > 0 && argv[0]) + *result = std::stoi(argv[0]); + else + *result = -1; + + return 0; +} + +int sbn::ICARUSBNBRetriever::get_trigger_type_matching_gate(sqlite3 *db, int func(void*,int,char**,char**), int run, long long int gate_time, float threshold) const +{ + int trigger_type(-1), query_status; + std::stringstream query; + query << "SELECT trigger_type FROM triggerdata WHERE gate_type=1 AND run_number =" + << run + << " AND ABS(1000000000*wr_seconds + wr_nanoseconds - " + << std::fixed << gate_time + << ") < " + << threshold*1000000 + << " ORDER BY ABS(1000000000*wr_seconds + wr_nanoseconds - " + << std::fixed << gate_time + << ") LIMIT 1;"; + + query_status = sqlite3_exec(db, query.str().c_str(), func, &trigger_type, NULL); + if (query_status != SQLITE_OK) + { + mf::LogError("BNBEXTRetriever") << "SQL error: " << sqlite3_errmsg(db); + trigger_type = -1; + } + return trigger_type; +} + +sbn::ICARUSBNBRetriever::ICARUSBNBRetriever(Parameters const& params) + : EDProducer{params}, + fTimePad(params().TimePadding()), + raw_data_label(params().RawDataLabel()), + fDeviceUsedForTiming(params().DeviceUsedForTiming()), + bfp( ifbeam_handle->getBeamFolder(params().Bundle(), params().URL(), params().TimeWindow())), + bfp_mwr( ifbeam_handle->getBeamFolder(params().MultiWireBundle(), params().URL(), params().MWR_TimeWindow())), + fTriggerDatabaseFile(params().TriggerDatabaseFile()) +{ + + // Check fTimePad is positive + if (fTimePad < 0) { + throw art::Exception(art::errors::Configuration) + << "Parameter `TimePadding` must be non-negative (" << fTimePad << " was specified).\n"; + }//End Time check + + // how close in time does the spill time have to be from the DAQ time (in seconds). + // If these are too large then it fails to capture the device + // If these are too small then the time jitter in devices means we miss good data + // + // These values should likely not be changed unless authors of the IFBeam API are consulted + // + bfp->set_epsilon(0.02); //20 ms, this was tuned by hand and compared to IFBeamDB times + bfp_mwr->set_epsilon(0.5); + + //bfp_mwr->setValidWindow(86400); + bfp_mwr->setValidWindow(3605); + produces< std::vector< sbn::BNBSpillInfo >, art::InSubRun >(); + TotalBeamSpills = 0; + + cet::search_path sp("FW_SEARCH_PATH"); + std::string trigDB_path = sp.find_file(fTriggerDatabaseFile.c_str()); + + rc = sqlite3_open(trigDB_path.c_str(), &db); + if(rc) + { + fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); + throw art::Exception(art::errors::NotFound) + << "Can't open database: " << sqlite3_errmsg(db); + } + +} + + +void sbn::ICARUSBNBRetriever::produce(art::Event& e) +{ + + // If this is the first event in the run, then ignore it + // We do not currently have the ability to figure out the first + // spill that the DAQ was sensitive to, so don't try to save any + // spill information + // + // TODO: long-term goal -- can we fix this? + // FIXME This is wrong.... + // Need to use: ICARUSTriggerV3Fragment long getTotalTriggerBNBMaj() const + + if (e.event() == 1) return; + + run_number = e.id().run(); + + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + + //We only want to process BNB gates, i.e. type 1 + if(triggerInfo.gate_type != 1) return; + // Keep track of the number of beam gates the DAQ thinks + // are in this job + TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; + + + MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); + + + int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); + + + if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) + mf::LogDebug("ICARUSBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; + else + mf::LogDebug("ICARUSBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; + +}//end iteration over art::Events + + +sbn::ICARUSBNBRetriever::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& e) const { + + //Here we read in the artdaq Fragments and extract three pieces of information: + // 1. The time of the current event, t_current_event + // 2. the time of the previously triggered event, t_previous_event (NOTE: Events are non-sequential!) + // 3. the number of beam spills since the previously triggered event, number_of_gates_since_previous_event + + auto const & raw_data = e.getProduct< std::vector >({ raw_data_label, "ICARUSTriggerV3" }); + auto const & extraTrigInfo = e.getProduct< sbn::ExtraTriggerInfo >("daqTrigger"); + + TriggerInfo_t triggerInfo; + + triggerInfo.WR_to_Spill_conversion = extraTrigInfo.WRtimeToTriggerTime; + + for(auto raw_datum : raw_data){ + + uint64_t artdaq_ts = raw_datum.timestamp(); + icarus::ICARUSTriggerV3Fragment frag(raw_datum); + std::string data = frag.GetDataString(); + char *buffer = const_cast(data.c_str()); + icarus::ICARUSTriggerInfo datastream_info = icarus::parse_ICARUSTriggerV3String(buffer); + triggerInfo.gate_type = datastream_info.gate_type; + triggerInfo.number_of_gates_since_previous_event = frag.getDeltaGatesBNBMaj(); + + /* + The DAQ trigger time is issued at the Beam Extraction Signal (BES) which is issued + 36 ms *after* the $1D of the BNB, which is what is used in the IFBeam database + + We subtract 36ms from the Trigger time to match our triggers to the spills in the + IFBeam database + + */ + + triggerInfo.t_current_event = static_cast(artdaq_ts-3.6e7)/(1000000000.0); //check this offset... + if(triggerInfo.gate_type == 1) + triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); + else + triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampOther()-3.6e7))/(1000000000.0); + + } + + mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Previous : " << triggerInfo.t_previous_event << ", Current : " << triggerInfo.t_current_event << ", Spill Count " << triggerInfo.number_of_gates_since_previous_event << std::endl; + + return triggerInfo; +} + + +sbn::ICARUSBNBRetriever::MWRdata_t sbn::ICARUSBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { + + // These lines get everything primed within the IFBeamDB + // They seem redundant but they are needed + try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} + try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} + + //The multiwire chambers provide their + // data in a vector format but we'll have + // to sort through it in std::string format + // to correctly unpack it + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + std::vector< std::vector< double> > MWR_times; + unpacked_MWR.resize(3); + MWR_times.resize(3); + std::string packed_data_str; + + //Create a list of all the MWR devices with their different + // memory buffer increments + // generally in the format: "E:.{Memory Block}" + std::vector vars = bfp_mwr->GetDeviceList(); + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; + // Tracking the time from the IFBeamDB + double time_for_mwr; + + // this is an iterator to track which of the + // three devices we will be working with + int dev = 0; + + // The MWR devices are annoying and have confusing buffer + // what we'll do is sort through all of them first and then + // match them to the closest spills in time + // + + // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; + int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; + mf::LogDebug("ICARUSBNBRetriever") << " t_steps " << t_steps << std::endl; + + for(int t = 0; t < t_steps; t++){//Iterate through time increments + for (std::string const& var : vars) {// Iterate through the devices + + //Make sure we have a device + if(var.empty()){ + //mf::LogDebug("ICARUSBNBRetriever") << " NO MWR DEVICES?!" << std::endl; + continue; + } + /// Check the device name and interate the double-vector index + if(var.find("M875BB") != std::string::npos ) dev = 0; + else if(var.find("M876BB") != std::string::npos ) dev = 1; + else if(var.find("MMBTBB") != std::string::npos ) dev = 2; + else{ + //mf::LogDebug("ICARUSBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; + continue;} + + time_for_mwr = 0; + + try{ + //Pull the MWR data for the device + // these data are "packed" + std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); + + //We'll convert this into a format + // that we can unpack doubles >> strings + // + packed_data_str.clear(); + packed_data_str += std::to_string(int(time_for_mwr)); + packed_data_str.append(","); + packed_data_str.append(var); + packed_data_str.append(",,"); + + /* for(auto const value: packed_MWR){ + packed_data_str += ','; + packed_data_str += std::to_string(int(value)); + }*/ + for(int j = 0; j < int(packed_MWR.size()); j++){ + packed_data_str += std::to_string(int(packed_MWR[j])); + if(j < int(packed_MWR.size())-1) + packed_data_str.append(","); + } + + // Use Zarko's unpacking function to turn this into consumeable data + std::vector MWR_times_temp; + + // There is a 35 ms offset between the toriod and the MWR times + // we'll just remove that here to match to the spill times + std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); + + //There are four events that are packed into one MWR IFBeam entry + for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ + + // If this entry has a unique time them store it for later + if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ + unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); + MWR_times[dev].push_back(MWR_times_temp[s]); + }//check for unique time + }//Iterate through the unpacked events + }//try + catch (WebAPIException &we) { + //Ignore when we can't find the MWR devices + // they don't always report and the timing of them can be annoying + + }//catch + }// Iterate over all the multiwire devices + }// Iterate over all times + + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; + mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; + + return { std::move(MWR_times), std::move(unpacked_MWR) }; +} + + +int sbn::ICARUSBNBRetriever::matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos +) const { + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + //Here we will start collecting all the other beamline devices + // First we get the times that the beamline device fired + // we have to pick a specific variable to use + std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); + + mf::LogDebug("ICARUSBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; + + // We'll keep track of how many of these spills match to our + // DAQ trigger times + int spill_count = 0; + int spills_removed = 0; + std::vector matched_MWR; + matched_MWR.resize(3); + + + // NOTE: for now, this is dead code because we don't + // do anything for the first event in a run. We may want to revisit + // this later to understand if there is a way we can do the POT + // accounting in the first event. + // + // Need to handle the first event in a run differently + if(isFirstEventInRun){ + + //We'll remove the spills after our event + int spills_after_our_target = 0; + // iterate through all the spills to find the + // spills that are after our triggered event + for (size_t i = 0; i < times_temps.size(); i++) { + if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ + spills_after_our_target++; + } + }//end loop through spill times + + // Remove the spills after our trigger + times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); + + // Remove the spills before the start of our Run + times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); + + }//end fix for "first event" + + ///reject time_stamps which have a trigger_type == 1 from data-base + //To-Do + + // mf::LogDebug("ICARUSBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; + // mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; + // mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; + + // Iterating through each of the beamline times + for (size_t i = 0; i < times_temps.size(); i++) { + + // Only continue if these times are matched to our DAQ time + //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; + + if(!isFirstEventInRun){//We already addressed the "first event" above + if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ + //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + spills_removed++; + continue;} + if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ + spills_removed++; + //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + continue;} + } + + //check if this spill is is minbias + /* + 40 ms was selected to be close to but outside the 66 ms + time of the next spill (when the beam is running at 15 Hz) + DocDB 33155 provides documentation of this + */ + + mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; + + if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ + mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; + + continue; + } + + //Great we found a matched spill! Let's count it + spill_count++; + + //Loop through the multiwire devices: + + for(int dev = 0; dev < int(MWR_times.size()); dev++){ + + //Loop through the multiwire times: + double Tdiff = 1000000000.; + matched_MWR[dev] = 0; + + for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ + + //found a candidate match! + if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} + + bool best_match = true; + + //Check for a better match... + for (size_t j = 0; j < times_temps.size(); j++) { + if( j == i) continue; + if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} + if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} + + //is there a better match later in the spill sequence + if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < + fabs((MWR_times[dev][mwrt] - times_temps[i]))){ + //we can have patience... + best_match = false; + break; + } + }//end better match check + + //Verified best match! + if(best_match == true){ + matched_MWR[dev] = mwrt; + Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); + } + + }//end loop over MWR times + + }//end loop over MWR devices + + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); + + beamInfos.push_back(std::move(spillInfo)); + + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + }//end iteration over beam device times + + // mf::LogDebug("ICARUSBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; + + return spill_count; +} + + +sbn::BNBSpillInfo sbn::ICARUSBNBRetriever::makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const +{ + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + // initializing all of our device carriers + // device definitions can be found in BNBSpillInfo.h + + double TOR860 = 0; // units e12 protons + double TOR875 = 0; // units e12 protons + double LM875A = 0; // units R/s + double LM875B = 0; // units R/s + double LM875C = 0; // units R/s + double HP875 = 0; // units mm + double VP875 = 0; // units mm + double HPTG1 = 0; // units mm + double VPTG1 = 0; // units mm + double HPTG2 = 0; // units mm + double VPTG2 = 0; // units mm + double BTJT2 = 0; // units Deg C + double THCURR = 0; // units kiloAmps + + double TOR860_time = 0; // units s + + // Here we request all the devices + // since sometimes devices fail to report we'll + // allow each to throw an exception but still move forward + // interpreting these failures will be part of the beam quality analyses + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + //crunch the times + unsigned long int time_closest_int = (int) TOR860_time; + double time_closest_ns = (TOR860_time - time_closest_int)*1e9; + + //Store everything in our data-product + sbn::BNBSpillInfo beamInfo; + beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.LM875A = LM875A; + beamInfo.LM875B = LM875B; + beamInfo.LM875C = LM875C; + beamInfo.HP875 = HP875; + beamInfo.VP875 = VP875; + beamInfo.HPTG1 = HPTG1; + beamInfo.VPTG1 = VPTG1; + beamInfo.HPTG2 = HPTG2; + beamInfo.VPTG2 = VPTG2; + beamInfo.BTJT2 = BTJT2; + beamInfo.THCURR = THCURR; + beamInfo.spill_time_s = time_closest_int; + beamInfo.spill_time_ns = time_closest_ns; + + for(auto const& MWRdata: unpacked_MWR){ + std::ignore = MWRdata; + assert(!MWRdata.empty()); + } + + if(unpacked_MWR[0].empty()){ + beamInfo.M875BB.clear(); + beamInfo.M875BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; + beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); + } + + if(unpacked_MWR[1].empty()){ + beamInfo.M876BB.clear(); + beamInfo.M876BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; + beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); + } + + if(unpacked_MWR[2].empty()){ + beamInfo.MMBTBB.clear(); + beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; + beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); + } + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun + + return beamInfo; +} + + +void sbn::ICARUSBNBRetriever::beginSubRun(art::SubRun& sr) +{ + return; +} + +//____________________________________________________________________________ +void sbn::ICARUSBNBRetriever::endSubRun(art::SubRun& sr) +{ + // We will add all of the BNBSpillInfo data-products to the + // art::SubRun so it persists + // currently this is ~2.7 kB/event or ~0.07 kB/spill + +mf::LogDebug("ICARUSBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; +mf::LogDebug("ICARUSBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; + + auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); + std::swap(*p, fOutbeamInfos); + + sr.put(std::move(p), art::subRunFragment()); + + return; +} + +DEFINE_ART_MODULE(sbn::ICARUSBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp new file mode 100644 index 000000000..48d0bda3f --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include "MWRData.h" + +using namespace std; + +namespace sbn{ + + std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const +{ + + std::vector > unpacked_data; + unpacked_data.resize(4); + short data[444]; + + std::vector row(0); + boost::split(row, packed_data, boost::is_any_of(",")); + if (row.size()==447) { + for (int i=3;i<447;i++) { + data[i-3]=atoi(row[i].c_str()); + } + string devname=row[1].substr(0,8); + for (int idev=0;idev<4;idev++) { + mwrpulse_t mwr=getMWRdata(data,idev); + time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); + for (int ich=0;ich<48;ich++) { + unpacked_data[idev].push_back(mwr.hor[ich]); + } + for (int ich=0;ich<48;ich++) { + unpacked_data[idev].push_back(mwr.ver[ich]); + } + } + } else { + cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< +namespace sbn{ +class MWRData +{ + typedef struct swicheader_t { + long timesec; + long timensec; + long gpstime1; + long gpstime2; + short boosterevent; + short mievent; + short hz15micnt; + long delta1f; + short pulsemi; + short pulsesc; + } swicheader_t; + + typedef struct mwrpulse_t { + short hor[48]; + short ver[48]; + swicheader_t sheader; + } mwrpulse_t; + + static long flipByte(long data) + { + return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); + } + + mwrpulse_t getMWRdata(short* data, int nblock) const; + + public: + std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; +}; +} + +#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt new file mode 100644 index 000000000..d04512753 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt @@ -0,0 +1,34 @@ +find_package(ifbeam) +find_package(ifdh_art) + + +art_make_library(LIBRARIES Boost::system + LIBRARY_NAME sbn_SBNDBNBSpillInfoRetriever_MWRData + SOURCE MWRData.cpp +) + +cet_build_plugin(SBNDBNBRetriever art::module + LIBRARIES + art::Persistency_Common + art::Utilities canvas::canvas + cetlib::cetlib cetlib_except::cetlib_except + ROOT::X3d + Boost::system + messagefacility::MF_MessageLogger + ifbeam::ifbeam + ifdh_art::IFBeam_service + SQLite::SQLite3 + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND + artdaq_core::artdaq-core_Utilities + sbn_SBNDBNBSpillInfoRetriever_MWRData + sbnobj::Common_POTAccounting + larcorealg::CoreUtils +) + +install_headers() +install_fhicl() +install_source() + diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp new file mode 100644 index 000000000..48d0bda3f --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include "MWRData.h" + +using namespace std; + +namespace sbn{ + + std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const +{ + + std::vector > unpacked_data; + unpacked_data.resize(4); + short data[444]; + + std::vector row(0); + boost::split(row, packed_data, boost::is_any_of(",")); + if (row.size()==447) { + for (int i=3;i<447;i++) { + data[i-3]=atoi(row[i].c_str()); + } + string devname=row[1].substr(0,8); + for (int idev=0;idev<4;idev++) { + mwrpulse_t mwr=getMWRdata(data,idev); + time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); + for (int ich=0;ich<48;ich++) { + unpacked_data[idev].push_back(mwr.hor[ich]); + } + for (int ich=0;ich<48;ich++) { + unpacked_data[idev].push_back(mwr.ver[ich]); + } + } + } else { + cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< +namespace sbn{ +class MWRData +{ + typedef struct swicheader_t { + long timesec; + long timensec; + long gpstime1; + long gpstime2; + short boosterevent; + short mievent; + short hz15micnt; + long delta1f; + short pulsemi; + short pulsesc; + } swicheader_t; + + typedef struct mwrpulse_t { + short hor[48]; + short ver[48]; + swicheader_t sheader; + } mwrpulse_t; + + static long flipByte(long data) + { + return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); + } + + mwrpulse_t getMWRdata(short* data, int nblock) const; + + public: + std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; +}; +} + +#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc new file mode 100644 index 000000000..a0a75b2ad --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -0,0 +1,600 @@ +//////////////////////////////////////////////////////////////////////// +// Class: SBNDBNBRetriever +// Plugin Type: producer +// File: SBNDBNBRetriever_module.cc +// +//////////////////////////////////////////////////////////////////////// + +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +#include +#include +#include +#include + +#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" +#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" +#include "artdaq-core/Data/ContainerFragment.hh" +//#include "sbndcode/Decoders/PTB/sbndptb.h" +#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" + +#include "ifdh_art/IFBeamService/IFBeam_service.h" +#include "ifbeam_c.h" +#include "MWRData.h" + +#include "larcorealg/CoreUtils/counter.h" + +namespace sbn { + class SBNDBNBRetriever; +} + +class sbn::SBNDBNBRetriever : public art::EDProducer { +public: + explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); + // Required functions. + void produce(art::Event & e) override; + void beginSubRun(art::SubRun& sr) override; + void endSubRun(art::SubRun& sr) override; + + // Plugins should not be copied or assigned. + SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; + + +private: + // Declare member data here. + std::vector< sbn::BNBSpillInfo > fOutbeamInfos; + double fTimePad; + std::string fInputLabel; + std::string fInputNonContainerInstance; + std::string fDeviceUsedForTiming; + std::string fOutputInstance; + std::string raw_data_label; + int fDebugLevel; + sbn::MWRData mwrdata; + art::ServiceHandle ifbeam_handle; + std::unique_ptr bfp; + std::unique_ptr bfp_mwr; + + struct PTBInfo_t { + double prevPTBTimeStamp = 0; + unsigned int GateCounter = 0; // FIXME needs to be integral type + }; + + struct TriggerInfo_t { + double t_current_event = 0; + double t_previous_event = 0; + unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type + }; + + struct MWRdata_t { + std::vector< std::vector > MWR_times; + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + }; + + static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] + + TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; + double extractTDCTimeStamp(art::Handle > cont_frags) const; + MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; + int matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos + ) const; + unsigned int TotalBeamSpills; + sbn::BNBSpillInfo makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; +}; + +sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) + : EDProducer{params} { + raw_data_label = params.get("raw_data_label", "daq"); + fInputLabel = params.get("InputLabel"); + fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); + fTimePad = params.get("TimePadding"); + fInputNonContainerInstance = params.get("InputNonContainerInstance"); + fOutputInstance = params.get("OutputInstance"); + fDebugLevel = params.get("DebugLevel",0); + bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); + bfp->set_epsilon(0.02); + bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); + bfp_mwr->set_epsilon(0.5); + bfp_mwr->setValidWindow(3605); + TotalBeamSpills = 0; +} + +int eventNum =0; +int _run; +int _subrun; +int _event; + +void sbn::SBNDBNBRetriever::produce(art::Event & e) +{ + + // If this is the first event in the run, then ignore it + // We do not currently have the ability to figure out the first + // spill that the DAQ was sensitive to, so don't try to save any + // spill information + + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; + MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); + + int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); + + if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) + mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; + else + mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; +} + +sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { + int numcont = 0; + PTBInfo_t PTBInfo; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) + { + if(ctb_frag.Trigger(word_i)){ + uint32_t wt = 0; + uint32_t word_type = ctb_frag.Word(word_i)->word_type; + wt = word_type; + if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) + { + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + } + } + } //End of loop over the number of trigger words + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return PTBInfo; +} + +double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { + int numcont = 0; + uint64_t TDCTimeStamp = 0; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::TDCTimestampFragment tdc_frag(frag); + TDCTimeStamp = tdc_frag.getTDCTimestamp()->timestamp_ns()/1e9; + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return TDCTimeStamp; +} + +sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { + // Using TDC for current event, but PTB for previous event + art::InputTag PTB_itag("daq", "ContainerPTB"); + auto PTB_cont_frags = e.getHandle(PTB_itag); + + art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); + auto TDC_cont_frags = e.getHandle(TDC_itag); + + PTBInfo_t PTBInfo; + TriggerInfo_t triggerInfo; + PTBInfo = extractPTBInfo(PTB_cont_frags); + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + + triggerInfo.t_current_event = TDCTimeStamp; + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; + triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; + + return triggerInfo; +} + +sbn::SBNDBNBRetriever::MWRdata_t sbn::SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { + + // These lines get everything primed within the IFBeamDB. + try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; + try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; + + // The multiwire chambers provide their + // data in a vector format but we'll have + // to sort through it in std::string format + // to correctly unpack it + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + std::vector< std::vector< double> > MWR_times; + unpacked_MWR.resize(3); + MWR_times.resize(3); + std::string packed_data_str; + + // Create a list of all the MWR devices with their different + // memory buffer increments + // generally in the format: "E:.{Memory Block}" + std::vector vars = bfp_mwr->GetDeviceList(); + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; + // Tracking the time from the IFBeamDB + double time_for_mwr; + + // this is an iterator to track which of the + // three devices we will be working with + int dev = 0; + + // The MWR devices are annoying and have confusing buffer + // what we'll do is sort through all of them first and then + // match them to the closest spills in time + // + + // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; + int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; + mf::LogDebug("SBNDBNBRetriever") << " t_steps " << t_steps << std::endl; + + for(int t = 0; t < t_steps; t++){//Iterate through time increments + for (std::string const& var : vars) {// Iterate through the devices + + //Make sure we have a device + if(var.empty()){ + //mf::LogDebug("SBNDBNBRetriever") << " NO MWR DEVICES?!" << std::endl; + continue; + } + /// Check the device name and interate the double-vector index + if(var.find("M875BB") != std::string::npos ) dev = 0; + else if(var.find("M876BB") != std::string::npos ) dev = 1; + else if(var.find("MMBTBB") != std::string::npos ) dev = 2; + else{ + //mf::LogDebug("SBNDBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; + continue;} + + time_for_mwr = 0; + + try{ + + //Pull the MWR data for the device + // these data are "packed" + std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); + + //We'll convert this into a format + // that we can unpack doubles >> strings + // + packed_data_str.clear(); + packed_data_str += std::to_string(int(time_for_mwr)); + packed_data_str.append(","); + packed_data_str.append(var); + packed_data_str.append(",,"); + + /* for(auto const value: packed_MWR){ + packed_data_str += ','; + packed_data_str += std::to_string(int(value)); + }*/ + for(int j = 0; j < int(packed_MWR.size()); j++){ + packed_data_str += std::to_string(int(packed_MWR[j])); + if(j < int(packed_MWR.size())-1) + packed_data_str.append(","); + } + + // Use Zarko's unpacking function to turn this into consumeable data + std::vector MWR_times_temp; + + // There is a 35 ms offset between the toriod and the MWR times + // we'll just remove that here to match to the spill times + std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); + + //There are four events that are packed into one MWR IFBeam entry + for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ + + // If this entry has a unique time them store it for later + if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ + unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); + MWR_times[dev].push_back(MWR_times_temp[s]); + }//check for unique time + }//Iterate through the unpacked events + }//try + catch (WebAPIException &we) { + //Ignore when we can't find the MWR devices + // they don't always report and the timing of them can be annoying + }//catch + }// Iterate over all the multiwire devices + }// Iterate over all times + + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; + + return { std::move(MWR_times), std::move(unpacked_MWR) }; +} + +int sbn::SBNDBNBRetriever::matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos +) const { + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + //Here we will start collecting all the other beamline devices + // First we get the times that the beamline device fired + // we have to pick a specific variable to use + std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); + + mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; + + // We'll keep track of how many of these spills match to our + // DAQ trigger times + int spill_count = 0; + int spills_removed = 0; + std::vector matched_MWR; + matched_MWR.resize(3); + + // NOTE: for now, this is dead code because we don't + // do anything for the first event in a run. We may want to revisit + // this later to understand if there is a way we can do the POT + // accounting in the first event. + // + // Need to handle the first event in a run differently + if(isFirstEventInRun){ + //We'll remove the spills after our event + int spills_after_our_target = 0; + // iterate through all the spills to find the + // spills that are after our triggered event + for (size_t i = 0; i < times_temps.size(); i++) { + if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ + spills_after_our_target++; + } + }//end loop through spill times + + // Remove the spills after our trigger + times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); + + // Remove the spills before the start of our Run + times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); + + }//end fix for "first event" + + ///reject time_stamps which have a trigger_type == 1 from data-base + //To-Do + + // mf::LogDebug("SBNDBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; + + // Iterating through each of the beamline times + for (size_t i = 0; i < times_temps.size(); i++) { + + // Only continue if these times are matched to our DAQ time + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; + + if(!isFirstEventInRun){//We already addressed the "first event" above + if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ + //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + spills_removed++; + continue;} + if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ + spills_removed++; + //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + continue;} + } + + //check if this spill is is minbias + /* + 40 ms was selected to be close to but outside the 66 ms + time of the next spill (when the beam is running at 15 Hz) + DocDB 33155 provides documentation of this + */ + + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; + + // if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; + + // continue; + //} + + //Great we found a matched spill! Let's count it + spill_count++; + + //Loop through the multiwire devices: + + for(int dev = 0; dev < int(MWR_times.size()); dev++){ + + //Loop through the multiwire times: + double Tdiff = 1000000000.; + matched_MWR[dev] = 0; + + for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ + + //found a candidate match! + if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} + + bool best_match = true; + + //Check for a better match... + for (size_t j = 0; j < times_temps.size(); j++) { + if( j == i) continue; + if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} + if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} + + //is there a better match later in the spill sequence + if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < + fabs((MWR_times[dev][mwrt] - times_temps[i]))){ + //we can have patience... + best_match = false; + break; + } + }//end better match check + + //Verified best match! + if(best_match == true){ + matched_MWR[dev] = mwrt; + Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); + } + + }//end loop over MWR times + + }//end loop over MWR devices + + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); + + beamInfos.push_back(std::move(spillInfo)); + + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + }//end iteration over beam device times + + // mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; + + return spill_count; +} + +sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const +{ + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + // initializing all of our device carriers + // device definitions can be found in BNBSpillInfo.h + + double TOR860 = 0; // units e12 protons + double TOR875 = 0; // units e12 protons + double LM875A = 0; // units R/s + double LM875B = 0; // units R/s + double LM875C = 0; // units R/s + double HP875 = 0; // units mm + double VP875 = 0; // units mm + double HPTG1 = 0; // units mm + double VPTG1 = 0; // units mm + double HPTG2 = 0; // units mm + double VPTG2 = 0; // units mm + double BTJT2 = 0; // units Deg C + double THCURR = 0; // units kiloAmps + + double TOR860_time = 0; // units s + + // Here we request all the devices + // since sometimes devices fail to report we'll + // allow each to throw an exception but still move forward + // interpreting these failures will be part of the beam quality analyses + + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + //crunch the times + unsigned long int time_closest_int = (int) TOR860_time; + double time_closest_ns = (TOR860_time - time_closest_int)*1e9; + + //Store everything in our data-product + sbn::BNBSpillInfo beamInfo; + beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.LM875A = LM875A; + beamInfo.LM875B = LM875B; + beamInfo.LM875C = LM875C; + beamInfo.HP875 = HP875; + beamInfo.VP875 = VP875; + beamInfo.HPTG1 = HPTG1; + beamInfo.VPTG1 = VPTG1; + beamInfo.HPTG2 = HPTG2; + beamInfo.VPTG2 = VPTG2; + beamInfo.BTJT2 = BTJT2; + beamInfo.THCURR = THCURR; + beamInfo.spill_time_s = time_closest_int; + beamInfo.spill_time_ns = time_closest_ns; + + for(auto const& MWRdata: unpacked_MWR){ + std::ignore = MWRdata; + assert(!MWRdata.empty()); + } + + if(unpacked_MWR[0].empty()){ + beamInfo.M875BB.clear(); + beamInfo.M875BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; + beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); + } + + if(unpacked_MWR[1].empty()){ + beamInfo.M876BB.clear(); + beamInfo.M876BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; + beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); + } + + if(unpacked_MWR[2].empty()){ + beamInfo.MMBTBB.clear(); + beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; + beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); + } + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun + + return beamInfo; +} + +void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) +{ + return; +} + +void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) +{ + mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; + mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; + + auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); + std::swap(*p, fOutbeamInfos); + + sr.put(std::move(p), art::subRunFragment()); + + return; +} + +DEFINE_ART_MODULE(sbn::SBNDBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusspillinfo.fcl new file mode 100644 index 000000000..9bc7e15d2 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/icarusspillinfo.fcl @@ -0,0 +1,17 @@ + +BEGIN_PROLOG + +icarusbnbspillinfo: { + + module_type: "ICARUSBNBRetriever" + TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away + URL: "" #keep this blank and we're good + Bundle: "BoosterNeutrinoBeam_read" + MultiWireBundle: "BNBMultiWire" + TimeWindow: "700" #seconds + MWR_TimeWindow: "3601" #seconds + raw_data_label: "daq" + DeviceUsedForTiming: "E:TOR860" + TriggerDatabaseFile: "triggerDatabase/icarus_triggers.db" +} +END_PROLOG diff --git a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl new file mode 100644 index 000000000..68984021a --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl @@ -0,0 +1,46 @@ +#include "icarusbnbspillinfo.fcl" + +process_name: ICARUSBNBInfoGen + +services:{ + + message: { + debugModules: [ "*" ] + destinations: { + LogDebugFile:{ + type: "file" + filename: "debug.log" + append: false + threshold: "DEBUG" + categories: { + default: {} + } + } + } + } + IFBeam:{} +} + + +source: { + +} + +physics: { + producers: { + icarusbnbinfo: @local::icarusbnbspillinfo + } + + simulate: [icarusbnbinfo ] + stream1: [ out1 ] +} + +outputs: { + out1: { + module_type: RootOutput + fileName: "%ifb_%tc_icarusbnbinfo.root" + dataTier: "raw" + compressionLevel: 1 + } +} + diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 0c35b8a59..a478bc840 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -119,8 +119,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Time(); - srspacepoint.time_err = spacepoint.TimeErr(); + srspacepoint.time = spacepoint.Ts1(); + srspacepoint.time_err = spacepoint.Ts1Err(); srspacepoint.complete = spacepoint.Complete(); } @@ -131,8 +131,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Time(); - srsbndcrttrack.time_err = track.TimeErr(); + srsbndcrttrack.time = track.Ts1(); + srsbndcrttrack.time_err = track.Ts1Err(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From 1656232ea808aaf25bdbccf222aa7fbd7007bc99 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:46:04 -0600 Subject: [PATCH 025/367] Rename icarusspillinfo.fcl to icarusbnbspillinfo.fcl --- .../job/{icarusspillinfo.fcl => icarusbnbspillinfo.fcl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sbncode/BeamSpillInfoRetriever/job/{icarusspillinfo.fcl => icarusbnbspillinfo.fcl} (100%) diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl similarity index 100% rename from sbncode/BeamSpillInfoRetriever/job/icarusspillinfo.fcl rename to sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl From 6e3023f8236751c5a7394bfb69d8c0a3fb3beb6a Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Fri, 22 Nov 2024 13:07:25 -0600 Subject: [PATCH 026/367] New producer modules --- sbncode/BeamSpillInfoRetriever/CMakeLists.txt | 2 + .../SBNDBNBEXTRetriever/CMakeLists.txt | 27 + .../SBNDBNBEXTRetriever_module.cc | 214 +++++++ .../SBNDBNBRetriever_module.cc | 2 +- .../SBNDBNBZEROBIASRetriever/CMakeLists.txt | 34 ++ .../SBNDBNBZEROBIASRetriever/MWRData.cpp | 71 +++ .../SBNDBNBZEROBIASRetriever/MWRData.h | 39 ++ .../SBNDBNBZEROBIASRetriever_module.cc | 545 ++++++++++++++++++ .../job/run_sbndbnbextinfo_sbn.fcl | 46 ++ .../job/run_sbndbnbinfo_sbn.fcl | 2 + .../job/run_sbndbnbzerobiasinfo_sbn.fcl | 46 ++ .../job/sbndbnbextspillinfo.fcl | 21 + .../job/sbndbnbspillinfo.fcl | 2 +- .../job/sbndbnbzerobiasspillinfo.fcl | 21 + sbncode/CAFMaker/FillReco.cxx | 8 +- 15 files changed, 1074 insertions(+), 6 deletions(-) create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.h create mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc create mode 100644 sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl diff --git a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt index b99d4dcfa..2e5998b50 100644 --- a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt @@ -1,5 +1,7 @@ add_subdirectory(ICARUSBNBRetriever) add_subdirectory(SBNDBNBRetriever) +add_subdirectory(SBNDBNBEXTRetriever) +add_subdirectory(SBNDBNBZEROBIASRetriever) add_subdirectory(NuMIRetriever) add_subdirectory(BNBEXTRetriever) add_subdirectory(NuMIEXTRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt new file mode 100644 index 000000000..3877de304 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt @@ -0,0 +1,27 @@ +find_package(ifbeam) +find_package(ifdh_art) + +cet_build_plugin(SBNDBNBEXTRetriever art::module + LIBRARIES + art::Persistency_Common + art::Utilities canvas::canvas + cetlib::cetlib cetlib_except::cetlib_except + ROOT::X3d + Boost::system + messagefacility::MF_MessageLogger + ifbeam::ifbeam + ifdh_art::IFBeam_service + SQLite::SQLite3 + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND + artdaq_core::artdaq-core_Utilities + sbnobj::Common_POTAccounting + larcorealg::CoreUtils +) + +install_headers() +install_fhicl() +install_source() + diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc new file mode 100644 index 000000000..7ae66eedb --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc @@ -0,0 +1,214 @@ +//////////////////////////////////////////////////////////////////////// +// Class: SBNDBNBRetriever +// Plugin Type: producer +// File: SBNDBNBRetriever_module.cc +// +//////////////////////////////////////////////////////////////////////// + +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +#include +#include +#include +#include + +#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" +#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" +#include "artdaq-core/Data/ContainerFragment.hh" +//#include "sbndcode/Decoders/PTB/sbndptb.h" +#include "sbnobj/Common/POTAccounting/EXTCountInfo.h" + +#include "ifdh_art/IFBeamService/IFBeam_service.h" +#include "ifbeam_c.h" + +#include "larcorealg/CoreUtils/counter.h" + +namespace sbn { + class SBNDBNBRetriever; +} + +class sbn::SBNDBNBRetriever : public art::EDProducer { +public: + explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); + // Required functions. + void produce(art::Event & e) override; + void beginSubRun(art::SubRun& sr) override; + void endSubRun(art::SubRun& sr) override; + + // Plugins should not be copied or assigned. + SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; + + +private: + // Declare member data here. + std::vector< sbn::EXTCountInfo > fOutExtInfos; + struct PTBInfo_t { + double prevPTBTimeStamp = 0; + unsigned int GateCounter = 0; // FIXME needs to be integral type + }; + + struct TriggerInfo_t { + double t_current_event = 0; + double t_previous_event = 0; + unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type + }; + + TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; + double extractTDCTimeStamp(art::Handle > cont_frags) const; + + // input labels + std::string raw_data_label_; + float TotalEXTCounts; + float totalMinBias; + float evtCount; + float scale_factor; +}; + +sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) + : EDProducer{params} { + produces< std::vector< sbn::EXTCountInfo >, art::InSubRun >(); + TotalEXTCounts = 0; + totalMinBias = 0; + evtCount = 0; + scale_factor = 0; +} + +int eventNum =0; +int _run; +int _subrun; +int _event; + +void sbn::SBNDBNBRetriever::produce(art::Event & e) +{ + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + TotalEXTCounts += triggerInfo.number_of_gates_since_previous_event; + + if(triggerInfo.number_of_gates_since_previous_event > 0){ + evtCount++; + totalMinBias += triggerInfo.number_of_gates_since_previous_event; + } + + //Store everything in our data-product + sbn::EXTCountInfo extInfo; + extInfo.gates_since_last_trigger = triggerInfo.number_of_gates_since_previous_event; + + fOutExtInfos.push_back(extInfo); +} + +sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { + int numcont = 0; + PTBInfo_t PTBInfo; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) + { + if(ctb_frag.Trigger(word_i)){ + uint32_t wt = 0; + uint32_t word_type = ctb_frag.Word(word_i)->word_type; + wt = word_type; + if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(4)) + { + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + } + } + } //End of loop over the number of trigger words + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return PTBInfo; +} + +double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { + int numcont = 0; + uint64_t TDCTimeStamp = 0; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::TDCTimestampFragment tdc_frag(frag); + TDCTimeStamp = tdc_frag.getTDCTimestamp()->timestamp_ns()/1e9; + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return TDCTimeStamp; +} + +sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { + // Using TDC for current event, but PTB for previous event + art::InputTag PTB_itag("daq", "ContainerPTB"); + auto PTB_cont_frags = e.getHandle(PTB_itag); + + art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); + auto TDC_cont_frags = e.getHandle(TDC_itag); + + PTBInfo_t PTBInfo; + TriggerInfo_t triggerInfo; + PTBInfo = extractPTBInfo(PTB_cont_frags); + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + + triggerInfo.t_current_event = TDCTimeStamp; + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; + triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; + + return triggerInfo; +} + +void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) +{ + TotalEXTCounts = 0; + totalMinBias = 0; + evtCount = 0; + scale_factor = 0; + return; +} + +void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) +{ + // We will add all of the EXTCountInfo data-products to the + // art::SubRun so it persists + + if(evtCount != 0 && totalMinBias != 0) + scale_factor = 1. - (evtCount/totalMinBias); + else + std::cout << "FAILED! " << std::endl; + // probably want to throw an exception here + + for(auto ExtInfo : fOutExtInfos){ + + ExtInfo.gates_since_last_trigger *= scale_factor; + + } + + auto p = std::make_unique< std::vector< sbn::EXTCountInfo > >(fOutExtInfos); + + sr.put(std::move(p), art::subRunFragment()); + + return; +} + +DEFINE_ART_MODULE(sbn::SBNDBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index a0a75b2ad..0c7d42179 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -160,7 +160,7 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand uint32_t wt = 0; uint32_t word_type = ctb_frag.Word(word_i)->word_type; wt = word_type; - if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) + if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(2)) { PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt new file mode 100644 index 000000000..675168065 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt @@ -0,0 +1,34 @@ +find_package(ifbeam) +find_package(ifdh_art) + + +art_make_library(LIBRARIES Boost::system + LIBRARY_NAME sbn_SBNDBNBZEROBIASSpillInfoRetriever_MWRData + SOURCE MWRData.cpp +) + +cet_build_plugin(SBNDBNBZEROBIASRetriever art::module + LIBRARIES + art::Persistency_Common + art::Utilities canvas::canvas + cetlib::cetlib cetlib_except::cetlib_except + ROOT::X3d + Boost::system + messagefacility::MF_MessageLogger + ifbeam::ifbeam + ifdh_art::IFBeam_service + SQLite::SQLite3 + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS + sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND + artdaq_core::artdaq-core_Utilities + sbn_SBNDBNBZEROBIASSpillInfoRetriever_MWRData + sbnobj::Common_POTAccounting + larcorealg::CoreUtils +) + +install_headers() +install_fhicl() +install_source() + diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp new file mode 100644 index 000000000..48d0bda3f --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include "MWRData.h" + +using namespace std; + +namespace sbn{ + + std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const +{ + + std::vector > unpacked_data; + unpacked_data.resize(4); + short data[444]; + + std::vector row(0); + boost::split(row, packed_data, boost::is_any_of(",")); + if (row.size()==447) { + for (int i=3;i<447;i++) { + data[i-3]=atoi(row[i].c_str()); + } + string devname=row[1].substr(0,8); + for (int idev=0;idev<4;idev++) { + mwrpulse_t mwr=getMWRdata(data,idev); + time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); + for (int ich=0;ich<48;ich++) { + unpacked_data[idev].push_back(mwr.hor[ich]); + } + for (int ich=0;ich<48;ich++) { + unpacked_data[idev].push_back(mwr.ver[ich]); + } + } + } else { + cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< +namespace sbn{ +class MWRData +{ + typedef struct swicheader_t { + long timesec; + long timensec; + long gpstime1; + long gpstime2; + short boosterevent; + short mievent; + short hz15micnt; + long delta1f; + short pulsemi; + short pulsesc; + } swicheader_t; + + typedef struct mwrpulse_t { + short hor[48]; + short ver[48]; + swicheader_t sheader; + } mwrpulse_t; + + static long flipByte(long data) + { + return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); + } + + mwrpulse_t getMWRdata(short* data, int nblock) const; + + public: + std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; +}; +} + +#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc new file mode 100644 index 000000000..424a30121 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -0,0 +1,545 @@ +//////////////////////////////////////////////////////////////////////// +// Class: SBNDBNBRetriever +// Plugin Type: producer +// File: SBNDBNBRetriever_module.cc +// +//////////////////////////////////////////////////////////////////////// + +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +#include +#include +#include +#include + +#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" +#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" +#include "artdaq-core/Data/ContainerFragment.hh" +//#include "sbndcode/Decoders/PTB/sbndptb.h" +#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" + +#include "ifdh_art/IFBeamService/IFBeam_service.h" +#include "ifbeam_c.h" +#include "MWRData.h" + +#include "larcorealg/CoreUtils/counter.h" + +namespace sbn { + class SBNDBNBRetriever; +} + +class sbn::SBNDBNBRetriever : public art::EDProducer { +public: + explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); + // Required functions. + void produce(art::Event & e) override; + void beginSubRun(art::SubRun& sr) override; + void endSubRun(art::SubRun& sr) override; + + // Plugins should not be copied or assigned. + SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; + SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; + + +private: + // Declare member data here. + std::vector< sbn::BNBSpillInfo > fOutbeamInfos; + double fTimePad; + std::string fInputLabel; + std::string fInputNonContainerInstance; + std::string fDeviceUsedForTiming; + std::string fOutputInstance; + std::string raw_data_label; + int fDebugLevel; + sbn::MWRData mwrdata; + art::ServiceHandle ifbeam_handle; + std::unique_ptr bfp; + std::unique_ptr bfp_mwr; + + struct PTBInfo_t { + double prevPTBTimeStamp = 0; + unsigned int GateCounter = 0; // FIXME needs to be integral type + }; + + struct TriggerInfo_t { + double t_current_event = 0; + double t_previous_event = 0; + unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type + }; + + struct MWRdata_t { + std::vector< std::vector > MWR_times; + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + }; + + static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] + + TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; + double extractTDCTimeStamp(art::Handle > cont_frags) const; + MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; + void matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos + ) const; + unsigned int TotalBeamSpills; + sbn::BNBSpillInfo makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; +}; + +sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) + : EDProducer{params} { + raw_data_label = params.get("raw_data_label", "daq"); + fInputLabel = params.get("InputLabel"); + fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); + fTimePad = params.get("TimePadding"); + fInputNonContainerInstance = params.get("InputNonContainerInstance"); + fOutputInstance = params.get("OutputInstance"); + fDebugLevel = params.get("DebugLevel",0); + bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); + bfp->set_epsilon(0.02); + bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); + bfp_mwr->set_epsilon(0.5); + bfp_mwr->setValidWindow(3605); + TotalBeamSpills = 0; + + produces< std::vector >(); +} + +int eventNum =0; +int _run; +int _subrun; +int _event; + +void sbn::SBNDBNBRetriever::produce(art::Event & e) +{ + + // If this is the first event in the run, then ignore it + // We do not currently have the ability to figure out the first + // spill that the DAQ was sensitive to, so don't try to save any + // spill information + + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; + MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); + + matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); + + auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); + std::swap(*p, fOutbeamInfos); + e.put(std::move(p)); +} + +sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { + int numcont = 0; + PTBInfo_t PTBInfo; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) + { + if(ctb_frag.Trigger(word_i)){ + uint32_t wt = 0; + uint32_t word_type = ctb_frag.Word(word_i)->word_type; + wt = word_type; + if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) + { + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + } + } + } //End of loop over the number of trigger words + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return PTBInfo; +} + +double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { + int numcont = 0; + uint64_t TDCTimeStamp = 0; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + numcont++; + int numfrag = 0; + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + numfrag++; + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::TDCTimestampFragment tdc_frag(frag); + TDCTimeStamp = tdc_frag.getTDCTimestamp()->timestamp_ns()/1e9; + } //End of loop over the number of fragments per container + } //End of loop over the number of containers + return TDCTimeStamp; +} + +sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { + // Using TDC for current event, but PTB for previous event + art::InputTag PTB_itag("daq", "ContainerPTB"); + auto PTB_cont_frags = e.getHandle(PTB_itag); + + art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); + auto TDC_cont_frags = e.getHandle(TDC_itag); + + PTBInfo_t PTBInfo; + TriggerInfo_t triggerInfo; + PTBInfo = extractPTBInfo(PTB_cont_frags); + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + + triggerInfo.t_current_event = TDCTimeStamp; + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; + triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; + + return triggerInfo; +} + +sbn::SBNDBNBRetriever::MWRdata_t sbn::SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { + + // These lines get everything primed within the IFBeamDB. + try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; + try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; + try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; + + // The multiwire chambers provide their + // data in a vector format but we'll have + // to sort through it in std::string format + // to correctly unpack it + std::vector< std::vector< std::vector< int > > > unpacked_MWR; + std::vector< std::vector< double> > MWR_times; + unpacked_MWR.resize(3); + MWR_times.resize(3); + std::string packed_data_str; + + // Create a list of all the MWR devices with their different + // memory buffer increments + // generally in the format: "E:.{Memory Block}" + std::vector vars = bfp_mwr->GetDeviceList(); + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; + // Tracking the time from the IFBeamDB + double time_for_mwr; + + // this is an iterator to track which of the + // three devices we will be working with + int dev = 0; + + // The MWR devices are annoying and have confusing buffer + // what we'll do is sort through all of them first and then + // match them to the closest spills in time + // + + // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; + int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; + mf::LogDebug("SBNDBNBRetriever") << " t_steps " << t_steps << std::endl; + + for(int t = 0; t < t_steps; t++){//Iterate through time increments + for (std::string const& var : vars) {// Iterate through the devices + + //Make sure we have a device + if(var.empty()){ + //mf::LogDebug("SBNDBNBRetriever") << " NO MWR DEVICES?!" << std::endl; + continue; + } + /// Check the device name and interate the double-vector index + if(var.find("M875BB") != std::string::npos ) dev = 0; + else if(var.find("M876BB") != std::string::npos ) dev = 1; + else if(var.find("MMBTBB") != std::string::npos ) dev = 2; + else{ + //mf::LogDebug("SBNDBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; + continue;} + + time_for_mwr = 0; + + try{ + + //Pull the MWR data for the device + // these data are "packed" + std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); + + //We'll convert this into a format + // that we can unpack doubles >> strings + // + packed_data_str.clear(); + packed_data_str += std::to_string(int(time_for_mwr)); + packed_data_str.append(","); + packed_data_str.append(var); + packed_data_str.append(",,"); + + /* for(auto const value: packed_MWR){ + packed_data_str += ','; + packed_data_str += std::to_string(int(value)); + }*/ + for(int j = 0; j < int(packed_MWR.size()); j++){ + packed_data_str += std::to_string(int(packed_MWR[j])); + if(j < int(packed_MWR.size())-1) + packed_data_str.append(","); + } + + // Use Zarko's unpacking function to turn this into consumeable data + std::vector MWR_times_temp; + + // There is a 35 ms offset between the toriod and the MWR times + // we'll just remove that here to match to the spill times + std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); + + //There are four events that are packed into one MWR IFBeam entry + for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ + + // If this entry has a unique time them store it for later + if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ + unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); + MWR_times[dev].push_back(MWR_times_temp[s]); + }//check for unique time + }//Iterate through the unpacked events + }//try + catch (WebAPIException &we) { + //Ignore when we can't find the MWR devices + // they don't always report and the timing of them can be annoying + }//catch + }// Iterate over all the multiwire devices + }// Iterate over all times + + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; + + return { std::move(MWR_times), std::move(unpacked_MWR) }; +} + +void sbn::SBNDBNBRetriever::matchMultiWireData( + art::EventID const& eventID, + TriggerInfo_t const& triggerInfo, + MWRdata_t const& MWRdata, bool isFirstEventInRun, + std::vector< sbn::BNBSpillInfo >& beamInfos +) const { + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + //Here we will start collecting all the other beamline devices + // First we get the times that the beamline device fired + // we have to pick a specific variable to use + std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); + + mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; + + // We'll keep track of how many of these spills match to our + // DAQ trigger times + int spills_removed = 0; + std::vector matched_MWR; + matched_MWR.resize(3); + + // mf::LogDebug("SBNDBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; + // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; + + // Iterating through each of the beamline times + + double best_diff = 10000000000.0; + double diff; + size_t i = 0; + + for (size_t k = 0; k < times_temps.size(); k++){ + diff = times_temps[k] - (triggerInfo.t_current_event + fTimePad); + if( diff < 0 and diff < best_diff){ + if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ + spills_removed++; + continue;} + if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ + spills_removed++; + //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + continue;} + best_diff = diff; + i = k; + } + } + for(int dev = 0; dev < int(MWR_times.size()); dev++){ + + //Loop through the multiwire times: + double Tdiff = 1000000000.; + matched_MWR[dev] = 0; + + for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ + + //found a candidate match! + if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} + + bool best_match = true; + + //Check for a better match... + for (size_t j = 0; j < times_temps.size(); j++) { + if( j == i) continue; + if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} + if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} + + //is there a better match later in the spill sequence + if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < + fabs((MWR_times[dev][mwrt] - times_temps[i]))){ + //we can have patience... + best_match = false; + break; + } + }//end better match check + + //Verified best match! + if(best_match == true){ + matched_MWR[dev] = mwrt; + Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); + } + }//end loop over MWR times + }//end loop over MWR devices + + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); + + beamInfos.push_back(std::move(spillInfo)); + + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + //}//end iteration over beam device times + + // mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; + +} + +sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const +{ + + auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias + + // initializing all of our device carriers + // device definitions can be found in BNBSpillInfo.h + + double TOR860 = 0; // units e12 protons + double TOR875 = 0; // units e12 protons + double LM875A = 0; // units R/s + double LM875B = 0; // units R/s + double LM875C = 0; // units R/s + double HP875 = 0; // units mm + double VP875 = 0; // units mm + double HPTG1 = 0; // units mm + double VPTG1 = 0; // units mm + double HPTG2 = 0; // units mm + double VPTG2 = 0; // units mm + double BTJT2 = 0; // units Deg C + double THCURR = 0; // units kiloAmps + + double TOR860_time = 0; // units s + + // Here we request all the devices + // since sometimes devices fail to report we'll + // allow each to throw an exception but still move forward + // interpreting these failures will be part of the beam quality analyses + + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + //crunch the times + unsigned long int time_closest_int = (int) TOR860_time; + double time_closest_ns = (TOR860_time - time_closest_int)*1e9; + + //Store everything in our data-product + sbn::BNBSpillInfo beamInfo; + beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units + beamInfo.LM875A = LM875A; + beamInfo.LM875B = LM875B; + beamInfo.LM875C = LM875C; + beamInfo.HP875 = HP875; + beamInfo.VP875 = VP875; + beamInfo.HPTG1 = HPTG1; + beamInfo.VPTG1 = VPTG1; + beamInfo.HPTG2 = HPTG2; + beamInfo.VPTG2 = VPTG2; + beamInfo.BTJT2 = BTJT2; + beamInfo.THCURR = THCURR; + beamInfo.spill_time_s = time_closest_int; + beamInfo.spill_time_ns = time_closest_ns; + + for(auto const& MWRdata: unpacked_MWR){ + std::ignore = MWRdata; + assert(!MWRdata.empty()); + } + + if(unpacked_MWR[0].empty()){ + beamInfo.M875BB.clear(); + beamInfo.M875BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; + beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); + } + + if(unpacked_MWR[1].empty()){ + beamInfo.M876BB.clear(); + beamInfo.M876BB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; + beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); + } + + if(unpacked_MWR[2].empty()){ + beamInfo.MMBTBB.clear(); + beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds + } + else{ + beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; + beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); + } + // We do not write these to the art::Events because + // we can filter events but want to keep all the POT + // information, so we'll write it to the SubRun + + beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun + + return beamInfo; +} + +void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) +{ + return; +} + +void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) +{ + return; +} + +DEFINE_ART_MODULE(sbn::SBNDBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl new file mode 100644 index 000000000..e20bc0323 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl @@ -0,0 +1,46 @@ +#include "sbndbnbextspillinfo.fcl" + +process_name: SBNDBNBEXTInfoGen + +services:{ + + message: { + debugModules: [ "*" ] + destinations: { + LogDebugFile:{ + type: "file" + filename: "debug.log" + append: false + threshold: "DEBUG" + categories: { + default: {} + } + } + } + } + IFBeam:{} +} + + +source: { +} + +physics: { + producers: { + sbndbnbextinfo: @local::sbndbnbextspillinfo + } + + simulate: [sbndbnbextinfo ] + stream1: [ out1 ] +} + +outputs: { + out1: { + module_type: RootOutput + fileName: "%ifb_%tc_sbndbnbextinfo.root" + dataTier: "raw" + compressionLevel: 1 + } +} + +physics.producers.sbndbnbextinfo.fileNames: @local::outputs.out1.fileName diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl index b14918934..7f9f26df1 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl @@ -43,3 +43,5 @@ outputs: { compressionLevel: 1 } } + +physics.producers.sbndbnbinfo.fileNames: @local::outputs.out1.fileName diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl new file mode 100644 index 000000000..bcdf6635b --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl @@ -0,0 +1,46 @@ +#include "sbndbnbzerobiasspillinfo.fcl" + +process_name: SBNDBNBZEROBIASInfoGen + +services:{ + + message: { + debugModules: [ "*" ] + destinations: { + LogDebugFile:{ + type: "file" + filename: "debug.log" + append: false + threshold: "DEBUG" + categories: { + default: {} + } + } + } + } + IFBeam:{} +} + + +source: { +} + +physics: { + producers: { + sbndbnbzerobiasinfo: @local::sbndbnbzerobiasspillinfo + } + + simulate: [sbndbnbzerobiasinfo ] + stream1: [ out1 ] +} + +outputs: { + out1: { + module_type: RootOutput + fileName: "%ifb_%tc_sbndbnbzerobiasinfo.root" + dataTier: "raw" + compressionLevel: 1 + } +} + +physics.producers.sbndbnbzerobiasinfo.fileNames: @local::outputs.out1.fileName diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl new file mode 100644 index 000000000..14daf561f --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl @@ -0,0 +1,21 @@ +BEGIN_PROLOG + +sbndbnbextspillinfo: { + module_type: SBNDBNBEXTRetriever + InputLabel: "bnbext" + InputContainerInstance: "ContainerBNB" + InputNonContainerInstance: "BNB" + OutputInstance: "" + DebugLevel: 0 + TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away + URL: "https://dbdata3vm.fnal.gov:9443/ifbeam" + Bundle: "BoosterNeutrinoBeam_read" + MultiWireBundle: "BNBMultiWire" + TimeWindow: "700" #seconds + MWR_TimeWindow: "3601" #seconds + raw_data_label: "daq" + DeviceUsedForTiming: "E:TOR860" +} + +END_PROLOG + diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl index 2bf598456..4bdb732ef 100644 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl @@ -8,7 +8,7 @@ sbndbnbspillinfo: { OutputInstance: "" DebugLevel: 0 TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - URL: "" + URL: "" #Default URL having issues Nov 21 2024, used this instead https://dbdata3vm.fnal.gov:9443/ifbeam Bundle: "BoosterNeutrinoBeam_read" MultiWireBundle: "BNBMultiWire" TimeWindow: "700" #seconds diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl new file mode 100644 index 000000000..bb1c2302d --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl @@ -0,0 +1,21 @@ +BEGIN_PROLOG + +sbndbnbzerobiasspillinfo: { + module_type: SBNDBNBZEROBIASRetriever + InputLabel: "bnbzerobias" + InputContainerInstance: "ContainerBNB" + InputNonContainerInstance: "BNB" + OutputInstance: "" + DebugLevel: 0 + TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away + URL: "" + Bundle: "BoosterNeutrinoBeam_read" + MultiWireBundle: "BNBMultiWire" + TimeWindow: "700" #seconds + MWR_TimeWindow: "3601" #seconds + raw_data_label: "daq" + DeviceUsedForTiming: "E:TOR860" +} + +END_PROLOG + diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index a478bc840..0c35b8a59 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -119,8 +119,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Ts1(); - srspacepoint.time_err = spacepoint.Ts1Err(); + srspacepoint.time = spacepoint.Time(); + srspacepoint.time_err = spacepoint.TimeErr(); srspacepoint.complete = spacepoint.Complete(); } @@ -131,8 +131,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Ts1(); - srsbndcrttrack.time_err = track.Ts1Err(); + srsbndcrttrack.time = track.Time(); + srsbndcrttrack.time_err = track.TimeErr(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From e2d8f6a11cb783e0a9ce05c06666a6477703680c Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Mon, 25 Nov 2024 19:10:16 -0600 Subject: [PATCH 027/367] Rename EXT producers, add catch for TDC --- sbncode/BeamSpillInfoRetriever/CMakeLists.txt | 2 +- .../CMakeLists.txt | 2 +- .../ICARUSBNBEXTRetriever_module.cc} | 28 +++++++-------- .../SBNDBNBEXTRetriever_module.cc | 34 +++++++++---------- .../SBNDBNBRetriever_module.cc | 24 ++++++++++--- .../job/bnbextcountinfo.fcl | 10 ------ .../job/icarusbnbextcountinfo.fcl | 10 ++++++ .../job/run_bnbextinfo_sbn.fcl | 32 ----------------- .../job/run_icarusbnbextinfo_sbn.fcl | 32 +++++++++++++++++ 9 files changed, 94 insertions(+), 80 deletions(-) rename sbncode/BeamSpillInfoRetriever/{BNBEXTRetriever => ICARUSBNBEXTRetriever}/CMakeLists.txt (91%) rename sbncode/BeamSpillInfoRetriever/{BNBEXTRetriever/BNBEXTRetriever_module.cc => ICARUSBNBEXTRetriever/ICARUSBNBEXTRetriever_module.cc} (86%) delete mode 100644 sbncode/BeamSpillInfoRetriever/job/bnbextcountinfo.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/icarusbnbextcountinfo.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/run_bnbextinfo_sbn.fcl create mode 100644 sbncode/BeamSpillInfoRetriever/job/run_icarusbnbextinfo_sbn.fcl diff --git a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt index 2e5998b50..290ac1e29 100644 --- a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt @@ -1,9 +1,9 @@ add_subdirectory(ICARUSBNBRetriever) +add_subdirectory(ICARUSBNBEXTRetriever) add_subdirectory(SBNDBNBRetriever) add_subdirectory(SBNDBNBEXTRetriever) add_subdirectory(SBNDBNBZEROBIASRetriever) add_subdirectory(NuMIRetriever) -add_subdirectory(BNBEXTRetriever) add_subdirectory(NuMIEXTRetriever) add_subdirectory(job) diff --git a/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt similarity index 91% rename from sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/CMakeLists.txt rename to sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt index 1c49f8646..1b1cbce80 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt @@ -1,5 +1,5 @@ -cet_build_plugin(BNBEXTRetriever art::module +cet_build_plugin(ICARUSBNBEXTRetriever art::module LIBRARIES art::Persistency_Common art::Utilities canvas::canvas diff --git a/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/ICARUSBNBEXTRetriever_module.cc similarity index 86% rename from sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc rename to sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/ICARUSBNBEXTRetriever_module.cc index 1b7c79dd5..b54ea184f 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/ICARUSBNBEXTRetriever_module.cc @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////// -// Class: BNBEXTRetriever +// Class: ICARUSBNBEXTRetriever // Plugin Type: producer -// File: BNBEXTRetriever_module.cc +// File: ICARUSBNBEXTRetriever_module.cc // // Created by hand Thurs June 24th 2021 by J. Zennamo (FNAL) // @@ -36,10 +36,10 @@ #include namespace sbn { - class BNBEXTRetriever; + class ICARUSBNBEXTRetriever; } -class sbn::BNBEXTRetriever : public art::EDProducer { +class sbn::ICARUSBNBEXTRetriever : public art::EDProducer { public: struct Config { @@ -57,15 +57,15 @@ class sbn::BNBEXTRetriever : public art::EDProducer { using Parameters = art::EDProducer::Table; - explicit BNBEXTRetriever(Parameters const& params); + explicit ICARUSBNBEXTRetriever(Parameters const& params); // The compiler-generated destructor is fine for non-base // classes without bare pointers or other resource use. // Plugins should not be copied or assigned. - BNBEXTRetriever(BNBEXTRetriever const&) = delete; - BNBEXTRetriever(BNBEXTRetriever&&) = delete; - BNBEXTRetriever& operator=(BNBEXTRetriever const&) = delete; - BNBEXTRetriever& operator=(BNBEXTRetriever&&) = delete; + ICARUSBNBEXTRetriever(ICARUSBNBEXTRetriever const&) = delete; + ICARUSBNBEXTRetriever(ICARUSBNBEXTRetriever&&) = delete; + ICARUSBNBEXTRetriever& operator=(ICARUSBNBEXTRetriever const&) = delete; + ICARUSBNBEXTRetriever& operator=(ICARUSBNBEXTRetriever&&) = delete; // Required functions. void produce(art::Event& e) override; @@ -85,7 +85,7 @@ class sbn::BNBEXTRetriever : public art::EDProducer { }; -sbn::BNBEXTRetriever::BNBEXTRetriever(Parameters const& params) +sbn::ICARUSBNBEXTRetriever::ICARUSBNBEXTRetriever(Parameters const& params) : EDProducer{params}, raw_data_label_(params().RawDataLabel()) { @@ -97,7 +97,7 @@ sbn::BNBEXTRetriever::BNBEXTRetriever(Parameters const& params) scale_factor = 0; } -void sbn::BNBEXTRetriever::produce(art::Event& e) +void sbn::ICARUSBNBEXTRetriever::produce(art::Event& e) { //Here we read in the artdaq Fragments and extract three pieces of information: @@ -152,7 +152,7 @@ void sbn::BNBEXTRetriever::produce(art::Event& e) } //end loop over events -void sbn::BNBEXTRetriever::beginSubRun(art::SubRun& sr) +void sbn::ICARUSBNBEXTRetriever::beginSubRun(art::SubRun& sr) { TotalEXTCounts = 0; totalMinBias = 0; @@ -162,7 +162,7 @@ void sbn::BNBEXTRetriever::beginSubRun(art::SubRun& sr) } //____________________________________________________________________________ -void sbn::BNBEXTRetriever::endSubRun(art::SubRun& sr) +void sbn::ICARUSBNBEXTRetriever::endSubRun(art::SubRun& sr) { // We will add all of the EXTCountInfo data-products to the // art::SubRun so it persists @@ -186,4 +186,4 @@ void sbn::BNBEXTRetriever::endSubRun(art::SubRun& sr) return; } -DEFINE_ART_MODULE(sbn::BNBEXTRetriever) +DEFINE_ART_MODULE(sbn::ICARUSBNBEXTRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc index 7ae66eedb..108881fbf 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////// -// Class: SBNDBNBRetriever +// Class: SBNDBNBEXTRetriever // Plugin Type: producer -// File: SBNDBNBRetriever_module.cc +// File: SBNDBNBEXTRetriever_module.cc // //////////////////////////////////////////////////////////////////////// @@ -32,22 +32,22 @@ #include "larcorealg/CoreUtils/counter.h" namespace sbn { - class SBNDBNBRetriever; + class SBNDBNBEXTRetriever; } -class sbn::SBNDBNBRetriever : public art::EDProducer { +class sbn::SBNDBNBEXTRetriever : public art::EDProducer { public: - explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); + explicit SBNDBNBEXTRetriever(fhicl::ParameterSet const & params); // Required functions. void produce(art::Event & e) override; void beginSubRun(art::SubRun& sr) override; void endSubRun(art::SubRun& sr) override; // Plugins should not be copied or assigned. - SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; + SBNDBNBEXTRetriever(SBNDBNBEXTRetriever const &) = delete; + SBNDBNBEXTRetriever(SBNDBNBEXTRetriever &&) = delete; + SBNDBNBEXTRetriever & operator = (SBNDBNBEXTRetriever const &) = delete; + SBNDBNBEXTRetriever & operator = (SBNDBNBEXTRetriever &&) = delete; private: @@ -76,7 +76,7 @@ class sbn::SBNDBNBRetriever : public art::EDProducer { float scale_factor; }; -sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) +sbn::SBNDBNBEXTRetriever::SBNDBNBEXTRetriever(fhicl::ParameterSet const & params) : EDProducer{params} { produces< std::vector< sbn::EXTCountInfo >, art::InSubRun >(); TotalEXTCounts = 0; @@ -90,7 +90,7 @@ int _run; int _subrun; int _event; -void sbn::SBNDBNBRetriever::produce(art::Event & e) +void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) { TriggerInfo_t const triggerInfo = extractTriggerInfo(e); TotalEXTCounts += triggerInfo.number_of_gates_since_previous_event; @@ -107,7 +107,7 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) fOutExtInfos.push_back(extInfo); } -sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { +sbn::SBNDBNBEXTRetriever::PTBInfo_t sbn::SBNDBNBEXTRetriever::extractPTBInfo(art::Handle > cont_frags) const { int numcont = 0; PTBInfo_t PTBInfo; for (auto const& cont : *cont_frags) @@ -139,7 +139,7 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand return PTBInfo; } -double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { +double sbn::SBNDBNBEXTRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { int numcont = 0; uint64_t TDCTimeStamp = 0; for (auto const& cont : *cont_frags) @@ -158,7 +158,7 @@ double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle(PTB_itag); @@ -178,7 +178,7 @@ sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(a return triggerInfo; } -void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) +void sbn::SBNDBNBEXTRetriever::beginSubRun(art::SubRun& sr) { TotalEXTCounts = 0; totalMinBias = 0; @@ -187,7 +187,7 @@ void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) return; } -void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) +void sbn::SBNDBNBEXTRetriever::endSubRun(art::SubRun& sr) { // We will add all of the EXTCountInfo data-products to the // art::SubRun so it persists @@ -211,4 +211,4 @@ void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) return; } -DEFINE_ART_MODULE(sbn::SBNDBNBRetriever) +DEFINE_ART_MODULE(sbn::SBNDBNBEXTRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 0c7d42179..0714f5b3f 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -12,9 +12,11 @@ #include "art/Framework/Principal/Run.h" #include "art/Framework/Principal/SubRun.h" #include "canvas/Utilities/InputTag.h" +#include "canvas/Utilities/Exception.h" #include "fhiclcpp/ParameterSet.h" #include "messagefacility/MessageLogger/MessageLogger.h" +#include #include #include #include @@ -67,6 +69,7 @@ class sbn::SBNDBNBRetriever : public art::EDProducer { std::unique_ptr bfp_mwr; struct PTBInfo_t { + double currPTBTimeStamp = 0; double prevPTBTimeStamp = 0; unsigned int GateCounter = 0; // FIXME needs to be integral type }; @@ -101,6 +104,7 @@ class sbn::SBNDBNBRetriever : public art::EDProducer { sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) : EDProducer{params} { + produces< std::vector< sbn::BNBSpillInfo >, art::InSubRun >(); raw_data_label = params.get("raw_data_label", "daq"); fInputLabel = params.get("InputLabel"); fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); @@ -162,9 +166,11 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand wt = word_type; if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(2)) { - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; + PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp/20).to_ullong()/50e6; PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; } } } //End of loop over the number of trigger words @@ -175,6 +181,7 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { int numcont = 0; + uint64_t TDCTimeStamp = 0; for (auto const& cont : *cont_frags) { @@ -193,7 +200,7 @@ double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle(PTB_itag); @@ -203,9 +210,16 @@ sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(a PTBInfo_t PTBInfo; TriggerInfo_t triggerInfo; PTBInfo = extractPTBInfo(PTB_cont_frags); - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - triggerInfo.t_current_event = TDCTimeStamp; + if (TDC_cont_frags) { + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + triggerInfo.t_current_event = TDCTimeStamp; + } + else{ + mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; + triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; + } + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; @@ -588,7 +602,7 @@ void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) { mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; - + auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); std::swap(*p, fOutbeamInfos); diff --git a/sbncode/BeamSpillInfoRetriever/job/bnbextcountinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/bnbextcountinfo.fcl deleted file mode 100644 index e8191e2dc..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/bnbextcountinfo.fcl +++ /dev/null @@ -1,10 +0,0 @@ - -BEGIN_PROLOG - -bnbextcountinfo: { - - module_type: "BNBEXTRetriever" - raw_data_label: "daq" - -} -END_PROLOG diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusbnbextcountinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusbnbextcountinfo.fcl new file mode 100644 index 000000000..cabe02824 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/icarusbnbextcountinfo.fcl @@ -0,0 +1,10 @@ + +BEGIN_PROLOG + +icarusbnbextcountinfo: { + + module_type: "ICARUSBNBEXTRetriever" + raw_data_label: "daq" + +} +END_PROLOG diff --git a/sbncode/BeamSpillInfoRetriever/job/run_bnbextinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_bnbextinfo_sbn.fcl deleted file mode 100644 index fbee5871f..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/run_bnbextinfo_sbn.fcl +++ /dev/null @@ -1,32 +0,0 @@ -#include "bnbextcountinfo.fcl" - -process_name: BNBEXTInfoGen - -services:{ - IFBeam:{} -} - - -source: { - -} - -physics: { - producers: { - bnbextinfo: @local::bnbextcountinfo - } - - simulate: [bnbextinfo ] - stream1: [ out1 ] - -} - -outputs: { - out1: { - module_type: RootOutput - fileName: "%ifb_%tc_bnbextinfo.root" - dataTier: "raw" - compressionLevel: 1 - } -} - diff --git a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbextinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbextinfo_sbn.fcl new file mode 100644 index 000000000..c73bd8fc6 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbextinfo_sbn.fcl @@ -0,0 +1,32 @@ +#include "icarusbnbextcountinfo.fcl" + +process_name: ICARUSBNBEXTInfoGen + +services:{ + IFBeam:{} +} + + +source: { + +} + +physics: { + producers: { + icarusbnbextinfo: @local::icarusbnbextcountinfo + } + + simulate: [icarusbnbextinfo ] + stream1: [ out1 ] + +} + +outputs: { + out1: { + module_type: RootOutput + fileName: "%ifb_%tc_icarusbnbextinfo.root" + dataTier: "raw" + compressionLevel: 1 + } +} + From 96682e93647964f4aa78985a56a4cbbb5f92f8cf Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Wed, 27 Nov 2024 16:50:28 -0600 Subject: [PATCH 028/367] Temp debug lines, TDC catch --- .../SBNDBNBEXTRetriever_module.cc | 35 ++++++++-- .../SBNDBNBRetriever_module.cc | 26 +++++-- .../SBNDBNBZEROBIASRetriever_module.cc | 67 +++++++++++++++---- 3 files changed, 107 insertions(+), 21 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc index 108881fbf..eaa3424fc 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc @@ -54,6 +54,7 @@ class sbn::SBNDBNBEXTRetriever : public art::EDProducer { // Declare member data here. std::vector< sbn::EXTCountInfo > fOutExtInfos; struct PTBInfo_t { + double currPTBTimeStamp = 0; double prevPTBTimeStamp = 0; unsigned int GateCounter = 0; // FIXME needs to be integral type }; @@ -92,7 +93,16 @@ int _event; void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) { + + std::cout << "new_event: " << e.event() << std::endl; + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + + std::cout << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; + std::cout << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; + std::cout << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; + + TotalEXTCounts += triggerInfo.number_of_gates_since_previous_event; if(triggerInfo.number_of_gates_since_previous_event > 0){ @@ -108,6 +118,8 @@ void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) } sbn::SBNDBNBEXTRetriever::PTBInfo_t sbn::SBNDBNBEXTRetriever::extractPTBInfo(art::Handle > cont_frags) const { + int HLT_count = 0; + int numcont = 0; PTBInfo_t PTBInfo; for (auto const& cont : *cont_frags) @@ -128,20 +140,26 @@ sbn::SBNDBNBEXTRetriever::PTBInfo_t sbn::SBNDBNBEXTRetriever::extractPTBInfo(art wt = word_type; if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(4)) { - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + HLT_count++; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers + + std::cout << "HLT_count: " << HLT_count << std::endl; return PTBInfo; } double sbn::SBNDBNBEXTRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { int numcont = 0; - uint64_t TDCTimeStamp = 0; + double TDCTimeStamp = 0; for (auto const& cont : *cont_frags) { artdaq::ContainerFragment cont_frag(cont); @@ -152,7 +170,7 @@ double sbn::SBNDBNBEXTRetriever::extractTDCTimeStamp(art::Handletimestamp_ns()/1e9; + TDCTimeStamp = static_cast(tdc_frag.getTDCTimestamp()->timestamp_ns())/1e9; } //End of loop over the number of fragments per container } //End of loop over the number of containers return TDCTimeStamp; @@ -169,9 +187,16 @@ sbn::SBNDBNBEXTRetriever::TriggerInfo_t sbn::SBNDBNBEXTRetriever::extractTrigger PTBInfo_t PTBInfo; TriggerInfo_t triggerInfo; PTBInfo = extractPTBInfo(PTB_cont_frags); - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - triggerInfo.t_current_event = TDCTimeStamp; + if (TDC_cont_frags) { + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + triggerInfo.t_current_event = TDCTimeStamp; + } + else{ + mf::LogDebug("SBNDBNBEXTRetriever") << " Missing TDC Contaienr Fragments!!! " << std::endl; + triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; + } + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 0714f5b3f..a77aa9dab 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -133,7 +133,14 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) // spill that the DAQ was sensitive to, so don't try to save any // spill information + std::cout << "new_event: " << e.event() << std::endl; + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + + std::cout << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; + std::cout << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; + std::cout << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; + TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); @@ -146,6 +153,8 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) } sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { + int HLT_count = 0; + int numcont = 0; PTBInfo_t PTBInfo; for (auto const& cont : *cont_frags) @@ -166,23 +175,28 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand wt = word_type; if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(2)) { + + HLT_count++; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; - PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp/20).to_ullong()/50e6; PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp/20).to_ullong()/50e6; PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers + + std::cout << "HLT_count: " << HLT_count << std::endl; return PTBInfo; } double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { int numcont = 0; - uint64_t TDCTimeStamp = 0; + double TDCTimeStamp = 0; for (auto const& cont : *cont_frags) { artdaq::ContainerFragment cont_frag(cont); @@ -193,7 +207,7 @@ double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handletimestamp_ns()/1e9; + TDCTimeStamp = static_cast(tdc_frag.getTDCTimestamp()->timestamp_ns())/1e9; } //End of loop over the number of fragments per container } //End of loop over the number of containers return TDCTimeStamp; @@ -217,6 +231,7 @@ sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(a } else{ mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; + std::cout << " Missing TDC Container Fragments!!! " << std::endl; triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; } @@ -517,7 +532,7 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo // allow each to throw an exception but still move forward // interpreting these failures will be part of the beam quality analyses - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n"; std::cout << "ifbeam_failed" << std::endl;} try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -534,6 +549,9 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo //crunch the times unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; + + std::cout << "TOR860_time: " << std::setprecision(19) << TOR860_time << std::endl; + std::cout << "TOR860: " << TOR860 << std::endl; //Store everything in our data-product sbn::BNBSpillInfo beamInfo; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index 424a30121..5cf95fe2d 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -67,6 +67,7 @@ class sbn::SBNDBNBRetriever : public art::EDProducer { std::unique_ptr bfp_mwr; struct PTBInfo_t { + double currPTBTimeStamp = 0; double prevPTBTimeStamp = 0; unsigned int GateCounter = 0; // FIXME needs to be integral type }; @@ -131,7 +132,14 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) // spill that the DAQ was sensitive to, so don't try to save any // spill information + std::cout << "new_event: " << e.event() << std::endl; + TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + + std::cout << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; + std::cout << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; + std::cout << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; + TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); @@ -143,6 +151,8 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) } sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { + int HLT_count = 0; + int numcont = 0; PTBInfo_t PTBInfo; for (auto const& cont : *cont_frags) @@ -163,20 +173,27 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand wt = word_type; if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) { - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + HLT_count++; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + // uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; + uint64_t RawcurrPTBTimeStamp = ctb_frag.TimeStamp(word_i) * 20; PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers + + std::cout << "HLT_count: " << HLT_count << std::endl; return PTBInfo; } double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { int numcont = 0; - uint64_t TDCTimeStamp = 0; + double TDCTimeStamp = 0; for (auto const& cont : *cont_frags) { artdaq::ContainerFragment cont_frag(cont); @@ -186,8 +203,8 @@ double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handletimestamp_ns()/1e9; + sbndaq::TDCTimestampFragment tdc_frag(frag); + TDCTimeStamp = static_cast(tdc_frag.getTDCTimestamp()->timestamp_ns()) / 1e9; } //End of loop over the number of fragments per container } //End of loop over the number of containers return TDCTimeStamp; @@ -204,12 +221,35 @@ sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(a PTBInfo_t PTBInfo; TriggerInfo_t triggerInfo; PTBInfo = extractPTBInfo(PTB_cont_frags); - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - triggerInfo.t_current_event = TDCTimeStamp; + if (TDC_cont_frags) { + double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + triggerInfo.t_current_event = TDCTimeStamp; + } + else{ + mf::LogDebug("SBNDBNBZEROBIASRetriever") << " Missing TDC Container Fragments!!!" << std::endl; + std::cout << " Missing TDC Container Fragments!!!" << std::endl; + triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; + } + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; + std::cout << "PTBdiff: " << PTBInfo.currPTBTimeStamp-PTBInfo.prevPTBTimeStamp << std::endl; + + if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ + std::cout << "Caught PTB bug, PTB late" << std::endl; + std::cout << "Before: " << triggerInfo.t_previous_event << std::endl; + triggerInfo.t_previous_event+=1; + std::cout << "After: " << triggerInfo.t_previous_event << std::endl; + } + else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ + std::cout << "Caught PTB bug, PTB early" << std::endl; + std::cout << "Before: " << triggerInfo.t_previous_event << std::endl; + triggerInfo.t_previous_event-=1; + std::cout << "After: " << triggerInfo.t_previous_event << std::endl; + } + return triggerInfo; } @@ -364,13 +404,13 @@ void sbn::SBNDBNBRetriever::matchMultiWireData( for (size_t k = 0; k < times_temps.size(); k++){ diff = times_temps[k] - (triggerInfo.t_current_event + fTimePad); + if( diff < 0 and diff < best_diff){ - if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ + if(times_temps[k] > (triggerInfo.t_current_event)+fTimePad){ spills_removed++; continue;} - if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ + if(times_temps[k] <= (triggerInfo.t_previous_event)+fTimePad){ spills_removed++; - //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; continue;} best_diff = diff; i = k; @@ -455,8 +495,8 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo // since sometimes devices fail to report we'll // allow each to throw an exception but still move forward // interpreting these failures will be part of the beam quality analyses - - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n"; std::cout << "ifbeam_failed" << std::endl;} try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -473,7 +513,10 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo //crunch the times unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - + + std::cout << "TOR860_time: " << std::setprecision(19) << TOR860_time << std::endl; + std::cout << "TOR860: " << TOR860 << std::endl; + //Store everything in our data-product sbn::BNBSpillInfo beamInfo; beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units From ee61b197b82a128a0fb9bc735314bb963ac4933a Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Tue, 12 Nov 2024 11:31:07 -0600 Subject: [PATCH 029/367] introduced counters for bottomCRT in a comment for future use, currently unused --- sbncode/CAFMaker/CAFMaker_module.cc | 5 +++-- sbncode/CAFMaker/FillReco.cxx | 1 + sbncode/CAFMaker/FillReco.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 35f4d1347..091f4c984 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1478,10 +1478,11 @@ void CAFMaker::produce(art::Event& evt) noexcept { if(crtpmtmatch_handle.isValid()){ const std::vector &crtpmtmatches = *crtpmtmatch_handle; for (unsigned i = 0; i < crtpmtmatches.size(); i++) { - int topen = 0, topex = 0, sideen = 0, sideex = 0; + int topen = 0, topex = 0, sideen = 0, sideex = 0; // bottomen = 0, bottomex = 0; srcrtpmtmatches.emplace_back(); FillCRTPMTMatch(crtpmtmatches[i], - topen, topex, sideen, sideex, + topen, topex, sideen, sideex, + //bottomen, bottomex, srcrtpmtmatches.back()); } } diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 38b72e79b..5bb47af33 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -139,6 +139,7 @@ namespace caf void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, int &topen, int &topex, int &sideen, int &sideex, + //int &bottomen, int &bottomex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty){ // allowEmpty does not (yet) matter here diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 044aacddc..89333749d 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -226,6 +226,7 @@ namespace caf bool allowEmpty = false); void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, int &topen, int &topex, int &sideen, int &sidex, + //int &bottomen, int &bottomex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty = false); From 64b637e3fc68e2ecf378c93c60987143aa58a530 Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Tue, 3 Dec 2024 13:42:20 -0600 Subject: [PATCH 030/367] replace uint with unsigned int in FillCRTPMTMatch --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillReco.cxx | 5 +++-- sbncode/CAFMaker/FillReco.h | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 091f4c984..3bf49275a 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1478,7 +1478,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { if(crtpmtmatch_handle.isValid()){ const std::vector &crtpmtmatches = *crtpmtmatch_handle; for (unsigned i = 0; i < crtpmtmatches.size(); i++) { - int topen = 0, topex = 0, sideen = 0, sideex = 0; // bottomen = 0, bottomex = 0; + unsigned int topen = 0, topex = 0, sideen = 0, sideex = 0; // bottomen = 0, bottomex = 0; srcrtpmtmatches.emplace_back(); FillCRTPMTMatch(crtpmtmatches[i], topen, topex, sideen, sideex, diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 5bb47af33..e7ee66a20 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -138,8 +138,9 @@ namespace caf } void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, - int &topen, int &topex, int &sideen, int &sideex, - //int &bottomen, int &bottomex, + unsigned int topen, unsigned int topex, + unsigned int sideen, unsigned int sideex, + //unsigned int &bottomen, unsigned int &bottomex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty){ // allowEmpty does not (yet) matter here diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 89333749d..90e413829 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -225,8 +225,9 @@ namespace caf caf::SROpFlash &srflash, bool allowEmpty = false); void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, - int &topen, int &topex, int &sideen, int &sidex, - //int &bottomen, int &bottomex, + unsigned int topen, unsigned int topex, + unsigned int sideen, unsigned int sidex, + //unsigned int &bottomen, unsigned int &bottomex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty = false); From 9a61b036cf7c2ec7ea3ad103263be4a9cf3d322b Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Tue, 3 Dec 2024 16:28:13 -0600 Subject: [PATCH 031/367] remove unused counters from FillCRTPMTMatch function --- sbncode/CAFMaker/CAFMaker_module.cc | 6 +----- sbncode/CAFMaker/FillReco.cxx | 4 +--- sbncode/CAFMaker/FillReco.h | 3 --- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 3bf49275a..4e6ee0234 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1478,12 +1478,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { if(crtpmtmatch_handle.isValid()){ const std::vector &crtpmtmatches = *crtpmtmatch_handle; for (unsigned i = 0; i < crtpmtmatches.size(); i++) { - unsigned int topen = 0, topex = 0, sideen = 0, sideex = 0; // bottomen = 0, bottomex = 0; srcrtpmtmatches.emplace_back(); - FillCRTPMTMatch(crtpmtmatches[i], - topen, topex, sideen, sideex, - //bottomen, bottomex, - srcrtpmtmatches.back()); + FillCRTPMTMatch(crtpmtmatches[i], srcrtpmtmatches.back()); } } diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index e7ee66a20..3a31de7ef 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -138,9 +138,6 @@ namespace caf } void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, - unsigned int topen, unsigned int topex, - unsigned int sideen, unsigned int sideex, - //unsigned int &bottomen, unsigned int &bottomex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty){ // allowEmpty does not (yet) matter here @@ -157,6 +154,7 @@ namespace caf srmatch.flashPosition = SRVector3D (match.flashPosition.X(), match.flashPosition.Y(), match.flashPosition.Z()); srmatch.flashYWidth = match.flashYWidth; srmatch.flashZWidth = match.flashZWidth; + unsigned int topen = 0, topex = 0, sideen = 0, sideex = 0; for(const auto& matchedCRTHit : match.matchedCRTHits){ caf::SRMatchedCRT matchedCRT; matchedCRT.PMTTimeDiff = matchedCRTHit.PMTTimeDiff; diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 90e413829..1271279fd 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -225,9 +225,6 @@ namespace caf caf::SROpFlash &srflash, bool allowEmpty = false); void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, - unsigned int topen, unsigned int topex, - unsigned int sideen, unsigned int sidex, - //unsigned int &bottomen, unsigned int &bottomex, caf::SRCRTPMTMatch &srmatch, bool allowEmpty = false); From 83f8895d064ea4da0e135628a60a8b6ce0f2a48d Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Thu, 5 Dec 2024 21:16:57 -0600 Subject: [PATCH 032/367] remove scaling, add debug --- .../SBNDBNBEXTRetriever_module.cc | 39 ++++---- .../SBNDBNBRetriever_module.cc | 37 +++++--- .../SBNDBNBZEROBIASRetriever_module.cc | 90 ++++++++++++------- 3 files changed, 101 insertions(+), 65 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc index eaa3424fc..2246dde03 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc @@ -74,7 +74,6 @@ class sbn::SBNDBNBEXTRetriever : public art::EDProducer { float TotalEXTCounts; float totalMinBias; float evtCount; - float scale_factor; }; sbn::SBNDBNBEXTRetriever::SBNDBNBEXTRetriever(fhicl::ParameterSet const & params) @@ -83,7 +82,6 @@ sbn::SBNDBNBEXTRetriever::SBNDBNBEXTRetriever(fhicl::ParameterSet const & params TotalEXTCounts = 0; totalMinBias = 0; evtCount = 0; - scale_factor = 0; } int eventNum =0; @@ -94,13 +92,13 @@ int _event; void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) { - std::cout << "new_event: " << e.event() << std::endl; + mf::LogDebug("SBNDBNBEXTRetriever") << "new_event: " << e.event() << std::endl; TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - std::cout << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; - std::cout << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; - std::cout << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; + mf::LogDebug("SBNDBNBEXTRetriever") << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; + mf::LogDebug("SBNDBNBEXTRetriever") << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBEXTRetriever") << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; TotalEXTCounts += triggerInfo.number_of_gates_since_previous_event; @@ -113,7 +111,6 @@ void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) //Store everything in our data-product sbn::EXTCountInfo extInfo; extInfo.gates_since_last_trigger = triggerInfo.number_of_gates_since_previous_event; - fOutExtInfos.push_back(extInfo); } @@ -147,13 +144,13 @@ sbn::SBNDBNBEXTRetriever::PTBInfo_t sbn::SBNDBNBEXTRetriever::extractPTBInfo(art PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20).to_ullong()/50e6; PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + break; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers - std::cout << "HLT_count: " << HLT_count << std::endl; return PTBInfo; } @@ -200,6 +197,19 @@ sbn::SBNDBNBEXTRetriever::TriggerInfo_t sbn::SBNDBNBEXTRetriever::extractTrigger triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; + if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ + mf::LogDebug("SBNDBNBEXTRetriever") << "Caught PTB bug, PTB late" << std::endl; + mf::LogDebug("SBNDBNBEXTRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; + triggerInfo.t_previous_event+=1; + mf::LogDebug("SBNDBNBEXTRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; + } + else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ + mf::LogDebug("SBNDBNBEXTRetriever") << "Caught PTB bug, PTB early" << std::endl; + mf::LogDebug("SBNDBNBEXTRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; + triggerInfo.t_previous_event-=1; + mf::LogDebug("SBNDBNBEXTRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; + } + return triggerInfo; } @@ -208,7 +218,6 @@ void sbn::SBNDBNBEXTRetriever::beginSubRun(art::SubRun& sr) TotalEXTCounts = 0; totalMinBias = 0; evtCount = 0; - scale_factor = 0; return; } @@ -217,18 +226,6 @@ void sbn::SBNDBNBEXTRetriever::endSubRun(art::SubRun& sr) // We will add all of the EXTCountInfo data-products to the // art::SubRun so it persists - if(evtCount != 0 && totalMinBias != 0) - scale_factor = 1. - (evtCount/totalMinBias); - else - std::cout << "FAILED! " << std::endl; - // probably want to throw an exception here - - for(auto ExtInfo : fOutExtInfos){ - - ExtInfo.gates_since_last_trigger *= scale_factor; - - } - auto p = std::make_unique< std::vector< sbn::EXTCountInfo > >(fOutExtInfos); sr.put(std::move(p), art::subRunFragment()); diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index a77aa9dab..8fbfae9ea 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -133,13 +133,13 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) // spill that the DAQ was sensitive to, so don't try to save any // spill information - std::cout << "new_event: " << e.event() << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "new_event: " << e.event() << std::endl; TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - std::cout << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; - std::cout << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; - std::cout << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); @@ -153,7 +153,6 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) } sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { - int HLT_count = 0; int numcont = 0; PTBInfo_t PTBInfo; @@ -173,23 +172,24 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand uint32_t wt = 0; uint32_t word_type = ctb_frag.Word(word_i)->word_type; wt = word_type; + mf::LogDebug("SBNDBNBRetriever") << "GateCounter!: " << ctb_frag.Trigger(word_i)->gate_counter << std::endl; if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(2)) { - HLT_count++; - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp/20).to_ullong()/50e6; PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " prevPTBTimeStamp: " << PTBInfo.prevPTBTimeStamp << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " currPTBTimeStamp: " << PTBInfo.currPTBTimeStamp << std::endl; + break; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers - std::cout << "HLT_count: " << HLT_count << std::endl; return PTBInfo; } @@ -231,13 +231,26 @@ sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(a } else{ mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; - std::cout << " Missing TDC Container Fragments!!! " << std::endl; + mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; } triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; + if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ + mf::LogDebug("SBNDBNBRetriever") << "Caught PTB bug, PTB late" << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; + triggerInfo.t_previous_event+=1; + mf::LogDebug("SBNDBNBRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; + } + else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ + mf::LogDebug("SBNDBNBRetriever") << "Caught PTB bug, PTB early" << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; + triggerInfo.t_previous_event-=1; + mf::LogDebug("SBNDBNBRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; + } + return triggerInfo; } @@ -532,7 +545,7 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo // allow each to throw an exception but still move forward // interpreting these failures will be part of the beam quality analyses - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n"; std::cout << "ifbeam_failed" << std::endl;} + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -550,8 +563,8 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - std::cout << "TOR860_time: " << std::setprecision(19) << TOR860_time << std::endl; - std::cout << "TOR860: " << TOR860 << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "TOR860_time: " << std::setprecision(19) << TOR860_time << std::endl; + mf::LogDebug("SBNDBNBRetriever") << "TOR860: " << TOR860 << std::endl; //Store everything in our data-product sbn::BNBSpillInfo beamInfo; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index 5cf95fe2d..b87e7bca0 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -115,8 +115,8 @@ sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); TotalBeamSpills = 0; - - produces< std::vector >(); + produces< std::vector< sbn::BNBSpillInfo >, art::InEvent >(); + // produces< std::vector >(); } int eventNum =0; @@ -132,13 +132,20 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) // spill that the DAQ was sensitive to, so don't try to save any // spill information - std::cout << "new_event: " << e.event() << std::endl; + if (e.event() == 1) { + auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); + std::swap(*p, fOutbeamInfos); + e.put(std::move(p)); + return; + } + + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "new_event: " << e.event() << std::endl; TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - std::cout << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; - std::cout << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; - std::cout << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "triggerInfo.t_current_event: " << std::setprecision(25) << triggerInfo.t_current_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "triggerInfo.t_previous_event: " << std::setprecision(25) << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); @@ -151,7 +158,6 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) } sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { - int HLT_count = 0; int numcont = 0; PTBInfo_t PTBInfo; @@ -173,21 +179,23 @@ sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Hand wt = word_type; if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) { - HLT_count++; - - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20.0; // uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; - uint64_t RawcurrPTBTimeStamp = ctb_frag.TimeStamp(word_i) * 20; - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; - PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20).to_ullong()/50e6; + uint64_t RawcurrPTBTimeStamp = ctb_frag.TimeStamp(word_i) * 20.0; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20.0).to_ullong()/50e6; + PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20.0).to_ullong()/50e6; PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + + mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " prevPTBTimeStamp: " << PTBInfo.prevPTBTimeStamp << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " currPTBTimeStamp: " << PTBInfo.currPTBTimeStamp << std::endl; + + break; } } } //End of loop over the number of trigger words } //End of loop over the number of fragments per container } //End of loop over the number of containers - std::cout << "HLT_count: " << HLT_count << std::endl; return PTBInfo; } @@ -228,26 +236,24 @@ sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(a } else{ mf::LogDebug("SBNDBNBZEROBIASRetriever") << " Missing TDC Container Fragments!!!" << std::endl; - std::cout << " Missing TDC Container Fragments!!!" << std::endl; triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; } triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - std::cout << "PTBdiff: " << PTBInfo.currPTBTimeStamp-PTBInfo.prevPTBTimeStamp << std::endl; if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ - std::cout << "Caught PTB bug, PTB late" << std::endl; - std::cout << "Before: " << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Caught PTB bug, PTB late" << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; triggerInfo.t_previous_event+=1; - std::cout << "After: " << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; } else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ - std::cout << "Caught PTB bug, PTB early" << std::endl; - std::cout << "Before: " << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Caught PTB bug, PTB early" << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; triggerInfo.t_previous_event-=1; - std::cout << "After: " << triggerInfo.t_previous_event << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; } return triggerInfo; @@ -398,6 +404,25 @@ void sbn::SBNDBNBRetriever::matchMultiWireData( // Iterating through each of the beamline times + if(isFirstEventInRun){ + //We'll remove the spills after our event + int spills_after_our_target = 0; + // iterate through all the spills to find the + // spills that are after our triggered event + for (size_t i = 0; i < times_temps.size(); i++) { + if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ + spills_after_our_target++; + } + }//end loop through spill times + + // Remove the spills after our trigger + times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); + + // Remove the spills before the start of our Run + times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); + + }//end fix for "first event" + double best_diff = 10000000000.0; double diff; size_t i = 0; @@ -406,12 +431,14 @@ void sbn::SBNDBNBRetriever::matchMultiWireData( diff = times_temps[k] - (triggerInfo.t_current_event + fTimePad); if( diff < 0 and diff < best_diff){ - if(times_temps[k] > (triggerInfo.t_current_event)+fTimePad){ - spills_removed++; - continue;} - if(times_temps[k] <= (triggerInfo.t_previous_event)+fTimePad){ - spills_removed++; - continue;} + if(!isFirstEventInRun){ + if(times_temps[k] > (triggerInfo.t_current_event)+fTimePad){ + spills_removed++; + continue;} + if(times_temps[k] <= (triggerInfo.t_previous_event)+fTimePad){ + spills_removed++; + continue;} + } best_diff = diff; i = k; } @@ -469,7 +496,6 @@ void sbn::SBNDBNBRetriever::matchMultiWireData( sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const { - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias // initializing all of our device carriers @@ -496,7 +522,7 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo // allow each to throw an exception but still move forward // interpreting these failures will be part of the beam quality analyses - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n"; std::cout << "ifbeam_failed" << std::endl;} + try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -514,8 +540,8 @@ sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo unsigned long int time_closest_int = (int) TOR860_time; double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - std::cout << "TOR860_time: " << std::setprecision(19) << TOR860_time << std::endl; - std::cout << "TOR860: " << TOR860 << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "TOR860_time: " << std::setprecision(25) << TOR860_time << std::endl; + mf::LogDebug("SBNDBNBZEROBIASRetriever") << "TOR860: " << TOR860 << std::endl; //Store everything in our data-product sbn::BNBSpillInfo beamInfo; From 9b11cdc20a38da2f36e724492fb19fbf704a0f21 Mon Sep 17 00:00:00 2001 From: = <=> Date: Mon, 9 Dec 2024 12:28:30 -0600 Subject: [PATCH 033/367] Updating again to final version of code as approved --- sbncode/DetSim/FilterSimEnergyDeposits_module.cc | 10 +++++----- sbncode/DetSim/fcl/icarus_simedepfilter.fcl | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sbncode/DetSim/FilterSimEnergyDeposits_module.cc b/sbncode/DetSim/FilterSimEnergyDeposits_module.cc index 18f911de4..802887c91 100644 --- a/sbncode/DetSim/FilterSimEnergyDeposits_module.cc +++ b/sbncode/DetSim/FilterSimEnergyDeposits_module.cc @@ -43,7 +43,7 @@ class FilterSimEnergyDeposits : public art::EDProducer { art::InputTag fInitSimEnergyDepositLabel; geo::BoxBoundedGeo fBox; static constexpr auto kModuleName = "FilterSimEnergyDeposit"; - const double ShiftX(double z); + double ShiftX(double z) const; double fA; double fB; double fC; @@ -57,9 +57,9 @@ FilterSimEnergyDeposits::FilterSimEnergyDeposits(fhicl::ParameterSet const& p) , fBox{p.get("P1_X"), p.get("P2_X"), p.get("P1_Y"), p.get("P2_Y"), p.get("P1_Z"), p.get("P2_Z")} - , fA{p.get("A", 0.0)} - , fB{p.get("B", 0.0)} - , fC{p.get("C", 0.0)} + , fA{p.get("A")} + , fB{p.get("B")} + , fC{p.get("C")} { // Call appropriate produces<>() functions here. // Call appropriate consumes<>() for any products to be retrieved by this module. @@ -67,7 +67,7 @@ FilterSimEnergyDeposits::FilterSimEnergyDeposits(fhicl::ParameterSet const& p) } -const double FilterSimEnergyDeposits::ShiftX(double z) +double FilterSimEnergyDeposits::ShiftX(double z) const { //known as a "Hill equation" from fitting distribution of angle corrected tracks looking at the deflection as it gets closer to z = 0 double a = fA; diff --git a/sbncode/DetSim/fcl/icarus_simedepfilter.fcl b/sbncode/DetSim/fcl/icarus_simedepfilter.fcl index 59485c690..1a697cea8 100644 --- a/sbncode/DetSim/fcl/icarus_simedepfilter.fcl +++ b/sbncode/DetSim/fcl/icarus_simedepfilter.fcl @@ -9,6 +9,7 @@ simedepfilter_ind1gap: { P2_X: 400 #cm, create a box that spans the full x,y range. Not super-precise. P2_Y: 200 #cm, create a box that spans the full x,y range. Not super-precise. P2_Z: 2 #cm, other edge of the filtered gap based on the 37 mm total size of the wire gap + # Values from SBN DocDB 38701: A: -0.431172 B: -2.52724 C: 0.22043 From c3fb800517c251d03aab19dcffdebef85c14e52f Mon Sep 17 00:00:00 2001 From: Ibrahim Safa Date: Tue, 17 Dec 2024 09:54:51 -0600 Subject: [PATCH 034/367] iterate patch number --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ff5fc4d3..e385cc614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 09.89.01.01 LANGUAGES CXX) +project(sbncode VERSION 09.89.01.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") From 4294a7ef8c230b9cbdce728d7b5459e6a2dc87dd Mon Sep 17 00:00:00 2001 From: Ibrahim Safa Date: Tue, 17 Dec 2024 10:10:15 -0600 Subject: [PATCH 035/367] sbnanaobj dependency --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index 199bb72ff..fef37738f 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v09_89_01 - -sbnanaobj v09_23_00_01 - +sbnanaobj v09_23_00_02 - sbndaq_artdaq_core v1_09_00of1 - sbndata v01_07 - sbnobj v09_19_00_01 - From ed691882b497b91cdf425fd588e6430c65939018 Mon Sep 17 00:00:00 2001 From: Ibrahim Safa Date: Thu, 9 Jan 2025 11:12:37 -0600 Subject: [PATCH 036/367] update to larsoft 89_02 --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e385cc614..569807112 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 09.89.01.02 LANGUAGES CXX) +project(sbncode VERSION 09.89.01.03 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index fef37738f..b8123f07d 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v09_89_01 - +larsoft v09_89_02 - sbnanaobj v09_23_00_02 - sbndaq_artdaq_core v1_09_00of1 - sbndata v01_07 - From 8b1417c6e55fefea43874d6d6872a06e4b0b4a89 Mon Sep 17 00:00:00 2001 From: Ibrahim Safa Date: Thu, 9 Jan 2025 11:15:21 -0600 Subject: [PATCH 037/367] sbncode version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 569807112..49ff333aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 09.89.01.03 LANGUAGES CXX) +project(sbncode VERSION 09.89.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") From f39290c042260d1d86414ce2844a3373b46eb9b9 Mon Sep 17 00:00:00 2001 From: Gianluca Petrillo Date: Sat, 18 Jan 2025 14:25:27 -0600 Subject: [PATCH 038/367] SBN job metadata: full system implementation and documentation, and sbncode GIT version --- CMakeLists.txt | 2 +- fcl/CMakeLists.txt | 1 + fcl/util/CMakeLists.txt | 1 + fcl/util/dump_sbnjobmetadata.fcl | 41 ++ sbncode/Metadata/CMakeLists.txt | 45 +++ sbncode/Metadata/DumpJobEnvironment_module.cc | 176 +++++++++ sbncode/Metadata/GITrepoVersion.cxx.in | 16 + sbncode/Metadata/GITrepoVersion.h.in | 18 + sbncode/Metadata/GlobalMetadataRegistry.cxx | 69 ++++ sbncode/Metadata/GlobalMetadataRegistry.h | 88 +++++ .../Metadata/JobEnvironmentInfoExtractor.cxx | 149 +++++++ .../Metadata/JobEnvironmentInfoExtractor.h | 146 +++++++ .../Metadata/RepositoryVersionReportUtils.cpp | 71 ++++ .../Metadata/RepositoryVersionReportUtils.h | 60 +++ sbncode/Metadata/RepositoryVersionReporter.h | 75 ++++ sbncode/Metadata/SBNsourceMetadataSystem.dox | 367 ++++++++++++++++++ sbncode/Metadata/SaveJobEnvironment_plugin.cc | 331 ++++++++++++++++ .../Metadata/sbncodeRepositoryVersion_tool.cc | 62 +++ 18 files changed, 1717 insertions(+), 1 deletion(-) create mode 100644 fcl/util/CMakeLists.txt create mode 100644 fcl/util/dump_sbnjobmetadata.fcl create mode 100644 sbncode/Metadata/DumpJobEnvironment_module.cc create mode 100644 sbncode/Metadata/GITrepoVersion.cxx.in create mode 100644 sbncode/Metadata/GITrepoVersion.h.in create mode 100644 sbncode/Metadata/GlobalMetadataRegistry.cxx create mode 100644 sbncode/Metadata/GlobalMetadataRegistry.h create mode 100644 sbncode/Metadata/JobEnvironmentInfoExtractor.cxx create mode 100644 sbncode/Metadata/JobEnvironmentInfoExtractor.h create mode 100644 sbncode/Metadata/RepositoryVersionReportUtils.cpp create mode 100644 sbncode/Metadata/RepositoryVersionReportUtils.h create mode 100644 sbncode/Metadata/RepositoryVersionReporter.h create mode 100644 sbncode/Metadata/SBNsourceMetadataSystem.dox create mode 100644 sbncode/Metadata/SaveJobEnvironment_plugin.cc create mode 100644 sbncode/Metadata/sbncodeRepositoryVersion_tool.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 80358d54a..a261d54fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,6 @@ project(sbncode VERSION 09.92.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") - include(CetCMakeEnv) cet_cmake_env() @@ -82,6 +81,7 @@ find_package( Boost COMPONENTS system filesystem REQUIRED ) include(ArtDictionary) include(ArtMake) include(BuildPlugins) +include(SBNutils) add_subdirectory(sbncode) add_subdirectory(fcl) diff --git a/fcl/CMakeLists.txt b/fcl/CMakeLists.txt index 3b6d71246..9a1d7be80 100644 --- a/fcl/CMakeLists.txt +++ b/fcl/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(gen) add_subdirectory(g4) add_subdirectory(caf) +add_subdirectory(util) install_fhicl() diff --git a/fcl/util/CMakeLists.txt b/fcl/util/CMakeLists.txt new file mode 100644 index 000000000..13355789a --- /dev/null +++ b/fcl/util/CMakeLists.txt @@ -0,0 +1 @@ +install_fhicl() diff --git a/fcl/util/dump_sbnjobmetadata.fcl b/fcl/util/dump_sbnjobmetadata.fcl new file mode 100644 index 000000000..2b14d3c68 --- /dev/null +++ b/fcl/util/dump_sbnjobmetadata.fcl @@ -0,0 +1,41 @@ +# +# File: dump_sbnjobmetadata.fcl +# Purpose: Prints on screen all the job SBN metadata stored in an input file. +# Author: Gianluca Petrillo (petrillo@slac.stanford.edu) +# Date: January 20, 2025 +# +# Reads and prints on screen the SBN job environment information from the input +# file. +# +# Changes +# -------- +# +# [20250120] (petrillo@slac.stanford.edu) +# original version +# + +#include "messages_icarus.fcl" + +process_name: JobMeta + +# use `icarus_message_services_interactive` to see dump on screen +services.message: @local::icarus_message_services_prod + +services.message.destinations.MetadataLog: { + type: file + filename: "JobEnvironment.log" + append: false + threshold: INFO + categories: { + DumpJobEnvironment: { limit: -1 } + default: { limit: 0 } + } +} + +outputs.metadataDumper: { + module_type: "DumpJobEnvironment" +} + +physics: { + streams: [ metadataDumper ] +} diff --git a/sbncode/Metadata/CMakeLists.txt b/sbncode/Metadata/CMakeLists.txt index 6cf9127e5..67cc0d27a 100644 --- a/sbncode/Metadata/CMakeLists.txt +++ b/sbncode/Metadata/CMakeLists.txt @@ -1,5 +1,21 @@ cet_enable_asserts() +GenerateRepoVersionSource(${CMAKE_PROJECT_NAME}) + +message(DEBUG "Generated source file '${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h'") + +art_make_library( + LIBRARIES + sbnobj::Common_Metadata + larcorealg::headers + art::Persistency_Provenance + art::Utilities + canvas::canvas + messagefacility::MF_MessageLogger + fhiclcpp::fhiclcpp + ) + + set( sbn_meta_lib_list art::Framework_Core art::Framework_Principal art::Framework_Services_Registry @@ -21,6 +37,35 @@ cet_build_plugin( MetadataSBN art::service art::Framework_IO_detail ) +cet_build_plugin(SaveJobEnvironment art::ResultsProducer + LIBRARIES + sbncode::Metadata + sbnobj::Common_Metadata + art_root_io::TFileService_service + art_root_io::tfile_support + art::Framework_Services_Registry + ) + +# cet_build_plugin(DumpJobEnvironment art::ResultsProducer +# LIBRARIES +# sbnobj::Common_Metadata +# ) + +cet_build_plugin(DumpJobEnvironment art::Output + LIBRARIES + sbnobj::Common_Metadata + ) + +cet_build_plugin(sbncodeRepositoryVersion art::tool + LIBRARIES + sbncode::Metadata + sbnobj::Metadata + sbnobj::Common_Metadata + ) + + +install_headers(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h") +install_source(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.cxx") install_headers() install_fhicl() install_source() diff --git a/sbncode/Metadata/DumpJobEnvironment_module.cc b/sbncode/Metadata/DumpJobEnvironment_module.cc new file mode 100644 index 000000000..93e4b8eb8 --- /dev/null +++ b/sbncode/Metadata/DumpJobEnvironment_module.cc @@ -0,0 +1,176 @@ +/** + * @file sbncode/Metadata/DumpJobEnvironment_module.cc + * @brief Producer module writing job environment information into output. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + */ + +// local libraries +#include "sbnobj/Common/Metadata/JobEnvironmentInfo.h" + +// framework libraries +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/OutputModule.h" +#include "art/Framework/Principal/ResultsPrincipal.h" +#include "art/Framework/Principal/Results.h" +#include "art/Framework/Principal/Provenance.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Persistency/Provenance/ModuleContext.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/types/ConfigurationTable.h" // fhicl::WrappedTable +#include "fhiclcpp/types/TableFragment.h" +#include "fhiclcpp/types/Atom.h" + +// C++ standard libraries +#include +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { class DumpJobEnvironment; } +/** + * @brief Output module dumping input versions to screen. + * + * The output module can be added to any of the end paths of an _art_ job to + * get a complete dump of the SBN job environment metadata stored into the input + * file. + * + * For example: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * process_name: JobMeta + * + * services.message.destinations.MetadataLog: { + * type: file + * filename: "JobEnvironment.log" + * append: false + * threshold: INFO + * categories: { + * DumpJobEnvironment: { limit: -1 } + * default: { limit: 0 } + * } + * } + * + * outputs.metadataDumper: { module_type: "DumpJobEnvironment" } + * + * physics.streams: [ metadataDumper ] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * will dump the metadata into a text file named `JobEnvironment.log`. + * + */ +class sbn::DumpJobEnvironment: public art::OutputModule { + public: + + /// Module configuration. + struct Config { + + using Name = fhicl::Name; + using Comment = fhicl::Comment; + + fhicl::TableFragment OutputModuleConfig; + + fhicl::Atom LogCategory { + Name{ "LogCategory" }, + Comment{ "name of the messagefacility output category to be used" }, + "DumpJobEnvironment" + }; + + }; // Config + + using Parameters + = fhicl::WrappedTable; + + explicit DumpJobEnvironment(Parameters const& params); + + private: + + // --- BEGIN --- Configuration ----------------------------------------------- + + std::string const fLogCategory; ///< Messagefacility category for the output. + + // --- END ----- Configuration ----------------------------------------------- + + + /// Dumps the information from an handle into the output stream. + template + void dumpInformation( + Stream& out, + art::Handle> const& infoHandle + ) const; + + + + void write(art::EventPrincipal&) override {} + void writeRun(art::RunPrincipal&) override {} + void writeSubRun(art::SubRunPrincipal&) override {} + + /// Reads and prints all the metadata data products. + void readResults(art::ResultsPrincipal const& results) override; + +}; // sbn::DumpJobEnvironment + + +// ----------------------------------------------------------------------------- +// --- Implementation +// ----------------------------------------------------------------------------- +sbn::DumpJobEnvironment::DumpJobEnvironment(Parameters const& params) + : OutputModule{ params().OutputModuleConfig } + , fLogCategory{ params().LogCategory() } +{} + + +// ----------------------------------------------------------------------------- +void sbn::DumpJobEnvironment::readResults + (art::ResultsPrincipal const& principal) +{ + if (!principal.size()) return; + + art::ModuleContext const moduleContext{ moduleDescription() }; + art::Results const& results = principal.makeResults(moduleContext); + + std::vector>> infoHandles + = results.getMany>(); + + mf::LogInfo out{ fLogCategory }; + out << "Found " << infoHandles.size() << " job information entries in input."; + + for (art::Handle> const& infoHandle + : infoHandles + ) { + out << '\n' << std::string(80, '*') << '\n'; + dumpInformation(out, infoHandle); + } + +} // sbn::DumpJobEnvironment::readResults() + + +// ----------------------------------------------------------------------------- +template +void sbn::DumpJobEnvironment::dumpInformation( + Stream& out, + art::Handle> const& infoHandle +) const { + + art::Provenance const* provenance = infoHandle.provenance(); + if (provenance) { + out << "Information from '" << provenance->inputTag().encode() << "'"; + } + else { + out << "Information with unknown provenance"; + } + + if (infoHandle.isValid()) { + out << " from " << infoHandle->size() << " sources\n"; + for (sbn::JobEnvironmentInfo const& info: *infoHandle) { + out << std::string(80, '=') << '\n' << info; + } + } + else out << "\n[information not available]\n"; + +} // sbn::DumpJobEnvironment::dumpInformation() + + +// ----------------------------------------------------------------------------- +DEFINE_ART_MODULE(sbn::DumpJobEnvironment) + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GITrepoVersion.cxx.in b/sbncode/Metadata/GITrepoVersion.cxx.in new file mode 100644 index 000000000..0d2a35157 --- /dev/null +++ b/sbncode/Metadata/GITrepoVersion.cxx.in @@ -0,0 +1,16 @@ +/** + * @file ${gitRepoVersionSourceStem}.cxx + * @brief GIT version for repository `${gitRepoName}`. + * @author automatically generated; + * template: Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see ${gitRepoVersionSourceStem}.h + */ + +#include "${gitRepoVersionSourceStem}.h" + +// ----------------------------------------------------------------------------- +const char RepositoryVersion_${gitRepoName}[] = "${gitRepoVersion}"; + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GITrepoVersion.h.in b/sbncode/Metadata/GITrepoVersion.h.in new file mode 100644 index 000000000..a3210703d --- /dev/null +++ b/sbncode/Metadata/GITrepoVersion.h.in @@ -0,0 +1,18 @@ +/** + * @file ${gitRepoVersionSourceStem}.h + * @brief GIT version for repository `${gitRepoName}`. + * @author automatically generated; + * template: Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see ${gitRepoVersionSourceStem}.cxx + */ + +#ifndef ${gitRepoName}_${gitRepoVersionSourceStem}_H +#define ${gitRepoName}_${gitRepoVersionSourceStem}_H + + +/// Repository version for ${gitRepoName}. +extern const char RepositoryVersion_${gitRepoName}[]; + + +#endif // ${gitRepoName}_${gitRepoVersionSourceStem}_H diff --git a/sbncode/Metadata/GlobalMetadataRegistry.cxx b/sbncode/Metadata/GlobalMetadataRegistry.cxx new file mode 100644 index 000000000..139e0e941 --- /dev/null +++ b/sbncode/Metadata/GlobalMetadataRegistry.cxx @@ -0,0 +1,69 @@ +/** + * @file sbncode/Metadata/GlobalMetadataRegistry.cxx + * @brief Centralized metadata tracker (implementation file). + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @file sbncode/Metadata/GlobalMetadataRegistry.h + */ + +// library header +#include "sbncode/Metadata/GlobalMetadataRegistry.h" + +// ----------------------------------------------------------------------------- +// global instance: +sbn::GlobalMetadataRegistry sbn::GlobalMetadataRegistry::GlobalRegistry; + + +// ----------------------------------------------------------------------------- +std::lock_guard sbn::GlobalMetadataRegistry::readAccess() const { + return std::lock_guard{ fAccessMutex }; +} + + +// ----------------------------------------------------------------------------- +std::lock_guard sbn::GlobalMetadataRegistry::writeAccess() const { + return std::lock_guard{ fAccessMutex }; +} + + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::registerMetadata + (Name_t name, Value_t value) -> GlobalMetadataRegistry& +{ + + auto const accessGrant = writeAccess(); + + fRegistry.insert(std::move(name), std::move(value)); + + return *this; + +} // sbn::GlobalMetadataRegistry::registerMetadata() + + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::getPtr(Name_t const& name) const + -> Value_t const* +{ + auto const accessGrant = readAccess(); + return registry().getPtr(name); +} + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::get(Name_t const& name) const + -> std::optional +{ + auto const accessGrant = readAccess(); + return registry().get(name); +} + + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::get + (Name_t const& name, Value_t const& defValue) const -> Value_t +{ + auto const accessGrant = readAccess(); + return registry().get(name, defValue); +} + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GlobalMetadataRegistry.h b/sbncode/Metadata/GlobalMetadataRegistry.h new file mode 100644 index 000000000..a0484a9f0 --- /dev/null +++ b/sbncode/Metadata/GlobalMetadataRegistry.h @@ -0,0 +1,88 @@ +/** + * @file sbncode/Metadata/GlobalMetadataRegistry.h + * @brief Centralized metadata tracker. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + */ + + +#ifndef SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H +#define SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H + + +// SBN libraries +#include "sbnobj/Common/Metadata/OrderedPairList.h" + +// C++ standard libraries +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { class GlobalMetadataRegistry; } +/** + * @brief A simple class with singleton access storing data in concurrent way. + * + * The registry is a simple key-value (string-string) sorted list (implemented + * from `OrderedPairList`). + * + * It provides a singleton instance (`instance()`) and it is designed to be + * thread-safe (by blunt mutex'ing). + * + */ +class sbn::GlobalMetadataRegistry { + + static GlobalMetadataRegistry GlobalRegistry; ///< Singleton instance. + + mutable std::mutex fAccessMutex; + + sbn::OrderedPairList fRegistry; + + + /// Grant read access. + [[nodiscard]] std::lock_guard readAccess() const; + + /// Grants (exclusive) write access. + [[nodiscard]] std::lock_guard writeAccess() const; + + + public: + + // These types need to match the ones in sbn::OrderedPairList + using Name_t = std::string; ///< Type of metadata name. + using Value_t = std::string; ///< Type of metadata value. + + + /// Adds a key-value pair to the registry + /// @return this object + GlobalMetadataRegistry& registerMetadata(Name_t name, Value_t value); + + + // --- BEGIN --- Queries --------------------------------------------------- + /// @name Queries + /// @{ + + /// Returns the complete registry of metadata. **This is not thread-safe!** + sbn::OrderedPairList const& registry() const + { return fRegistry; } + + /// Returns a pointer to the value of the requested metadata `name`, + /// or `nullptr` if none. + Value_t const* getPtr(Name_t const& name) const; + + /// Returns the value of requested metadata `name`, `std::nullopt` if none. + std::optional get(Name_t const& name) const; + + /// Returns the value of the requested metadata `name`, or `defValue` if none. + Value_t get(Name_t const& name, Value_t const& defValue) const; + + /// @} + // --- END ----- Queries --------------------------------------------------- + + + /// Returns the global instance of this class (read/write). + static GlobalMetadataRegistry& instance() { return GlobalRegistry; } + +}; // GlobalMetadataRegistry + + +#endif // SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H diff --git a/sbncode/Metadata/JobEnvironmentInfoExtractor.cxx b/sbncode/Metadata/JobEnvironmentInfoExtractor.cxx new file mode 100644 index 000000000..4a7ec971f --- /dev/null +++ b/sbncode/Metadata/JobEnvironmentInfoExtractor.cxx @@ -0,0 +1,149 @@ +/** + * @file sbncode/Metadata/JobEnvironmentInfoExtractor.cxx + * @brief Algorithm extracting information from the job execution environment. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + * @see sbncode/Metadata/JobEnvironmentInfoExtractor.h + */ + +// library header +#include "sbncode/Metadata/JobEnvironmentInfoExtractor.h" + +// SBN libraries +#include "sbncode/Metadata/RepositoryVersionReportUtils.h" +#include "sbncode/Metadata/RepositoryVersionReporter.h" + +// LArSoft libraries +#include "larcorealg/CoreUtils/enumerate.h" + +// framework libraries +#include "art/Persistency/Provenance/ModuleDescription.h" +#include "art/Utilities/make_tool.h" +#include "canvas/Utilities/Exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/ParameterSet.h" + +// C/C++ standard library +#include +#include +#include // std::move() + +// system libraries +#include // strchr() +#include // environ + + +// ----------------------------------------------------------------------------- +std::vector const +sbn::JobEnvironmentInfoExtractor::Config::DefaultDropVars = { + R"|(.*%%$)|" // BASH function pattern + , R"|(.*\(\)$)|" // another BASH function pattern +}; + + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfoExtractor::JobEnvironmentInfoExtractor + (Config const& config /* = Config{} */) + : fDropVars{ prepareRegEx(config.dropVars) } + , fRepositoryReports{ config.repositories } + , fLogCategory{ config.logCategory } +{ + +} + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfo sbn::JobEnvironmentInfoExtractor::extract + (art::ModuleDescription const& moduleInfo) +{ + + sbn::JobEnvironmentInfo info; + + info.processName = moduleInfo.processName(); + info.artVersion = moduleInfo.releaseVersion(); + + info.sources = extractSourceVersions(); + + info.variables = extractEnvironmentVariables(); + + return info; + +} // sbn::JobEnvironmentInfoExtractor::extract() + + +// ----------------------------------------------------------------------------- +auto sbn::JobEnvironmentInfoExtractor::extractSourceVersions() const + -> sbn::OrderedPairList +{ + + // take advantage of the basic + sbn::OrderedPairList sourceVersions; + addVersionFromRepositories(sourceVersions, fRepositoryReports); + sourceVersions.finish(); + + return sourceVersions; + +} // sbn::JobEnvironmentInfoExtractor::extractSourceVersions() + + +// ----------------------------------------------------------------------------- +auto sbn::JobEnvironmentInfoExtractor::extractEnvironmentVariables() const + -> sbn::OrderedPairList +{ + + sbn::OrderedPairList vars; + + char** itemPtr = environ; + while (const char* item = *(itemPtr++)) { + + const char* sep = strchr(item, '='); + + std::string name, value; + if (sep) { + name = std::string{ item, sep++ }; + value = std::string{ sep }; + } + else { + mf::LogDebug{ fLogCategory } + << "Environment element '" << item << "' is not in name=value form."; + name = item; + } + + // apply drop filters + if (matchPatterns(name, fDropVars) < fDropVars.size()) + continue; + + vars.items.emplace_back(std::move(name), std::move(value)); + + } // while + + vars.finish(); + + return vars; + +} // sbn::JobEnvironmentInfoExtractor::extractEnvironmentVariables() + + +// ----------------------------------------------------------------------------- +std::size_t sbn::JobEnvironmentInfoExtractor::matchPatterns + (std::string const& value, std::vector const& patterns) +{ + for (auto const& [ iPattern, pattern ]: util::enumerate(patterns)) + if (std::regex_match(value, pattern)) return iPattern; + return patterns.size(); +} + + +// ----------------------------------------------------------------------------- +std::vector sbn::JobEnvironmentInfoExtractor::prepareRegEx + (std::vector const& patterns) +{ + std::vector regex; + regex.reserve(patterns.size()); + for (std::string const& pattern: patterns) regex.emplace_back(pattern); + return regex; +} + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/JobEnvironmentInfoExtractor.h b/sbncode/Metadata/JobEnvironmentInfoExtractor.h new file mode 100644 index 000000000..4c480a3a2 --- /dev/null +++ b/sbncode/Metadata/JobEnvironmentInfoExtractor.h @@ -0,0 +1,146 @@ +/** + * @file sbncode/Metadata/JobEnvironmentInfoExtractor.h + * @brief Algorithm extracting information from the job execution environment. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + * @see sbncode/Metadata/JobEnvironmentInfoExtractor.cxx + */ + +#ifndef SBNCODE_METADATA_JOBENVIRONMENTINFOEXTRACTOR_H +#define SBNCODE_METADATA_JOBENVIRONMENTINFOEXTRACTOR_H + + +// local libraries +#include "sbnobj/Common/Metadata/JobEnvironmentInfo.h" + +// C++ standard libraries +#include +#include +#include + + +// ----------------------------------------------------------------------------- +namespace art { class ModuleDescription; } // forward declarations + +// ----------------------------------------------------------------------------- +namespace sbn { class JobEnvironmentInfoExtractor; } +/** + * @brief Extracts job execution environment information. + * + * In its simplest form, the information is saved into a + * `sbn::JobEnvironmentInfo` object: + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * sbn::JobEnvironmentInfoExtractor extractor; + * sbn::JobEnvironmentInfo const info = extractor(moduleDescription()); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * The `moduleDescription()` is a _art_ module member function, and as such this + * call is bound to the _art_ framework. However, if the context does not allow + * for a `art::ModuleDescription` object, partial information can still be + * retrieved which does not need that object. + * + * + * Configuration + * -------------- + * + * The configuration object, `Config`, includes the following configurable + * elements: + * * `dropVars`: a list of regular expression (`std::regex`) patterns to be + * matched to the environment variable names; if the name of a variable + * matches any of the the full patterns specified here, its value is not + * included in the metadata. This is useful to exclude known irrelevant + * variables (for example, shell functions). + * * `repositories`: a list of names of repositories to query for their + * version. For each repository ``, an attempt to load a _art_ tool + * named `RepositoryVersion` with an empty configuration parameter + * set is attempted, and on success all the information obtained from the + * tool is integrated into the metadata. + * * `logCategory`: this algorithm uses messagefacility library to emit + * messages to console. This is the category these messages are assigned to. + * + * + */ +class sbn::JobEnvironmentInfoExtractor { + + public: + + /// Configuration record. + struct Config { + + /// Default value of `dropVars`. + static std::vector const DefaultDropVars; + + /// Remove environment variables with names matching these patterns. + std::vector dropVars = DefaultDropVars; + + /// Look for the GIT version of these repositories. + std::vector repositories{ "sbncode" }; + + std::string logCategory = "JobEnvironmentInfoExtractor"; + + // needed because of compiler bugs + // https://bugs.llvm.org/show_bug.cgi?id=36684 + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645 + Config() {} + + }; // Config + + + /// Constructor with configuration. + JobEnvironmentInfoExtractor(Config const& config = Config{}); + + /// Extracts all the information from the environment. + sbn::JobEnvironmentInfo extract + (art::ModuleDescription const& moduleInfo); // not guaranteed to be const! + + /** + * @brief Extracts all the information from the environment. + * @param moduleInfo information about the _art_ module being executed + * @return an object with all extracted metadata + */ + sbn::JobEnvironmentInfo operator() (art::ModuleDescription const& moduleInfo) + { return extract(moduleInfo); } + + // --- BEGIN --- Partial metadata extraction ------------------------------- + /** + * @name Partial metadata extraction + * + * The member functions in this group allow the extraction of part of the job + * metadata. The function `extract()` includes the information from all of + * them, plus some more. + */ + /// @{ + + /// Returns the environment variables. + sbn::OrderedPairList extractEnvironmentVariables() const; + + /// Returns the version of the source repositories. + sbn::OrderedPairList extractSourceVersions() const; + + /// @} + // --- END ----- Partial metadata extraction ------------------------------- + + private: + + std::vector fDropVars; ///< Remove variables with matching names. + + ///< Names of the repositories to ask for a version report to. + std::vector fRepositoryReports; + + std::string fLogCategory; + + /// Converts all the patterns into regular expression objects. + static std::vector prepareRegEx + (std::vector const& patterns); + + /// @brief Returns the index of the first pattern `value` matches. + /// @return index of the first matched pattern, `patterns.size()` if none + static std::size_t matchPatterns + (std::string const& value, std::vector const& patterns); + +}; // sbn::JobEnvironmentInfoExtractor + + +// ----------------------------------------------------------------------------- + +#endif // SBNCODE_METADATA_JOBENVIRONMENTINFOEXTRACTOR_H diff --git a/sbncode/Metadata/RepositoryVersionReportUtils.cpp b/sbncode/Metadata/RepositoryVersionReportUtils.cpp new file mode 100644 index 000000000..5e9665657 --- /dev/null +++ b/sbncode/Metadata/RepositoryVersionReportUtils.cpp @@ -0,0 +1,71 @@ +/** + * @file sbncode/Metadata/RepositoryVersionReportUtils.cxx + * @brief Interface for _art_ tool reporting the version of packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see sbncode/Metadata/RepositoryVersionReportUtils.h + */ + +// library header +#include "sbncode/Metadata/RepositoryVersionReportUtils.h" + +// SBN libraries +#include "sbncode/Metadata/RepositoryVersionReporter.h" + +// framework libraries +#include "art/Utilities/make_tool.h" +#include "canvas/Utilities/Exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/ParameterSet.h" + +// C/C++ standard library +#include // std::unique_ptr<> + + +// ----------------------------------------------------------------------------- +bool sbn::addVersionFromRepository + (sbn::OrderedPairList& versionList, std::string const& repoName) +{ + + std::string const toolName = repoName + "RepositoryVersion"; + + fhicl::ParameterSet config; + config.put("tool_type", toolName); + + std::unique_ptr reportTool; + try { + reportTool = art::make_tool(config); + } + catch(cet::exception const& e) { + mf::LogWarning{ "RepositoryVersionReporter" } + << "No report from repository '" << repoName << "': tool not found."; + mf::LogDebug{ "RepositoryVersionReporter" } << "Error:\n" << e; + return false; + } + + // blindly add everything + versionList.items.insert + (versionList.items.end(), reportTool->begin(), reportTool->end()); + + return true; + +} // sbn::addVersionFromRepository() + + +// ----------------------------------------------------------------------------- +std::vector sbn::addVersionFromRepositories( + sbn::OrderedPairList& versionList, std::vector const& repoNames +) { + + std::vector missingRepos; + for (std::string const& repoName: repoNames) { + if (addVersionFromRepository(versionList, repoName)) continue; + missingRepos.push_back(repoName); + } + + return repoNames; + +} // sbn::addVersionFromRepositories() + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/RepositoryVersionReportUtils.h b/sbncode/Metadata/RepositoryVersionReportUtils.h new file mode 100644 index 000000000..1c7cea867 --- /dev/null +++ b/sbncode/Metadata/RepositoryVersionReportUtils.h @@ -0,0 +1,60 @@ +/** + * @file sbncode/Metadata/RepositoryVersionReportUtils.h + * @brief Interface for _art_ tool reporting the version of packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see sbncode/Metadata/RepositoryVersionReportUtils.cxx + */ + +#ifndef SBNCODE_METADATA_REPOSITORYVERSIONREPORTUTILS_H +#define SBNCODE_METADATA_REPOSITORYVERSIONREPORTUTILS_H + + +// SBN libraries +#include "sbnobj/Common/Metadata/OrderedPairList.h" + +// C/C++ standard library +#include +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { + + /** + * @brief Adds versions from the specified repository. + * @param[out] versionList version list to add to + * @param repoName name of the repository to be queried + * @return whether the repository plugin could be loaded + * + * The plugin with name `repoName + "RepositoryVersion"` is loaded and its + * report is appended to `versionList`. + * It will be necessary to call `versionList.finish()` after all the additions + * are done. + * + * This utility is used in the + * @ref SBNsourceMetadataSystem "repository version tracking system". + */ + bool addVersionFromRepository + (sbn::OrderedPairList& versionList, std::string const& repoName); + + + /** + * @brief Adds versions from the specified repositories. + * @param[out] versionList version list to add to + * @param repoNames name of the repositories to be queried + * @return which repositories which could not be reached + * @see addVersionFromRepository + * + * This is equivalent to repeatedly calling `addVersionFromRepository()`. + */ + std::vector addVersionFromRepositories( + sbn::OrderedPairList& versionList, std::vector const& repoNames + ); + +} // namespace sbn + + +// ----------------------------------------------------------------------------- + +#endif // SBNCODE_METADATA_REPOSITORYVERSIONREPORTUTILS_H diff --git a/sbncode/Metadata/RepositoryVersionReporter.h b/sbncode/Metadata/RepositoryVersionReporter.h new file mode 100644 index 000000000..55e2e05bf --- /dev/null +++ b/sbncode/Metadata/RepositoryVersionReporter.h @@ -0,0 +1,75 @@ +/** + * @file sbncode/Metadata/RepositoryVersionReporter.h + * @brief Interface for _art_ tool reporting the version of packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * + */ + +#ifndef SBNCODE_METADATA_REPOSITORYVERSIONREPORTER_H +#define SBNCODE_METADATA_REPOSITORYVERSIONREPORTER_H + + +// SBN libraries +#include "sbnobj/Common/Metadata/OrderedPairList.h" + +// C/C++ standard library +#include // std::distance() + + +// ----------------------------------------------------------------------------- +namespace sbn { class RepositoryVersionReporter; } +/** + * @brief Interface for _art_ tool reporting the version of packages. + * + * An object reporting package versions will return them as a range of pairs + * package name/package version, each element being a string. + * + * This interface is not at all generic, and the iterators that are returned + * are exactly `const_iterator` ones defined in this interface, which are + * iterators of the collection `vector_t` also defined here, which is exactly + * a `std::vector`. + * + * @note At this point there is no polymorphic interface: derived classes will + * fetch their data at construction time and keep it for anybody curious + * to learn it. In the future an actual virtual interface could become + * necessary, and at that point it would be clearer what it should + * contain. + * + */ +struct sbn::RepositoryVersionReporter { + + /// Type of the name of a package (a `std::string`). + using PackageName_t = sbn::OrderedPairList::Key_t; + + /// Type of the version of a package (a `std::string`). + using PackegaVersion_t = sbn::OrderedPairList::Value_t; + + // standard C++ container types + using value_type = sbn::OrderedPairList::value_type; + using size_type = sbn::OrderedPairList::size_type; + using const_iterator = sbn::OrderedPairList::const_iterator; + + + /// Collected packages and their versions. + sbn::OrderedPairList packageVersions; + + + /// Begin-iterator for the package-version pairs. + const_iterator begin() const { return packageVersions.begin(); } + + /// End-iterator for the package-version pairs. + const_iterator end() const { return packageVersions.end(); } + + /// Returns whether there is no entry in the report. + bool empty() const noexcept { return begin() == end(); } + + /// Returns the number of items in the report. + size_type size() const { return std::distance(begin(), end()); } + +}; // sbn::RepositoryVersionReporter + + +// ----------------------------------------------------------------------------- + +#endif // SBNCODE_METADATA_REPOSITORYVERSIONREPORTER_H diff --git a/sbncode/Metadata/SBNsourceMetadataSystem.dox b/sbncode/Metadata/SBNsourceMetadataSystem.dox new file mode 100644 index 000000000..fa843ba25 --- /dev/null +++ b/sbncode/Metadata/SBNsourceMetadataSystem.dox @@ -0,0 +1,367 @@ +/** @page SBNsourceMetadataSystem Source code and execution environment metadata system in SBN code +@author Gianluca Petrillo (petrillo@slac.stanford.edu) + + +At highest level, the plugin `SaveJobEnvironment` allows storage of metadata +into the _art_/ROOT and `TFileService` files, and the output module +`DumpJobEnvironment` prints the information saved in a _art_/ROOT file on +console. + +The system to achieve that result is quite convoluted, and this documentation +will describe that in detail. + + +Which information is extracted +=============================== + +The extraction algorithm, `sbn::JobEnvironmentInfoExtractor`, includes +information ("metadata") about: + * The execution environment of the job: + * the complete dump of environment variables (except the ones identified as + shell functions); when using UPS, this can be used to track the version + of the products (UPS packages) set up during the job. + * The GIT version of the repositories used during the build process of the + code for some selected source code repositories. + * Information from the software being executed: + * _art_ process name; + * _art_ version. + +This information is extracted for each _art_ process; since typically each final +output file is the result of a sequence of jobs, the output files will contain +multiple metadata sets, for each of the input and job that ended into the file +data. + + +How the information is stored for later use +============================================ + +The goal of the system is to save the metadata into each output file, so that it +is always known wherever the data is. + +Our current data system includes four output carriers: + 1. _art_/ROOT files, managed directly by _art_ and with a rigid format; + 2. `TFileService` supplemental ROOT file, also managed by _art_ but with a + format that is freer; + 3. LArCV files shipped to SPINE reconstruction framework; + 4. Common Analysis Format (CAF), managed by SBN via a _art_ module. + +At the moment of writing (at the inception of this system), the metadata is only +written into the _art_/ROOT and the `TFileService` output files. + +In addition, the system needs a way to store some of the information that would +not be available at run time: an example is the version of the software included +in the build, which is usually a GIT tag that does not survive to the +distributed binary code. +The options of where to keep this information include: as a executable code +(library) that software can link to and call/read; FHiCL configuration that jobs +can include; simple text files that jobs can read. + +There are limitations and shortcomings in each of the options. +The choice of this system was to include the version into an executable library. +The reason why the text file was not chosen is that it requires a convention of +where the file can be found, which is not trivial given the relocation of +distributed code. +The reason why FHiCL configuration was not preferred is that only _art_/ROOT +files automatically include that information. In addition, each job +configuration needs to know _exactly_ which repositories are being included, +since FHiCL parser does not tolerate missing information. The first limitation +can be worked around, for example with the experimental `icaruscode` module +`SaveConfigurationIntoTFile`, which was never fully completed or tested. +The selected option, library code, has ways to address these issues. There is +already a tracking system in place for the libraries, and _art_ has a "factory" +system that can find by name libraries (plug-ins) to be loaded dynamically. +As for the comparison with FHiCL, the code can be configured to look for a large +number of repository libraries, and if one is missing, the resulting error +(for example a thrown C++ exception) can be programmatically caught and handled. +The limitation of this option will be discussed later in this section. + +The difficulty of this system is that it needs to connect very heterogeneous +information sources, which never available all at the same time. +The source repository is available only in the build stage, while the execution +environment is present only... well, during the job execution. +The strategy is then to create one shared library for each repository, with +a standard name (`RepositoryVersion_\`), with the repository +version information, and to have some modular software that can read these +libraries, collect their information in a single place and then write it. +This is how it was implemented for the single repository named : + 1. CMake discovers the name of the repository from its remote source + (`git remote origin get-url`). + 2. CMake executes a `git describe` call (`git` executable must be available). + 3. CMake generates a C++ header and source file via `configure_file()` starting + from two template files (`GITrepoVersion.{h,cxx}.in`), and creates the + source files `RepositoryVersion_.{h,cxx}`. + 4. CMake creates the local directory library as usual + (e.g. `art_make_library`), which will include the two generated files too. + 5. The two generated files are added to the list of files to install. + +This happens in the source directory that is going to be hosting the library, by +convention `/Metadata` (e.g. in `sbncode/Metadata/CMakeLists.txt`). +The first three steps are collected in macros saved in `SBNutils.cmake`, which +must be included. + +A relevant question with this method is where the `SBNutils.cmake` macro library +should be hosted. The chosen repository must be at the root of the dependencies +of all the repositories that we need to version, but there is not such a root: +`sbnobj` (hosting _art_/ROOT data products) depends only on `lardataobj`, and +`sbnanaobj` (CAF data objects) depends only on ROOT (so, ironically, the root +dependency in our source tree _is_ in fact ROOT, but unfortunately it does not +make sense to add this infrastructure in there). The practical workaround to +this riddle is to duplicate the macro file, which obvious maintenance +consequences. + +@note An **important limitation** of this system is that the information is + extracted by CMake, when the build system decides to run CMake and when + CMake decides to (re)generate the files -- which may be never: at the + moment of writing, the details are not yet clear. + To make sure that the GIT versions are correct, the only safe way is to + zap the area (`mrb z`) and build everything from scratch. This is always + a good idea anyway after one thinks the code is ready for prime time. + Again, remember: after code is committed to GIT, an integral rebuild is + likely needed for the code version metadata to reflect the new repository + status. + +@note The presence of an actual library do be dynamically linked to is necessary + and can't be replaced by inline definitions in the header files. + The reason is that the system needs to support some level of delegation + (see the next section) where a package needs to provide information of + a different one which can't on its own. For example, `sbnobj` can extract + and store its own version, but it lacks the dependencies necessary to + provide it to _art_. Therefore, `sbncode` will be in charge of saving + `sbnobj` metadata in addition to its own. Given this structure, if + `sbnobj` version is stored in a header, `sbncode` will learn it at compile + time and keep it hard-coded. It is possible though that the job loads an + updated `sbnobj` instead of the one used during `sbncode` build, in which + case `sbncode` would still report the version hard-coded at the time of + its own build. + This practice is prone to many issues (the scenario described here + outlines a common one) and should be avoided; however, the metadata system + implemented here is a diagnostic tools and as such should be designed to + be more resilient than average. + + +How to arrange a repository with a version library +--------------------------------------------------- + +1. `SBNutils.cmake` needs to be included. It is stored, willy-nilly, in + `sbnobj`. The most obvious option is to add things into the main + `CMakeLists.txt` file of the repository; namely: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + find_package( sbnobj REQUIRED ) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + in the `find_package` section not present already, and + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + include(SBNutils) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + just after the inclusion of CETmodules/_art_ macro files and definitely + _before_ the `add_subdirectory()` calls. +2. Check the directory `/Metadata`. + 1. If it does not exist or does not contain a `CMakeLists.txt`: + 1. create it, and add the line + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + add_subdirectory(Metadata) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + to the `/CMakeLists.txt` (in the same directory where + the new `Metadata` directory is); + 2. copy into there from `sbnobj/Metadata` the file `CMakeLists.txt`, + which should be portable enough; or add lines as below. + 2. If it does exist, add to its `CMakeLists.txt`: + 1. at the top of the file (before the build commands): + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + GenerateRepoVersionSource(${CMAKE_PROJECT_NAME}) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + which calls the source generation macro from SBNutils; + 2. at the end add to the usual `install_Xxxx()` calls these ones: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + install_headers(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h") + install_source(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.cxx") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + which add the `.cxx` and `.h` files to the files to install; + 3. make sure that there is a `art_make_library()` call or equivalent + build command in the file; if there is none, or if there are only + plugin or dictionary build calls (`e.g. `cet_build_plugin()`), add + explicitly a + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + art_make_library() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + or a more explicit (and _art_-independent) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + cet_make_library( + SOURCE + "${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h" + "${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.cxx" + ) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + which will create a library with only the source file generated here. +3. Copy into there from `sbnobj/Metadata` the files `GITrepoVersion.{h,cxx}.in`. + Or write some custom ones (but remember that the _art_ tool needs the + implementation details). + +Note that in principle every `${CMAKE_PROJECT_NAME}` above can be replaced with +the actual CMake project name, hard-coded (e.g. `sbncode`). The only drawback is +that such lines need a further editing when copied into other repositories. + + + +How the information is extracted and serialized in the output +============================================================== + +When a job is executed, the version of all the repositories should ideally be +loaded and then saved into all the relevant output files. +The strategy for _art_ jobs (`lar`) is no less complex than the one described in +the previous paragraph. The choice was to save the information into a _art_ data +product. +Among the complications: + * The data product should be stored to have the least possible duplication. + * Metadata from the input files needs to be propagated into the output files; + and there can be multiple input files, multiple output files, and not in a + one-to-one correspondence. + +This is the general strategy: + + 1. Metadata is stored into a _results-level data product_, which is an + output-file-level data product (as opposed to run-level, subrun-level or + event-level) bound to the output module (e.g. `RootOutput`). + The class of the data product is defined in `sbnobj`. + 2. A plugin will take care of writing the metadata as a data product. This + plugin is specific to output modules like `RootOutput` and is somehow + different, but similar, to _art_ modules. The plugin has also the task of + attempting to collect the relevant information from all the possible + source repositories, as listed in the FHiCL configuration of the plugin. + If the information from a source repository is not available, that source is + simply not included in the metadata. The output plugin is defined in + `sbncode`, which is the lowest _art_-aware repository under our control. + 3. The plugin, called `SaveJobEnvironment`, calls an extractor utility, + `sbn::JobEnvironmentInfoExtractor`, which utilizes _art_ tools to + dynamically load information from all the source repositories. + Tools have conventional names (`RepositoryVersion`). + 4. Each tool is given the chance to provide arbitrary metadata, but they are + expected to fill in with the name and version of their repository. + +The factorization of the extractor utility from the output plugin allows to use +the utility also on other contexts, for example when running CAF maker. However, +because of the use of the _art_ tool infrastructure, it stills requires _art_ to +be functional. In addition, some of the information is extracted from _art_ +itself (e.g. the process name), so _art_ is also necessary as information source +if the full information is desired. + +A limitation of the _art_-tool-based strategy is that the repository containing +the tool must depend on _art_. Several source repositories do not fulfil this +requirement, by design; e.g. `sbnobj` and `icarusalg`. These repositories still +need to be instrumented with CMake instructions to generate the repository +version library (repositories which do not create libraries are very rare), and +one of the plugins of the dependent repositories must be in charge of reading +the version of these repositories together with their own. So for example +`sbnobj` will generate a `sbnobj_Metadata` library, and _art_ tool +`sbnobjRepositoryVersion` in `sbncode` will link to both `sbncode::Metadata` +for the version of `sbncode`, and to `sbnobj::Metadata` for the version of +non-art-aware repository it depends on, `sbnobj`. Since the dependencies of +each repository are known and quite stable, the tool can hard-code them. +In addition, if a dependency is _art_-aware, the tool can take care of the +dependency subtree for that dependency recursively, by call the tool of that +dependency (duplicate metadata entries will be expected to be the same anyway). + + +### Results-level products + +Results-level products were introduced in _art_ as a mean to have data products +spanning multiple runs. While some interface is similar to the other principals +(`art::Event`, `art::Run`), their usage and accessibility is deeply different. + +The key point is this: **only output modules can access Results-level data +products** (not only `RootOutput` specifically). +This comes with a list of obvious and explicit clumsiness: there is no such a +thing like an _art_ module writing a Results-level data product. In fact, no +such a thing like an _art_ module _reading_ that data product either. +The `DumpJobEnvironment` facility offered here is in fact an _output module_: +producer and analysis modules can't learn the versions that the version +data products in the input files hold. They can however use the same algorithm +as `SaveJobEnvironment` uses (that is another output plugin) to extract the +versions it then saved in the Results-type data product: the information +extraction algorithm is factorized as `sbn::JobEnvironmentInfoExtractor` and its +return type is a class `sbn::JobEnvironmentInfo` (`sbnobj`) well suited to be +a _art_ data product. + + + +How to arrange a repository with the tool +------------------------------------------ + +The tools will depend on the repository version libraries of the current package +and its dependencies, and on _art_. It is recommended to place their source code +in the same directory as the repository version library. +Step by step: + + 1. Utilize the `/Metadata` directory where the version library + source code should already be. In that case, the name of that library for + linking will be `::Metadata`. + 2. Create the tool source `RepositoryVersion_tool.cc` by + copying the source code from + `sbncode/Metadata/sbncodeRepositoryVersion_tool.cc` or + `icaruscode/Metadata/icaruscodeRepositoryVersion_tool.cc`. + 3. Add to the `CMakeLists.txt` file instructions to build the tool: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + cet_build_plugin(RepositoryVersion art::tool + LIBRARIES + ::Metadata + sbncode::Metadata + sbnobj::Common_Metadata + ) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Additional libraries may be needed for the dependencies. + 4. Customize the tool source. + * If this repository _has_ dependent non-art repositories, add them to the + tool (the one in `icaruscode`, `icaruscodeRepositoryVersion`, already + shows how, with `icarusalg`): link to the dependent version libraries, + and add metadata entries for them. + * If this repository _is_ a dependency of another _art_-aware repository, + considering updating the tool in that repository to load this one and + store information from it. The tool in `icaruscode`, + `icaruscodeRepositoryVersion`, shows how (with `sbncode`). + 5. In the relevant configurations of the output plugin `SaveJobEnvironment`, + add the name of the repository the tool is covering (the `` + above). + + +How metadata can be accessed from the input files +================================================== + +The plugin `SaveJobEnvironment` can write the metadata into the _art_/ROOT file +and into the `TFileService` output file. + +The metadata in the _art_/ROOT file is stored as a Results-level data product, +and can therefore be read only by output modules. That does mean that producer +and analyzer _art_ modules will not be able to access that metadata. +However, an output module `DumpJobEnvironment` is provided that dumps the full +metadata on console output (configurable via `message` service). +The configuration of that module is as simple as: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +outputs.metadataDumper: { + module_type: "DumpJobEnvironment" +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and, as usual, `metadataDumper` must be added in one of the end paths in the +`physics` configuration table. This type of configuration is provided in +`sbncode` as `dump_jobmetadata.fcl`. + +Metadata saved into a `TFileService` ROOT file will be in the main ROOT +directory of the file. See the documentation of `SaveJobEnvironment` plugin +for the details. + + + +Future improvements +==================== + +* Currently the metadata seen from all input so far is stored into the current + output file; it may happen then that an output file stores metadata from an + input file that was already closed when the output file started been filled. + That metadata has no reason to reside in that output file. +* There is going to be a large amount of duplication: all input files likely + have almost identical metadata, but we save each individually. A system to + collect the shared metadata in a single list may be desirable to reduce the + metadata size. +* If there is demand, the system can be extended to create also a FHiCL + configuration with the version of the repository. + + + */ diff --git a/sbncode/Metadata/SaveJobEnvironment_plugin.cc b/sbncode/Metadata/SaveJobEnvironment_plugin.cc new file mode 100644 index 000000000..70364dc4d --- /dev/null +++ b/sbncode/Metadata/SaveJobEnvironment_plugin.cc @@ -0,0 +1,331 @@ +/** + * @file sbncode/Metadata/SaveJobEnvironment_plugin.cc + * @brief Producer module writing job environment information into output. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + */ + +// SBN libraries +#include "sbncode/Metadata/JobEnvironmentInfoExtractor.h" +#include "sbnobj/Common/Metadata/JobEnvironmentInfo.h" + +// framework libraries +#include "art_root_io/TFileService.h" +#include "art_root_io/TFileDirectory.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/ResultsProducer.h" +#include "art/Framework/Principal/Results.h" +#include "art/Framework/Principal/Handle.h" +#include "canvas/Utilities/Exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/types/Sequence.h" +#include "fhiclcpp/types/OptionalAtom.h" + +// ROOT libraries +#include "TFile.h" +#include "TDirectory.h" + +// C/C++ libraries +#include // std::back_inserter() +#include // std::make_unique() +#include +#include // std::move() +#include + + + +// ----------------------------------------------------------------------------- +namespace sbn { class SaveJobEnvironment; } +/** + * @brief Writes information from the job execution environment into output. + * + * This result-level module writes into the `art::Results` an object with + * information about the environment where the job is being executed. + * + * Information is extracted by the `sbn::JobEnvironmentInfoExtractor` algorithm. + * + * To add a new repository to the source of metadata collected by this plugin, + * see the instructions and explanations in + * @ref SBNsourceMetadataSystem "the SBN metadata system documentation". + * + * + * Output + * ------- + * + * In _art_/ROOT output file, `art::Results` level: + * * `std::vector` objects including all the ones + * found in the input files, and in addition, for this job: + * * a snapshot of the full environment (like in `getEnv()` C function), + * lexicographically sorted as for the object requirement. + * + * The information from this job is also saved in the `TFileService` output + * file, if that service is configured. Input information is currently not + * written into the `TFileService` output. Also note that the information is + * saved in the main directory of the file, as opposed to the usual subdirectory + * named after the module. The name of the object is `EnvInfo`, and, if + * `sbn::JobEnvironmentInfo` dictionary library is available to ROOT, one simple + * way to see it is to open the ROOT file with the ROOT interpreter and execute + * `EvtInfo->dump(std::cout);`. + * + * + * Module configuration + * --------------------- + * + * * `Repositories` (list of strings; default: see `DefaultRepositories`): + * the list of repositories whose version reporting tool will be queried. + * Directly passed as `JobEnvironmentInfoExtractor::Config::repositories` + * (see) to the exctraction algorithm. + * * `WriteToTFileService` (flag, optional): if set to `false`, the information + * will not be written into the `TFileService` output file; if it is set to + * `true`, it will be written into the output of file the service, which is + * required to be configured; if the parameter is omitted, the information + * will be written only if the service is available. + * + * + * Service dependencies + * --------------------- + * + * * `TFileService` (required only if `WriteToTFileService` is set to `true`) + * for output into the `TFile` managed by that service. + * + */ +class sbn::SaveJobEnvironment: public art::ResultsProducer { + + public: + + /// List of repository tools to be loaded by default. + static std::vector const DefaultRepositories; + + struct Config { + + using Name = fhicl::Name; + using Comment = fhicl::Comment; + + fhicl::Sequence Repositories{ + Name{ "Repositories" }, + Comment{ "Names of the repositories with version reporting tools" }, + DefaultRepositories + }; + + fhicl::OptionalAtom WriteToTFileService{ + Name{ "WriteToTFileService" }, + Comment + { "enables or disables writing to TFileService (default: if available)" } + }; + + }; // Config + + using Parameters = Table; + + + /// Constructor. + SaveJobEnvironment(Parameters const& params); + + /// Fetches the information. + virtual void beginJob() override; + + /// Reads the information on each new input file. + virtual void readResults(art::Results const& results) override; + + /// Writes the information at output closure time. + virtual void writeResults(art::Results& results) override; + + /// Clears after writing: does nothing. + virtual void clear() override; + + /// Write information to `TFileService` file if available. + virtual void endJob() override; + + + private: + + // --- BEGIN --- Configuration ----------------------------------------------- + + /// Names of the repositories to query for version metadata. + std::vector const fRepositoryNames; + + bool const fWriteToTFileService; ///< Whether to write info to `TFileService`. + + // --- END ----- Configuration ----------------------------------------------- + + + sbn::JobEnvironmentInfoExtractor fInfoExtractor; ///< Extraction algorithm. + + ///< All information from the input to be written, in the order it was read. + std::vector fInputInfo; + + /// Information from this job to be written. + sbn::JobEnvironmentInfo fJobInfo; + + + /// Fetches and returns all the information. + sbn::JobEnvironmentInfo fetchInformation(); + + + /// Writes the current information into `outDir`. + void writeInformationToTFile(TDirectory& outDir) const; + + /// Returns a correctly configured information extractor algorithm. + sbn::JobEnvironmentInfoExtractor makeInfoExtractor() const; + + + /// Returns whether we should write to `TFileService`. + static bool parseWriteToTFileService + (std::optional writeToTFileService); + + +}; // sbn::SaveJobEnvironment + + +// ----------------------------------------------------------------------------- +// --- Implementation +// ----------------------------------------------------------------------------- +std::vector const sbn::SaveJobEnvironment::DefaultRepositories { + "sbncode", "sbndcode", "icaruscode" +}; + + +// ----------------------------------------------------------------------------- +sbn::SaveJobEnvironment::SaveJobEnvironment(Parameters const& params) + : fRepositoryNames{ params().Repositories() } + , fWriteToTFileService + { parseWriteToTFileService(params().WriteToTFileService()) } + , fInfoExtractor{ makeInfoExtractor() } +{ + + produces>(); + + if (fWriteToTFileService) { + mf::LogInfo{ "SaveJobEnvironment" } + << "Will also save information into TFileService output file."; + } + +} // sbn::SaveJobEnvironment::SaveJobEnvironment() + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::beginJob() { + + fJobInfo = fetchInformation(); + +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::readResults(art::Results const& results) { + + std::vector const infoHandles + = results.getMany>(); + + mf::LogDebug{ "SaveJobEnvironment" } + << "Found " << infoHandles.size() << " job information products in input."; + + for (art::Handle> const& infoHandle + : infoHandles) + { + if (!infoHandle.isValid()) continue; + std::copy + (infoHandle->begin(), infoHandle->end(), back_inserter(fInputInfo)); + } // for + +} // sbn::SaveJobEnvironment::readResults() + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::writeResults(art::Results& results) { + + mf::LogDebug{ "SaveJobEnvironment" } + << "Information saved into art/ROOT output file:\n\n" << fJobInfo; + + auto allInfo + = std::make_unique>(fInputInfo); + allInfo->push_back(fJobInfo); + + // one copy each call + results.put(std::move(allInfo)); + +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::clear() { +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::endJob() { + + if (fWriteToTFileService) { + + writeInformationToTFile(art::ServiceHandle()->file()); + + } + +} // sbn::SaveJobEnvironment::endJob() + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfo sbn::SaveJobEnvironment::fetchInformation() { + + return fInfoExtractor.extract(moduleDescription()); + +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::writeInformationToTFile(TDirectory& outDir) const +{ + + // assuming copy constructor will be used + outDir.WriteObject(&fJobInfo, "EnvInfo"); + +} // sbn::SaveJobEnvironment::writeInformationToTFile() + + +// ----------------------------------------------------------------------------- +bool sbn::SaveJobEnvironment::parseWriteToTFileService + (std::optional writeToTFileService) +{ + // if is requested that we don't write it to TFileService, stop it here: + if (!writeToTFileService.value_or(true)) return false; + + // so either there is no explicit request, or that request is to use it: + // at this point, we do need to know if TFileService is available + // and if it's there, we'll want to write into it + try { + art::ServiceHandle(); + return true; + } + catch(art::Exception& e) { + if (e.categoryCode() != art::errors::ServiceNotFound) + throw; // something else entirely is happening: propagate the exception + + // not available: do we need it? + if (!writeToTFileService) return false; // no explicit request, so no + + // there is a request (and if we are here it was positive): complain! + throw art::Exception{ art::errors::Configuration, "", e } + << "SaveJobEnvironment explicitly requested saving into TFileService" + " output, but TFileService is not configured.\n"; + + } + +} // sbn::SaveJobEnvironment::parseWriteToTFileService() + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfoExtractor +sbn::SaveJobEnvironment::makeInfoExtractor() const { + + JobEnvironmentInfoExtractor::Config config; + config.repositories = fRepositoryNames; + return JobEnvironmentInfoExtractor{ config }; + +} // sbn::SaveJobEnvironment::makeInfoExtractor() + + +// ----------------------------------------------------------------------------- +DEFINE_ART_RESULTS_PLUGIN(sbn::SaveJobEnvironment) + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/sbncodeRepositoryVersion_tool.cc b/sbncode/Metadata/sbncodeRepositoryVersion_tool.cc new file mode 100644 index 000000000..8941ac4e2 --- /dev/null +++ b/sbncode/Metadata/sbncodeRepositoryVersion_tool.cc @@ -0,0 +1,62 @@ +/** + * @file RepositoryVersion_sbncode_tool.cc + * @brief _art_ tool reporting the version of `sbncode`-related packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * + */ + +// SBN libraries +#include "sbncode/Metadata/RepositoryVersionReporter.h" +#include "sbncode/Metadata/RepositoryVersion_sbncode.h" +#include "sbnobj/Metadata/RepositoryVersion_sbnobj.h" + +// framework libraries +#include "art/Utilities/ToolMacros.h" +#include "art/Utilities/ToolConfigTable.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +// C++ standard libraries +#include +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { struct sbncodeRepositoryVersion; } +/** + * @brief Implements the `sbn::RepositoryVersionReporter` interface for + * `sbncode`. + * + * It collects information from the following repositories: `sbncode` and + * `sbnobj`. + * + */ +struct sbn::sbncodeRepositoryVersion: public sbn::RepositoryVersionReporter { + + struct Config {}; + + using Parameters = art::ToolConfigTable; + + sbncodeRepositoryVersion(Parameters const&); + +}; // sbn::sbncodeRepositoryVersion() + + +// ----------------------------------------------------------------------------- +// --- implementation +// ----------------------------------------------------------------------------- +sbn::sbncodeRepositoryVersion::sbncodeRepositoryVersion(Parameters const&) { + + packageVersions.items.emplace_back("sbnobj", ::RepositoryVersion_sbnobj); + packageVersions.items.emplace_back("sbncode", ::RepositoryVersion_sbncode); + + packageVersions.finish(); + +} + + +// ----------------------------------------------------------------------------- +DEFINE_ART_CLASS_TOOL(sbn::sbncodeRepositoryVersion) + + +// ----------------------------------------------------------------------------- From 3e4d0a9c7c816caa9859c09e44e70909bafad93b Mon Sep 17 00:00:00 2001 From: Gianluca Petrillo Date: Tue, 21 Jan 2025 20:39:22 -0600 Subject: [PATCH 039/367] Removed unused class. These were written when I thought that libraries would register the repository versions as soon as loaded. Eventually I moved to dynamic loading plugin objects when the information is needed. --- sbncode/Metadata/GlobalMetadataRegistry.cxx | 69 ---------------- sbncode/Metadata/GlobalMetadataRegistry.h | 88 --------------------- 2 files changed, 157 deletions(-) delete mode 100644 sbncode/Metadata/GlobalMetadataRegistry.cxx delete mode 100644 sbncode/Metadata/GlobalMetadataRegistry.h diff --git a/sbncode/Metadata/GlobalMetadataRegistry.cxx b/sbncode/Metadata/GlobalMetadataRegistry.cxx deleted file mode 100644 index 139e0e941..000000000 --- a/sbncode/Metadata/GlobalMetadataRegistry.cxx +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file sbncode/Metadata/GlobalMetadataRegistry.cxx - * @brief Centralized metadata tracker (implementation file). - * @author Gianluca Petrillo (petrillo@slac.stanford.edu) - * @date January 18, 2025 - * @file sbncode/Metadata/GlobalMetadataRegistry.h - */ - -// library header -#include "sbncode/Metadata/GlobalMetadataRegistry.h" - -// ----------------------------------------------------------------------------- -// global instance: -sbn::GlobalMetadataRegistry sbn::GlobalMetadataRegistry::GlobalRegistry; - - -// ----------------------------------------------------------------------------- -std::lock_guard sbn::GlobalMetadataRegistry::readAccess() const { - return std::lock_guard{ fAccessMutex }; -} - - -// ----------------------------------------------------------------------------- -std::lock_guard sbn::GlobalMetadataRegistry::writeAccess() const { - return std::lock_guard{ fAccessMutex }; -} - - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::registerMetadata - (Name_t name, Value_t value) -> GlobalMetadataRegistry& -{ - - auto const accessGrant = writeAccess(); - - fRegistry.insert(std::move(name), std::move(value)); - - return *this; - -} // sbn::GlobalMetadataRegistry::registerMetadata() - - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::getPtr(Name_t const& name) const - -> Value_t const* -{ - auto const accessGrant = readAccess(); - return registry().getPtr(name); -} - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::get(Name_t const& name) const - -> std::optional -{ - auto const accessGrant = readAccess(); - return registry().get(name); -} - - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::get - (Name_t const& name, Value_t const& defValue) const -> Value_t -{ - auto const accessGrant = readAccess(); - return registry().get(name, defValue); -} - - -// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GlobalMetadataRegistry.h b/sbncode/Metadata/GlobalMetadataRegistry.h deleted file mode 100644 index a0484a9f0..000000000 --- a/sbncode/Metadata/GlobalMetadataRegistry.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file sbncode/Metadata/GlobalMetadataRegistry.h - * @brief Centralized metadata tracker. - * @author Gianluca Petrillo (petrillo@slac.stanford.edu) - * @date January 18, 2025 - */ - - -#ifndef SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H -#define SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H - - -// SBN libraries -#include "sbnobj/Common/Metadata/OrderedPairList.h" - -// C++ standard libraries -#include - - -// ----------------------------------------------------------------------------- -namespace sbn { class GlobalMetadataRegistry; } -/** - * @brief A simple class with singleton access storing data in concurrent way. - * - * The registry is a simple key-value (string-string) sorted list (implemented - * from `OrderedPairList`). - * - * It provides a singleton instance (`instance()`) and it is designed to be - * thread-safe (by blunt mutex'ing). - * - */ -class sbn::GlobalMetadataRegistry { - - static GlobalMetadataRegistry GlobalRegistry; ///< Singleton instance. - - mutable std::mutex fAccessMutex; - - sbn::OrderedPairList fRegistry; - - - /// Grant read access. - [[nodiscard]] std::lock_guard readAccess() const; - - /// Grants (exclusive) write access. - [[nodiscard]] std::lock_guard writeAccess() const; - - - public: - - // These types need to match the ones in sbn::OrderedPairList - using Name_t = std::string; ///< Type of metadata name. - using Value_t = std::string; ///< Type of metadata value. - - - /// Adds a key-value pair to the registry - /// @return this object - GlobalMetadataRegistry& registerMetadata(Name_t name, Value_t value); - - - // --- BEGIN --- Queries --------------------------------------------------- - /// @name Queries - /// @{ - - /// Returns the complete registry of metadata. **This is not thread-safe!** - sbn::OrderedPairList const& registry() const - { return fRegistry; } - - /// Returns a pointer to the value of the requested metadata `name`, - /// or `nullptr` if none. - Value_t const* getPtr(Name_t const& name) const; - - /// Returns the value of requested metadata `name`, `std::nullopt` if none. - std::optional get(Name_t const& name) const; - - /// Returns the value of the requested metadata `name`, or `defValue` if none. - Value_t get(Name_t const& name, Value_t const& defValue) const; - - /// @} - // --- END ----- Queries --------------------------------------------------- - - - /// Returns the global instance of this class (read/write). - static GlobalMetadataRegistry& instance() { return GlobalRegistry; } - -}; // GlobalMetadataRegistry - - -#endif // SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H From 448561a072cbf540cb4f5f277734af71f60ea03e Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Thu, 13 Feb 2025 18:43:26 -0600 Subject: [PATCH 040/367] Remove SBND modules --- .../SBNDBNBEXTRetriever/CMakeLists.txt | 27 - .../SBNDBNBEXTRetriever_module.cc | 236 ------- .../SBNDBNBRetriever/CMakeLists.txt | 34 - .../SBNDBNBRetriever/MWRData.cpp | 71 -- .../SBNDBNBRetriever/MWRData.h | 39 -- .../SBNDBNBRetriever_module.cc | 645 ------------------ .../SBNDBNBZEROBIASRetriever/CMakeLists.txt | 34 - .../SBNDBNBZEROBIASRetriever/MWRData.cpp | 71 -- .../SBNDBNBZEROBIASRetriever/MWRData.h | 39 -- .../SBNDBNBZEROBIASRetriever_module.cc | 614 ----------------- .../job/run_sbndbnbextinfo_sbn.fcl | 46 -- .../job/run_sbndbnbinfo_sbn.fcl | 47 -- .../job/run_sbndbnbzerobiasinfo_sbn.fcl | 46 -- .../job/sbndbnbextspillinfo.fcl | 21 - .../job/sbndbnbspillinfo.fcl | 21 - .../job/sbndbnbzerobiasspillinfo.fcl | 21 - sbncode/CAFMaker/FillReco.cxx | 8 +- 17 files changed, 4 insertions(+), 2016 deletions(-) delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.h delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.h delete mode 100644 sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc delete mode 100644 sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl delete mode 100644 sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt deleted file mode 100644 index 3877de304..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -find_package(ifbeam) -find_package(ifdh_art) - -cet_build_plugin(SBNDBNBEXTRetriever art::module - LIBRARIES - art::Persistency_Common - art::Utilities canvas::canvas - cetlib::cetlib cetlib_except::cetlib_except - ROOT::X3d - Boost::system - messagefacility::MF_MessageLogger - ifbeam::ifbeam - ifdh_art::IFBeam_service - SQLite::SQLite3 - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND - artdaq_core::artdaq-core_Utilities - sbnobj::Common_POTAccounting - larcorealg::CoreUtils -) - -install_headers() -install_fhicl() -install_source() - diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc deleted file mode 100644 index 2246dde03..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc +++ /dev/null @@ -1,236 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Class: SBNDBNBEXTRetriever -// Plugin Type: producer -// File: SBNDBNBEXTRetriever_module.cc -// -//////////////////////////////////////////////////////////////////////// - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -#include "canvas/Utilities/InputTag.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include -#include -#include -#include - -#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" -#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" -#include "artdaq-core/Data/ContainerFragment.hh" -//#include "sbndcode/Decoders/PTB/sbndptb.h" -#include "sbnobj/Common/POTAccounting/EXTCountInfo.h" - -#include "ifdh_art/IFBeamService/IFBeam_service.h" -#include "ifbeam_c.h" - -#include "larcorealg/CoreUtils/counter.h" - -namespace sbn { - class SBNDBNBEXTRetriever; -} - -class sbn::SBNDBNBEXTRetriever : public art::EDProducer { -public: - explicit SBNDBNBEXTRetriever(fhicl::ParameterSet const & params); - // Required functions. - void produce(art::Event & e) override; - void beginSubRun(art::SubRun& sr) override; - void endSubRun(art::SubRun& sr) override; - - // Plugins should not be copied or assigned. - SBNDBNBEXTRetriever(SBNDBNBEXTRetriever const &) = delete; - SBNDBNBEXTRetriever(SBNDBNBEXTRetriever &&) = delete; - SBNDBNBEXTRetriever & operator = (SBNDBNBEXTRetriever const &) = delete; - SBNDBNBEXTRetriever & operator = (SBNDBNBEXTRetriever &&) = delete; - - -private: - // Declare member data here. - std::vector< sbn::EXTCountInfo > fOutExtInfos; - struct PTBInfo_t { - double currPTBTimeStamp = 0; - double prevPTBTimeStamp = 0; - unsigned int GateCounter = 0; // FIXME needs to be integral type - }; - - struct TriggerInfo_t { - double t_current_event = 0; - double t_previous_event = 0; - unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - }; - - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; - double extractTDCTimeStamp(art::Handle > cont_frags) const; - - // input labels - std::string raw_data_label_; - float TotalEXTCounts; - float totalMinBias; - float evtCount; -}; - -sbn::SBNDBNBEXTRetriever::SBNDBNBEXTRetriever(fhicl::ParameterSet const & params) - : EDProducer{params} { - produces< std::vector< sbn::EXTCountInfo >, art::InSubRun >(); - TotalEXTCounts = 0; - totalMinBias = 0; - evtCount = 0; -} - -int eventNum =0; -int _run; -int _subrun; -int _event; - -void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) -{ - - mf::LogDebug("SBNDBNBEXTRetriever") << "new_event: " << e.event() << std::endl; - - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - - mf::LogDebug("SBNDBNBEXTRetriever") << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; - mf::LogDebug("SBNDBNBEXTRetriever") << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; - mf::LogDebug("SBNDBNBEXTRetriever") << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; - - - TotalEXTCounts += triggerInfo.number_of_gates_since_previous_event; - - if(triggerInfo.number_of_gates_since_previous_event > 0){ - evtCount++; - totalMinBias += triggerInfo.number_of_gates_since_previous_event; - } - - //Store everything in our data-product - sbn::EXTCountInfo extInfo; - extInfo.gates_since_last_trigger = triggerInfo.number_of_gates_since_previous_event; - fOutExtInfos.push_back(extInfo); -} - -sbn::SBNDBNBEXTRetriever::PTBInfo_t sbn::SBNDBNBEXTRetriever::extractPTBInfo(art::Handle > cont_frags) const { - int HLT_count = 0; - - int numcont = 0; - PTBInfo_t PTBInfo; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck - for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) - { - if(ctb_frag.Trigger(word_i)){ - uint32_t wt = 0; - uint32_t word_type = ctb_frag.Word(word_i)->word_type; - wt = word_type; - if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(4)) - { - HLT_count++; - - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; - uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; - PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20).to_ullong()/50e6; - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; - break; - } - } - } //End of loop over the number of trigger words - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - - return PTBInfo; -} - -double sbn::SBNDBNBEXTRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { - int numcont = 0; - double TDCTimeStamp = 0; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::TDCTimestampFragment tdc_frag(frag); - TDCTimeStamp = static_cast(tdc_frag.getTDCTimestamp()->timestamp_ns())/1e9; - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - return TDCTimeStamp; -} - -sbn::SBNDBNBEXTRetriever::TriggerInfo_t sbn::SBNDBNBEXTRetriever::extractTriggerInfo(art::Event const& e) const { - // Using TDC for current event, but PTB for previous event - art::InputTag PTB_itag("daq", "ContainerPTB"); - auto PTB_cont_frags = e.getHandle(PTB_itag); - - art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); - auto TDC_cont_frags = e.getHandle(TDC_itag); - - PTBInfo_t PTBInfo; - TriggerInfo_t triggerInfo; - PTBInfo = extractPTBInfo(PTB_cont_frags); - - if (TDC_cont_frags) { - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - triggerInfo.t_current_event = TDCTimeStamp; - } - else{ - mf::LogDebug("SBNDBNBEXTRetriever") << " Missing TDC Contaienr Fragments!!! " << std::endl; - triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; - } - - triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; - triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - - if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ - mf::LogDebug("SBNDBNBEXTRetriever") << "Caught PTB bug, PTB late" << std::endl; - mf::LogDebug("SBNDBNBEXTRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; - triggerInfo.t_previous_event+=1; - mf::LogDebug("SBNDBNBEXTRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; - } - else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ - mf::LogDebug("SBNDBNBEXTRetriever") << "Caught PTB bug, PTB early" << std::endl; - mf::LogDebug("SBNDBNBEXTRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; - triggerInfo.t_previous_event-=1; - mf::LogDebug("SBNDBNBEXTRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; - } - - return triggerInfo; -} - -void sbn::SBNDBNBEXTRetriever::beginSubRun(art::SubRun& sr) -{ - TotalEXTCounts = 0; - totalMinBias = 0; - evtCount = 0; - return; -} - -void sbn::SBNDBNBEXTRetriever::endSubRun(art::SubRun& sr) -{ - // We will add all of the EXTCountInfo data-products to the - // art::SubRun so it persists - - auto p = std::make_unique< std::vector< sbn::EXTCountInfo > >(fOutExtInfos); - - sr.put(std::move(p), art::subRunFragment()); - - return; -} - -DEFINE_ART_MODULE(sbn::SBNDBNBEXTRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt deleted file mode 100644 index d04512753..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -find_package(ifbeam) -find_package(ifdh_art) - - -art_make_library(LIBRARIES Boost::system - LIBRARY_NAME sbn_SBNDBNBSpillInfoRetriever_MWRData - SOURCE MWRData.cpp -) - -cet_build_plugin(SBNDBNBRetriever art::module - LIBRARIES - art::Persistency_Common - art::Utilities canvas::canvas - cetlib::cetlib cetlib_except::cetlib_except - ROOT::X3d - Boost::system - messagefacility::MF_MessageLogger - ifbeam::ifbeam - ifdh_art::IFBeam_service - SQLite::SQLite3 - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND - artdaq_core::artdaq-core_Utilities - sbn_SBNDBNBSpillInfoRetriever_MWRData - sbnobj::Common_POTAccounting - larcorealg::CoreUtils -) - -install_headers() -install_fhicl() -install_source() - diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp deleted file mode 100644 index 48d0bda3f..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/MWRData.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "MWRData.h" - -using namespace std; - -namespace sbn{ - - std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const -{ - - std::vector > unpacked_data; - unpacked_data.resize(4); - short data[444]; - - std::vector row(0); - boost::split(row, packed_data, boost::is_any_of(",")); - if (row.size()==447) { - for (int i=3;i<447;i++) { - data[i-3]=atoi(row[i].c_str()); - } - string devname=row[1].substr(0,8); - for (int idev=0;idev<4;idev++) { - mwrpulse_t mwr=getMWRdata(data,idev); - time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.hor[ich]); - } - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.ver[ich]); - } - } - } else { - cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< -namespace sbn{ -class MWRData -{ - typedef struct swicheader_t { - long timesec; - long timensec; - long gpstime1; - long gpstime2; - short boosterevent; - short mievent; - short hz15micnt; - long delta1f; - short pulsemi; - short pulsesc; - } swicheader_t; - - typedef struct mwrpulse_t { - short hor[48]; - short ver[48]; - swicheader_t sheader; - } mwrpulse_t; - - static long flipByte(long data) - { - return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); - } - - mwrpulse_t getMWRdata(short* data, int nblock) const; - - public: - std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; -}; -} - -#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc deleted file mode 100644 index 8fbfae9ea..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ /dev/null @@ -1,645 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Class: SBNDBNBRetriever -// Plugin Type: producer -// File: SBNDBNBRetriever_module.cc -// -//////////////////////////////////////////////////////////////////////// - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -#include "canvas/Utilities/InputTag.h" -#include "canvas/Utilities/Exception.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include -#include -#include -#include -#include - -#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" -#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" -#include "artdaq-core/Data/ContainerFragment.hh" -//#include "sbndcode/Decoders/PTB/sbndptb.h" -#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" - -#include "ifdh_art/IFBeamService/IFBeam_service.h" -#include "ifbeam_c.h" -#include "MWRData.h" - -#include "larcorealg/CoreUtils/counter.h" - -namespace sbn { - class SBNDBNBRetriever; -} - -class sbn::SBNDBNBRetriever : public art::EDProducer { -public: - explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); - // Required functions. - void produce(art::Event & e) override; - void beginSubRun(art::SubRun& sr) override; - void endSubRun(art::SubRun& sr) override; - - // Plugins should not be copied or assigned. - SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; - - -private: - // Declare member data here. - std::vector< sbn::BNBSpillInfo > fOutbeamInfos; - double fTimePad; - std::string fInputLabel; - std::string fInputNonContainerInstance; - std::string fDeviceUsedForTiming; - std::string fOutputInstance; - std::string raw_data_label; - int fDebugLevel; - sbn::MWRData mwrdata; - art::ServiceHandle ifbeam_handle; - std::unique_ptr bfp; - std::unique_ptr bfp_mwr; - - struct PTBInfo_t { - double currPTBTimeStamp = 0; - double prevPTBTimeStamp = 0; - unsigned int GateCounter = 0; // FIXME needs to be integral type - }; - - struct TriggerInfo_t { - double t_current_event = 0; - double t_previous_event = 0; - unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - }; - - struct MWRdata_t { - std::vector< std::vector > MWR_times; - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - }; - - static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] - - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; - double extractTDCTimeStamp(art::Handle > cont_frags) const; - MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; - int matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos - ) const; - unsigned int TotalBeamSpills; - sbn::BNBSpillInfo makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; -}; - -sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) - : EDProducer{params} { - produces< std::vector< sbn::BNBSpillInfo >, art::InSubRun >(); - raw_data_label = params.get("raw_data_label", "daq"); - fInputLabel = params.get("InputLabel"); - fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); - fTimePad = params.get("TimePadding"); - fInputNonContainerInstance = params.get("InputNonContainerInstance"); - fOutputInstance = params.get("OutputInstance"); - fDebugLevel = params.get("DebugLevel",0); - bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); - bfp->set_epsilon(0.02); - bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); - bfp_mwr->set_epsilon(0.5); - bfp_mwr->setValidWindow(3605); - TotalBeamSpills = 0; -} - -int eventNum =0; -int _run; -int _subrun; -int _event; - -void sbn::SBNDBNBRetriever::produce(art::Event & e) -{ - - // If this is the first event in the run, then ignore it - // We do not currently have the ability to figure out the first - // spill that the DAQ was sensitive to, so don't try to save any - // spill information - - mf::LogDebug("SBNDBNBRetriever") << "new_event: " << e.event() << std::endl; - - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - - mf::LogDebug("SBNDBNBRetriever") << "triggerInfo.t_current_event: " << std::setprecision(19) << triggerInfo.t_current_event << std::endl; - mf::LogDebug("SBNDBNBRetriever") << "triggerInfo.t_previous_event: " << std::setprecision(19) << triggerInfo.t_previous_event << std::endl; - mf::LogDebug("SBNDBNBRetriever") << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; - - TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); - - int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); - - if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) - mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; - else - mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; -} - -sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { - - int numcont = 0; - PTBInfo_t PTBInfo; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck - for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) - { - if(ctb_frag.Trigger(word_i)){ - uint32_t wt = 0; - uint32_t word_type = ctb_frag.Word(word_i)->word_type; - wt = word_type; - mf::LogDebug("SBNDBNBRetriever") << "GateCounter!: " << ctb_frag.Trigger(word_i)->gate_counter << std::endl; - if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(2)) - { - - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; - uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; - PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp/20).to_ullong()/50e6; - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " prevPTBTimeStamp: " << PTBInfo.prevPTBTimeStamp << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " currPTBTimeStamp: " << PTBInfo.currPTBTimeStamp << std::endl; - break; - } - } - } //End of loop over the number of trigger words - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - - return PTBInfo; -} - -double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { - int numcont = 0; - - double TDCTimeStamp = 0; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::TDCTimestampFragment tdc_frag(frag); - TDCTimeStamp = static_cast(tdc_frag.getTDCTimestamp()->timestamp_ns())/1e9; - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - return TDCTimeStamp; -} - -sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { - // Using TDC for current event, but PTB for previous event. Exception for case where no TDC. - art::InputTag PTB_itag("daq", "ContainerPTB"); - auto PTB_cont_frags = e.getHandle(PTB_itag); - - art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); - auto TDC_cont_frags = e.getHandle(TDC_itag); - - PTBInfo_t PTBInfo; - TriggerInfo_t triggerInfo; - PTBInfo = extractPTBInfo(PTB_cont_frags); - - if (TDC_cont_frags) { - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - triggerInfo.t_current_event = TDCTimeStamp; - } - else{ - mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; - triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; - } - - triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; - triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - - if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ - mf::LogDebug("SBNDBNBRetriever") << "Caught PTB bug, PTB late" << std::endl; - mf::LogDebug("SBNDBNBRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; - triggerInfo.t_previous_event+=1; - mf::LogDebug("SBNDBNBRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; - } - else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ - mf::LogDebug("SBNDBNBRetriever") << "Caught PTB bug, PTB early" << std::endl; - mf::LogDebug("SBNDBNBRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; - triggerInfo.t_previous_event-=1; - mf::LogDebug("SBNDBNBRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; - } - - return triggerInfo; -} - -sbn::SBNDBNBRetriever::MWRdata_t sbn::SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { - - // These lines get everything primed within the IFBeamDB. - try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; - try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; - - // The multiwire chambers provide their - // data in a vector format but we'll have - // to sort through it in std::string format - // to correctly unpack it - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - std::vector< std::vector< double> > MWR_times; - unpacked_MWR.resize(3); - MWR_times.resize(3); - std::string packed_data_str; - - // Create a list of all the MWR devices with their different - // memory buffer increments - // generally in the format: "E:.{Memory Block}" - std::vector vars = bfp_mwr->GetDeviceList(); - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; - // Tracking the time from the IFBeamDB - double time_for_mwr; - - // this is an iterator to track which of the - // three devices we will be working with - int dev = 0; - - // The MWR devices are annoying and have confusing buffer - // what we'll do is sort through all of them first and then - // match them to the closest spills in time - // - - // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; - int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; - mf::LogDebug("SBNDBNBRetriever") << " t_steps " << t_steps << std::endl; - - for(int t = 0; t < t_steps; t++){//Iterate through time increments - for (std::string const& var : vars) {// Iterate through the devices - - //Make sure we have a device - if(var.empty()){ - //mf::LogDebug("SBNDBNBRetriever") << " NO MWR DEVICES?!" << std::endl; - continue; - } - /// Check the device name and interate the double-vector index - if(var.find("M875BB") != std::string::npos ) dev = 0; - else if(var.find("M876BB") != std::string::npos ) dev = 1; - else if(var.find("MMBTBB") != std::string::npos ) dev = 2; - else{ - //mf::LogDebug("SBNDBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; - continue;} - - time_for_mwr = 0; - - try{ - - //Pull the MWR data for the device - // these data are "packed" - std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); - - //We'll convert this into a format - // that we can unpack doubles >> strings - // - packed_data_str.clear(); - packed_data_str += std::to_string(int(time_for_mwr)); - packed_data_str.append(","); - packed_data_str.append(var); - packed_data_str.append(",,"); - - /* for(auto const value: packed_MWR){ - packed_data_str += ','; - packed_data_str += std::to_string(int(value)); - }*/ - for(int j = 0; j < int(packed_MWR.size()); j++){ - packed_data_str += std::to_string(int(packed_MWR[j])); - if(j < int(packed_MWR.size())-1) - packed_data_str.append(","); - } - - // Use Zarko's unpacking function to turn this into consumeable data - std::vector MWR_times_temp; - - // There is a 35 ms offset between the toriod and the MWR times - // we'll just remove that here to match to the spill times - std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); - - //There are four events that are packed into one MWR IFBeam entry - for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ - - // If this entry has a unique time them store it for later - if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ - unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); - MWR_times[dev].push_back(MWR_times_temp[s]); - }//check for unique time - }//Iterate through the unpacked events - }//try - catch (WebAPIException &we) { - //Ignore when we can't find the MWR devices - // they don't always report and the timing of them can be annoying - }//catch - }// Iterate over all the multiwire devices - }// Iterate over all times - - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; - - return { std::move(MWR_times), std::move(unpacked_MWR) }; -} - -int sbn::SBNDBNBRetriever::matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos -) const { - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - //Here we will start collecting all the other beamline devices - // First we get the times that the beamline device fired - // we have to pick a specific variable to use - std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); - - mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; - - // We'll keep track of how many of these spills match to our - // DAQ trigger times - int spill_count = 0; - int spills_removed = 0; - std::vector matched_MWR; - matched_MWR.resize(3); - - // NOTE: for now, this is dead code because we don't - // do anything for the first event in a run. We may want to revisit - // this later to understand if there is a way we can do the POT - // accounting in the first event. - // - // Need to handle the first event in a run differently - if(isFirstEventInRun){ - //We'll remove the spills after our event - int spills_after_our_target = 0; - // iterate through all the spills to find the - // spills that are after our triggered event - for (size_t i = 0; i < times_temps.size(); i++) { - if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ - spills_after_our_target++; - } - }//end loop through spill times - - // Remove the spills after our trigger - times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); - - // Remove the spills before the start of our Run - times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); - - }//end fix for "first event" - - ///reject time_stamps which have a trigger_type == 1 from data-base - //To-Do - - // mf::LogDebug("SBNDBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; - - // Iterating through each of the beamline times - for (size_t i = 0; i < times_temps.size(); i++) { - - // Only continue if these times are matched to our DAQ time - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; - - if(!isFirstEventInRun){//We already addressed the "first event" above - if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ - //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - spills_removed++; - continue;} - if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ - spills_removed++; - //mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - continue;} - } - - //check if this spill is is minbias - /* - 40 ms was selected to be close to but outside the 66 ms - time of the next spill (when the beam is running at 15 Hz) - DocDB 33155 provides documentation of this - */ - - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; - - // if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; - - // continue; - //} - - //Great we found a matched spill! Let's count it - spill_count++; - - //Loop through the multiwire devices: - - for(int dev = 0; dev < int(MWR_times.size()); dev++){ - - //Loop through the multiwire times: - double Tdiff = 1000000000.; - matched_MWR[dev] = 0; - - for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ - - //found a candidate match! - if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} - - bool best_match = true; - - //Check for a better match... - for (size_t j = 0; j < times_temps.size(); j++) { - if( j == i) continue; - if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} - if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} - - //is there a better match later in the spill sequence - if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < - fabs((MWR_times[dev][mwrt] - times_temps[i]))){ - //we can have patience... - best_match = false; - break; - } - }//end better match check - - //Verified best match! - if(best_match == true){ - matched_MWR[dev] = mwrt; - Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); - } - - }//end loop over MWR times - - }//end loop over MWR devices - - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); - - beamInfos.push_back(std::move(spillInfo)); - - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - }//end iteration over beam device times - - // mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; - - return spill_count; -} - -sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const -{ - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - // initializing all of our device carriers - // device definitions can be found in BNBSpillInfo.h - - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps - - double TOR860_time = 0; // units s - - // Here we request all the devices - // since sometimes devices fail to report we'll - // allow each to throw an exception but still move forward - // interpreting these failures will be part of the beam quality analyses - - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - - //crunch the times - unsigned long int time_closest_int = (int) TOR860_time; - double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - - mf::LogDebug("SBNDBNBRetriever") << "TOR860_time: " << std::setprecision(19) << TOR860_time << std::endl; - mf::LogDebug("SBNDBNBRetriever") << "TOR860: " << TOR860 << std::endl; - - //Store everything in our data-product - sbn::BNBSpillInfo beamInfo; - beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.LM875A = LM875A; - beamInfo.LM875B = LM875B; - beamInfo.LM875C = LM875C; - beamInfo.HP875 = HP875; - beamInfo.VP875 = VP875; - beamInfo.HPTG1 = HPTG1; - beamInfo.VPTG1 = VPTG1; - beamInfo.HPTG2 = HPTG2; - beamInfo.VPTG2 = VPTG2; - beamInfo.BTJT2 = BTJT2; - beamInfo.THCURR = THCURR; - beamInfo.spill_time_s = time_closest_int; - beamInfo.spill_time_ns = time_closest_ns; - - for(auto const& MWRdata: unpacked_MWR){ - std::ignore = MWRdata; - assert(!MWRdata.empty()); - } - - if(unpacked_MWR[0].empty()){ - beamInfo.M875BB.clear(); - beamInfo.M875BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; - beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); - } - - if(unpacked_MWR[1].empty()){ - beamInfo.M876BB.clear(); - beamInfo.M876BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; - beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); - } - - if(unpacked_MWR[2].empty()){ - beamInfo.MMBTBB.clear(); - beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; - beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); - } - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun - - return beamInfo; -} - -void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) -{ - return; -} - -void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) -{ - mf::LogDebug("SBNDBNBRetriever")<< "Total number of DAQ Spills : " << TotalBeamSpills << std::endl; - mf::LogDebug("SBNDBNBRetriever")<< "Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl; - - auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); - std::swap(*p, fOutbeamInfos); - - sr.put(std::move(p), art::subRunFragment()); - - return; -} - -DEFINE_ART_MODULE(sbn::SBNDBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt deleted file mode 100644 index 675168065..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -find_package(ifbeam) -find_package(ifdh_art) - - -art_make_library(LIBRARIES Boost::system - LIBRARY_NAME sbn_SBNDBNBZEROBIASSpillInfoRetriever_MWRData - SOURCE MWRData.cpp -) - -cet_build_plugin(SBNDBNBZEROBIASRetriever art::module - LIBRARIES - art::Persistency_Common - art::Utilities canvas::canvas - cetlib::cetlib cetlib_except::cetlib_except - ROOT::X3d - Boost::system - messagefacility::MF_MessageLogger - ifbeam::ifbeam - ifdh_art::IFBeam_service - SQLite::SQLite3 - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_SBND - artdaq_core::artdaq-core_Utilities - sbn_SBNDBNBZEROBIASSpillInfoRetriever_MWRData - sbnobj::Common_POTAccounting - larcorealg::CoreUtils -) - -install_headers() -install_fhicl() -install_source() - diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp deleted file mode 100644 index 48d0bda3f..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/MWRData.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "MWRData.h" - -using namespace std; - -namespace sbn{ - - std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const -{ - - std::vector > unpacked_data; - unpacked_data.resize(4); - short data[444]; - - std::vector row(0); - boost::split(row, packed_data, boost::is_any_of(",")); - if (row.size()==447) { - for (int i=3;i<447;i++) { - data[i-3]=atoi(row[i].c_str()); - } - string devname=row[1].substr(0,8); - for (int idev=0;idev<4;idev++) { - mwrpulse_t mwr=getMWRdata(data,idev); - time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.hor[ich]); - } - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.ver[ich]); - } - } - } else { - cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< -namespace sbn{ -class MWRData -{ - typedef struct swicheader_t { - long timesec; - long timensec; - long gpstime1; - long gpstime2; - short boosterevent; - short mievent; - short hz15micnt; - long delta1f; - short pulsemi; - short pulsesc; - } swicheader_t; - - typedef struct mwrpulse_t { - short hor[48]; - short ver[48]; - swicheader_t sheader; - } mwrpulse_t; - - static long flipByte(long data) - { - return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); - } - - mwrpulse_t getMWRdata(short* data, int nblock) const; - - public: - std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; -}; -} - -#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc deleted file mode 100644 index b87e7bca0..000000000 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ /dev/null @@ -1,614 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Class: SBNDBNBRetriever -// Plugin Type: producer -// File: SBNDBNBRetriever_module.cc -// -//////////////////////////////////////////////////////////////////////// - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -#include "canvas/Utilities/InputTag.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include -#include -#include -#include - -#include "sbndaq-artdaq-core/Overlays/SBND/PTBFragment.hh" -#include "sbndaq-artdaq-core/Overlays/SBND/TDCTimestampFragment.hh" -#include "artdaq-core/Data/ContainerFragment.hh" -//#include "sbndcode/Decoders/PTB/sbndptb.h" -#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" - -#include "ifdh_art/IFBeamService/IFBeam_service.h" -#include "ifbeam_c.h" -#include "MWRData.h" - -#include "larcorealg/CoreUtils/counter.h" - -namespace sbn { - class SBNDBNBRetriever; -} - -class sbn::SBNDBNBRetriever : public art::EDProducer { -public: - explicit SBNDBNBRetriever(fhicl::ParameterSet const & params); - // Required functions. - void produce(art::Event & e) override; - void beginSubRun(art::SubRun& sr) override; - void endSubRun(art::SubRun& sr) override; - - // Plugins should not be copied or assigned. - SBNDBNBRetriever(SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever(SBNDBNBRetriever &&) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever const &) = delete; - SBNDBNBRetriever & operator = (SBNDBNBRetriever &&) = delete; - - -private: - // Declare member data here. - std::vector< sbn::BNBSpillInfo > fOutbeamInfos; - double fTimePad; - std::string fInputLabel; - std::string fInputNonContainerInstance; - std::string fDeviceUsedForTiming; - std::string fOutputInstance; - std::string raw_data_label; - int fDebugLevel; - sbn::MWRData mwrdata; - art::ServiceHandle ifbeam_handle; - std::unique_ptr bfp; - std::unique_ptr bfp_mwr; - - struct PTBInfo_t { - double currPTBTimeStamp = 0; - double prevPTBTimeStamp = 0; - unsigned int GateCounter = 0; // FIXME needs to be integral type - }; - - struct TriggerInfo_t { - double t_current_event = 0; - double t_previous_event = 0; - unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - }; - - struct MWRdata_t { - std::vector< std::vector > MWR_times; - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - }; - - static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] - - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - PTBInfo_t extractPTBInfo(art::Handle > cont_frags) const; - double extractTDCTimeStamp(art::Handle > cont_frags) const; - MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; - void matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos - ) const; - unsigned int TotalBeamSpills; - sbn::BNBSpillInfo makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; -}; - -sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) - : EDProducer{params} { - raw_data_label = params.get("raw_data_label", "daq"); - fInputLabel = params.get("InputLabel"); - fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); - fTimePad = params.get("TimePadding"); - fInputNonContainerInstance = params.get("InputNonContainerInstance"); - fOutputInstance = params.get("OutputInstance"); - fDebugLevel = params.get("DebugLevel",0); - bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); - bfp->set_epsilon(0.02); - bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); - bfp_mwr->set_epsilon(0.5); - bfp_mwr->setValidWindow(3605); - TotalBeamSpills = 0; - produces< std::vector< sbn::BNBSpillInfo >, art::InEvent >(); - // produces< std::vector >(); -} - -int eventNum =0; -int _run; -int _subrun; -int _event; - -void sbn::SBNDBNBRetriever::produce(art::Event & e) -{ - - // If this is the first event in the run, then ignore it - // We do not currently have the ability to figure out the first - // spill that the DAQ was sensitive to, so don't try to save any - // spill information - - if (e.event() == 1) { - auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); - std::swap(*p, fOutbeamInfos); - e.put(std::move(p)); - return; - } - - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "new_event: " << e.event() << std::endl; - - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); - - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "triggerInfo.t_current_event: " << std::setprecision(25) << triggerInfo.t_current_event << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "triggerInfo.t_previous_event: " << std::setprecision(25) << triggerInfo.t_previous_event << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "triggerInfo.number_of_gates_since_previous_event: " << triggerInfo.number_of_gates_since_previous_event << std::endl; - - TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); - - matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); - - auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); - std::swap(*p, fOutbeamInfos); - e.put(std::move(p)); -} - -sbn::SBNDBNBRetriever::PTBInfo_t sbn::SBNDBNBRetriever::extractPTBInfo(art::Handle > cont_frags) const { - - int numcont = 0; - PTBInfo_t PTBInfo; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::CTBFragment ctb_frag(frag); // somehow the name CTBFragment stuck - for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) - { - if(ctb_frag.Trigger(word_i)){ - uint32_t wt = 0; - uint32_t word_type = ctb_frag.Word(word_i)->word_type; - wt = word_type; - if (wt == 2 && ctb_frag.Trigger(word_i)->IsTrigger(1)) - { - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20.0; - // uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; - uint64_t RawcurrPTBTimeStamp = ctb_frag.TimeStamp(word_i) * 20.0; - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20.0).to_ullong()/50e6; - PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp / 20.0).to_ullong()/50e6; - PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; - - mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " prevPTBTimeStamp: " << PTBInfo.prevPTBTimeStamp << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << std::setprecision(25) << " currPTBTimeStamp: " << PTBInfo.currPTBTimeStamp << std::endl; - - break; - } - } - } //End of loop over the number of trigger words - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - - return PTBInfo; -} - -double sbn::SBNDBNBRetriever::extractTDCTimeStamp(art::Handle > cont_frags) const { - int numcont = 0; - double TDCTimeStamp = 0; - for (auto const& cont : *cont_frags) - { - artdaq::ContainerFragment cont_frag(cont); - numcont++; - int numfrag = 0; - for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) - { - numfrag++; - artdaq::Fragment frag = *cont_frag[fragi]; - sbndaq::TDCTimestampFragment tdc_frag(frag); - TDCTimeStamp = static_cast(tdc_frag.getTDCTimestamp()->timestamp_ns()) / 1e9; - } //End of loop over the number of fragments per container - } //End of loop over the number of containers - return TDCTimeStamp; -} - -sbn::SBNDBNBRetriever::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { - // Using TDC for current event, but PTB for previous event - art::InputTag PTB_itag("daq", "ContainerPTB"); - auto PTB_cont_frags = e.getHandle(PTB_itag); - - art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); - auto TDC_cont_frags = e.getHandle(TDC_itag); - - PTBInfo_t PTBInfo; - TriggerInfo_t triggerInfo; - PTBInfo = extractPTBInfo(PTB_cont_frags); - - if (TDC_cont_frags) { - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); - triggerInfo.t_current_event = TDCTimeStamp; - } - else{ - mf::LogDebug("SBNDBNBZEROBIASRetriever") << " Missing TDC Container Fragments!!!" << std::endl; - triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp; - } - - triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp; - triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - - - if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp >= 1){ - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Caught PTB bug, PTB late" << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; - triggerInfo.t_previous_event+=1; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; - } - else if(triggerInfo.t_current_event - PTBInfo.currPTBTimeStamp <= -1){ - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Caught PTB bug, PTB early" << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "Before: " << triggerInfo.t_previous_event << std::endl; - triggerInfo.t_previous_event-=1; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "After: " << triggerInfo.t_previous_event << std::endl; - } - - return triggerInfo; -} - -sbn::SBNDBNBRetriever::MWRdata_t sbn::SBNDBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { - - // These lines get everything primed within the IFBeamDB. - try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; - try{bfp_mwr->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; - try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {}; - - // The multiwire chambers provide their - // data in a vector format but we'll have - // to sort through it in std::string format - // to correctly unpack it - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - std::vector< std::vector< double> > MWR_times; - unpacked_MWR.resize(3); - MWR_times.resize(3); - std::string packed_data_str; - - // Create a list of all the MWR devices with their different - // memory buffer increments - // generally in the format: "E:.{Memory Block}" - std::vector vars = bfp_mwr->GetDeviceList(); - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; - // Tracking the time from the IFBeamDB - double time_for_mwr; - - // this is an iterator to track which of the - // three devices we will be working with - int dev = 0; - - // The MWR devices are annoying and have confusing buffer - // what we'll do is sort through all of them first and then - // match them to the closest spills in time - // - - // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; - int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; - mf::LogDebug("SBNDBNBRetriever") << " t_steps " << t_steps << std::endl; - - for(int t = 0; t < t_steps; t++){//Iterate through time increments - for (std::string const& var : vars) {// Iterate through the devices - - //Make sure we have a device - if(var.empty()){ - //mf::LogDebug("SBNDBNBRetriever") << " NO MWR DEVICES?!" << std::endl; - continue; - } - /// Check the device name and interate the double-vector index - if(var.find("M875BB") != std::string::npos ) dev = 0; - else if(var.find("M876BB") != std::string::npos ) dev = 1; - else if(var.find("MMBTBB") != std::string::npos ) dev = 2; - else{ - //mf::LogDebug("SBNDBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; - continue;} - - time_for_mwr = 0; - - try{ - - //Pull the MWR data for the device - // these data are "packed" - std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); - - //We'll convert this into a format - // that we can unpack doubles >> strings - // - packed_data_str.clear(); - packed_data_str += std::to_string(int(time_for_mwr)); - packed_data_str.append(","); - packed_data_str.append(var); - packed_data_str.append(",,"); - - /* for(auto const value: packed_MWR){ - packed_data_str += ','; - packed_data_str += std::to_string(int(value)); - }*/ - for(int j = 0; j < int(packed_MWR.size()); j++){ - packed_data_str += std::to_string(int(packed_MWR[j])); - if(j < int(packed_MWR.size())-1) - packed_data_str.append(","); - } - - // Use Zarko's unpacking function to turn this into consumeable data - std::vector MWR_times_temp; - - // There is a 35 ms offset between the toriod and the MWR times - // we'll just remove that here to match to the spill times - std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); - - //There are four events that are packed into one MWR IFBeam entry - for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ - - // If this entry has a unique time them store it for later - if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ - unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); - MWR_times[dev].push_back(MWR_times_temp[s]); - }//check for unique time - }//Iterate through the unpacked events - }//try - catch (WebAPIException &we) { - //Ignore when we can't find the MWR devices - // they don't always report and the timing of them can be annoying - }//catch - }// Iterate over all the multiwire devices - }// Iterate over all times - - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; - mf::LogDebug("SBNDBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; - - return { std::move(MWR_times), std::move(unpacked_MWR) }; -} - -void sbn::SBNDBNBRetriever::matchMultiWireData( - art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, - std::vector< sbn::BNBSpillInfo >& beamInfos -) const { - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - //Here we will start collecting all the other beamline devices - // First we get the times that the beamline device fired - // we have to pick a specific variable to use - std::vector times_temps = bfp->GetTimeList(fDeviceUsedForTiming); - - mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Number of time spills : " << times_temps.size() << std::endl; - - // We'll keep track of how many of these spills match to our - // DAQ trigger times - int spills_removed = 0; - std::vector matched_MWR; - matched_MWR.resize(3); - - // mf::LogDebug("SBNDBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; - // mf::LogDebug("SBNDBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; - - // Iterating through each of the beamline times - - if(isFirstEventInRun){ - //We'll remove the spills after our event - int spills_after_our_target = 0; - // iterate through all the spills to find the - // spills that are after our triggered event - for (size_t i = 0; i < times_temps.size(); i++) { - if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ - spills_after_our_target++; - } - }//end loop through spill times - - // Remove the spills after our trigger - times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); - - // Remove the spills before the start of our Run - times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); - - }//end fix for "first event" - - double best_diff = 10000000000.0; - double diff; - size_t i = 0; - - for (size_t k = 0; k < times_temps.size(); k++){ - diff = times_temps[k] - (triggerInfo.t_current_event + fTimePad); - - if( diff < 0 and diff < best_diff){ - if(!isFirstEventInRun){ - if(times_temps[k] > (triggerInfo.t_current_event)+fTimePad){ - spills_removed++; - continue;} - if(times_temps[k] <= (triggerInfo.t_previous_event)+fTimePad){ - spills_removed++; - continue;} - } - best_diff = diff; - i = k; - } - } - for(int dev = 0; dev < int(MWR_times.size()); dev++){ - - //Loop through the multiwire times: - double Tdiff = 1000000000.; - matched_MWR[dev] = 0; - - for(int mwrt = 0; mwrt < int(MWR_times[dev].size()); mwrt++){ - - //found a candidate match! - if(fabs((MWR_times[dev][mwrt] - times_temps[i])) >= Tdiff){continue;} - - bool best_match = true; - - //Check for a better match... - for (size_t j = 0; j < times_temps.size(); j++) { - if( j == i) continue; - if(times_temps[j] > (triggerInfo.t_current_event+fTimePad)){continue;} - if(times_temps[j] <= (triggerInfo.t_previous_event+fTimePad)){continue;} - - //is there a better match later in the spill sequence - if(fabs((MWR_times[dev][mwrt] - times_temps[j])) < - fabs((MWR_times[dev][mwrt] - times_temps[i]))){ - //we can have patience... - best_match = false; - break; - } - }//end better match check - - //Verified best match! - if(best_match == true){ - matched_MWR[dev] = mwrt; - Tdiff = fabs((MWR_times[dev][mwrt] - times_temps[i])); - } - }//end loop over MWR times - }//end loop over MWR devices - - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); - - beamInfos.push_back(std::move(spillInfo)); - - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - //}//end iteration over beam device times - - // mf::LogDebug("SBNDBNBRetriever") << "matchMultiWireData:: Total spills counted: " << spill_count << " Total spills removed : " << spills_removed << std::endl; - -} - -sbn::BNBSpillInfo sbn::SBNDBNBRetriever::makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const -{ - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - // initializing all of our device carriers - // device definitions can be found in BNBSpillInfo.h - - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps - - double TOR860_time = 0; // units s - - // Here we request all the devices - // since sometimes devices fail to report we'll - // allow each to throw an exception but still move forward - // interpreting these failures will be part of the beam quality analyses - - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - - //crunch the times - unsigned long int time_closest_int = (int) TOR860_time; - double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "TOR860_time: " << std::setprecision(25) << TOR860_time << std::endl; - mf::LogDebug("SBNDBNBZEROBIASRetriever") << "TOR860: " << TOR860 << std::endl; - - //Store everything in our data-product - sbn::BNBSpillInfo beamInfo; - beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.LM875A = LM875A; - beamInfo.LM875B = LM875B; - beamInfo.LM875C = LM875C; - beamInfo.HP875 = HP875; - beamInfo.VP875 = VP875; - beamInfo.HPTG1 = HPTG1; - beamInfo.VPTG1 = VPTG1; - beamInfo.HPTG2 = HPTG2; - beamInfo.VPTG2 = VPTG2; - beamInfo.BTJT2 = BTJT2; - beamInfo.THCURR = THCURR; - beamInfo.spill_time_s = time_closest_int; - beamInfo.spill_time_ns = time_closest_ns; - - for(auto const& MWRdata: unpacked_MWR){ - std::ignore = MWRdata; - assert(!MWRdata.empty()); - } - - if(unpacked_MWR[0].empty()){ - beamInfo.M875BB.clear(); - beamInfo.M875BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; - beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); - } - - if(unpacked_MWR[1].empty()){ - beamInfo.M876BB.clear(); - beamInfo.M876BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; - beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); - } - - if(unpacked_MWR[2].empty()){ - beamInfo.MMBTBB.clear(); - beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; - beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); - } - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun - - return beamInfo; -} - -void sbn::SBNDBNBRetriever::beginSubRun(art::SubRun& sr) -{ - return; -} - -void sbn::SBNDBNBRetriever::endSubRun(art::SubRun& sr) -{ - return; -} - -DEFINE_ART_MODULE(sbn::SBNDBNBRetriever) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl deleted file mode 100644 index e20bc0323..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl +++ /dev/null @@ -1,46 +0,0 @@ -#include "sbndbnbextspillinfo.fcl" - -process_name: SBNDBNBEXTInfoGen - -services:{ - - message: { - debugModules: [ "*" ] - destinations: { - LogDebugFile:{ - type: "file" - filename: "debug.log" - append: false - threshold: "DEBUG" - categories: { - default: {} - } - } - } - } - IFBeam:{} -} - - -source: { -} - -physics: { - producers: { - sbndbnbextinfo: @local::sbndbnbextspillinfo - } - - simulate: [sbndbnbextinfo ] - stream1: [ out1 ] -} - -outputs: { - out1: { - module_type: RootOutput - fileName: "%ifb_%tc_sbndbnbextinfo.root" - dataTier: "raw" - compressionLevel: 1 - } -} - -physics.producers.sbndbnbextinfo.fileNames: @local::outputs.out1.fileName diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl deleted file mode 100644 index 7f9f26df1..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl +++ /dev/null @@ -1,47 +0,0 @@ -#include "sbndbnbspillinfo.fcl" - -process_name: SBNDBNBInfoGen - -services:{ - - message: { - debugModules: [ "*" ] - destinations: { - LogDebugFile:{ - type: "file" - filename: "debug.log" - append: false - threshold: "DEBUG" - categories: { - default: {} - } - } - } - } - IFBeam:{} -} - - -source: { - -} - -physics: { - producers: { - sbndbnbinfo: @local::sbndbnbspillinfo - } - - simulate: [sbndbnbinfo ] - stream1: [ out1 ] -} - -outputs: { - out1: { - module_type: RootOutput - fileName: "%ifb_%tc_sbndbnbinfo.root" - dataTier: "raw" - compressionLevel: 1 - } -} - -physics.producers.sbndbnbinfo.fileNames: @local::outputs.out1.fileName diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl deleted file mode 100644 index bcdf6635b..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbzerobiasinfo_sbn.fcl +++ /dev/null @@ -1,46 +0,0 @@ -#include "sbndbnbzerobiasspillinfo.fcl" - -process_name: SBNDBNBZEROBIASInfoGen - -services:{ - - message: { - debugModules: [ "*" ] - destinations: { - LogDebugFile:{ - type: "file" - filename: "debug.log" - append: false - threshold: "DEBUG" - categories: { - default: {} - } - } - } - } - IFBeam:{} -} - - -source: { -} - -physics: { - producers: { - sbndbnbzerobiasinfo: @local::sbndbnbzerobiasspillinfo - } - - simulate: [sbndbnbzerobiasinfo ] - stream1: [ out1 ] -} - -outputs: { - out1: { - module_type: RootOutput - fileName: "%ifb_%tc_sbndbnbzerobiasinfo.root" - dataTier: "raw" - compressionLevel: 1 - } -} - -physics.producers.sbndbnbzerobiasinfo.fileNames: @local::outputs.out1.fileName diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl deleted file mode 100644 index 14daf561f..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbextspillinfo.fcl +++ /dev/null @@ -1,21 +0,0 @@ -BEGIN_PROLOG - -sbndbnbextspillinfo: { - module_type: SBNDBNBEXTRetriever - InputLabel: "bnbext" - InputContainerInstance: "ContainerBNB" - InputNonContainerInstance: "BNB" - OutputInstance: "" - DebugLevel: 0 - TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - URL: "https://dbdata3vm.fnal.gov:9443/ifbeam" - Bundle: "BoosterNeutrinoBeam_read" - MultiWireBundle: "BNBMultiWire" - TimeWindow: "700" #seconds - MWR_TimeWindow: "3601" #seconds - raw_data_label: "daq" - DeviceUsedForTiming: "E:TOR860" -} - -END_PROLOG - diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl deleted file mode 100644 index 4bdb732ef..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl +++ /dev/null @@ -1,21 +0,0 @@ -BEGIN_PROLOG - -sbndbnbspillinfo: { - module_type: SBNDBNBRetriever - InputLabel: "bnb" - InputContainerInstance: "ContainerBNB" - InputNonContainerInstance: "BNB" - OutputInstance: "" - DebugLevel: 0 - TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - URL: "" #Default URL having issues Nov 21 2024, used this instead https://dbdata3vm.fnal.gov:9443/ifbeam - Bundle: "BoosterNeutrinoBeam_read" - MultiWireBundle: "BNBMultiWire" - TimeWindow: "700" #seconds - MWR_TimeWindow: "3601" #seconds - raw_data_label: "daq" - DeviceUsedForTiming: "E:TOR860" -} - -END_PROLOG - diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl deleted file mode 100644 index bb1c2302d..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbzerobiasspillinfo.fcl +++ /dev/null @@ -1,21 +0,0 @@ -BEGIN_PROLOG - -sbndbnbzerobiasspillinfo: { - module_type: SBNDBNBZEROBIASRetriever - InputLabel: "bnbzerobias" - InputContainerInstance: "ContainerBNB" - InputNonContainerInstance: "BNB" - OutputInstance: "" - DebugLevel: 0 - TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - URL: "" - Bundle: "BoosterNeutrinoBeam_read" - MultiWireBundle: "BNBMultiWire" - TimeWindow: "700" #seconds - MWR_TimeWindow: "3601" #seconds - raw_data_label: "daq" - DeviceUsedForTiming: "E:TOR860" -} - -END_PROLOG - diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index db4abc88f..358be7d94 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -122,8 +122,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Time(); - srspacepoint.time_err = spacepoint.TimeErr(); + srspacepoint.time = spacepoint.Ts1(); + srspacepoint.time_err = spacepoint.Ts1Err(); srspacepoint.complete = spacepoint.Complete(); } @@ -134,8 +134,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Time(); - srsbndcrttrack.time_err = track.TimeErr(); + srsbndcrttrack.time = track.Ts1(); + srsbndcrttrack.time_err = track.Ts1Err(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From 0aef7afb681a671508e8504214032f83e819af66 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Thu, 13 Feb 2025 19:20:20 -0600 Subject: [PATCH 041/367] $1D offset was hardcoded! Change BES offset to fcl param. --- .../ICARUSBNBRetriever_module.cc | 14 +++++++++----- .../job/icarusbnbspillinfo.fcl | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index f559c1df8..86e6f9d34 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -121,6 +121,7 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { // input labels std::vector< sbn::BNBSpillInfo > fOutbeamInfos; double fTimePad; + double fBESOffset; std::string fURL; MWRData mwrdata; int run_number; @@ -257,6 +258,7 @@ int sbn::ICARUSBNBRetriever::get_trigger_type_matching_gate(sqlite3 *db, int fun sbn::ICARUSBNBRetriever::ICARUSBNBRetriever(Parameters const& params) : EDProducer{params}, fTimePad(params().TimePadding()), + fBESOffset(params().BESOffset()), raw_data_label(params().RawDataLabel()), fDeviceUsedForTiming(params().DeviceUsedForTiming()), bfp( ifbeam_handle->getBeamFolder(params().Bundle(), params().URL(), params().TimeWindow())), @@ -370,11 +372,12 @@ sbn::ICARUSBNBRetriever::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerIn */ - triggerInfo.t_current_event = static_cast(artdaq_ts-3.6e7)/(1000000000.0); //check this offset... + double BESinTSUnits = fBESOffset*1e9; // flc param is in seconds need to convert to match TS + triggerInfo.t_current_event = static_cast(artdaq_ts-BESinTSUnits)/(1000000000.0); //check this offset... if(triggerInfo.gate_type == 1) - triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampBNBMaj()-3.6e7))/(1e9); + triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampBNBMaj()-BESinTSUnits))/(1e9); else - triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampOther()-3.6e7))/(1000000000.0); + triggerInfo.t_previous_event = (static_cast(frag.getLastTimestampOther()-BESinTSUnits))/(1000000000.0); } @@ -581,9 +584,10 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( DocDB 33155 provides documentation of this */ - mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << 3.6e7 << std::endl; + double BESinTSUnits = fBESOffset*1e9; // flc param is in seconds need to convert to match TS + mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: trigger type : " << get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+BESinTSUnits, 40.) << " times : spill " << times_temps[i]*1.e9 << " - " << triggerInfo.WR_to_Spill_conversion << " + " << BESinTSUnits << std::endl; - if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+3.6e7, 40.) == 1){ + if(get_trigger_type_matching_gate(db, callback_trigger_type, run_number, times_temps[i]*1.e9-triggerInfo.WR_to_Spill_conversion+BESinTSUnits, 40.) == 1){ mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "matchMultiWireData:: Skipped a MinBias gate at : " << times_temps[i]*1000. << std::endl; continue; diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl index 9bc7e15d2..a7b4b0dbc 100644 --- a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl @@ -5,6 +5,7 @@ icarusbnbspillinfo: { module_type: "ICARUSBNBRetriever" TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away + BESOffset: 0.036 #unit seconds, we expect the BES to be about 35 ms from $1D. Need to adjust search range accordingly. URL: "" #keep this blank and we're good Bundle: "BoosterNeutrinoBeam_read" MultiWireBundle: "BNBMultiWire" From f22e5e5bf78a6aa69e96426246dbaa30df77e8c4 Mon Sep 17 00:00:00 2001 From: icaromx Date: Thu, 6 Mar 2025 11:03:30 -0600 Subject: [PATCH 042/367] updated code for making cafs from overlay files now using v10 --- sbncode/CAFMaker/CAFMakerParams.h | 4 ++++ sbncode/CAFMaker/CAFMaker_module.cc | 24 +++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index d05eb8b9b..dab095902 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -44,6 +44,10 @@ namespace caf Atom SaveGENIEEventRecord { Name("SaveGENIEEventRecord"), Comment("Whether to produce GENIE event record to the output file"), false }; + + Atom OverrideRealData { Name("OverrideRealData"), + Comment("Whether to ignore things aimed at real data -- e.g. if instead the event in an overlay"), false + }; Atom PrescaleFactor { Name("PrescaleFactor"), Comment("Factor by which to prescale unblind events"), 10 diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 2728b395f..62feede18 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -199,7 +199,8 @@ class CAFMaker : public art::EDProducer { std::string fSourceFile; std::uint32_t fSourceFileHash; - + + bool fOverrideRealData; bool fFirstInSubRun; unsigned int fIndexInFile = SRHeader::NoSourceIndex; bool fFirstBlindInSubRun; @@ -401,6 +402,7 @@ class CAFMaker : public art::EDProducer { // Note: we will define isRealData on a per event basis in produce function [using event.isRealData()], at least for now. fCafFilename = fParams.CAFFilename(); + fOverrideRealData = fParams.OverrideRealData(); fFlatCafFilename = fParams.FlatCAFFilename(); // Normally CAFMaker is run wit no output ART stream, so these go @@ -847,9 +849,18 @@ void CAFMaker::beginSubRun(art::SubRun& sr) { std::cout << std::endl; abort(); } - + if ( fOverrideRealData ) { + // Expects a generator POT summary then... + if(auto pot_handle = sr.getHandle(fParams.GenLabel())){ + fSubRunPOT = pot_handle->totgoodpot; + fTotalPOT += fSubRunPOT; + }else{ + std::cout << "Did not find MC POT info under " << fParams.GenLabel() << std::endl; + if(fParams.StrictMode()) abort(); + } + }else{ if(bnb_spill){ - FillExposure(*bnb_spill, fBNBInfo, fSubRunPOT); + FillExposure(*bnb_spill, fBNBInfo, fSubRunPOT); fTotalPOT += fSubRunPOT; // Find the spill for each event and fill the event map: @@ -908,10 +919,9 @@ void CAFMaker::beginSubRun(art::SubRun& sr) { << std::endl; if(fParams.StrictMode()) abort(); } - // Otherwise, if one label is blank, maybe no POT was the expected result } - + } std::cout << "POT: " << fSubRunPOT << std::endl; fFirstInSubRun = true; @@ -1263,8 +1273,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { bool const firstInFile = (fIndexInFile++ == 0); - // is this event real data? - bool isRealData = evt.isRealData(); + // is this event real data? -- BH: if fOverrideRealData, treat it as MC. Otherwise, get the info from the art event. + bool isRealData = ( fOverrideRealData ? false : evt.isRealData() ); std::unique_ptr> srcol( new std::vector); From 1e5f3c8867cd39c3f874776cce04bc684d96d7ee Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Fri, 7 Mar 2025 14:30:23 +0100 Subject: [PATCH 043/367] This commit introduces the CRTHitT0 tagging tracks in the sbncode IF enabled, It should work for both ICARUS and SBND. --- sbncode/Calibration/TrackCaloSkimmer.h | 30 ++- .../Calibration/TrackCaloSkimmer_module.cc | 188 +++++++++++++----- .../fcl/icarus/icarus_trackcalo_skimmer.fcl | 34 +++- 3 files changed, 202 insertions(+), 50 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index 4881f9f2f..6c96f6417 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -61,6 +61,9 @@ #include "larsim/MCCheater/ParticleInventoryService.h" #include "sbnobj/Common/Calibration/TrackCaloSkimmerObj.h" +#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.cc" +#include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.cc" + #include "ITCSSelectionTool.h" namespace sbn { @@ -90,6 +93,16 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { } private: + + struct T0TimingInfo { + double t0Pandora; + double t0CRTTrack; + double t0CRTHit; + bool hasT0Pandora; + bool hasT0CRTTrack; + bool hasT0CRTHit; + }; + // Internal data struct struct GlobalTrackInfo { geo::Point_t start; @@ -117,13 +130,14 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { // Fill vars void FillTrack(const recob::Track &track, - const recob::PFParticle &pfp, float t0, float t0CRT, + const recob::PFParticle &pfp, const T0TimingInfo &t0Info, const std::vector> &hits, const std::vector &thms, const std::vector> &sps, const std::vector> &calo, const std::map> &rawdigits, const std::vector &tracks, + const geo::GeometryCore *geo, const geo::WireReadoutGeom *wireReadout, const detinfo::DetectorClocksData &clock_data, const cheat::BackTrackerService *bt_serv, @@ -157,11 +171,14 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { unsigned hkey, const recob::TrackHitMeta &thm, const recob::Track &trk, + const T0TimingInfo &t0Info, const art::Ptr &sp, const std::vector> &calo, + const geo::GeometryCore *geo, const geo::WireReadoutGeom *wireReadout, const detinfo::DetectorClocksData &dclock, - const cheat::BackTrackerService *bt_serv); + const cheat::BackTrackerService *bt_serv, + const detinfo::DetectorPropertiesData &dprop); void DoTailFit(); @@ -187,7 +204,14 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { bool fFillTrackEndHits; float fTrackEndHitWireBox; float fTrackEndHitTimeBox; - + bool fIncludeCRTHitTagging; + bool fIncludeTopCRT; + bool fIncludeSideCRT; + double fTopCRTDistanceCutStopping; + double fTopCRTDistanceCutPassing; + double fSideCRTDistanceCutStopping; + double fSideCRTDistanceCutPassing; + // tools std::vector> fSelectionTools; diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 35581662a..b38fa393b 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -82,6 +82,14 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) fHitRawDigitsTickCollectWidth = p.get("HitRawDigitsTickCollectWidth", 50.); fHitRawDigitsWireCollectWidth = p.get("HitRawDigitsWireCollectWidth", 5); fTailFitResidualRange = p.get("TailFitResidualRange", 5.); + fIncludeCRTHitTagging = p.get("IncludeCRTHitTagging", false); + fIncludeTopCRT = p.get("IncludeTopCRT", false); + fIncludeSideCRT = p.get("IncludeSideCRT", false); + fTopCRTDistanceCutStopping = p.get("TopCRTDistanceCut_stopping", 100.); + fTopCRTDistanceCutPassing = p.get("TopCRTDistanceCut_throughgoing", 100.); + fSideCRTDistanceCutStopping = p.get("SideCRTDistanceCut_stopping", 100.); + fSideCRTDistanceCutPassing = p.get("SideCRTDistanceCut_throughgoing", 100.); + if (fTailFitResidualRange > 10.) { std::cout << "sbn::TrackCaloSkimmer: Bad tail fit residual range config :(" << fTailFitResidualRange << "). Fits will not be meaningful.\n"; } @@ -95,7 +103,6 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) for (const fhicl::ParameterSet &p: selection_tool_configs) { fSelectionTools.push_back(art::make_tool(p)); } - // Setup meta info fMeta.iproc = -1; fMeta.ifile = -1; @@ -128,11 +135,9 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) fMeta.subrun = sub; fMeta.run = run; fMeta.time = e.time().value(); - // Services const geo::GeometryCore *geometry = lar::providerFrom(); - const geo::WireReadoutGeom *wireReadout = - &art::ServiceHandle()->Get(); + const geo::WireReadoutGeom *wireReadout = &art::ServiceHandle()->Get(); auto const clock_data = art::ServiceHandle()->DataFor(e); auto const dprop = art::ServiceHandle()->DataFor(e, clock_data); @@ -214,7 +219,8 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) // PFP-associated data std::vector> fmT0; for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { - if (fT0producers[i_label] != "crttrackmatching") + if ((fT0producers[i_label] != "crttrackmatching") && + (fT0producers[i_label] != "CRTT0Tagging")) fmT0.emplace_back(PFParticleList, e, fT0producers[i_label]); } art::FindManyP PFParticleSPs(PFParticleList, e, fPFPproducer); @@ -223,14 +229,30 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) art::ValidHandle> tracks = e.getValidHandle>(fTRKproducer); std::vector> fmT02; - float crtLabel = std::numeric_limits::signaling_NaN(); + float crttrackLabel = std::numeric_limits::signaling_NaN(); for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { if (fT0producers[i_label] == "crttrackmatching"){ - crtLabel = i_label; + crttrackLabel = i_label; fmT02.emplace_back(tracks, e, fT0producers[i_label]); } } + std::vector> fmCRTHitT0Tagging; + for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { + if (fT0producers[i_label] == "CRTT0Tagging"){ + + fmCRTHitT0Tagging.emplace_back(tracks, e, fT0producers[i_label]); + } + } + + // Recover information on the CRTHitT0TaggingInfo + std::vector> fmCRTHitT0TaggingInfo; + for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { + if (fT0producers[i_label] == "CRTT0Tagging") + fmCRTHitT0TaggingInfo.emplace_back(PFParticleList, e, fT0producers[i_label]); + } + + // Track - associated data art::FindManyP fmTracks(PFParticleList, e, fTRKproducer); @@ -338,41 +360,58 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } } } - + bool hasT0 = false, hasPandoraT0 = false, hasCRTTrackT0 = false, hasCRTHitT0 = false; int whicht0 = -1; - float t0 = std::numeric_limits::signaling_NaN(); + double t0 = std::numeric_limits::signaling_NaN(); for (unsigned i_t0 = 0; i_t0 < fmT0.size(); i_t0++) { if (fmT0[i_t0].isValid() && fmT0[i_t0].at(p_pfp.key()).size()) { t0 = fmT0[i_t0].at(p_pfp.key()).at(0)->Time(); whicht0 = i_t0; - + hasPandoraT0 = true; if (fVerbose) std::cout << "Track: " << trkPtr->ID() << " Has T0 (" << fT0producers[i_t0] << ")\n"; - break; } } - - float t0CRT = std::numeric_limits::signaling_NaN(); + double t0CRTTrack = std::numeric_limits::signaling_NaN(); for (unsigned i_t0 = 0; i_t0 < fmT02.size(); i_t0++) { if (fmT02[i_t0].isValid()) { try { - t0CRT = fmT02[i_t0].data(trkPtr.key()).ref().Time(); + t0CRTTrack = fmT02[i_t0].data(trkPtr.key()).ref().Time(); whicht0 = i_t0; - - if (fVerbose) std::cout << "Track: " << trkPtr->ID() << " Has CRTT0 (" << fT0producers[crtLabel] << ")\n"; - } - catch(...) {} + hasCRTTrackT0 = true; + if (fVerbose) std::cout << "Track: " << trkPtr->ID() << " Has CRTT0 (" << fT0producers[crttrackLabel] << ")\n"; + } + catch(...) {} break; } } - if (fRequireT0 && whicht0 < 0) { - continue; + double t0CRTHit = std::numeric_limits::signaling_NaN(); + + if(fIncludeCRTHitTagging){ + for (unsigned i_t0 = 0; i_t0 < fmCRTHitT0Tagging.size(); i_t0++) { + if (fmCRTHitT0Tagging[i_t0].isValid() && fmCRTHitT0Tagging[i_t0].at(trkPtr.key()).size()) { + t0CRTHit = fmCRTHitT0Tagging[i_t0].at(trkPtr.key()).at(0)->Time(); + hasCRTHitT0 = true; + if (fVerbose) std::cout<<"This Track "<ID()<<" Has a CRTHitT0 "<ID() << " time: " << t0 << std::endl; - if (fVerbose) std::cout << "Processing new track! ID: " << trkPtr->ID() << " timeCRT: " << t0CRT << std::endl; + T0TimingInfo thisTrackTimingInfo = {t0, t0CRTTrack, t0CRTHit, hasPandoraT0, hasCRTTrackT0, hasCRTHitT0}; + hasT0 = hasPandoraT0 || hasCRTTrackT0 || hasCRTHitT0; + // "whicht0" should reflect the T0 used for the reconstruction of the drift coordinate. + if(!hasT0) whicht0 = -1 ; + // In this way, if a track is T0 tagged from Pandora and CRT tagged, which T0 reflects the Pandora Tag. + else if (hasPandoraT0) whicht0 = 0 ; + else if (hasCRTTrackT0) whicht0 = 1 ; + else if (hasCRTHitT0) whicht0 = 2 ; + + if (fRequireT0 && !hasT0) continue; + if (!fIncludeCRTHitTagging && whicht0==2) continue; + if (fVerbose) std::cout << "Processing new track! ID: " << trkPtr->ID() << " time: " << t0 << " timeCRTTrack: " << t0CRTTrack << " timeCRTHit "<whicht0 = whicht0; - FillTrackDaughterRays(*trkPtr, pfp, PFParticleList, PFParticleSPs); if (fFillTrackEndHits) FillTrackEndHits(geometry, wireReadout, dprop, *trkPtr, allHits, allHitSPs); @@ -395,16 +432,22 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) // Save? bool select = false; if (!fSelectionTools.size()) select = true; - // Take the OR of each selection tool int i_select = 0; for (const std::unique_ptr &t: fSelectionTools) { if (t->DoSelect(*fTrack)) { select = true; - if (!isnan(fTrack->t0CRT) && isnan(fTrack->t0)) - i_select = i_select + 10; - if (!isnan(fTrack->t0CRT) && !isnan(fTrack->t0)) + if (!isnan(fTrack->t0[1]) && isnan(fTrack->t0[0])) + i_select = i_select + 10; + if (!isnan(fTrack->t0[1]) && !isnan(fTrack->t0[0])) i_select = i_select + 100; + + // Note: if the order inside Selection Tools is swapped, also the selected condition + // will change meaning. Currently the order (e.g. ICARUS caloskim_cryow_nodigits_goldentracks) + // is stopping, anodetocathode, passing, so selected==0 are stopping, selected==1 are anode to + // cathode, selected==2 are passing. + // A more robust way should be using an enum for selected. + fTrack->selected = i_select; fTrack->nprescale = t->GetPrescale(); break; @@ -412,6 +455,36 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) i_select ++; } + bool crtHitSysRejected = false, crtHitDistanceRejected = false; + Vector3D PCADirFit; + PCADirFit.x = std::numeric_limits::signaling_NaN(); + PCADirFit.y = std::numeric_limits::signaling_NaN(); + PCADirFit.z = std::numeric_limits::signaling_NaN(); + // If CRTHitTagged are considered, and the CRTT0 is used for this track + if(fIncludeCRTHitTagging && whicht0 ==2){ + for (unsigned i_t0 = 0; i_t0 < fmCRTHitT0TaggingInfo.size(); i_t0++) { + if (fmCRTHitT0TaggingInfo[i_t0].isValid() && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).size()) { + // Reject tracks matched with Top or Side CRTs if requested + if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==0 && !fIncludeTopCRT) crtHitSysRejected = true; + if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==1 && !fIncludeSideCRT) crtHitSysRejected = true; + // Reject tracks matched with CRTs, but the distance is greater than acceptable cuts. + // Cuts are different for Top and Side CRTs, also, cuts are different for stopping or passing particles. + if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==0 && (fTrack->selected == 2 || fTrack->selected == 1) && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fTopCRTDistanceCutPassing) crtHitDistanceRejected = true; + if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==0 && fTrack->selected == 0 && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fTopCRTDistanceCutStopping) crtHitDistanceRejected = true; + if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==1 && (fTrack->selected == 2 || fTrack->selected == 1) && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fSideCRTDistanceCutPassing) crtHitDistanceRejected = true; + if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==1 && fTrack->selected == 0 && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fSideCRTDistanceCutStopping) crtHitDistanceRejected = true; + // Fill PCA track direction information + PCADirFit.x = fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->PCAEigenVector.X(); + PCADirFit.y = fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->PCAEigenVector.Y(); + PCADirFit.z = fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->PCAEigenVector.Z(); + + break; + } + } + } + fTrack->PCAdir = PCADirFit; + if (fIncludeCRTHitTagging && whicht0==2 && crtHitSysRejected) continue; + if(crtHitDistanceRejected) continue; // Save! if (select) { if (fVerbose) std::cout << "Track Selected! By tool: " << i_select << std::endl; @@ -800,12 +873,10 @@ sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, TVector3 loc_mdx_v = h_p - direction * (planeGeo.WirePitch() / 2.); TVector3 loc_pdx_v = h_p + direction * (planeGeo.WirePitch() / 2.); - // Convert types for helper functions geo::Point_t loc_mdx(loc_mdx_v.X(), loc_mdx_v.Y(), loc_mdx_v.Z()); geo::Point_t loc_pdx(loc_pdx_v.X(), loc_pdx_v.Y(), loc_pdx_v.Z()); geo::Point_t h_p_point(h_p.X(), h_p.Y(), h_p.Z()); - auto const driftdir = geo->TPC(plane).DriftDir(); loc_mdx = TrajectoryToWirePosition(loc_mdx, driftdir); loc_pdx = TrajectoryToWirePosition(loc_pdx, driftdir); @@ -1062,13 +1133,14 @@ void sbn::TrackCaloSkimmer::FillTrackDaughterRays(const recob::Track &trk, } void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, - const recob::PFParticle &pfp, float t0, float t0CRT, + const recob::PFParticle &pfp, const T0TimingInfo &t0Info, const std::vector> &hits, const std::vector &thms, const std::vector> &sps, const std::vector> &calo, const std::map> &rawdigits, const std::vector &tracks, + const geo::GeometryCore *geo, const geo::WireReadoutGeom *wireReadout, const detinfo::DetectorClocksData &clock_data, const cheat::BackTrackerService *bt_serv, @@ -1077,8 +1149,10 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, // Fill top level stuff fTrack->meta = fMeta; - fTrack->t0 = t0; - fTrack->t0CRT = t0CRT; + fTrack->t0.clear(); + fTrack->t0.push_back(t0Info.t0Pandora); + fTrack->t0.push_back(t0Info.t0CRTTrack); + fTrack->t0.push_back(t0Info.t0CRTHit); fTrack->id = track.ID(); fTrack->clear_cosmic_muon = pfp.Parent() == recob::PFParticle::kPFParticlePrimary; @@ -1089,18 +1163,27 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, fTrack->end.z = track.End().Z(); fTrack->dir.x = track.StartDirection().X(); fTrack->dir.y = track.StartDirection().Y(); - fTrack->dir.z = track.StartDirection().Z(); - + fTrack->dir.z = track.StartDirection().Z(); //If track is only CRTt0 tagged, undo the assumed trigger correction - if (!isnan(fTrack->t0)) { + if (t0Info.hasT0Pandora) { fTrack->start.x = track.Start().X(); fTrack->end.x = track.End().X(); - } - else if (isnan(fTrack->t0) && !isnan(fTrack->t0CRT)) { + } else if (!t0Info.hasT0Pandora && t0Info.hasT0CRTTrack) { const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); - - fTrack->start.x = track.Start().X() + driftv*t0CRT*1e-3; - fTrack->end.x = track.End().X() + driftv*t0CRT*1e-3; + // Comment from Francesco: I am not sure of the below formula. + // SBND has two TPCs with a common cathode like ICARUS, the driftvelocity + // returns the absolute value, but the displacement (basically the + below) + // depends on the TPC, in one case is + and in the other is negative. + // In this way the displacement is always in the same direction, working for + // one TPC, but not for the other. + fTrack->start.x = track.Start().X() + driftv*t0Info.t0CRTTrack*1e-3; + fTrack->end.x = track.End().X() + driftv*t0Info.t0CRTTrack*1e-3; + } else if (!t0Info.hasT0Pandora && t0Info.hasT0CRTHit){ + // If the track does not have a a Pandora T0, the tracks will always be either on the left or (ex Or) right of the cathode. + int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); + const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); + fTrack->start.x = track.Start().X() + driftDir*driftv*t0Info.t0CRTHit*1e-3; + fTrack->end.x = track.End().X() + driftDir*driftv*t0Info.t0CRTHit*1e-3; } if (hits.size() > 0) { @@ -1109,7 +1192,7 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, // Fill each hit for (unsigned i_hit = 0; i_hit < hits.size(); i_hit++) { - sbn::TrackHitInfo hinfo = MakeHit(*hits[i_hit], hits[i_hit].key(), *thms[i_hit], track, sps[i_hit], calo, wireReadout, clock_data, bt_serv); + sbn::TrackHitInfo hinfo = MakeHit(*hits[i_hit], hits[i_hit].key(), *thms[i_hit], track, t0Info, sps[i_hit], calo, geo, wireReadout, clock_data, bt_serv, dprop); if (hinfo.h.plane == 0) { fTrack->hits0.push_back(hinfo); } @@ -1269,11 +1352,14 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, unsigned hkey, const recob::TrackHitMeta &thm, const recob::Track &trk, + const T0TimingInfo &t0Info, const art::Ptr &sp, const std::vector> &calo, + const geo::GeometryCore *geo, const geo::WireReadoutGeom *wireReadout, const detinfo::DetectorClocksData &dclock, - const cheat::BackTrackerService *bt_serv) { + const cheat::BackTrackerService *bt_serv, + const detinfo::DetectorPropertiesData &dprop) { // TrackHitInfo to save sbn::TrackHitInfo hinfo; @@ -1347,6 +1433,13 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, } } + // This is needed to reconstrut drift coordinate using a different Time + int driftDir = geo->TPC(hit.WireID()).DriftDir().X(); + const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); + double anodeDistance = std::numeric_limits::signaling_NaN(); + if(t0Info.hasT0CRTHit) anodeDistance = (hit.PeakTime()-dclock.Time2Tick(dclock.TriggerTime())-t0Info.t0CRTHit*1e-3/dclock.TPCClock().TickPeriod())*dclock.TPCClock().TickPeriod()*driftv; + double wirePlaneX = wireReadout->Plane(geo::PlaneID(hit.WireID().Cryostat, hit.WireID().TPC, hit.WireID().Plane)).GetCenter().X(); + double recoX = wirePlaneX - driftDir*anodeDistance; // Information from the TrackHitMeta bool badhit = (thm.Index() == std::numeric_limits::max()) || (!trk.HasValidPoint(thm.Index())); @@ -1356,7 +1449,10 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, // Save trajectory information if we can if (!badhit) { geo::Point_t loc = trk.LocationAtPoint(thm.Index()); + + // The tp X coordinate is reconstructed only if it does not have a PandoraT0. hinfo.tp.x = loc.X(); + if(t0Info.hasT0CRTHit && !t0Info.hasT0Pandora && !isnan(hinfo.tp.x)) hinfo.tp.x = recoX; hinfo.tp.y = loc.Y(); hinfo.tp.z = loc.Z(); @@ -1387,15 +1483,15 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, // Save SpacePoint information if (sp) { hinfo.h.sp.x = sp->position().x(); + // If the track has a Pandora T0, do not displace, track is already reconstructed at the correct position + if(t0Info.hasT0CRTHit && !t0Info.hasT0Pandora) hinfo.h.sp.x = sp->position().x() + driftDir*driftv*t0Info.t0CRTHit*1e-3; hinfo.h.sp.y = sp->position().y(); hinfo.h.sp.z = sp->position().z(); - hinfo.h.hasSP = true; } else { hinfo.h.hasSP = false; } - return hinfo; } diff --git a/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl index 4953e8823..7fc940ced 100644 --- a/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl @@ -114,6 +114,32 @@ selectall: { RequireT0: false } +# Include also crthittagged tracks +caloskim_crthittagging_cryoe: @local::caloskim_cryoe +caloskim_crthittagging_cryoe.IncludeCRTHitTagging: true +caloskim_crthittagging_cryoe.IncludeTopCRT: true +caloskim_crthittagging_cryoe.IncludeSideCRT: false +caloskim_crthittagging_cryoe.TopCRTDistanceCut_stopping: 100. +caloskim_crthittagging_cryoe.TopCRTDistanceCut_throughgoing: 100. +caloskim_crthittagging_cryoe.SideCRTDistanceCut_stopping: 100. +caloskim_crthittagging_cryoe.SideCRTDistanceCut_throughgoing: 100. + + +caloskim_crthittagging_cryow: @local::caloskim_cryow +caloskim_crthittagging_cryow.IncludeCRTHitTagging: true +caloskim_crthittagging_cryow.IncludeTopCRT: true +caloskim_crthittagging_cryow.IncludeSideCRT: false +caloskim_crthittagging_cryow.TopCRTDistanceCut_stopping: 60. +caloskim_crthittagging_cryow.TopCRTDistanceCut_throughgoing: 50. +caloskim_crthittagging_cryow.SideCRTDistanceCut_stopping: 100. +caloskim_crthittagging_cryow.SideCRTDistanceCut_throughgoing: 100. + +crthittagged_stopping_selection: @local::stopping_selection +crthittagged_stopping_selection.AllowT0: [true, false, true] + +crthittagged_throughgoing_selection: @local::throughgoing_selection +crthittagged_throughgoing_selection.AllowT0: [true, false, true] + # Require T0 tag, don't save raw waveforms, caloskim_cryow_nodigits_goldentracks: @local::caloskim_cryow_nodigits caloskim_cryow_nodigits_goldentracks.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection] @@ -142,4 +168,10 @@ caloskim_cryoe_nodigits_goldentracks_not0: @local::caloskim_cryoe_nodigits caloskim_cryoe_nodigits_goldentracks_not0.RequireT0: false caloskim_cryoe_nodigits_goldentracks_not0.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection, @local::selectall] -END_PROLOG +# Require T0 tag, allow Top CRT Hit tagging, do save raw waveforms +caloskim_cryow_crthittagged_goldentracks: @local::caloskim_crthittagging_cryow +caloskim_cryow_crthittagged_goldentracks.SelectionTools: [@local::crthittagged_stopping_selection, @local::a2c_selection, @local::crthittagged_throughgoing_selection] +caloskim_cryoe_crthittagged_goldentracks: @local::caloskim_crthittagging_cryoe +caloskim_cryoe_crthittagged_goldentracks.SelectionTools: [@local::crthittagged_stopping_selection, @local::a2c_selection, @local::crthittagged_throughgoing_selection] + +END_PROLOG \ No newline at end of file From 5c2a3f5ebc20ea0c35911be8d1f1d8c7241a8b5a Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Tue, 11 Mar 2025 19:05:41 -0500 Subject: [PATCH 044/367] Update MergeSimSourceSBN to new interface. --- sbncode/LArG4/MergeSimSourcesSBN_module.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sbncode/LArG4/MergeSimSourcesSBN_module.cc b/sbncode/LArG4/MergeSimSourcesSBN_module.cc index da84303a7..ee4967227 100644 --- a/sbncode/LArG4/MergeSimSourcesSBN_module.cc +++ b/sbncode/LArG4/MergeSimSourcesSBN_module.cc @@ -119,6 +119,12 @@ class sbn::MergeSimSourcesSBN : public art::EDProducer { false // default }; + fhicl::Atom SkipTrackIDOffsets { + fhicl::Name{"SkipTrackIDOffsets"}, + fhicl::Comment{"whether to skip track ID offsets in merge"}, + false // default + }; + fhicl::Sequence AuxDetHitsInstanceLabels{ fhicl::Name{"AuxDetHitsInstanceLabels"}, fhicl::Comment{"labels of AuxDetHits collections to merge"}, @@ -158,6 +164,7 @@ class sbn::MergeSimSourcesSBN : public art::EDProducer { bool const fFillSimChannels; bool const fFillAuxDetSimChannels; bool const fFillSimEnergyDeposits; + bool const fSkipTrackIDOffsets; std::vector const fEnergyDepositionInstances; bool const fFillAuxDetHits; std::vector const fAuxDetHitsInstanceLabels; @@ -202,6 +209,7 @@ sbn::MergeSimSourcesSBN::MergeSimSourcesSBN(Parameters const& params) , fFillSimEnergyDeposits( getOptionalValue(params().FillSimEnergyDeposits) .value_or(art::ServiceHandle()->FillSimEnergyDeposits())) + , fSkipTrackIDOffsets(params().SkipTrackIDOffsets()) , fEnergyDepositionInstances(params().EnergyDepositInstanceLabels()) , fFillAuxDetHits(params().FillAuxDetHits()) , fAuxDetHitsInstanceLabels(params().AuxDetHitsInstanceLabels()) @@ -349,7 +357,7 @@ void sbn::MergeSimSourcesSBN::produce(art::Event& e) if (fFillSimChannels) { auto const& input_scCol = e.getProduct>(input_label); - MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source); + MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source, fSkipTrackIDOffsets); } if (fFillAuxDetSimChannels) { From d46b410642a5bbbbda485b4809783cac02488c71 Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Wed, 12 Mar 2025 13:54:27 -0500 Subject: [PATCH 045/367] Refactor T0 producers. Put each T0 origin into its own variable. Factorize CRT hit information filling code. --- sbncode/Calibration/TrackCaloSkimmer.h | 7 +- .../Calibration/TrackCaloSkimmer_module.cc | 196 ++++++++---------- .../fcl/icarus/icarus_trackcalo_skimmer.fcl | 6 +- .../fcl/sbnd/sbnd_trackcalo_skimmer.fcl | 2 +- 4 files changed, 93 insertions(+), 118 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index 6c96f6417..c35f9ecd5 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -179,14 +179,19 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { const detinfo::DetectorClocksData &dclock, const cheat::BackTrackerService *bt_serv, const detinfo::DetectorPropertiesData &dprop); + void FillTrackCRTHitInfo(const std::vector> &tag); + // helpers void DoTailFit(); + bool PointIsContained(const std::vector &vols, geo::Point_t p); // config // tags art::InputTag fPFPproducer; - std::vector fT0producers; + art::InputTag fPFPT0producer; + art::InputTag fCRTTrackT0producer; + art::InputTag fCRTHitT0producer; art::InputTag fCALOproducer; art::InputTag fTRKproducer; art::InputTag fTRKHMproducer; diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index b38fa393b..8b424aed7 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -68,7 +68,10 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) { // Grab config fPFPproducer = p.get< art::InputTag > ("PFPproducer","pandoraGausCryo0"); - fT0producers = p.get< std::vector > ("T0producers", {"pandoraGausCryo0"} ); + fPFPT0producer = p.get< art::InputTag > ("PFPT0producer", "pandoraGausCryo0"); + fCRTTrackT0producer = p.get< art::InputTag >("CRTTrackT0producer", "crttrackmatching"); + fCRTHitT0producer = p.get< art::InputTag >("CRTHitT0producer", "CRTT0Tagging"); + fCALOproducer = p.get< art::InputTag > ("CALOproducer"); fTRKproducer = p.get< art::InputTag > ("TRKproducer" ); fTRKHMproducer= p.get< art::InputTag > ("TRKHMproducer", ""); @@ -103,6 +106,7 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) for (const fhicl::ParameterSet &p: selection_tool_configs) { fSelectionTools.push_back(art::make_tool(p)); } + // Setup meta info fMeta.iproc = -1; fMeta.ifile = -1; @@ -217,41 +221,20 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } // PFP-associated data - std::vector> fmT0; - for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { - if ((fT0producers[i_label] != "crttrackmatching") && - (fT0producers[i_label] != "CRTT0Tagging")) - fmT0.emplace_back(PFParticleList, e, fT0producers[i_label]); - } + art::FindManyP fmT0PFP(PFParticleList, e, fPFPT0producer); art::FindManyP PFParticleSPs(PFParticleList, e, fPFPproducer); // Now we don't need to guard access to further data. If this is an empty event it should be caught by PFP's or Hit's art::ValidHandle> tracks = e.getValidHandle>(fTRKproducer); - std::vector> fmT02; - float crttrackLabel = std::numeric_limits::signaling_NaN(); - for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { - if (fT0producers[i_label] == "crttrackmatching"){ - crttrackLabel = i_label; - fmT02.emplace_back(tracks, e, fT0producers[i_label]); - } - } - - std::vector> fmCRTHitT0Tagging; - for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { - if (fT0producers[i_label] == "CRTT0Tagging"){ - - fmCRTHitT0Tagging.emplace_back(tracks, e, fT0producers[i_label]); - } - } - - // Recover information on the CRTHitT0TaggingInfo - std::vector> fmCRTHitT0TaggingInfo; - for (unsigned i_label = 0; i_label < fT0producers.size(); i_label++) { - if (fT0producers[i_label] == "CRTT0Tagging") - fmCRTHitT0TaggingInfo.emplace_back(PFParticleList, e, fT0producers[i_label]); - } + // Get CRT T0s + // + // Tracks (SBND style) + art::FindManyP fmT0CRTTrack(tracks, e, fCRTTrackT0producer); + // Hits (ICARUS style) + art::FindManyP fmT0CRTHit(tracks, e, fCRTHitT0producer); + art::FindManyP fmCRTHitT0TaggingInfo(PFParticleList, e, fCRTHitT0producer); // Track - associated data art::FindManyP fmTracks(PFParticleList, e, fTRKproducer); @@ -360,58 +343,64 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } } } - bool hasT0 = false, hasPandoraT0 = false, hasCRTTrackT0 = false, hasCRTHitT0 = false; + + // Collect T0s + bool hasT0 = false, hasPFPT0 = false, hasCRTTrackT0 = false, hasCRTHitT0 = false; int whicht0 = -1; - double t0 = std::numeric_limits::signaling_NaN(); - for (unsigned i_t0 = 0; i_t0 < fmT0.size(); i_t0++) { - if (fmT0[i_t0].isValid() && fmT0[i_t0].at(p_pfp.key()).size()) { - t0 = fmT0[i_t0].at(p_pfp.key()).at(0)->Time(); - whicht0 = i_t0; - hasPandoraT0 = true; - if (fVerbose) std::cout << "Track: " << trkPtr->ID() << " Has T0 (" << fT0producers[i_t0] << ")\n"; - break; - } + + double t0PFP = std::numeric_limits::signaling_NaN(); + if (fmT0PFP.isValid() && fmT0PFP.at(p_pfp.key()).size()) { + t0PFP = fmT0PFP.at(p_pfp.key()).at(0)->Time(); + hasPFPT0 = true; + if (fVerbose) std::cout << "Track: " << trkPtr->ID() << " Has PFPT0 (" << fPFPT0producer << ")\n"; } + double t0CRTTrack = std::numeric_limits::signaling_NaN(); - for (unsigned i_t0 = 0; i_t0 < fmT02.size(); i_t0++) { - if (fmT02[i_t0].isValid()) { - try { - t0CRTTrack = fmT02[i_t0].data(trkPtr.key()).ref().Time(); - whicht0 = i_t0; - hasCRTTrackT0 = true; - if (fVerbose) std::cout << "Track: " << trkPtr->ID() << " Has CRTT0 (" << fT0producers[crttrackLabel] << ")\n"; - } - catch(...) {} - break; - } + if (fmT0CRTTrack.isValid() && fmT0CRTTrack.at(trkPtr.key()).size()) { + t0CRTTrack = fmT0CRTTrack.data(trkPtr.key()).at(0)->Time(); + hasCRTTrackT0 = true; } double t0CRTHit = std::numeric_limits::signaling_NaN(); - - if(fIncludeCRTHitTagging){ - for (unsigned i_t0 = 0; i_t0 < fmCRTHitT0Tagging.size(); i_t0++) { - if (fmCRTHitT0Tagging[i_t0].isValid() && fmCRTHitT0Tagging[i_t0].at(trkPtr.key()).size()) { - t0CRTHit = fmCRTHitT0Tagging[i_t0].at(trkPtr.key()).at(0)->Time(); - hasCRTHitT0 = true; - if (fVerbose) std::cout<<"This Track "<ID()<<" Has a CRTHitT0 "<Time(); + + // Whether to select the wall of the hit + bool crtHitSysRejected = (tag.Sys == 0 && !fIncludeTopCRT) || (tag.Sys==1 && !fIncludeSideCRT); + + // Whether to cut on the distance (depends on whether track is stopping) + geo::Point_t end {trkPtr->Start().X(), trkPtr->Start().Y(), trkPtr->Start().Z()}; + if (!hasPFPT0 && trkHits.size()) { // correct X position if we need to + int driftDir = geometry->TPC(trkHits.at(0)->WireID()).DriftDir().X(); + double driftv = dprop.DriftVelocity(); + end.SetX(end.X() + time*driftDir*driftv*1e-3); + } + bool trackIsStopping = PointIsContained(AVs, end); + + bool crtHitDistanceRejected = trackIsStopping ? + ((tag.Sys == 0) ? (tag.Distance > fTopCRTDistanceCutStopping) : (tag.Distance > fSideCRTDistanceCutStopping)) : + ((tag.Sys == 0) ? (tag.Distance > fTopCRTDistanceCutPassing) : (tag.Distance > fSideCRTDistanceCutPassing)); + + if (!crtHitSysRejected && !crtHitDistanceRejected) { + t0CRTHit = time; + hasCRTHitT0 = true; } } - T0TimingInfo thisTrackTimingInfo = {t0, t0CRTTrack, t0CRTHit, hasPandoraT0, hasCRTTrackT0, hasCRTHitT0}; - hasT0 = hasPandoraT0 || hasCRTTrackT0 || hasCRTHitT0; + T0TimingInfo thisTrackTimingInfo = {t0PFP, t0CRTTrack, t0CRTHit, hasPFPT0, hasCRTTrackT0, hasCRTHitT0}; + hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0; + // "whicht0" should reflect the T0 used for the reconstruction of the drift coordinate. if(!hasT0) whicht0 = -1 ; - // In this way, if a track is T0 tagged from Pandora and CRT tagged, which T0 reflects the Pandora Tag. - else if (hasPandoraT0) whicht0 = 0 ; + // In this way, if a track is T0 tagged from PFP and CRT tagged, which T0 reflects the PFP Tag. + else if (hasPFPT0) whicht0 = 0 ; else if (hasCRTTrackT0) whicht0 = 1 ; else if (hasCRTHitT0) whicht0 = 2 ; if (fRequireT0 && !hasT0) continue; - if (!fIncludeCRTHitTagging && whicht0==2) continue; - if (fVerbose) std::cout << "Processing new track! ID: " << trkPtr->ID() << " time: " << t0 << " timeCRTTrack: " << t0CRTTrack << " timeCRTHit "<ID() << " time: " << t0PFP << " timeCRTTrack: " << t0CRTTrack << " timeCRTHit "< &t: fSelectionTools) { if (t->DoSelect(*fTrack)) { select = true; - if (!isnan(fTrack->t0[1]) && isnan(fTrack->t0[0])) - i_select = i_select + 10; - if (!isnan(fTrack->t0[1]) && !isnan(fTrack->t0[0])) - i_select = i_select + 100; - - // Note: if the order inside Selection Tools is swapped, also the selected condition - // will change meaning. Currently the order (e.g. ICARUS caloskim_cryow_nodigits_goldentracks) - // is stopping, anodetocathode, passing, so selected==0 are stopping, selected==1 are anode to - // cathode, selected==2 are passing. - // A more robust way should be using an enum for selected. - fTrack->selected = i_select; fTrack->nprescale = t->GetPrescale(); break; @@ -455,36 +436,6 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) i_select ++; } - bool crtHitSysRejected = false, crtHitDistanceRejected = false; - Vector3D PCADirFit; - PCADirFit.x = std::numeric_limits::signaling_NaN(); - PCADirFit.y = std::numeric_limits::signaling_NaN(); - PCADirFit.z = std::numeric_limits::signaling_NaN(); - // If CRTHitTagged are considered, and the CRTT0 is used for this track - if(fIncludeCRTHitTagging && whicht0 ==2){ - for (unsigned i_t0 = 0; i_t0 < fmCRTHitT0TaggingInfo.size(); i_t0++) { - if (fmCRTHitT0TaggingInfo[i_t0].isValid() && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).size()) { - // Reject tracks matched with Top or Side CRTs if requested - if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==0 && !fIncludeTopCRT) crtHitSysRejected = true; - if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==1 && !fIncludeSideCRT) crtHitSysRejected = true; - // Reject tracks matched with CRTs, but the distance is greater than acceptable cuts. - // Cuts are different for Top and Side CRTs, also, cuts are different for stopping or passing particles. - if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==0 && (fTrack->selected == 2 || fTrack->selected == 1) && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fTopCRTDistanceCutPassing) crtHitDistanceRejected = true; - if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==0 && fTrack->selected == 0 && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fTopCRTDistanceCutStopping) crtHitDistanceRejected = true; - if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==1 && (fTrack->selected == 2 || fTrack->selected == 1) && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fSideCRTDistanceCutPassing) crtHitDistanceRejected = true; - if(fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Sys==1 && fTrack->selected == 0 && fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->Distance > fSideCRTDistanceCutStopping) crtHitDistanceRejected = true; - // Fill PCA track direction information - PCADirFit.x = fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->PCAEigenVector.X(); - PCADirFit.y = fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->PCAEigenVector.Y(); - PCADirFit.z = fmCRTHitT0TaggingInfo[i_t0].at(trkPtr.key()).at(0)->PCAEigenVector.Z(); - - break; - } - } - } - fTrack->PCAdir = PCADirFit; - if (fIncludeCRTHitTagging && whicht0==2 && crtHitSysRejected) continue; - if(crtHitDistanceRejected) continue; // Save! if (select) { if (fVerbose) std::cout << "Track Selected! By tool: " << i_select << std::endl; @@ -1132,6 +1083,26 @@ void sbn::TrackCaloSkimmer::FillTrackDaughterRays(const recob::Track &trk, } +bool sbn::TrackCaloSkimmer::PointIsContained(const std::vector &vols, geo::Point_t p) { + for (auto const &v: vols) { + if (v.ContainsPosition(p)) return true; + } + return false; +} + +void sbn::TrackCaloSkimmer::FillTrackCRTHitInfo(const std::vector> &tag) { + fTrack->PCAdir.x = std::numeric_limits::signaling_NaN(); + fTrack->PCAdir.y = std::numeric_limits::signaling_NaN(); + fTrack->PCAdir.z = std::numeric_limits::signaling_NaN(); + + if (!tag.size()) return; + + const sbn::crt::CRTHitT0TaggingInfo &t = *tag.at(0); + fTrack->PCAdir.x = t.PCAEigenVector.X(); + fTrack->PCAdir.y = t.PCAEigenVector.Y(); + fTrack->PCAdir.z = t.PCAEigenVector.Z(); +} + void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, const recob::PFParticle &pfp, const T0TimingInfo &t0Info, const std::vector> &hits, @@ -1149,10 +1120,9 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, // Fill top level stuff fTrack->meta = fMeta; - fTrack->t0.clear(); - fTrack->t0.push_back(t0Info.t0Pandora); - fTrack->t0.push_back(t0Info.t0CRTTrack); - fTrack->t0.push_back(t0Info.t0CRTHit); + fTrack->t0PFP = t0Info.t0Pandora; + fTrack->t0CRTTrack = t0Info.t0CRTTrack; + fTrack->t0CRTHit = t0Info.t0CRTHit; fTrack->id = track.ID(); fTrack->clear_cosmic_muon = pfp.Parent() == recob::PFParticle::kPFParticlePrimary; @@ -1168,7 +1138,7 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, if (t0Info.hasT0Pandora) { fTrack->start.x = track.Start().X(); fTrack->end.x = track.End().X(); - } else if (!t0Info.hasT0Pandora && t0Info.hasT0CRTTrack) { + } else if (t0Info.hasT0CRTTrack) { const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); // Comment from Francesco: I am not sure of the below formula. // SBND has two TPCs with a common cathode like ICARUS, the driftvelocity @@ -1178,7 +1148,7 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, // one TPC, but not for the other. fTrack->start.x = track.Start().X() + driftv*t0Info.t0CRTTrack*1e-3; fTrack->end.x = track.End().X() + driftv*t0Info.t0CRTTrack*1e-3; - } else if (!t0Info.hasT0Pandora && t0Info.hasT0CRTHit){ + } else if (t0Info.hasT0CRTHit){ // If the track does not have a a Pandora T0, the tracks will always be either on the left or (ex Or) right of the cathode. int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); diff --git a/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl index 7fc940ced..6f6c5fe65 100644 --- a/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/icarus/icarus_trackcalo_skimmer.fcl @@ -26,7 +26,7 @@ caloskim_cryoe: { module_type: TrackCaloSkimmer CALOproducer: "caloskimCalorimetryCryoE" TRKproducer: "pandoraTrackGausCryoE" - T0producers: ["pandoraGausCryoE"] + PFPT0producer: "pandoraGausCryoE" PFPproducer: "pandoraGausCryoE" G4producer: "" SimChannelproducer: "" @@ -43,7 +43,7 @@ caloskim_cryow: { module_type: TrackCaloSkimmer CALOproducer: "caloskimCalorimetryCryoW" TRKproducer: "pandoraTrackGausCryoW" - T0producers: ["pandoraGausCryoW"] + PFPT0producer: "pandoraGausCryoW" PFPproducer: "pandoraGausCryoW" G4producer: "" SimChannelproducer: "" @@ -174,4 +174,4 @@ caloskim_cryow_crthittagged_goldentracks.SelectionTools: [@local::crthittagged_s caloskim_cryoe_crthittagged_goldentracks: @local::caloskim_crthittagging_cryoe caloskim_cryoe_crthittagged_goldentracks.SelectionTools: [@local::crthittagged_stopping_selection, @local::a2c_selection, @local::crthittagged_throughgoing_selection] -END_PROLOG \ No newline at end of file +END_PROLOG diff --git a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl index ea73bdd9b..8735ed405 100644 --- a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl @@ -27,7 +27,7 @@ caloskim: { module_type: TrackCaloSkimmer CALOproducer: "caloskimCalorimetry" TRKproducer: "pandoraTrack" - T0producers: ["pandora", "crttrackmatching"] + PFPT0producer: "pandora" PFPproducer: "pandora" G4producer: "largeant" SimChannelproducer: "simtpc2d:simpleSC" From 735905a07807627c8a089e8b1e401e89bc36f6f6 Mon Sep 17 00:00:00 2001 From: Tingjun Yang Date: Fri, 14 Mar 2025 11:30:42 -0500 Subject: [PATCH 046/367] Make sure string is not empty before adding it to metadata. --- sbncode/Metadata/FileCatalogMetadataSBN_service.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sbncode/Metadata/FileCatalogMetadataSBN_service.cc b/sbncode/Metadata/FileCatalogMetadataSBN_service.cc index d16ce8b42..97ed33d73 100644 --- a/sbncode/Metadata/FileCatalogMetadataSBN_service.cc +++ b/sbncode/Metadata/FileCatalogMetadataSBN_service.cc @@ -61,13 +61,13 @@ void util::FileCatalogMetadataSBN::postBeginJob() // Add metadata. - mds->addMetadata("fcl.name", fFCLName); - mds->addMetadata(fExperiment + "_project.name", fProjectName); - mds->addMetadata(fExperiment + "_project.stage", fProjectStage); - mds->addMetadata(fExperiment + "_project.version", fProjectVersion); - mds->addMetadata(fExperiment + "_project.software", fProjectSoftware); - mds->addMetadata("production.name", fProductionName); - mds->addMetadata("production.type", fProductionType); + if (!fFCLName.empty()) mds->addMetadata("fcl.name", fFCLName); + if (!fProjectName.empty()) mds->addMetadata(fExperiment + "_project.name", fProjectName); + if (!fProjectStage.empty()) mds->addMetadata(fExperiment + "_project.stage", fProjectStage); + if (!fProjectVersion.empty()) mds->addMetadata(fExperiment + "_project.version", fProjectVersion); + if (!fProjectSoftware.empty()) mds->addMetadata(fExperiment + "_project.software", fProjectSoftware); + if (!fProductionName.empty()) mds->addMetadata("production.name", fProductionName); + if (!fProductionType.empty()) mds->addMetadata("production.type", fProductionType); std::ostringstream ostr; if(fMerge >= 0) { if(fMerge > 0) From f1a7e632bfabb43aca5f2b4a717bcefb248a2e23 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Tue, 18 Mar 2025 13:30:25 -0500 Subject: [PATCH 047/367] remove newly-duplicate code in icarus --- .../ICARUSBNBRetriever/CMakeLists.txt | 26 +- .../ICARUSBNBRetriever_module.cc | 302 +----------------- .../ICARUSBNBRetriever/MWRData.cpp | 71 ---- .../ICARUSBNBRetriever/MWRData.h | 39 --- sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h | 2 + 5 files changed, 17 insertions(+), 423 deletions(-) delete mode 100644 sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp delete mode 100644 sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.h diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt index 2668311a3..a9379d867 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt @@ -1,34 +1,12 @@ find_package(ifbeam) find_package(ifdh_art) - -art_make_library(LIBRARIES Boost::system - LIBRARY_NAME sbn_ICARUSBNBSpillInfoRetriever_MWRData - SOURCE MWRData.cpp -) - - cet_build_plugin(ICARUSBNBRetriever art::module LIBRARIES - art::Persistency_Common - art::Utilities canvas::canvas - cetlib::cetlib cetlib_except::cetlib_except - ROOT::X3d - Boost::system - messagefacility::MF_MessageLogger - ifbeam::ifbeam - ifdh_art::IFBeam_service - SQLite::SQLite3 - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_Common - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays - sbndaq_artdaq_core::sbndaq-artdaq-core_Overlays_ICARUS - artdaq_core::artdaq-core_Utilities - sbn_ICARUSBNBSpillInfoRetriever_MWRData - sbnobj::Common_POTAccounting - larcorealg::CoreUtils + sbn_SBNDPOTTools + SQLite::SQLite3 ) install_headers() install_fhicl() install_source() - diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index 86e6f9d34..6be19dc1b 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -10,33 +10,12 @@ */ #include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -#include "canvas/Utilities/InputTag.h" -#include "fhiclcpp/types/Atom.h" #include "messagefacility/MessageLogger/MessageLogger.h" -#include "larcorealg/CoreUtils/counter.h" - -#include "artdaq-core/Data/Fragment.hh" -#include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV3Fragment.hh" -#include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" - #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" - -#include "ifdh_art/IFBeamService/IFBeam_service.h" -#include "ifbeam_c.h" -#include "MWRData.h" - -#include -#include -#include - +#include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" +#include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" +#include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV3Fragment.hh" #include -#include -#include namespace sbn { class ICARUSBNBRetriever; @@ -55,7 +34,13 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { Comment{ "extension to the time window considered when collecting spills [seconds]" }, 0.0333 // default }; - + + fhicl::Atom BESOffset { + Name{ "BESOffset" }, + Comment{ "Offset between beam early warning signal and $1D [seconds]" }, + 0.036 // default + }; + fhicl::Atom RawDataLabel { Name{ "raw_data_label" }, Comment{ "art data product instance name for trigger information (product label is 'daq')" } @@ -138,32 +123,10 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { sqlite3 *db; int rc; - struct TriggerInfo_t { - int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI - double t_current_event = 0; - double t_previous_event = 0; - unsigned int number_of_gates_since_previous_event = 0; // FIXME needs to be integral type - std::int64_t WR_to_Spill_conversion = 0; - }; - - struct MWRdata_t { - std::vector< std::vector > MWR_times; - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - }; - - static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] /// Returns the information of the trigger in the current event. TriggerInfo_t extractTriggerInfo(art::Event const& e) const; - - /** - * @brief Determines spill times and extracts data based on multiwire devices. - * @param triggerInfo information from the trigger of this event - * @return times and unpacked data, per device (`"M875BB"`, `"M876BB"`, `"MMBTBB"`) - */ - MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo) const; - /** * @brief Matches spill times with multiwire chamber data from the database. * @param eventID ID of the event the information is associated to @@ -180,17 +143,6 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { std::vector< sbn::BNBSpillInfo >& beamInfos ) const; - /** - * @brief Assembles and returns a spill information record. - * @param eventID ID of the event the information is associated to - * @param time time of the spill - * @param MWRdata all extracted data from multiwire chambers - * @param matched_MWR data from multiwire chambers matched with the time - * @return a `sbn::BNBSpillInfo` object with information on the spill at `time` - */ - sbn::BNBSpillInfo makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const; - /** * @brief SQLite callback function for retrieving trigger_type from a query. * @param data Pointer to the integer where the trigger type will be stored. @@ -323,14 +275,10 @@ void sbn::ICARUSBNBRetriever::produce(art::Event& e) // Keep track of the number of beam gates the DAQ thinks // are in this job TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - - - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo); - + MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); - if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) mf::LogDebug("ICARUSBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; else @@ -339,7 +287,7 @@ void sbn::ICARUSBNBRetriever::produce(art::Event& e) }//end iteration over art::Events -sbn::ICARUSBNBRetriever::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& e) const { +sbn::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& e) const { //Here we read in the artdaq Fragments and extract three pieces of information: // 1. The time of the current event, t_current_event @@ -386,123 +334,6 @@ sbn::ICARUSBNBRetriever::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerIn return triggerInfo; } - -sbn::ICARUSBNBRetriever::MWRdata_t sbn::ICARUSBNBRetriever::extractSpillTimes(TriggerInfo_t const& triggerInfo) const { - - // These lines get everything primed within the IFBeamDB - // They seem redundant but they are needed - try{bfp->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} - try{bfp_mwr->FillCache((triggerInfo.t_previous_event)-fTimePad);} catch (WebAPIException &we) {} - - //The multiwire chambers provide their - // data in a vector format but we'll have - // to sort through it in std::string format - // to correctly unpack it - std::vector< std::vector< std::vector< int > > > unpacked_MWR; - std::vector< std::vector< double> > MWR_times; - unpacked_MWR.resize(3); - MWR_times.resize(3); - std::string packed_data_str; - - //Create a list of all the MWR devices with their different - // memory buffer increments - // generally in the format: "E:.{Memory Block}" - std::vector vars = bfp_mwr->GetDeviceList(); - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR Device Blocks Found : " << vars.size() << std::endl; - // Tracking the time from the IFBeamDB - double time_for_mwr; - - // this is an iterator to track which of the - // three devices we will be working with - int dev = 0; - - // The MWR devices are annoying and have confusing buffer - // what we'll do is sort through all of them first and then - // match them to the closest spills in time - // - - // int t_steps = int(((triggerInfo.t_previous_event - fTimePad) - (triggerInfo.t_current_event + fTimePad))/0.5)+25; - int t_steps = int(((triggerInfo.t_current_event + fTimePad) - (triggerInfo.t_previous_event - fTimePad - 20.))/0.5)+25; - mf::LogDebug("ICARUSBNBRetriever") << " t_steps " << t_steps << std::endl; - - for(int t = 0; t < t_steps; t++){//Iterate through time increments - for (std::string const& var : vars) {// Iterate through the devices - - //Make sure we have a device - if(var.empty()){ - //mf::LogDebug("ICARUSBNBRetriever") << " NO MWR DEVICES?!" << std::endl; - continue; - } - /// Check the device name and interate the double-vector index - if(var.find("M875BB") != std::string::npos ) dev = 0; - else if(var.find("M876BB") != std::string::npos ) dev = 1; - else if(var.find("MMBTBB") != std::string::npos ) dev = 2; - else{ - //mf::LogDebug("ICARUSBNBRetriever") << " NOT matched to a MWR DEVICES?!" << var << std::endl; - continue;} - - time_for_mwr = 0; - - try{ - //Pull the MWR data for the device - // these data are "packed" - std::vector packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.t_previous_event)-20.-fTimePad+double(0.5*t),var,&time_for_mwr); - - //We'll convert this into a format - // that we can unpack doubles >> strings - // - packed_data_str.clear(); - packed_data_str += std::to_string(int(time_for_mwr)); - packed_data_str.append(","); - packed_data_str.append(var); - packed_data_str.append(",,"); - - /* for(auto const value: packed_MWR){ - packed_data_str += ','; - packed_data_str += std::to_string(int(value)); - }*/ - for(int j = 0; j < int(packed_MWR.size()); j++){ - packed_data_str += std::to_string(int(packed_MWR[j])); - if(j < int(packed_MWR.size())-1) - packed_data_str.append(","); - } - - // Use Zarko's unpacking function to turn this into consumeable data - std::vector MWR_times_temp; - - // There is a 35 ms offset between the toriod and the MWR times - // we'll just remove that here to match to the spill times - std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay); - - //There are four events that are packed into one MWR IFBeam entry - for(std::size_t s: util::counter(unpacked_MWR_temp.size())){ - - // If this entry has a unique time them store it for later - if(std::find(MWR_times[dev].begin(), MWR_times[dev].end(), MWR_times_temp[s]) == MWR_times[dev].end()){ - unpacked_MWR[dev].push_back(unpacked_MWR_temp[s]); - MWR_times[dev].push_back(MWR_times_temp[s]); - }//check for unique time - }//Iterate through the unpacked events - }//try - catch (WebAPIException &we) { - //Ignore when we can't find the MWR devices - // they don't always report and the timing of them can be annoying - - }//catch - }// Iterate over all the multiwire devices - }// Iterate over all times - - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[0] times : " << MWR_times[0].size() << std::endl; - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl; - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[1] times : " << MWR_times[1].size() << std::endl; - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl; - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[2] times : " << MWR_times[2].size() << std::endl; - mf::LogDebug("ICARUSBNBRetriever") << " Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl; - - return { std::move(MWR_times), std::move(unpacked_MWR) }; -} - - int sbn::ICARUSBNBRetriever::matchMultiWireData( art::EventID const& eventID, TriggerInfo_t const& triggerInfo, @@ -636,7 +467,7 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( }//end loop over MWR devices - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR); + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp); beamInfos.push_back(std::move(spillInfo)); @@ -651,113 +482,6 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( return spill_count; } - -sbn::BNBSpillInfo sbn::ICARUSBNBRetriever::makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR) const -{ - - auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias - - // initializing all of our device carriers - // device definitions can be found in BNBSpillInfo.h - - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps - - double TOR860_time = 0; // units s - - // Here we request all the devices - // since sometimes devices fail to report we'll - // allow each to throw an exception but still move forward - // interpreting these failures will be part of the beam quality analyses - try{bfp->GetNamedData(time, "E:TOR860@",&TOR860,&TOR860_time);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:TOR875",&TOR875);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG1",&VPTG1);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:HPTG2",&HPTG2);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("ICARUSBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - - //crunch the times - unsigned long int time_closest_int = (int) TOR860_time; - double time_closest_ns = (TOR860_time - time_closest_int)*1e9; - - //Store everything in our data-product - sbn::BNBSpillInfo beamInfo; - beamInfo.TOR860 = TOR860*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.TOR875 = TOR875*1e12; //add in factor of 1e12 protons to get correct POT units - beamInfo.LM875A = LM875A; - beamInfo.LM875B = LM875B; - beamInfo.LM875C = LM875C; - beamInfo.HP875 = HP875; - beamInfo.VP875 = VP875; - beamInfo.HPTG1 = HPTG1; - beamInfo.VPTG1 = VPTG1; - beamInfo.HPTG2 = HPTG2; - beamInfo.VPTG2 = VPTG2; - beamInfo.BTJT2 = BTJT2; - beamInfo.THCURR = THCURR; - beamInfo.spill_time_s = time_closest_int; - beamInfo.spill_time_ns = time_closest_ns; - - for(auto const& MWRdata: unpacked_MWR){ - std::ignore = MWRdata; - assert(!MWRdata.empty()); - } - - if(unpacked_MWR[0].empty()){ - beamInfo.M875BB.clear(); - beamInfo.M875BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M875BB = unpacked_MWR[0][matched_MWR[0]]; - beamInfo.M875BB_spill_time_diff = (MWR_times[0][matched_MWR[0]] - time); - } - - if(unpacked_MWR[1].empty()){ - beamInfo.M876BB.clear(); - beamInfo.M876BB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.M876BB = unpacked_MWR[1][matched_MWR[1]]; - beamInfo.M876BB_spill_time_diff = (MWR_times[1][matched_MWR[1]] - time); - } - - if(unpacked_MWR[2].empty()){ - beamInfo.MMBTBB.clear(); - beamInfo.MMBTBB_spill_time_diff = -999;//units in seconds - } - else{ - beamInfo.MMBTBB = unpacked_MWR[2][matched_MWR[2]]; - beamInfo.MMBTBB_spill_time_diff = (MWR_times[2][matched_MWR[2]] - time); - } - // We do not write these to the art::Events because - // we can filter events but want to keep all the POT - // information, so we'll write it to the SubRun - - beamInfo.event = eventID.event(); // the rest of ID is known by art::SubRun - - return beamInfo; -} - - void sbn::ICARUSBNBRetriever::beginSubRun(art::SubRun& sr) { return; diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp deleted file mode 100644 index 48d0bda3f..000000000 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/MWRData.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "MWRData.h" - -using namespace std; - -namespace sbn{ - - std::vector< std::vector < int > > MWRData::unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset) const -{ - - std::vector > unpacked_data; - unpacked_data.resize(4); - short data[444]; - - std::vector row(0); - boost::split(row, packed_data, boost::is_any_of(",")); - if (row.size()==447) { - for (int i=3;i<447;i++) { - data[i-3]=atoi(row[i].c_str()); - } - string devname=row[1].substr(0,8); - for (int idev=0;idev<4;idev++) { - mwrpulse_t mwr=getMWRdata(data,idev); - time_stamp.push_back(mwr.sheader.timesec+mwr.sheader.timensec/1000000000.+timeoffset); - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.hor[ich]); - } - for (int ich=0;ich<48;ich++) { - unpacked_data[idev].push_back(mwr.ver[ich]); - } - } - } else { - cout <<"BeamSpillInfoRetriever: MRWData: Bad data!"< -namespace sbn{ -class MWRData -{ - typedef struct swicheader_t { - long timesec; - long timensec; - long gpstime1; - long gpstime2; - short boosterevent; - short mievent; - short hz15micnt; - long delta1f; - short pulsemi; - short pulsesc; - } swicheader_t; - - typedef struct mwrpulse_t { - short hor[48]; - short ver[48]; - swicheader_t sheader; - } mwrpulse_t; - - static long flipByte(long data) - { - return ((data>>16)&0x0000FFFF) | ((data<<16)&0xFFFF0000); - } - - mwrpulse_t getMWRdata(short* data, int nblock) const; - - public: - std::vector< std::vector < int > > unpackMWR(std::string packed_data, std::vector &time_stamp, double timeoffset=0) const; -}; -} - -#endif /* #ifndef _MWRDATA_H */ diff --git a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h b/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h index 46d16c709..250d9dfda 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h +++ b/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h @@ -22,9 +22,11 @@ namespace sbn{ } PTBInfo_t; typedef struct TriggerInfo_t { + int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI double t_current_event = 0; double t_previous_event = 0; unsigned int number_of_gates_since_previous_event = 0; + std::int64_t WR_to_Spill_conversion = 0; } TriggerInfo_t; typedef struct MWRdata_t { From bbb400facf141dc2d88e8f6e7dabb52ef7f96117 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Tue, 18 Mar 2025 13:39:52 -0500 Subject: [PATCH 048/367] rename POTTools --- sbncode/BeamSpillInfoRetriever/CMakeLists.txt | 4 +- .../ICARUSBNBRetriever/CMakeLists.txt | 2 +- .../ICARUSBNBRetriever_module.cc | 41 +++---------------- .../{SBNDPOTTools.cpp => POTTools.cpp} | 2 +- .../{SBNDPOTTools.h => POTTools.h} | 0 .../SBNDBNBEXTRetriever/CMakeLists.txt | 2 +- .../SBNDBNBEXTRetriever_module.cc | 3 +- .../SBNDBNBRetriever/CMakeLists.txt | 2 +- .../SBNDBNBRetriever_module.cc | 2 +- .../SBNDBNBZEROBIASRetriever/CMakeLists.txt | 2 +- .../SBNDBNBZEROBIASRetriever_module.cc | 2 +- 11 files changed, 15 insertions(+), 47 deletions(-) rename sbncode/BeamSpillInfoRetriever/{SBNDPOTTools.cpp => POTTools.cpp} (99%) rename sbncode/BeamSpillInfoRetriever/{SBNDPOTTools.h => POTTools.h} (100%) diff --git a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt index 56decf315..bb6237405 100644 --- a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt @@ -27,8 +27,8 @@ art_make_library( sbn_MWRData larcorealg::CoreUtils - LIBRARY_NAME sbn_SBNDPOTTools - SOURCE SBNDPOTTools.cpp + LIBRARY_NAME sbn_POTTools + SOURCE POTTools.cpp ) install_headers() diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt index a9379d867..ffa6afb95 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt @@ -3,7 +3,7 @@ find_package(ifdh_art) cet_build_plugin(ICARUSBNBRetriever art::module LIBRARIES - sbn_SBNDPOTTools + sbn_POTTools SQLite::SQLite3 ) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index 6be19dc1b..ccdac097f 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -12,7 +12,7 @@ #include "art/Framework/Core/EDProducer.h" #include "messagefacility/MessageLogger/MessageLogger.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" -#include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV3Fragment.hh" #include @@ -259,10 +259,6 @@ void sbn::ICARUSBNBRetriever::produce(art::Event& e) // We do not currently have the ability to figure out the first // spill that the DAQ was sensitive to, so don't try to save any // spill information - // - // TODO: long-term goal -- can we fix this? - // FIXME This is wrong.... - // Need to use: ICARUSTriggerV3Fragment long getTotalTriggerBNBMaj() const if (e.event() == 1) return; @@ -277,7 +273,7 @@ void sbn::ICARUSBNBRetriever::produce(art::Event& e) TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); - int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos); + int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, fOutbeamInfos); if(spill_count > int(triggerInfo.number_of_gates_since_previous_event)) mf::LogDebug("ICARUSBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << " \t \t ::: WRONG!"<< std::endl; @@ -357,37 +353,10 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( std::vector matched_MWR; matched_MWR.resize(3); - - // NOTE: for now, this is dead code because we don't - // do anything for the first event in a run. We may want to revisit - // this later to understand if there is a way we can do the POT - // accounting in the first event. - // - // Need to handle the first event in a run differently - if(isFirstEventInRun){ - - //We'll remove the spills after our event - int spills_after_our_target = 0; - // iterate through all the spills to find the - // spills that are after our triggered event - for (size_t i = 0; i < times_temps.size(); i++) { - if(times_temps[i] > (triggerInfo.t_current_event+fTimePad)){ - spills_after_our_target++; - } - }//end loop through spill times - - // Remove the spills after our trigger - times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end()); - - // Remove the spills before the start of our Run - times_temps.erase(times_temps.begin(), times_temps.end() - std::min(int(triggerInfo.number_of_gates_since_previous_event), int(times_temps.size()))); - - }//end fix for "first event" - - ///reject time_stamps which have a trigger_type == 1 from data-base - //To-Do + ///reject time_stamps which have a trigger_type == 1 from data-base + //To-Do - // mf::LogDebug("ICARUSBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; + // mf::LogDebug("ICARUSBNBRetriever") << "Total number of Times we're going to test: " << times_temps.size() << std::endl; // mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Upper Limit : " << (triggerInfo.t_current_event)+fTimePad << std::endl; // mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Lower Limit : " << (triggerInfo.t_previous_event)+fTimePad << std::endl; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp similarity index 99% rename from sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp rename to sbncode/BeamSpillInfoRetriever/POTTools.cpp index 9acb26ab2..10086ba03 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -1,4 +1,4 @@ -#include "SBNDPOTTools.h" +#include "POTTools.h" using namespace std; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h b/sbncode/BeamSpillInfoRetriever/POTTools.h similarity index 100% rename from sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h rename to sbncode/BeamSpillInfoRetriever/POTTools.h diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt index d7f43205a..8a16ef2e9 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt @@ -3,7 +3,7 @@ find_package(ifdh_art) cet_build_plugin(SBNDBNBEXTRetriever art::module LIBRARIES - sbn_SBNDPOTTools + sbn_POTTools ) install_headers() diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc index 298734bff..b6f3e7827 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc @@ -8,7 +8,7 @@ #include "art/Framework/Core/EDProducer.h" #include "messagefacility/MessageLogger/MessageLogger.h" #include "sbnobj/Common/POTAccounting/EXTCountInfo.h" -#include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" namespace sbn { class SBNDBNBEXTRetriever; @@ -28,7 +28,6 @@ class sbn::SBNDBNBEXTRetriever : public art::EDProducer { SBNDBNBEXTRetriever & operator = (SBNDBNBEXTRetriever const &) = delete; SBNDBNBEXTRetriever & operator = (SBNDBNBEXTRetriever &&) = delete; - private: // Declare member data here. std::vector< sbn::EXTCountInfo > fOutExtInfos; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt index ea89ae916..72a102476 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt @@ -3,7 +3,7 @@ find_package(ifdh_art) cet_build_plugin(SBNDBNBRetriever art::module LIBRARIES - sbn_SBNDPOTTools + sbn_POTTools ) install_headers() diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 5e709c2b0..0de226122 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -8,7 +8,7 @@ #include "art/Framework/Core/EDProducer.h" #include "messagefacility/MessageLogger/MessageLogger.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" -#include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" namespace sbn { class SBNDBNBRetriever; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt index d1ef9e65f..8edd88618 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt @@ -3,7 +3,7 @@ find_package(ifdh_art) cet_build_plugin(SBNDBNBZEROBIASRetriever art::module LIBRARIES - sbn_SBNDPOTTools + sbn_POTTools ) install_headers() diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index fa7e8b793..399c036d0 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -8,7 +8,7 @@ #include "art/Framework/Core/EDProducer.h" #include "messagefacility/MessageLogger/MessageLogger.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" -#include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" namespace sbn { class SBNDBNBZEROBIASRetriever; From 0d29aa310cb0a9fc67a6faa45b791ee19803b7ef Mon Sep 17 00:00:00 2001 From: Gianluca Petrillo Date: Wed, 19 Mar 2025 01:11:31 -0500 Subject: [PATCH 049/367] sbncode now depends on sbnalg instead of sbnobj/sbnanaobj --- ups/product_deps | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ups/product_deps b/ups/product_deps index 6e42d051e..867e3df0c 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,10 +255,9 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v10_04_05 - -sbnanaobj v10_00_00 - +sbnalg v10_04_05 - sbndaq_artdaq_core v1_10_04 - sbndata v01_07 - -sbnobj v10_00_06 - systematicstools v01_04_04 - nusystematics v1_05_04 - cetmodules v3_24_01 - only_for_build @@ -317,11 +316,11 @@ end_product_list # #################################### -qualifier larsoft sbnobj sbnanaobj sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics notes -c14:debug c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug -nq- -c14:prof c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof -nq- -e26:debug e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug -nq- -e26:prof e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof -nq- +qualifier larsoft sbnalg sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics notes +c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug -nq- +c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof -nq- +e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug -nq- +e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof -nq- end_qualifier_list #################################### From 631dc9f385cf5c4527d5b5be129d50d199aa05f7 Mon Sep 17 00:00:00 2001 From: Nathaniel Rowe Date: Wed, 19 Mar 2025 14:38:01 -0500 Subject: [PATCH 050/367] matchMultiWire changes --- .../ICARUSBNBRetriever_module.cc | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index ccdac097f..16d383fd0 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -139,7 +139,7 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { int matchMultiWireData( art::EventID const& eventID, TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, + MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const; @@ -333,7 +333,7 @@ sbn::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& int sbn::ICARUSBNBRetriever::matchMultiWireData( art::EventID const& eventID, TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, bool isFirstEventInRun, + MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const { @@ -366,16 +366,14 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( // Only continue if these times are matched to our DAQ time //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Time # : " << i << std::endl; - if(!isFirstEventInRun){//We already addressed the "first event" above - if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ - //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - spills_removed++; - continue;} - if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ - spills_removed++; - //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; - continue;} - } + if(times_temps[i] > (triggerInfo.t_current_event)+fTimePad){ + //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + spills_removed++; + continue;} + if(times_temps[i] <= (triggerInfo.t_previous_event)+fTimePad){ + spills_removed++; + //mf::LogDebug("ICARUSBNBRetriever") << std::setprecision(19) << "Removed! : " << times_temps[i] << std::endl; + continue;} //check if this spill is is minbias /* From 5234493b599f6cd58e0bc7bf4caf0de244277efd Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Mon, 24 Mar 2025 10:00:55 -0500 Subject: [PATCH 051/367] Add in option to shift SimEnergyDepositLites to TriggerSimAdjuster --- sbncode/DetSim/AdjustSimForTrigger_module.cc | 27 +++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/sbncode/DetSim/AdjustSimForTrigger_module.cc b/sbncode/DetSim/AdjustSimForTrigger_module.cc index 14c7cabe2..5f6c5eee9 100644 --- a/sbncode/DetSim/AdjustSimForTrigger_module.cc +++ b/sbncode/DetSim/AdjustSimForTrigger_module.cc @@ -22,6 +22,7 @@ #include "lardataobj/Simulation/AuxDetSimChannel.h" #include "lardataobj/Simulation/BeamGateInfo.h" #include "lardataobj/Simulation/SimEnergyDeposit.h" +#include "lardataobj/Simulation/SimEnergyDepositLite.h" #include "lardataobj/Simulation/SimPhotons.h" #include @@ -49,11 +50,13 @@ class AdjustSimForTrigger : public art::EDProducer { art::InputTag fInitAuxDetSimChannelLabel; art::InputTag fInitBeamGateInfoLabel; art::InputTag fInitSimEnergyDepositLabel; + art::InputTag fInitSimEnergyDepositLiteLabel; art::InputTag fInitSimPhotonsLabel; art::InputTag fInitWaveformLabel; bool fShiftAuxDetIDEs; bool fShiftBeamGateInfo; bool fShiftSimEnergyDeposits; + bool fShiftSimEnergyDepositLites; bool fShiftSimPhotons; bool fShiftWaveforms; double fAdditionalOffset; @@ -66,29 +69,33 @@ AdjustSimForTrigger::AdjustSimForTrigger(fhicl::ParameterSet const& p) , fInitAuxDetSimChannelLabel(p.get("InitAuxDetSimChannelLabel", "undefined")) , fInitBeamGateInfoLabel{p.get("InitBeamGateInfoLabel", "undefined")} , fInitSimEnergyDepositLabel{p.get("InitSimEnergyDepositLabel", "undefined")} + , fInitSimEnergyDepositLiteLabel{p.get("InitSimEnergyDepositLiteLabel", "undefined")} , fInitSimPhotonsLabel{p.get("InitSimPhotonsLabel", "undefined")} , fInitWaveformLabel(p.get("InitWaveformLabel", "undefined")) , fShiftAuxDetIDEs{p.get("ShiftAuxDetIDEs", false)} , fShiftBeamGateInfo{p.get("ShiftBeamGateInfo", false)} , fShiftSimEnergyDeposits{p.get("ShiftSimEnergyDeposits", false)} + , fShiftSimEnergyDepositLites{p.get("ShiftSimEnergyDepositLites", false)} , fShiftSimPhotons{p.get("ShiftSimPhotons", false)} , fShiftWaveforms{p.get("ShiftWaveforms", false)} , fAdditionalOffset{p.get("AdditionalOffset", 0.)} { if (!(fShiftSimEnergyDeposits || fShiftSimPhotons || fShiftWaveforms || fShiftAuxDetIDEs || - fShiftBeamGateInfo)) { + fShiftBeamGateInfo || fShiftSimEnergyDepositLites)) { throw art::Exception(art::errors::EventProcessorFailure) << kModuleName << ": NO SHIFTS ENABLED!\n"; } mf::LogInfo(kModuleName) << std::boolalpha << "SHIFTING AUXDETIDES? " << fShiftAuxDetIDEs << '\n' << "SHIFTING BEAMGATEINFO? " << fShiftBeamGateInfo << '\n' << "SHIFTING SIMENERGYDEPOSITS? " << fShiftSimEnergyDeposits << '\n' + << "SHIFTING SIMENERGYDEPOSITLITES? " << fShiftSimEnergyDepositLites << '\n' << "SHIFTING SIMPHOTONS? " << fShiftSimPhotons << '\n' << "SHIFTING OPDETWAVEFORMS? " << fShiftWaveforms; if (fShiftAuxDetIDEs) { produces>(); } if (fShiftBeamGateInfo) { produces>(); } if (fShiftSimEnergyDeposits) { produces>(); } + if (fShiftSimEnergyDepositLites) { produces>(); } if (fShiftSimPhotons) { produces>(); } if (fShiftWaveforms) { produces>(); } } @@ -205,6 +212,24 @@ void AdjustSimForTrigger::produce(art::Event& e) } e.put(std::move(pSimEDeps)); } + // and SimEnergyDepositLite's + if (fShiftSimEnergyDepositLites) { + auto const& simEDepLites = + e.getProduct>(fInitSimEnergyDepositLiteLabel); + + auto pSimEDepLites = std::make_unique>(); + + for (auto const& inSimEDepLite : simEDepLites) { + double energy = inSimEDepLite.Energy(); + geo::Point_t middlePos = inSimEDepLite.Position(); + double middleTime = inSimEDepLite.Time() + timeShiftForTrigger_ns; + int ID = inSimEDepLite.TrackID(); + + pSimEDepLites->emplace_back(energy, middlePos, middleTime, ID); + } + + e.put(std::move(pSimEDepLites)); + } // Repeat for sim::SimPhotons if (fShiftSimPhotons) { From 9eab1eb194baf212027667c97e1b13602294838d Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 27 Mar 2025 17:37:15 -0500 Subject: [PATCH 052/367] Update CMakeLists.txt and product deps --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ac609638..071970895 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.04.06.01 LANGUAGES CXX) +project(sbncode VERSION 10.04.07 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 23fd415f2..e8f5396d9 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_04_06 - -sbnalg v10_04_06_01 - +larsoft v10_04_07 - +sbnalg v10_04_07 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From 4a94e698042df11010e76a16b9d26949e93b1f6d Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Thu, 3 Apr 2025 09:45:21 +0100 Subject: [PATCH 053/367] Use Ts0 not Ts1 --- sbncode/CAFMaker/FillReco.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index f47265c1e..59d8e69f3 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -122,8 +122,8 @@ namespace caf srspacepoint.position = SRVector3D(spacepoint.X(), spacepoint.Y(), spacepoint.Z()); srspacepoint.position_err = SRVector3D(spacepoint.XErr(), spacepoint.YErr(), spacepoint.ZErr()); srspacepoint.pe = spacepoint.PE(); - srspacepoint.time = spacepoint.Ts1(); - srspacepoint.time_err = spacepoint.Ts1Err(); + srspacepoint.time = spacepoint.Ts0(); + srspacepoint.time_err = spacepoint.Ts0Err(); srspacepoint.complete = spacepoint.Complete(); } @@ -134,8 +134,8 @@ namespace caf for(auto const& point : track.Points()) srsbndcrttrack.points.emplace_back(point.X(), point.Y(), point.Z()); - srsbndcrttrack.time = track.Ts1(); - srsbndcrttrack.time_err = track.Ts1Err(); + srsbndcrttrack.time = track.Ts0(); + srsbndcrttrack.time_err = track.Ts0Err(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); } From f5403aa9205db75f577d003ed40d8b865e11cf7d Mon Sep 17 00:00:00 2001 From: nathanielerowe Date: Thu, 3 Apr 2025 10:24:18 -0500 Subject: [PATCH 054/367] Remove extra fcl --- .../job/sbndbnbspillinfo.fcl | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl deleted file mode 100644 index 26327a100..000000000 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbspillinfo.fcl +++ /dev/null @@ -1,17 +0,0 @@ -BEGIN_PROLOG - -sbndbnbspillinfo: { - module_type: "" - DebugLevel: 0 - TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away was 0.0333 - BESOffset: 0.035 #unit seconds, we expect the BES to be about 35 ms from $1D. Need to adjust search range accordingly. - URL: "" #Default URL having issues Nov 21 2024, used this instead https://dbdata3vm.fnal.gov:9443/ifbeam - Bundle: "BoosterNeutrinoBeam_read" - MultiWireBundle: "BNBMultiWire" - TimeWindow: "700" #seconds - MWR_TimeWindow: "3601" #seconds - DeviceUsedForTiming: "E:TOR860" -} - -END_PROLOG - From 42db454e27514578c45132dd81f1f464e61a32d0 Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Sat, 5 Apr 2025 16:59:48 -0500 Subject: [PATCH 055/367] Fix association bug --- sbncode/Calibration/TrackCaloSkimmer_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 8b424aed7..4588634cd 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -234,7 +234,7 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) // Hits (ICARUS style) art::FindManyP fmT0CRTHit(tracks, e, fCRTHitT0producer); - art::FindManyP fmCRTHitT0TaggingInfo(PFParticleList, e, fCRTHitT0producer); + art::FindManyP fmCRTHitT0TaggingInfo(tracks, e, fCRTHitT0producer); // Track - associated data art::FindManyP fmTracks(PFParticleList, e, fTRKproducer); From 4f505f666ab23a7750deed126ff42e532ee1043d Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Sat, 5 Apr 2025 19:25:59 -0500 Subject: [PATCH 056/367] Protect against overflow when filling flat GENIE record. --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 62feede18..32013baca 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1469,7 +1469,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { int iparticle=0; genie::GHepParticle * p = 0; - while( genie_rec->Particle(iparticle) != 0 ) { + while( (genie_rec->Particle(iparticle) != 0) && (iparticle < 250) ) { p = genie_rec->Particle(iparticle); fGenieEvtRec_brStdHepPdg[iparticle] = p->Pdg(); fGenieEvtRec_brStdHepStatus[iparticle] = (int) p->Status(); From 1e60e40d29898d7472af84434a00ad2820ac8b1f Mon Sep 17 00:00:00 2001 From: nathanielerowe Date: Mon, 7 Apr 2025 13:33:01 -0500 Subject: [PATCH 057/367] Doxygen+namespace updates --- .../ICARUSBNBRetriever_module.cc | 31 +++++++------- sbncode/BeamSpillInfoRetriever/POTTools.cpp | 15 ++----- sbncode/BeamSpillInfoRetriever/POTTools.h | 40 ++++++++++++++++++- .../SBNDBNBEXTRetriever_module.cc | 4 +- .../SBNDBNBRetriever_module.cc | 24 +++++------ .../SBNDBNBZEROBIASRetriever_module.cc | 24 +++++------ .../job/icarusbnbspillinfo.fcl | 2 +- 7 files changed, 84 insertions(+), 56 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index 16d383fd0..8802db658 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -38,7 +38,6 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { fhicl::Atom BESOffset { Name{ "BESOffset" }, Comment{ "Offset between beam early warning signal and $1D [seconds]" }, - 0.036 // default }; fhicl::Atom RawDataLabel { @@ -58,27 +57,27 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { fhicl::Atom Bundle { Name{ "Bundle" }, - Comment{ "" } // explain what this is and which database/table it's looking for + Comment{ "Name of the collection of devices to grab from IFbeam for everything except MWRdevices." } }; fhicl::Atom TimeWindow { Name{ "TimeWindow" }, - Comment{ "" } // explain what this is, what's for and its unit + Comment{ "Window of time in seconds to use for non-mwr ifbeam queries." } }; fhicl::Atom MultiWireBundle { Name{ "MultiWireBundle" }, - Comment{ "" } // explain what this is and which database/table it's looking for + Comment{ "name of collections of devices to grab from IFbeam for use as MWRdevices." } }; fhicl::Atom MWR_TimeWindow { Name{ "MWR_TimeWindow" }, - Comment{ "" } // explain what this is, what's for and its unit + Comment{ "Window of time in seconds to use for mwr ifbeam queries." } }; fhicl::Atom TriggerDatabaseFile { Name{ "TriggerDatabaseFile" }, - Comment{ "" } // explain what this is, what's for and its unit + Comment{ "path of local database of all recorded events and their trigger, in SQLite format" } }; @@ -126,7 +125,7 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] /// Returns the information of the trigger in the current event. - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + sbn::pot::TriggerInfo_t extractTriggerInfo(art::Event const& e) const; /** * @brief Matches spill times with multiwire chamber data from the database. * @param eventID ID of the event the information is associated to @@ -138,8 +137,8 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { */ int matchMultiWireData( art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, + sbn::pot::TriggerInfo_t const& triggerInfo, + sbn::pot::MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const; @@ -264,14 +263,14 @@ void sbn::ICARUSBNBRetriever::produce(art::Event& e) run_number = e.id().run(); - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + sbn::pot::TriggerInfo_t const triggerInfo = extractTriggerInfo(e); //We only want to process BNB gates, i.e. type 1 if(triggerInfo.gate_type != 1) return; // Keep track of the number of beam gates the DAQ thinks // are in this job TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); + sbn::pot::MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, fOutbeamInfos); @@ -283,7 +282,7 @@ void sbn::ICARUSBNBRetriever::produce(art::Event& e) }//end iteration over art::Events -sbn::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& e) const { +sbn::pot::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& e) const { //Here we read in the artdaq Fragments and extract three pieces of information: // 1. The time of the current event, t_current_event @@ -293,7 +292,7 @@ sbn::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& auto const & raw_data = e.getProduct< std::vector >({ raw_data_label, "ICARUSTriggerV3" }); auto const & extraTrigInfo = e.getProduct< sbn::ExtraTriggerInfo >("daqTrigger"); - TriggerInfo_t triggerInfo; + sbn::pot::TriggerInfo_t triggerInfo; triggerInfo.WR_to_Spill_conversion = extraTrigInfo.WRtimeToTriggerTime; @@ -332,8 +331,8 @@ sbn::TriggerInfo_t sbn::ICARUSBNBRetriever::extractTriggerInfo(art::Event const& int sbn::ICARUSBNBRetriever::matchMultiWireData( art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, + sbn::pot::TriggerInfo_t const& triggerInfo, + sbn::pot::MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const { @@ -434,7 +433,7 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( }//end loop over MWR devices - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp); + sbn::BNBSpillInfo spillInfo = sbn::pot::makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp); beamInfos.push_back(std::move(spillInfo)); diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index 10086ba03..48751f675 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -2,11 +2,9 @@ using namespace std; -namespace sbn{ +namespace sbn::pot{ - // Function for extracting the PTB information (current timestamp, - // previous timestamp, gate counter). Used in SBND modules only. - sbn::PTBInfo_t extractPTBInfo(art::Handle > cont_frags, int HLT) { + sbn::pot::PTBInfo_t extractPTBInfo(art::Handle > cont_frags, int HLT) { bool foundHLT = false; PTBInfo_t PTBInfo; for (auto const& cont : *cont_frags) @@ -45,7 +43,6 @@ namespace sbn{ } } - // Function for extracting the TDC timestamp. Used in SBND modules only. double extractTDCTimeStamp(art::Handle > cont_frags) { double TDCTimeStamp = 0; @@ -62,8 +59,6 @@ namespace sbn{ return TDCTimeStamp; } - // Collect device information to make BNBSpillInfo object. Used in - // ICARUS and SBND modules. sbn::BNBSpillInfo makeBNBSpillInfo (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR, std::unique_ptr const& bfp) { @@ -170,9 +165,6 @@ namespace sbn{ return beamInfo; } - // Returns true if a time in IFBeam corresponds to a broken clock false if - // it is a real spill. Check this by seeing if all devices fire at once or - // if time is just a single outlier. bool BrokenClock(double time, std::unique_ptr const& bfp) { double TOR860 = 0; // units e12 protons @@ -221,8 +213,7 @@ namespace sbn{ } } - // extract spill times from the IFBeam data base. Used in SBND and ICARUS. - sbn::MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo, std::unique_ptr const& bfp, std::unique_ptr const& bfp_mwr, double fTimePad, double MWRtoroidDelay, sbn::MWRData mwrdata) { + sbn::pot::MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo, std::unique_ptr const& bfp, std::unique_ptr const& bfp_mwr, double fTimePad, double MWRtoroidDelay, sbn::MWRData mwrdata) { // These lines get everything primed within the IFBeamDB. try{bfp->FillCache((triggerInfo.t_current_event)+fTimePad);} catch (WebAPIException &we) {}; diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.h b/sbncode/BeamSpillInfoRetriever/POTTools.h index 250d9dfda..43bb6b68a 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.h +++ b/sbncode/BeamSpillInfoRetriever/POTTools.h @@ -14,7 +14,8 @@ #include "sbncode/BeamSpillInfoRetriever/MWRData.h" #include "larcorealg/CoreUtils/counter.h" -namespace sbn{ +namespace sbn::pot{ + typedef struct PTBInfo_t { double currPTBTimeStamp = 1e20; double prevPTBTimeStamp = 0; @@ -34,10 +35,47 @@ namespace sbn{ std::vector< std::vector< std::vector< int > > > unpacked_MWR; } MWRdata_t; + /** + * @brief Extracts information from PTB for use in SBND POT accounting. + * + * @param cont_frags The PTB fragments to examine. + * @param HLT The high level trigger we are searching for. + */ PTBInfo_t extractPTBInfo(art::Handle > cont_frags, int HLT); + + /** + * @brief Extracts information from TDC for use in SBND POT accounting. + * + * @param cont_frags The TDC fragments to examine. + */ double extractTDCTimeStamp(art::Handle > cont_frags); + + /** + * @brief Checks for a known IFBeam issue where TOR clocks are incorrect. + * @return true if a time in IFBeam corresponds to a broken clock false if + * it is a real spill. + * @details Check validity by seeing if all devices fire at once or + * if time is just a single outlier. + * @param time The time for which we want to check for a spill. + * @param bfp beamfolder object to check. + */ bool BrokenClock(double time, std::unique_ptr const& bfp); + + /** + * @brief extract spill times from the IFBeam data base. Used in SBND and ICARUS. + * + * @param triggerInfo triggerInfo object to match + * @param bfp beamfolder to match + * @param bfp_mwr mwr devices have separate daq system, much treat separately + * @param fTimePad Padding to use in ifbeam queries + * @param MWRtoroidDelay Delay between MWR and toroids + * @param mwrdata MWRData to unpack + */ MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo, std::unique_ptr const& bfp, std::unique_ptr const& bfp_mwr, double fTimePad, double MWRtoroidDelay, sbn::MWRData mwrdata ); + + /** + * @brief Compile spill information into BNBSpillInfo object + */ sbn::BNBSpillInfo makeBNBSpillInfo(art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR, std::unique_ptr const& bfp); } diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc index b6f3e7827..a8b3f9d67 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/SBNDBNBEXTRetriever_module.cc @@ -31,7 +31,7 @@ class sbn::SBNDBNBEXTRetriever : public art::EDProducer { private: // Declare member data here. std::vector< sbn::EXTCountInfo > fOutExtInfos; - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + sbn::pot::TriggerInfo_t extractTriggerInfo(art::Event const& e) const; // input labels float TotalEXTCounts; }; @@ -46,7 +46,7 @@ void sbn::SBNDBNBEXTRetriever::produce(art::Event & e) { art::InputTag PTB_itag("daq", "ContainerPTB"); auto PTB_cont_frags = e.getHandle(PTB_itag); - PTBInfo_t PTBInfo = extractPTBInfo(PTB_cont_frags, 4); + sbn::pot::PTBInfo_t PTBInfo = sbn::pot::extractPTBInfo(PTB_cont_frags, 4); int SingleEventGateCounter = PTBInfo.GateCounter; TotalEXTCounts += SingleEventGateCounter; diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 0de226122..db0c44c21 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -40,11 +40,11 @@ class sbn::SBNDBNBRetriever : public art::EDProducer { art::ServiceHandle ifbeam_handle; static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + sbn::pot::TriggerInfo_t extractTriggerInfo(art::Event const& e) const; int matchMultiWireData( art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, + sbn::pot::TriggerInfo_t const& triggerInfo, + sbn::pot::MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const; unsigned int TotalBeamSpills; @@ -77,14 +77,14 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) } mf::LogDebug("SBNDBNBRetriever")<< "ptb_event: " << e.event() << std::endl; - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + sbn::pot::TriggerInfo_t const triggerInfo = extractTriggerInfo(e); if (triggerInfo.t_previous_event == 0) { return; } TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); + sbn::pot::MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, fOutbeamInfos); @@ -94,7 +94,7 @@ void sbn::SBNDBNBRetriever::produce(art::Event & e) mf::LogDebug("SBNDBNBRetriever")<< "Event Spills : " << spill_count << ", DAQ Spills : " << triggerInfo.number_of_gates_since_previous_event << std::endl; } -sbn::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { +sbn::pot::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e) const { // Using TDC for current event, but PTB for previous event. Exception for case where no TDC. art::InputTag PTB_itag("daq", "ContainerPTB"); auto PTB_cont_frags = e.getHandle(PTB_itag); @@ -102,11 +102,11 @@ sbn::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); auto TDC_cont_frags = e.getHandle(TDC_itag); - TriggerInfo_t triggerInfo; - PTBInfo_t PTBInfo = extractPTBInfo(PTB_cont_frags, 2); + sbn::pot::TriggerInfo_t triggerInfo; + sbn::pot::PTBInfo_t PTBInfo = sbn::pot::extractPTBInfo(PTB_cont_frags, 2); if (TDC_cont_frags) { - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + double TDCTimeStamp = sbn::pot::extractTDCTimeStamp(TDC_cont_frags); triggerInfo.t_current_event = TDCTimeStamp - fBESOffset; } else{ @@ -134,8 +134,8 @@ sbn::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event const& e int sbn::SBNDBNBRetriever::matchMultiWireData( art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, + sbn::pot::TriggerInfo_t const& triggerInfo, + sbn::pot::MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const { @@ -164,7 +164,7 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( spills_removed++; continue;} - if(BrokenClock(times_temps[i], bfp)){ + if(sbn::pot::BrokenClock(times_temps[i], bfp)){ continue; } diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index 399c036d0..3f6fc7eb8 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -41,11 +41,11 @@ class sbn::SBNDBNBZEROBIASRetriever : public art::EDProducer { std::vector< sbn::BNBSpillInfo > fOutbeamInfos; std::vector< sbn::BNBSpillInfo > fOutbeamInfosTotal; - TriggerInfo_t extractTriggerInfo(art::Event const& e) const; + sbn::pot::TriggerInfo_t extractTriggerInfo(art::Event const& e) const; void matchMultiWireData( art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, + sbn::pot::TriggerInfo_t const& triggerInfo, + sbn::pot::MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const; unsigned int TotalBeamSpills; @@ -79,7 +79,7 @@ void sbn::SBNDBNBZEROBIASRetriever::produce(art::Event & e) return; } - TriggerInfo_t const triggerInfo = extractTriggerInfo(e); + sbn::pot::TriggerInfo_t const triggerInfo = extractTriggerInfo(e); if (triggerInfo.t_previous_event == 0) { auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >(); @@ -89,7 +89,7 @@ void sbn::SBNDBNBZEROBIASRetriever::produce(art::Event & e) } TotalBeamSpills += triggerInfo.number_of_gates_since_previous_event; - MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); + sbn::pot::MWRdata_t const MWRdata = extractSpillTimes(triggerInfo, bfp, bfp_mwr, fTimePad, MWRtoroidDelay, mwrdata); matchMultiWireData(e.id(), triggerInfo, MWRdata, fOutbeamInfos); fOutbeamInfosTotal.insert(fOutbeamInfosTotal.end(),fOutbeamInfos.begin(),fOutbeamInfos.end()); @@ -98,7 +98,7 @@ void sbn::SBNDBNBZEROBIASRetriever::produce(art::Event & e) e.put(std::move(p)); } -sbn::TriggerInfo_t sbn::SBNDBNBZEROBIASRetriever::extractTriggerInfo(art::Event const& e) const { +sbn::pot::TriggerInfo_t sbn::SBNDBNBZEROBIASRetriever::extractTriggerInfo(art::Event const& e) const { // Using TDC for current event, but PTB for previous event art::InputTag PTB_itag("daq", "ContainerPTB"); auto PTB_cont_frags = e.getHandle(PTB_itag); @@ -106,11 +106,11 @@ sbn::TriggerInfo_t sbn::SBNDBNBZEROBIASRetriever::extractTriggerInfo(art::Event art::InputTag TDC_itag("daq", "ContainerTDCTIMESTAMP"); auto TDC_cont_frags = e.getHandle(TDC_itag); - TriggerInfo_t triggerInfo; - PTBInfo_t PTBInfo = extractPTBInfo(PTB_cont_frags, 1); + sbn::pot::TriggerInfo_t triggerInfo; + sbn::pot::PTBInfo_t PTBInfo = sbn::pot::extractPTBInfo(PTB_cont_frags, 1); if (TDC_cont_frags) { - double TDCTimeStamp = extractTDCTimeStamp(TDC_cont_frags); + double TDCTimeStamp = sbn::pot::extractTDCTimeStamp(TDC_cont_frags); triggerInfo.t_current_event = TDCTimeStamp - fBESOffset; } else{ @@ -138,8 +138,8 @@ sbn::TriggerInfo_t sbn::SBNDBNBZEROBIASRetriever::extractTriggerInfo(art::Event void sbn::SBNDBNBZEROBIASRetriever::matchMultiWireData( art::EventID const& eventID, - TriggerInfo_t const& triggerInfo, - MWRdata_t const& MWRdata, + sbn::pot::TriggerInfo_t const& triggerInfo, + sbn::pot::MWRdata_t const& MWRdata, std::vector< sbn::BNBSpillInfo >& beamInfos ) const { @@ -174,7 +174,7 @@ void sbn::SBNDBNBZEROBIASRetriever::matchMultiWireData( spills_removed++; continue;} - if(BrokenClock(times_temps[i], bfp)){ + if(sbn::pot::BrokenClock(times_temps[i], bfp)){ continue; } diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl index a7b4b0dbc..7c33421f8 100644 --- a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl @@ -5,7 +5,7 @@ icarusbnbspillinfo: { module_type: "ICARUSBNBRetriever" TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away - BESOffset: 0.036 #unit seconds, we expect the BES to be about 35 ms from $1D. Need to adjust search range accordingly. + BESOffset: 0.035746 #unit seconds, we expect the BES to be about 35 ms from $1D. Need to adjust search range accordingly. URL: "" #keep this blank and we're good Bundle: "BoosterNeutrinoBeam_read" MultiWireBundle: "BNBMultiWire" From 6318c45eb391b093f6cf6b8664466eac0f4634a0 Mon Sep 17 00:00:00 2001 From: Brinden Carlson Date: Mon, 7 Apr 2025 19:00:18 -0500 Subject: [PATCH 058/367] Update supera tag to include CRT for SBND --- sbncode/Supera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Supera b/sbncode/Supera index 844ebc5f2..d84d726d9 160000 --- a/sbncode/Supera +++ b/sbncode/Supera @@ -1 +1 @@ -Subproject commit 844ebc5f2ff5232942ad6c3b3761409534cc4574 +Subproject commit d84d726d95017f4b86a99537f6d86deeda3216c3 From 7b1f6f5f72c33adcf636775f4ab621f27454823d Mon Sep 17 00:00:00 2001 From: Brinden Carlson Date: Tue, 8 Apr 2025 11:02:10 -0500 Subject: [PATCH 059/367] Revert "Update supera tag to include CRT for SBND" This reverts commit 6318c45eb391b093f6cf6b8664466eac0f4634a0. --- sbncode/Supera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Supera b/sbncode/Supera index d84d726d9..844ebc5f2 160000 --- a/sbncode/Supera +++ b/sbncode/Supera @@ -1 +1 @@ -Subproject commit d84d726d95017f4b86a99537f6d86deeda3216c3 +Subproject commit 844ebc5f2ff5232942ad6c3b3761409534cc4574 From 3c5ddcdb8b9b35db2d76fa40ad3515c98821f1ad Mon Sep 17 00:00:00 2001 From: Brinden Carlson Date: Tue, 8 Apr 2025 11:08:40 -0500 Subject: [PATCH 060/367] Update Supera tag to support CRTs for SBND --- sbncode/Supera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Supera b/sbncode/Supera index 844ebc5f2..d84d726d9 160000 --- a/sbncode/Supera +++ b/sbncode/Supera @@ -1 +1 @@ -Subproject commit 844ebc5f2ff5232942ad6c3b3761409534cc4574 +Subproject commit d84d726d95017f4b86a99537f6d86deeda3216c3 From 566daded0fefef4ee471456a72ca591ab2ea9539 Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 10 Apr 2025 08:23:07 -0500 Subject: [PATCH 061/367] Update explicit references to 'EventWeightParameterSet::kMultisim' --- sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx index 640a84769..14d9c68f8 100644 --- a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx +++ b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx @@ -261,7 +261,7 @@ namespace sbn { //Let's make a weights based on the calculator you have requested - if(fParameterSet.fRWType == EventWeightParameterSet::kMultisim){ + if(fParameterSet.fRWType == EventWeightParameterSet::kMultiSim){ for (size_t i=0;isecond[i]; @@ -293,7 +293,7 @@ namespace sbn { return weights;//done, all 1 }// Hadronic parent check - if(fParameterSet.fRWType == EventWeightParameterSet::kMultisim){ + if(fParameterSet.fRWType == EventWeightParameterSet::kMultiSim){ for (unsigned int i = 0; int(weights.size()) < NUni; i++) {//if all weights are 1, no need to calculate weights; std::pair test_weight; @@ -338,7 +338,7 @@ namespace sbn { }; }//Iterate through the number of universes - }//Yes, Multisim + }//Yes, MultiSim } if(count_weights){ From eade067efa821ab8a1b26f63e10e94259fb5c0ac Mon Sep 17 00:00:00 2001 From: Giuseppe Cerati Date: Thu, 10 Apr 2025 21:25:50 -0500 Subject: [PATCH 062/367] add first NuGraph2 info to CAF --- sbncode/CAFMaker/CAFMakerParams.h | 18 +++++++ sbncode/CAFMaker/CAFMaker_module.cc | 39 +++++++++++++++ sbncode/CAFMaker/FillReco.cxx | 73 +++++++++++++++++++++++++++++ sbncode/CAFMaker/FillReco.h | 14 ++++++ 4 files changed, 144 insertions(+) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index d05eb8b9b..636fcda57 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -340,6 +340,24 @@ namespace caf "" //Empty by default, configured in icaruscode cafmaker_defs }; + Atom NuGraphSliceHitLabel { + Name("NuGraphSliceHitLabel"), + Comment("Label of NuGraph slice hit map."), + art::InputTag("nuslhits") + }; + + Atom NuGraphFilterLabel { + Name("NuGraphFilterLabel"), + Comment("Label of NuGraph filter."), + art::InputTag("NuGraph","filter") + }; + + Atom NuGraphSemanticLabel { + Name("NuGraphSemanticLabel"), + Comment("Label of NuGraph semantic."), + art::InputTag("NuGraph","semantic") + }; + Atom OpFlashLabel { Name("OpFlashLabel"), Comment("Label of PMT flash."), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 2728b395f..38a6e416c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -95,6 +95,7 @@ #include "lardataobj/RecoBase/Vertex.h" #include "lardataobj/RecoBase/Shower.h" #include "lardataobj/RecoBase/MCSFitResult.h" +#include "lardataobj/RecoBase/Cluster.h" #include "nusimdata/SimulationBase/MCFlux.h" #include "nusimdata/SimulationBase/MCTruth.h" @@ -1696,6 +1697,17 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } + // nu graph + std::vector< art::Handle> > ng2_slice_hit_map_handle(pandora_tag_suffixes.size()); + std::vector< art::Handle>> > ng2_filter_handle(pandora_tag_suffixes.size()); + std::vector< art::Handle>> > ng2_semantic_handle(pandora_tag_suffixes.size()); + for (unsigned i_tag = 0; i_tag < pandora_tag_suffixes.size(); i_tag++) { + const std::string &pandora_tag_suffix = pandora_tag_suffixes[i_tag]; + GetByLabelIfExists(evt, fParams.NuGraphSliceHitLabel().encode() + pandora_tag_suffix, ng2_slice_hit_map_handle[i_tag]); + GetByLabelIfExists(evt, fParams.NuGraphFilterLabel().label() + pandora_tag_suffix + ":" + fParams.NuGraphFilterLabel().instance(), ng2_filter_handle[i_tag]); + GetByLabelIfExists(evt, fParams.NuGraphSemanticLabel().label() + pandora_tag_suffix + ":" + fParams.NuGraphSemanticLabel().instance(), ng2_semantic_handle[i_tag]); + } + // The Standard Record // Branch entry definition -- contains list of slices, CRT information, and truth information StandardRecord rec; @@ -1752,6 +1764,12 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } + std::vector>> ng2_filter_vec; + std::vector>> ng2_semantic_vec; + art::fill_ptr_vector(ng2_filter_vec,ng2_filter_handle[producer]); + art::fill_ptr_vector(ng2_semantic_vec,ng2_semantic_handle[producer]); + FillSliceNuGraph(slcHits,*ng2_slice_hit_map_handle[producer],ng2_filter_vec,ng2_semantic_vec,recslc); + art::FindManyP fmOpT0 = FindManyPStrict(sliceList, evt, fParams.OpT0Label() + slice_tag_suff); std::vector> slcOpT0; @@ -1798,6 +1816,25 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::FindManyP fmSpacePointPFPs = FindManyPStrict(slcSpacePoints, evt, fParams.PFParticleLabel() + slice_tag_suff); + art::FindManyP fmPFPClusters = + FindManyPStrict(fmPFPart, evt, fParams.PFParticleLabel() + slice_tag_suff); + + std::vector>> fmPFPartHits; + // make Ptr's to clusters for cluster -> other object associations + if (fmPFPClusters.isValid()) { + for (size_t ipf=0; ipf> pfphits; + std::vector> pfclusters = fmPFPClusters.at(ipf); + art::FindManyP fmCluHits = FindManyPStrict(pfclusters, evt, fParams.PFParticleLabel() + slice_tag_suff); + for (size_t icl=0; icl fmShower = FindManyPStrict(fmPFPart, evt, fParams.RecoShowerLabel() + slice_tag_suff); @@ -2105,6 +2142,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillCNNScores(thisParticle, cnnScores, pfp); } + FillPPFNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp); + if (!thisTrack.empty()) { // it has a track! assert(thisTrack.size() == 1); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index f47265c1e..67b8b8f22 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -544,6 +544,26 @@ namespace caf } } + + void FillSliceNuGraph(const std::vector> &inputHits, + const std::vector &sliceHitsMap, + const std::vector>> &ngFilterResult, + const std::vector>> &ngSemanticResult, + caf::SRSlice &slice) + { + + //need to double check that the slice processed by NuGraph is the same under consideration + std::cout << "sizes=" << inputHits.size() << " " << sliceHitsMap.size() << " " << ngFilterResult.size() << " " << ngSemanticResult.size() << std::endl; + unsigned int nHits = inputHits.size(); + if (nHits==0 || nHits!=sliceHitsMap.size() || inputHits[0].key()!=sliceHitsMap[0]) return;//not the same slice! + + unsigned int npass = 0; + for ( unsigned int i = 0; i < nHits; i++ ) { + if (ngFilterResult.at(i)->at(0)>0.5) npass++; + } + slice.ng_filt_pass_frac = float(npass)/nHits; + } + //...................................................................... void FillTrackCRTHit(const std::vector> &t0match, @@ -950,6 +970,59 @@ namespace caf srpfp.cnnscore.nclusters = cnnscore->nClusters; } + void FillPPFNuGraph(const std::vector &sliceHitsMap, + const std::vector>> &ngFilterResult, + const std::vector>> &ngSemanticResult, + const std::vector> &pfpHits, + caf::SRPFP& srpfp, + bool allowEmpty) + { + + auto arg_max = [](std::vector const& vec) { + return std::distance(vec.begin(), std::max_element(vec.begin(), vec.end())); + }; + + // the nugraph elements are ordered the same as the sliceHitsMap + std::vector mappedhits; + for (auto& hit : pfpHits) { + auto it = std::find(sliceHitsMap.begin(), sliceHitsMap.end(), hit.key()); + if (it != sliceHitsMap.end()) { + size_t index = std::distance(sliceHitsMap.begin(), it); + mappedhits.push_back(index); + } + } + + if (mappedhits.size()>0) { + std::vector ng2sempfpcounts(5,0); + size_t ng2bkgpfpcount = 0; + for (size_t pos : mappedhits) { + auto scores = ngSemanticResult.at(pos); + std::vector ng2semscores; + for (size_t i=0;isize();i++) ng2semscores.push_back(scores->at(i)); + size_t sem_label = arg_max(ng2semscores); + ng2sempfpcounts[sem_label]++; + auto bkgscore = ngFilterResult.at(pos); + if (bkgscore->at(0)<0.5) ng2bkgpfpcount++; + } + srpfp.ng_sem_cat = arg_max(ng2sempfpcounts); + srpfp.ng_mip_frac = float(ng2sempfpcounts[0])/pfpHits.size(); + srpfp.ng_hip_frac = float(ng2sempfpcounts[1])/pfpHits.size(); + srpfp.ng_shr_frac = float(ng2sempfpcounts[2])/pfpHits.size(); + srpfp.ng_mhl_frac = float(ng2sempfpcounts[3])/pfpHits.size(); + srpfp.ng_dif_frac = float(ng2sempfpcounts[4])/pfpHits.size(); + srpfp.ng_bkg_frac = float(ng2bkgpfpcount)/pfpHits.size(); + } else { + srpfp.ng_sem_cat = -1; + srpfp.ng_mip_frac = -1.; + srpfp.ng_hip_frac = -1.; + srpfp.ng_shr_frac = -1.; + srpfp.ng_mhl_frac = -1.; + srpfp.ng_dif_frac = -1.; + srpfp.ng_bkg_frac = -1.; + } + + } + void FillHitVars(const recob::Hit& hit, unsigned producer, const recob::SpacePoint& spacepoint, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index c6df1ab39..5482077f1 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -20,6 +20,7 @@ #include "lardataobj/RecoBase/OpFlash.h" #include "lardataobj/RecoBase/OpHit.h" #include "lardataobj/AnalysisBase/Calorimetry.h" +#include "lardataobj/AnalysisBase/MVAOutput.h" #include "lardataobj/AnalysisBase/ParticleID.h" #include "lardataobj/AnalysisBase/T0.h" #include "lardataobj/RecoBase/PFParticleMetadata.h" @@ -104,6 +105,12 @@ namespace caf const std::vector> &inputPoints, caf::SRSlice &slice); + void FillSliceNuGraph(const std::vector> &inputHits, + const std::vector &sliceHitsMap, + const std::vector>> &ngFilterResult, + const std::vector>> &ngSemanticResult, + caf::SRSlice &slice); + bool SelectSlice(const caf::SRSlice &slice, bool cut_clear_cosmic); void FillTrackVars(const recob::Track& track, @@ -130,6 +137,13 @@ namespace caf caf::SRPFP& srpfp, bool allowEmpty = false); + void FillPPFNuGraph(const std::vector &sliceHitsMap, + const std::vector>> &ngFilterResult, + const std::vector>> &ngSemanticResult, + const std::vector> &pfpHits, + caf::SRPFP& srpfp, + bool allowEmpty= false); + void FillTrackCRTHit(const std::vector> &t0match, const std::vector> &hitmatch, bool use_ts0, From 33f56fbff4b31a34bb4787731269543ee85c99b0 Mon Sep 17 00:00:00 2001 From: Giuseppe Cerati Date: Thu, 10 Apr 2025 22:35:15 -0500 Subject: [PATCH 063/367] ensure CAF works if NuGraph2 products are not found --- sbncode/CAFMaker/CAFMakerParams.h | 6 +++--- sbncode/CAFMaker/CAFMaker_module.cc | 16 ++++++++++++---- sbncode/CAFMaker/FillReco.cxx | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 636fcda57..cf4cd7292 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -343,19 +343,19 @@ namespace caf Atom NuGraphSliceHitLabel { Name("NuGraphSliceHitLabel"), Comment("Label of NuGraph slice hit map."), - art::InputTag("nuslhits") + "" //Empty by default, please set to e.g. art::InputTag("nuslhits") }; Atom NuGraphFilterLabel { Name("NuGraphFilterLabel"), Comment("Label of NuGraph filter."), - art::InputTag("NuGraph","filter") + "" //Empty by default, please set to e.g. art::InputTag("NuGraph","filter") }; Atom NuGraphSemanticLabel { Name("NuGraphSemanticLabel"), Comment("Label of NuGraph semantic."), - art::InputTag("NuGraph","semantic") + "" //Empty by default, please set to e.g. art::InputTag("NuGraph","semantic") }; Atom OpFlashLabel { diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 38a6e416c..0e8b88482 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1766,9 +1766,15 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector>> ng2_filter_vec; std::vector>> ng2_semantic_vec; - art::fill_ptr_vector(ng2_filter_vec,ng2_filter_handle[producer]); - art::fill_ptr_vector(ng2_semantic_vec,ng2_semantic_handle[producer]); - FillSliceNuGraph(slcHits,*ng2_slice_hit_map_handle[producer],ng2_filter_vec,ng2_semantic_vec,recslc); + if (ng2_filter_handle[producer].isValid()) { + art::fill_ptr_vector(ng2_filter_vec,ng2_filter_handle[producer]); + } + if (ng2_semantic_handle[producer].isValid()) { + art::fill_ptr_vector(ng2_semantic_vec,ng2_semantic_handle[producer]); + } + if (ng2_slice_hit_map_handle[producer].isValid()) { + FillSliceNuGraph(slcHits,*ng2_slice_hit_map_handle[producer],ng2_filter_vec,ng2_semantic_vec,recslc); + } art::FindManyP fmOpT0 = FindManyPStrict(sliceList, evt, fParams.OpT0Label() + slice_tag_suff); @@ -2142,7 +2148,9 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillCNNScores(thisParticle, cnnScores, pfp); } - FillPPFNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp); + if (ng2_slice_hit_map_handle[producer].isValid()) { + FillPPFNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp); + } if (!thisTrack.empty()) { // it has a track! assert(thisTrack.size() == 1); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 67b8b8f22..1224a10da 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -553,7 +553,7 @@ namespace caf { //need to double check that the slice processed by NuGraph is the same under consideration - std::cout << "sizes=" << inputHits.size() << " " << sliceHitsMap.size() << " " << ngFilterResult.size() << " " << ngSemanticResult.size() << std::endl; + //std::cout << "sizes=" << inputHits.size() << " " << sliceHitsMap.size() << " " << ngFilterResult.size() << " " << ngSemanticResult.size() << std::endl; unsigned int nHits = inputHits.size(); if (nHits==0 || nHits!=sliceHitsMap.size() || inputHits[0].key()!=sliceHitsMap[0]) return;//not the same slice! From 3b15cc82213c50958b246b48364c0abeeaa96eca Mon Sep 17 00:00:00 2001 From: kjplows Date: Mon, 14 Apr 2025 01:36:24 -0500 Subject: [PATCH 064/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 071970895..3463744c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.04.07 LANGUAGES CXX) +project(sbncode VERSION 10.04.08 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index e8f5396d9..a2537dd84 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,12 +254,12 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_04_07 - -sbnalg v10_04_07 - +larsoft v10_04_08 - +sbnalg v10_04_08 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - -nusystematics v1_05_04 - +nusystematics v1_05_06 - cetmodules v3_24_01 - only_for_build end_product_list #################################### From 0e6df7634c636913ef165872c299277ac9b8f598 Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 17 Apr 2025 10:15:30 -0500 Subject: [PATCH 065/367] update signature with fSkipSimChannelTrackIDs (default false) --- sbncode/LArG4/MergeSimSourcesSBN_module.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sbncode/LArG4/MergeSimSourcesSBN_module.cc b/sbncode/LArG4/MergeSimSourcesSBN_module.cc index da84303a7..79e3b75f7 100644 --- a/sbncode/LArG4/MergeSimSourcesSBN_module.cc +++ b/sbncode/LArG4/MergeSimSourcesSBN_module.cc @@ -97,6 +97,12 @@ class sbn::MergeSimSourcesSBN : public art::EDProducer { true // default }; + fhicl::Atom SkipSimChannelTrackIDs{ + fhicl::Name{"SkipSimChannelTrackIDs"}, + fhicl::Comment{"Skip G4 track IDs in SimChannels"}, + false // default + }; + fhicl::Atom FillAuxDetSimChannels{ fhicl::Name{"FillAuxDetSimChannels"}, fhicl::Comment{"whether to merge AuxDetSimChannels"}, @@ -156,6 +162,7 @@ class sbn::MergeSimSourcesSBN : public art::EDProducer { bool const fFillMCParticlesAssociated; bool const fFillSimPhotons; bool const fFillSimChannels; + bool const fSkipSimChannelTrackIDs; bool const fFillAuxDetSimChannels; bool const fFillSimEnergyDeposits; std::vector const fEnergyDepositionInstances; @@ -198,6 +205,7 @@ sbn::MergeSimSourcesSBN::MergeSimSourcesSBN(Parameters const& params) , fFillMCParticlesAssociated(params().FillMCParticlesAssociated()) , fFillSimPhotons(params().FillSimPhotons()) , fFillSimChannels(params().FillSimChannels()) + , fSkipSimChannelTrackIDs(params().SkipSimChannelTrackIDs()) , fFillAuxDetSimChannels(params().FillAuxDetSimChannels()) , fFillSimEnergyDeposits( getOptionalValue(params().FillSimEnergyDeposits) @@ -349,7 +357,7 @@ void sbn::MergeSimSourcesSBN::produce(art::Event& e) if (fFillSimChannels) { auto const& input_scCol = e.getProduct>(input_label); - MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source); + MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source, !fSkipSimChannelTrackIDs); } if (fFillAuxDetSimChannels) { @@ -451,6 +459,7 @@ void sbn::MergeSimSourcesSBN::dumpConfiguration() const if (fFillMCParticlesAssociated) log << "\n - filling MCParticlesAssociated"; if (fFillSimChannels) log << "\n - filling SimChannels"; + if (fSkipSimChannelTrackIDs) log << "\n - skipping track IDs in filling SimChannels"; if (fFillAuxDetSimChannels) log << "\n - filling AuxDetSimChannels"; From d29a41cc34a266a23e4aee3ceaecc4bbf2c60c18 Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 17 Apr 2025 10:21:44 -0500 Subject: [PATCH 066/367] fix the bool --- sbncode/LArG4/MergeSimSourcesSBN_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/LArG4/MergeSimSourcesSBN_module.cc b/sbncode/LArG4/MergeSimSourcesSBN_module.cc index 79e3b75f7..19e1cbe1c 100644 --- a/sbncode/LArG4/MergeSimSourcesSBN_module.cc +++ b/sbncode/LArG4/MergeSimSourcesSBN_module.cc @@ -357,7 +357,7 @@ void sbn::MergeSimSourcesSBN::produce(art::Event& e) if (fFillSimChannels) { auto const& input_scCol = e.getProduct>(input_label); - MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source, !fSkipSimChannelTrackIDs); + MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source, fSkipSimChannelTrackIDs); } if (fFillAuxDetSimChannels) { From 59f21ed12df4db7f7fd2a5d66ec4f23ffd952cae Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 18 Apr 2025 06:33:37 -0500 Subject: [PATCH 067/367] please let me run the CI --- ups/product_deps | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ups/product_deps b/ups/product_deps index a2537dd84..7f73d7985 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,12 +254,12 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_04_08 - +larsoft v10_05_00 - sbnalg v10_04_08 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - -nusystematics v1_05_06 - +nusystematics v1_05_07 - cetmodules v3_24_01 - only_for_build end_product_list #################################### From 0bb036dec15dcddf34ea4614510c1bd5d1281e22 Mon Sep 17 00:00:00 2001 From: Tracy Usher Date: Mon, 21 Apr 2025 13:04:12 -0700 Subject: [PATCH 068/367] Introduce a version of the gaushitfinder module which uses as input the ChannelROIs instead of recob::Wire objects --- sbncode/CMakeLists.txt | 1 + sbncode/HitFinder/CMakeLists.txt | 54 ++ sbncode/HitFinder/GaussHitFinderSBN_module.cc | 669 ++++++++++++++++++ sbncode/HitFinder/hitfindermodules_sbn.fcl | 68 ++ sbncode/Supera | 2 +- 5 files changed, 793 insertions(+), 1 deletion(-) create mode 100644 sbncode/HitFinder/CMakeLists.txt create mode 100644 sbncode/HitFinder/GaussHitFinderSBN_module.cc create mode 100644 sbncode/HitFinder/hitfindermodules_sbn.fcl diff --git a/sbncode/CMakeLists.txt b/sbncode/CMakeLists.txt index 9b7cfc5ed..daed2590a 100644 --- a/sbncode/CMakeLists.txt +++ b/sbncode/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(GeometryTools) add_subdirectory(CosmicID) add_subdirectory(DetSim) add_subdirectory(Cluster3D) +add_subdirectory(HitFinder) # Supera # diff --git a/sbncode/HitFinder/CMakeLists.txt b/sbncode/HitFinder/CMakeLists.txt new file mode 100644 index 000000000..4961f4dcd --- /dev/null +++ b/sbncode/HitFinder/CMakeLists.txt @@ -0,0 +1,54 @@ + +art_make_library( + LIBRARIES + lardataobj::RawData + lardataobj::RecoBase + lardata::Utilities + fhiclcpp::fhiclcpp + cetlib::cetlib +) +set( MODULE_LIBRARIES + larcorealg::Geometry + larcorealg::Geometry + larcore::Geometry_Geometry_service + lardata::Utilities + larevt::Filters + lardataobj::RawData + larevt::CalibrationDBI_IOVData + larevt::CalibrationDBI_Providers + lardataobj::RecoBase + lardata::ArtDataHelper + larreco::RecoAlg + sbnobj::ICARUS_TPC + sbnobj::Common_Utilities + art::Framework_Core + art::Framework_Principal + art::Framework_Services_Registry + art_root_io::tfile_support ROOT::Core + art_root_io::TFileService_service + art::Persistency_Common + art::Persistency_Provenance + art::Utilities + canvas::canvas + messagefacility::MF_MessageLogger + messagefacility::headers + fhiclcpp::fhiclcpp + cetlib::cetlib + ROOT::Geom + ROOT::XMLIO + ROOT::Gdml + ROOT::FFTW + + ) +cet_build_plugin(GaussHitFinderSBN art::module + LIBRARIES ${MODULE_LIBRARIES} + larreco::HitFinder + larreco::CandidateHitFinderTool + larreco::PeakFitterTool + ) + + +install_headers() +install_fhicl() +install_source() + diff --git a/sbncode/HitFinder/GaussHitFinderSBN_module.cc b/sbncode/HitFinder/GaussHitFinderSBN_module.cc new file mode 100644 index 000000000..7dfe59334 --- /dev/null +++ b/sbncode/HitFinder/GaussHitFinderSBN_module.cc @@ -0,0 +1,669 @@ +//////////////////////////////////////////////////////////////////////// +// +// GaussHitFinder class +// +// jaasaadi@syr.edu +// +// This algorithm is designed to find hits on wires after deconvolution. +// ----------------------------------- +// This algorithm is based on the FFTHitFinder written by Brian Page, +// Michigan State University, for the ArgoNeuT experiment. +// +// +// The algorithm walks along the wire and looks for pulses above threshold +// The algorithm then attempts to fit n-gaussians to these pulses where n +// is set by the number of peaks found in the pulse +// If the Chi2/NDF returned is "bad" it attempts to fit n+1 gaussians to +// the pulse. If this is a better fit it then uses the parameters of the +// Gaussian fit to characterize the "hit" object +// +// To use this simply include the following in your producers: +// gaushit: @local::microboone_GaussHitFinderSBN +// gaushit: @local::argoneut_GaussHitFinderSBN +//////////////////////////////////////////////////////////////////////// + +// C/C++ standard library +#include // std::accumulate() +#include +#include // std::unique_ptr() +#include +#include // std::move() + +// Framework includes +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/SharedProducer.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "art/Utilities/Globals.h" +#include "art/Utilities/make_tool.h" +#include "art_root_io/TFileService.h" +#include "canvas/Persistency/Common/FindOneP.h" +#include "fhiclcpp/ParameterSet.h" + +// LArSoft Includes +#include "larcore/Geometry/WireReadout.h" +#include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t +#include "larreco/HitFinder/HitFilterAlg.h" + +#include "sbnobj/ICARUS/TPC/ChannelROI.h" +#include "sbnobj/Common/Utilities//HitCreator.h" +#include "sbnobj/ICARUS/TPC/Hit.h" + +#include "larreco/HitFinder/HitFinderTools/ICandidateHitFinder.h" +#include "larreco/HitFinder/HitFinderTools/IPeakFitter.h" + +// ROOT Includes +#include "TH1F.h" +#include "TMath.h" + +#include "tbb/concurrent_vector.h" +#include "tbb/parallel_for.h" + +namespace hit { + class GaussHitFinderSBN : public art::SharedProducer { + public: + explicit GaussHitFinderSBN(fhicl::ParameterSet const& pset, art::ProcessingFrame const&); + + private: + void produce(art::Event& evt, art::ProcessingFrame const&) override; + void beginJob(art::ProcessingFrame const&) override; + + std::vector FillOutHitParameterVector(const std::vector& input); + + const bool fFilterHits; + const bool fFillHists; + + const std::string fCalDataModuleLabel; + const std::string fAllHitsInstanceName; + + const std::vector fLongMaxHitsVec; /// fLongPulseWidthVec; /// + fAreaNormsVec; /// fPulseHeightCuts; + const std::vector fPulseWidthCuts; + const std::vector fPulseRatioCuts; + + std::atomic fEventCount{0}; + + //only Standard and Morphological implementation is threadsafe. + std::vector> + fHitFinderToolVec; ///< For finding candidate hits + // only Marqdt implementation is threadsafe. + std::unique_ptr fPeakFitterTool; ///< Perform fit to candidate peaks + //HitFilterAlg implementation is threadsafe. + std::unique_ptr fHitFilterAlg; ///< algorithm used to filter out noise hits + + //only used when fFillHists is true and in single threaded mode. + TH1F* fFirstChi2; + TH1F* fChi2; + + }; // class GaussHitFinderSBN + + //------------------------------------------------- + //------------------------------------------------- + GaussHitFinderSBN::GaussHitFinderSBN(fhicl::ParameterSet const& pset, art::ProcessingFrame const&) + : SharedProducer{pset} + , fFilterHits(pset.get("FilterHits", false)) + , fFillHists(pset.get("FillHists", false)) + , fCalDataModuleLabel(pset.get("CalDataModuleLabel")) + , fAllHitsInstanceName(pset.get("AllHitsInstanceName", "")) + , fLongMaxHitsVec(pset.get>("LongMaxHits", std::vector() = {25, 25, 25})) + , fLongPulseWidthVec( + pset.get>("LongPulseWidth", std::vector() = {16, 16, 16})) + , fMaxMultiHit(pset.get("MaxMultiHit")) + , fAreaMethod(pset.get("AreaMethod")) + , fAreaNormsVec(FillOutHitParameterVector(pset.get>("AreaNorms"))) + , fChi2NDF(pset.get("Chi2NDF")) + , fPulseHeightCuts( + pset.get>("PulseHeightCuts", std::vector() = {3.0, 3.0, 3.0})) + , fPulseWidthCuts( + pset.get>("PulseWidthCuts", std::vector() = {2.0, 1.5, 1.0})) + , fPulseRatioCuts( + pset.get>("PulseRatioCuts", std::vector() = {0.35, 0.40, 0.20})) + { + if (fFillHists && art::Globals::instance()->nthreads() > 1u) { + throw art::Exception(art::errors::Configuration) + << "Cannot fill histograms when multiple threads configured, please set fFillHists to " + "false or change number of threads to 1\n"; + } + async(); + if (fFilterHits) { + fHitFilterAlg = std::make_unique(pset.get("HitFilterAlg")); + } + + // recover the tool to do the candidate hit finding + // Recover the vector of fhicl parameters for the ROI tools + const fhicl::ParameterSet& hitFinderTools = pset.get("HitFinderToolVec"); + + fHitFinderToolVec.resize(hitFinderTools.get_pset_names().size()); + + for (const std::string& hitFinderTool : hitFinderTools.get_pset_names()) { + const fhicl::ParameterSet& hitFinderToolParamSet = + hitFinderTools.get(hitFinderTool); + size_t planeIdx = hitFinderToolParamSet.get("Plane"); + + fHitFinderToolVec.at(planeIdx) = + art::make_tool(hitFinderToolParamSet); + } + + // Recover the peak fitting tool + fPeakFitterTool = + art::make_tool(pset.get("PeakFitter")); + + // let HitCollectionCreator declare that we are going to produce + // hits and associations with wires and raw digits + // We want the option to output two hit collections, one filtered + // and one with all hits. The key to doing this will be a non-null + // instance name for the second collection + // (with no particular product label) + sbn::HitCollectionCreator::declare_products( + producesCollector(), fAllHitsInstanceName, true, false); //fMakeRawDigitAssns); + + // and now the filtered hits... + if (fAllHitsInstanceName != "") + sbn::HitCollectionCreator::declare_products( + producesCollector(), "", true, false); //fMakeRawDigitAssns); + + return; + } // GaussHitFinderSBN::GaussHitFinderSBN() + + //------------------------------------------------- + //------------------------------------------------- + std::vector GaussHitFinderSBN::FillOutHitParameterVector(const std::vector& input) + { + if (input.size() == 0) + throw std::runtime_error( + "GaussHitFinderSBN::FillOutHitParameterVector ERROR! Input config vector has zero size."); + + std::vector output; + auto const& wireReadoutGeom = art::ServiceHandle()->Get(); + const unsigned int N_PLANES = wireReadoutGeom.Nplanes(); + + if (input.size() == 1) + output.resize(N_PLANES, input[0]); + else if (input.size() == N_PLANES) + output = input; + else + throw std::runtime_error("GaussHitFinderSBN::FillOutHitParameterVector ERROR! Input config " + "vector size !=1 and !=N_PLANES."); + return output; + } + + //------------------------------------------------- + //------------------------------------------------- + void GaussHitFinderSBN::beginJob(art::ProcessingFrame const&) + { + // get access to the TFile service + art::ServiceHandle tfs; + + // ====================================== + // === Hit Information for Histograms === + if (fFillHists) { + fFirstChi2 = tfs->make("fFirstChi2", "#chi^{2}", 10000, 0, 5000); + fChi2 = tfs->make("fChi2", "#chi^{2}", 10000, 0, 5000); + } + } + + // This algorithm uses the fact that deconvolved signals are very smooth + // and looks for hits as areas between local minima that have signal above + // threshold. + //------------------------------------------------- + void GaussHitFinderSBN::produce(art::Event& evt, art::ProcessingFrame const&) + { + unsigned int count = fEventCount.fetch_add(1); + //================================================================================================== + + TH1::AddDirectory(kFALSE); + + auto const& wireReadoutGeom = art::ServiceHandle()->Get(); + + // ############################################### + // ### Making a ptr vector to put on the event ### + // ############################################### + // this contains the hit collection + // and its associations to wires and raw digits + sbn::HitCollectionCreator allHitCol(evt, fAllHitsInstanceName, true, false); + + // Handle the filtered hits collection... + sbn::HitCollectionCreator hcol(evt, "", true, false); + sbn::HitCollectionCreator* filteredHitCol = 0; + + if (fFilterHits) filteredHitCol = &hcol; + + //store in a thread safe way + struct hitstruct { + sbn::Hit hit_tbb; + art::Ptr channelROI_tbb; + }; + + tbb::concurrent_vector hitstruct_vec; + tbb::concurrent_vector filthitstruct_vec; + + // ########################################## + // ### Reading in the Wire List object(s) ### + // ########################################## + art::Handle> channelROIVecHandle; + evt.getByLabel(fCalDataModuleLabel, channelROIVecHandle); + + //################################################# + //### Set the charge determination method ### + //### Default is to compute the normalized area ### + //################################################# + std::function chargeFunc = + [](double /* peakMean */, + double peakAmp, + double peakWidth, + double areaNorm, + int /* low */, + int /* hi */) { return std::sqrt(2 * TMath::Pi()) * peakAmp * peakWidth / areaNorm; }; + + //############################################## + //### Alternative is to integrate over pulse ### + //############################################## + if (fAreaMethod == 0) + chargeFunc = [](double peakMean, + double peakAmp, + double peakWidth, + double /* areaNorm */, + int low, + int hi) { + double charge(0); + for (int sigPos = low; sigPos < hi; sigPos++) + charge += peakAmp * TMath::Gaus(sigPos, peakMean, peakWidth); + return charge; + }; + + //############################## + //### Looping over the wires ### + //############################## + tbb::parallel_for( + static_cast(0), + channelROIVecHandle->size(), + [&](size_t& channelROIIter) { + // #################################### + // ### Getting this particular channelROI ### + // #################################### + art::Ptr channelROI(channelROIVecHandle, channelROIIter); + + // --- Setting Channel Number and Signal type --- + + raw::ChannelID_t channel = channelROI->Channel(); + + // get the WireID for this hit + std::vector wids = wireReadoutGeom.ChannelToWire(channel); + // for now, just take the first option returned from ChannelToWire + geo::WireID wid = wids[0]; + // We need to know the plane to look up parameters + geo::PlaneID::PlaneID_t plane = wid.Plane; + + // ---------------------------------------------------------- + // -- Setting the appropriate signal widths and thresholds -- + // -- for the right plane. -- + // ---------------------------------------------------------- + + // ################################################# + // ### Set up to loop over ROI's for this wire ### + // ################################################# + const recob::ChannelROI::RegionsOfInterest_f signalROI = channelROI->SignalROIF(); + + tbb::parallel_for( + static_cast(0), + signalROI.n_ranges(), + [&](size_t& rangeIter) { + const auto& range = signalROI.range(rangeIter); + // ROI start time + raw::TDCtick_t roiFirstBinTick = range.begin_index(); + + // ########################################################### + // ### Scan the waveform and find candidate peaks + merge ### + // ########################################################### + + reco_tool::ICandidateHitFinder::HitCandidateVec hitCandidateVec; + reco_tool::ICandidateHitFinder::MergeHitCandidateVec mergedCandidateHitVec; + + fHitFinderToolVec.at(plane)->findHitCandidates( + range, 0, channel, count, hitCandidateVec); + fHitFinderToolVec.at(plane)->MergeHitCandidates( + range, hitCandidateVec, mergedCandidateHitVec); + + // ####################################################### + // ### Lets loop over the pulses we found on this wire ### + // ####################################################### + + for (auto& mergedCands : mergedCandidateHitVec) { + int startT = mergedCands.front().startTick; + int endT = mergedCands.back().stopTick; + + // ### Putting in a protection in case things went wrong ### + // ### In the end, this primarily catches the case where ### + // ### a fake pulse is at the start of the ROI ### + if (endT - startT < 5) continue; + + // ####################################################### + // ### Clearing the parameter vector for the new Pulse ### + // ####################################################### + + // === Setting The Number Of Gaussians to try === + int nGausForFit = mergedCands.size(); + + // ################################################## + // ### Calling the function for fitting Gaussians ### + // ################################################## + double chi2PerNDF(0.); + int NDF(1); + /*stand alone + reco_tool::IPeakFitter::PeakParamsVec peakParamsVec(nGausForFit); + */ + reco_tool::IPeakFitter::PeakParamsVec peakParamsVec; + + // ####################################################### + // ### If # requested Gaussians is too large then punt ### + // ####################################################### + if (mergedCands.size() <= fMaxMultiHit) { + fPeakFitterTool->findPeakParameters( + range.data(), mergedCands, peakParamsVec, chi2PerNDF, NDF); + + // If the chi2 is infinite then there is a real problem so we bail + if (!(chi2PerNDF < std::numeric_limits::infinity())) { + chi2PerNDF = 2. * fChi2NDF; + NDF = 2; + } + + if (fFillHists) fFirstChi2->Fill(chi2PerNDF); + } + + // ####################################################### + // ### If too large then force alternate solution ### + // ### - Make n hits from pulse train where n will ### + // ### depend on the fhicl parameter fLongPulseWidth ### + // ### Also do this if chi^2 is too large ### + // ####################################################### + if (mergedCands.size() > fMaxMultiHit || nGausForFit * chi2PerNDF > fChi2NDF) { + int longPulseWidth = fLongPulseWidthVec.at(plane); + int nHitsThisPulse = (endT - startT) / longPulseWidth; + + if (nHitsThisPulse > fLongMaxHitsVec.at(plane)) { + nHitsThisPulse = fLongMaxHitsVec.at(plane); + longPulseWidth = (endT - startT) / nHitsThisPulse; + } + + if (nHitsThisPulse * longPulseWidth < endT - startT) nHitsThisPulse++; + + int firstTick = startT; + int lastTick = std::min(firstTick + longPulseWidth, endT); + + peakParamsVec.clear(); + nGausForFit = nHitsThisPulse; + NDF = 1.; + chi2PerNDF = chi2PerNDF > fChi2NDF ? chi2PerNDF : -1.; + + for (int hitIdx = 0; hitIdx < nHitsThisPulse; hitIdx++) { + // This hit parameters + double ROIsumADC = + std::accumulate(range.begin() + firstTick, range.begin() + lastTick, 0.); + double peakSigma = (lastTick - firstTick) / 3.; // Set the width... + double peakAmp = 0.3989 * ROIsumADC / peakSigma; // Use gaussian formulation + double peakMean = (firstTick + lastTick) / 2.; + + // Store hit params + reco_tool::IPeakFitter::PeakFitParams_t peakParams; + + peakParams.peakCenter = peakMean; + peakParams.peakCenterError = 0.1 * peakMean; + peakParams.peakSigma = peakSigma; + peakParams.peakSigmaError = 0.1 * peakSigma; + peakParams.peakAmplitude = peakAmp; + peakParams.peakAmplitudeError = 0.1 * peakAmp; + + peakParamsVec.push_back(peakParams); + + // set for next loop + firstTick = lastTick; + lastTick = std::min(lastTick + longPulseWidth, endT); + } + } + + // ####################################################### + // ### Loop through returned peaks and make recob hits ### + // ####################################################### + + int numHits(0); + + // Make a container for what will be the filtered collection + std::vector filteredHitVec; + + float nextpeak(0); + float prevpeak(0); + float nextpeakSig(0); + float prevpeakSig(0); + float nsigmaADC(2.0); + float newright(0); + float newleft(0); + for (const auto& peakParams : peakParamsVec) { + // Extract values for this hit + float peakAmp = peakParams.peakAmplitude; + float peakMean = peakParams.peakCenter; + float peakWidth = peakParams.peakSigma; + + //std::cout<<" ans hits "< 0) { + prevpeak = (peakParamsVec.at(numHits - 1)).peakCenter; + prevpeakSig = (peakParamsVec.at(numHits - 1)).peakSigma; + //std::cout<<" ans size "<::const_iterator sumStartItr = range.begin() + startT; + std::vector::const_iterator sumEndItr = range.begin() + endT; + + //### limits for the sum of the Hit based on the gaussian peak and sigma + std::vector::const_iterator HitsumStartItr = + range.begin() + peakMean - nsigmaADC * peakWidth; + std::vector::const_iterator HitsumEndItr = + range.begin() + peakMean + nsigmaADC * peakWidth; + + if (nGausForFit > 1) { + if (numHits > 0) { + if ((peakMean - nsigmaADC * peakWidth) < (prevpeak + nsigmaADC * prevpeakSig)) { + float difPeak = peakMean - prevpeak; + float weightpeak = prevpeakSig / (prevpeakSig + peakWidth); + HitsumStartItr = range.begin() + prevpeak + difPeak * weightpeak; + newleft = prevpeak + difPeak * weightpeak; + } + } + + if (numHits < nGausForFit - 1) { + if ((peakMean + nsigmaADC * peakWidth) > (nextpeak - nsigmaADC * nextpeakSig)) { + float difPeak = nextpeak - peakMean; + float weightpeak = peakWidth / (nextpeakSig + peakWidth); + HitsumEndItr = range.begin() + peakMean + difPeak * weightpeak; + newright = peakMean + difPeak * weightpeak; + } + } + } + + //protection to avoid negative ranges + if (newright - newleft < 0) continue; + if (HitsumStartItr > HitsumEndItr) continue; + + //avoid ranges out of ROI if it happens + if (HitsumStartItr < sumStartItr) HitsumStartItr = sumStartItr; + + if (HitsumEndItr > sumEndItr) HitsumEndItr = sumEndItr; + + // ### Sum of ADC counts + float ROIsumADC = std::accumulate(sumStartItr, sumEndItr, 0.); + float HitsumADC = std::accumulate(HitsumStartItr, HitsumEndItr, 0.); + float peakTime = peakMean + roiFirstBinTick; + float chi2ByNDF = chi2PerNDF; // convert to float + + // ok, now create the hit + sbn::HitCreator hitcreator( + *channelROI, // channelROI reference + wid, // wire ID + startT + roiFirstBinTick, // start_tick TODO check + endT + roiFirstBinTick, // end_tick TODO check + peakWidth, // rms + peakTime, // peak_time + peakMeanErr, // sigma_peak_time + peakAmp, // peak_amplitude + peakAmpErr, // sigma_peak_amplitude + charge, // hit_integral + chargeErr, // hit_sigma_integral + ROIsumADC, // summedADC of the ROI + HitsumADC, // summedADC of the Hit + nGausForFit, // multiplicity + numHits, // local_index TODO check that the order is correct + chi2ByNDF, // goodness_of_fit + NDF // dof + ); + + if (filteredHitCol) filteredHitVec.push_back(hitcreator.copy()); + + const sbn::Hit hit(hitcreator.move()); + + // This loop will store ALL hits + hitstruct tmp{std::move(hit), channelROI}; + hitstruct_vec.push_back(std::move(tmp)); + + numHits++; + } // <---End loop over gaussians + + // Should we filter hits? + if (filteredHitCol && !filteredHitVec.empty()) { + // ####################################################################### + // Is all this sorting really necessary? Would it be faster to just loop + // through the hits and perform simple cuts on amplitude and width on a + // hit-by-hit basis, either here in the module (using fPulseHeightCuts and + // fPulseWidthCuts) or in HitFilterAlg? + // ####################################################################### + + // Sort in ascending peak height + std::sort(filteredHitVec.begin(), + filteredHitVec.end(), + [](const auto& left, const auto& right) { + return left.PeakAmplitude() > right.PeakAmplitude(); + }); + + // Reject if the first hit fails the PH/wid cuts + if (filteredHitVec.front().PeakAmplitude() < fPulseHeightCuts.at(plane) || + filteredHitVec.front().RMS() < fPulseWidthCuts.at(plane)) + filteredHitVec.clear(); + + // Now check other hits in the snippet + if (filteredHitVec.size() > 1) { + // The largest pulse height will now be at the front... + float largestPH = filteredHitVec.front().PeakAmplitude(); + + // Find where the pulse heights drop below threshold + float threshold(fPulseRatioCuts.at(plane)); + + std::vector::iterator smallHitItr = + std::find_if(filteredHitVec.begin(), + filteredHitVec.end(), + [largestPH, threshold](const auto& hit) { + return hit.PeakAmplitude() < 8. && + hit.PeakAmplitude() / largestPH < threshold; + }); + + // Shrink to fit + if (smallHitItr != filteredHitVec.end()) + filteredHitVec.resize(std::distance(filteredHitVec.begin(), smallHitItr)); + + // Resort in time order + std::sort(filteredHitVec.begin(), + filteredHitVec.end(), + [](const auto& left, const auto& right) { + return left.PeakTime() < right.PeakTime(); + }); + } + + // Copy the hits we want to keep to the filtered hit collection +// for (const auto& filteredHit : filteredHitVec) +// if (!fHitFilterAlg || fHitFilterAlg->IsGoodHit(filteredHit)) { +// hitstruct tmp{std::move(filteredHit), channelROI}; +// filthitstruct_vec.push_back(std::move(tmp)); +// } +// + if (fFillHists) fChi2->Fill(chi2PerNDF); + } + } //<---End loop over merged candidate hits + } //<---End looping over ROI's + ); //end tbb parallel for + } //<---End looping over all the wires + ); //end tbb parallel for + + for (size_t i = 0; i < hitstruct_vec.size(); i++) { + allHitCol.emplace_back(hitstruct_vec[i].hit_tbb, hitstruct_vec[i].channelROI_tbb); + } + + for (size_t j = 0; j < filthitstruct_vec.size(); j++) { + filteredHitCol->emplace_back(filthitstruct_vec[j].hit_tbb, filthitstruct_vec[j].channelROI_tbb); + } + + //================================================================================================== + // End of the event -- move the hit collection and the associations into the event + + if (filteredHitCol) { + + // If we filtered hits but no instance name was + // specified for the "all hits" collection, then + // only save the filtered hits to the event + if (fAllHitsInstanceName == "") { + filteredHitCol->put_into(evt); + + // otherwise, save both + } + else { + filteredHitCol->put_into(evt); + allHitCol.put_into(evt); + } + } + else { + allHitCol.put_into(evt); + } + } // End of produce() + + DEFINE_ART_MODULE(GaussHitFinderSBN) + +} // end of hit namespace diff --git a/sbncode/HitFinder/hitfindermodules_sbn.fcl b/sbncode/HitFinder/hitfindermodules_sbn.fcl new file mode 100644 index 000000000..6d7d55478 --- /dev/null +++ b/sbncode/HitFinder/hitfindermodules_sbn.fcl @@ -0,0 +1,68 @@ +// from larreco/RecoAlg: +#include "hitalgorithms.fcl" +#include "hitfindermodules.fcl" + +BEGIN_PROLOG + +# This defines a version of the Gauss Hit Finder that uses as input ChannelROIs instead of Wire +# In principle all default parameters remain the same. + +gauss_hitfinder: +{ + module_type: "GaussHitFinderSBN" + CalDataModuleLabel: "caldata" + MaxMultiHit: 5 # maximum hits for multi gaussia fit attempt + AreaMethod: 0 # 0 = area by integral, 1 = area by gaussian area formula + AreaNorms: [ 1.0, 1.0, 1.0 ] # normalizations that put signal area in + # same scale as peak height. + TryNplus1Fits: false # Don't try to refit with extra peak if bad chisq + LongMaxHits: [ 25, 25, 25] # max number hits in long pulse trains + LongPulseWidth: [ 10, 10, 10] # max widths for hits in long pulse trains + Chi2NDF: 500. # maximum Chisquared / NDF allowed to store fit, if fail + # will use "long" pulse method to return hit + AllHitsInstanceName: "" # If non-null then this will be the instance name of all hits output to event + # in this case there will be two hit collections, one filtered and one containing all hits + + # Candididate peak finding done by tool, one tool instantiated per plane (but could be other divisions too) + HitFinderToolVec: + { + CandidateHitsPlane0: @local::candhitfinder_standard # plane 0 + CandidateHitsPlane1: @local::candhitfinder_standard # plane 1 + CandidateHitsPlane2: @local::candhitfinder_standard # plane 2 + } + + # Declare the peak fitting tool + PeakFitter: @local::peakfitter_mrqdt + + # The below are for the hit filtering section of the gaushit finder + FilterHits: false # true = do not keep undesired hits according to settings of HitFilterAlg object + HitFilterAlg: + { + AlgName: "HitFilterAlg" + MinPulseHeight: [5.0, 5.0, 5.0] #minimum hit peak amplitude per plane + MinPulseSigma: [1.0, 1.0, 1.0] #minimum hit rms per plane + } + # In addition to the filter alg we can also filter hits on the same pulse train + PulseHeightCuts: [3.0, 3.0, 3.0 ] # Minimum pulse height + PulseWidthCuts: [2.0, 1.5, 1.0 ] # Minimum pulse width + PulseRatioCuts: [0.35, 0.40, 0.20] # Ratio of pulse height to width +} + +# Define sbn version of gaushit finder +gausshit_sbn: @local::gauss_hitfinder + +# Now set parameters for the GaussHitFinderSBN +# Note these are "default" for ICARUS and will move to a fcl file in icaruscode +gausshit_sbn.PeakFitter.MinWidth: 1 +gausshit_sbn.PeakFitter.FloatBaseline: false +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane0: @local::candhitfinder_standard +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane0.Plane: 0 +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane0.RoiThreshold: 9. +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane1: @local::candhitfinder_standard +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane1.Plane: 1 +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane1.RoiThreshold: 9.5 +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane2: @local::candhitfinder_standard +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane2.Plane: 2 +gausshit_sbn.HitFinderToolVec.CandidateHitsPlane2.RoiThreshold: 9. + +END_PROLOG diff --git a/sbncode/Supera b/sbncode/Supera index 844ebc5f2..d84d726d9 160000 --- a/sbncode/Supera +++ b/sbncode/Supera @@ -1 +1 @@ -Subproject commit 844ebc5f2ff5232942ad6c3b3761409534cc4574 +Subproject commit d84d726d95017f4b86a99537f6d86deeda3216c3 From dae37ab9f65a9e7ebc858203584eb4bda07692bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Tue, 22 Apr 2025 13:12:05 -0500 Subject: [PATCH 069/367] Create function to fill sbnd opflash --- sbncode/CAFMaker/CAFMaker_module.cc | 56 +++++++++++++++++++++-------- sbncode/CAFMaker/FillReco.cxx | 37 ++++++++++++++++++- sbncode/CAFMaker/FillReco.h | 9 ++++- 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 2728b395f..c50973961 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1654,26 +1654,52 @@ void CAFMaker::produce(art::Event& evt) noexcept { // Get all of the OpFlashes std::vector srflashes; + if(fDet == kICARUS) + { + for (const std::string& pandora_tag_suffix : pandora_tag_suffixes) { + art::Handle> flashes_handle; + GetByLabelStrict(evt, fParams.OpFlashLabel() + pandora_tag_suffix, flashes_handle); + // fill into event + if (flashes_handle.isValid()) { + const std::vector &opflashes = *flashes_handle; + int cryostat = ( pandora_tag_suffix.find("W") != std::string::npos ) ? 1 : 0; - for (const std::string& pandora_tag_suffix : pandora_tag_suffixes) { - art::Handle> flashes_handle; - GetByLabelStrict(evt, fParams.OpFlashLabel() + pandora_tag_suffix, flashes_handle); - // fill into event - if (flashes_handle.isValid()) { - const std::vector &opflashes = *flashes_handle; - int cryostat = ( pandora_tag_suffix.find("W") != std::string::npos ) ? 1 : 0; + // get associated OpHits for each OpFlash + art::FindMany findManyHits(flashes_handle, evt, fParams.OpFlashLabel() + pandora_tag_suffix); - // get associated OpHits for each OpFlash - art::FindMany findManyHits(flashes_handle, evt, fParams.OpFlashLabel() + pandora_tag_suffix); + int iflash=0; + for (const recob::OpFlash& flash : opflashes) { - int iflash=0; - for (const recob::OpFlash& flash : opflashes) { + std::vector const& ophits = findManyHits.at(iflash); - std::vector const& ophits = findManyHits.at(iflash); + srflashes.emplace_back(); + FillICARUSOpFlash(flash, ophits, cryostat, srflashes.back()); + iflash++; + } + } + } + } + else if(fDet == kSBND) + { + std::cout << " Adding flash for SBND" << std::endl; + std::vector tpc_suffixes_sbnd = {"tpc0", "tpc1"}; - srflashes.emplace_back(); - FillOpFlash(flash, ophits, cryostat, srflashes.back()); - iflash++; + for (size_t tpc=0; tpc> flashes_handle; + GetByLabelStrict(evt, fParams.OpFlashLabel() + tpc_suffixes_sbnd[tpc], flashes_handle); + // fill into event + if (flashes_handle.isValid()) { + const std::vector &opflashes = *flashes_handle; + // get associated OpHits for each OpFlash + art::FindMany findManyHits(flashes_handle, evt, fParams.OpFlashLabel() + tpc_suffixes_sbnd[tpc]); + int iflash=0; + for (const recob::OpFlash& flash : opflashes) { + std::vector const& ophits = findManyHits.at(iflash); + srflashes.emplace_back(); + FillSBNDOpFlash(flash, ophits, tpc, srflashes.back()); + iflash++; + } } } } diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index f47265c1e..590927ae1 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -179,7 +179,7 @@ namespace caf } - void FillOpFlash(const recob::OpFlash &flash, + void FillICARUSOpFlash(const recob::OpFlash &flash, std::vector const& hits, int cryo, caf::SROpFlash &srflash, @@ -227,6 +227,41 @@ namespace caf } } + void FillSBNDOpFlash(const recob::OpFlash &flash, + std::vector const& hits, + int tpc, + caf::SROpFlash &srflash, + bool allowEmpty) { + + srflash.setDefault(); + + srflash.time = flash.Time(); + srflash.timewidth = flash.TimeWidth(); + + double firstTime = std::numeric_limits::max(); + for(const auto& hit: hits){ + double const hitTime = hit->HasStartTime()? hit->StartTime(): hit->PeakTime(); + if (firstTime > hitTime) + firstTime = hitTime; + } + srflash.firsttime = firstTime; + srflash.tpc = tpc; + + srflash.totalpe = flash.TotalPE(); + srflash.fasttototal = flash.FastToTotal(); + srflash.onbeamtime = flash.OnBeamTime(); + + srflash.center.SetXYZ( -9999.f, flash.YCenter(), flash.ZCenter() ); + srflash.width.SetXYZ( -9999.f, flash.YWidth(), flash.ZWidth() ); + + // Checks if ( recob::OpFlash.XCenter() != std::numeric_limits::max() ) + // See LArSoft OpFlash.h at https://nusoft.fnal.gov/larsoft/doxsvn/html/OpFlash_8h_source.html + if ( flash.hasXCenter() ) { + srflash.center.SetX( flash.XCenter() ); + srflash.width.SetX( flash.XWidth() ); + } + } + std::vector double_to_float_vector(const std::vector& v) { std::vector ret; diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index c6df1ab39..6bc38ad92 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -217,11 +217,18 @@ namespace caf caf::SRSBNDCRTTrack &srsbndcrttrack, bool allowEmpty = false); - void FillOpFlash(const recob::OpFlash &flash, + void FillICARUSOpFlash(const recob::OpFlash &flash, std::vector const& hits, int cryo, caf::SROpFlash &srflash, bool allowEmpty = false); + + void FillSBNDOpFlash(const recob::OpFlash &flash, + std::vector const& hits, + int tpc, + caf::SROpFlash &srflash, + bool allowEmpty = false); + void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, caf::SRCRTPMTMatch &srmatch, bool allowEmpty = false); From 17d32814407a01523170be6f76ddef8944d4bf14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Tue, 22 Apr 2025 13:27:10 -0500 Subject: [PATCH 070/367] Remove printout --- sbncode/CAFMaker/CAFMaker_module.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index c50973961..bba87a23b 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1681,11 +1681,9 @@ void CAFMaker::produce(art::Event& evt) noexcept { } else if(fDet == kSBND) { - std::cout << " Adding flash for SBND" << std::endl; std::vector tpc_suffixes_sbnd = {"tpc0", "tpc1"}; for (size_t tpc=0; tpc> flashes_handle; GetByLabelStrict(evt, fParams.OpFlashLabel() + tpc_suffixes_sbnd[tpc], flashes_handle); // fill into event From 340e920270ddde71bb4e947a8cef2f31a8c7a109 Mon Sep 17 00:00:00 2001 From: Tracy Usher Date: Tue, 22 Apr 2025 13:28:03 -0700 Subject: [PATCH 071/367] Adding modules to translate between recob::Wire and ChannelROI (and vice versa) --- sbncode/HitFinder/ChannelROIToWire_module.cc | 166 ++++++++++++++++ sbncode/HitFinder/WireToChannelROI_module.cc | 182 ++++++++++++++++++ .../wirechannelroiconverters_sbn.fcl | 30 +++ 3 files changed, 378 insertions(+) create mode 100644 sbncode/HitFinder/ChannelROIToWire_module.cc create mode 100644 sbncode/HitFinder/WireToChannelROI_module.cc create mode 100644 sbncode/HitFinder/wirechannelroiconverters_sbn.fcl diff --git a/sbncode/HitFinder/ChannelROIToWire_module.cc b/sbncode/HitFinder/ChannelROIToWire_module.cc new file mode 100644 index 000000000..243d5a744 --- /dev/null +++ b/sbncode/HitFinder/ChannelROIToWire_module.cc @@ -0,0 +1,166 @@ +//////////////////////////////////////////////////////////////////////// +// +// ChannelROIToWire class - Converts from ChannelROI to Wire data +// +// usher@slac.stanford.edu +// +//////////////////////////////////////////////////////////////////////// + +// C/C++ standard libraries +#include +#include +#include // std::pair<> +#include // std::unique_ptr<> + +// framework libraries +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "canvas/Utilities/Exception.h" +#include "canvas/Utilities/InputTag.h" + +// LArSoft libraries +#include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t +#include "larcore/Geometry/WireReadout.h" +#include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom() +#include "larcorealg/CoreUtils/zip.h" +#include "lardataobj/RecoBase/Wire.h" +#include "lardata/ArtDataHelper/WireCreator.h" + +#include "sbnobj/ICARUS/TPC/ChannelROI.h" + +///creation of calibrated signals on wires +namespace caldata { + +class ChannelROIToWire : public art::EDProducer +{ +public: +// create calibrated signals on wires. this class runs +// an fft to remove the electronics shaping. + explicit ChannelROIToWire(fhicl::ParameterSet const& pset); + void produce(art::Event& evt); + void beginJob(); + void endJob(); + void reconfigure(fhicl::ParameterSet const& p); +private: + + std::vector fWireModuleLabelVec; ///< vector of modules that made digits + std::vector fOutInstanceLabelVec; ///< The output instance labels to apply + bool fDiagnosticOutput; ///< secret diagnostics flag + size_t fEventCount; ///< count of event processed + + const geo::WireReadoutGeom* fChannelMapAlg = &art::ServiceHandle()->Get(); + +}; // class ChannelROIToWire + +DEFINE_ART_MODULE(ChannelROIToWire) + +//------------------------------------------------- +ChannelROIToWire::ChannelROIToWire(fhicl::ParameterSet const& pset) : EDProducer{pset} +{ + this->reconfigure(pset); + + for(const auto& wireLabel : fOutInstanceLabelVec) + { + produces>(wireLabel); + } +} + +////////////////////////////////////////////////////// +void ChannelROIToWire::reconfigure(fhicl::ParameterSet const& pset) +{ + // Recover the parameters + fWireModuleLabelVec = pset.get>("WireModuleLabelVec", std::vector()={"decon1droi"}); + fOutInstanceLabelVec = pset.get> ("OutInstanceLabelVec", {"PHYSCRATEDATA"}); + fDiagnosticOutput = pset.get< bool >("DiagnosticOutput", false); + + if (fWireModuleLabelVec.size() != fOutInstanceLabelVec.size()) + { + throw art::Exception(art::errors::Configuration) << " Configured " << fOutInstanceLabelVec.size() + << " instance names (`OutInstanceLabelVec`) for " << fWireModuleLabelVec.size() + << " input products (`WireModuleLabelVec`)\n"; + } + + return; +} + +//------------------------------------------------- +void ChannelROIToWire::beginJob() +{ + fEventCount = 0; +} // beginJob + +////////////////////////////////////////////////////// +void ChannelROIToWire::endJob() +{ +} + +////////////////////////////////////////////////////// +void ChannelROIToWire::produce(art::Event& evt) +{ + // We need to loop through the list of Wire data we have been given + // This construct from Gianluca Petrillo who invented it and should be given all credit for it! + for(auto const& [channelLabel, instanceName] : util::zip(fWireModuleLabelVec, fOutInstanceLabelVec)) + { + // make a collection of Wires + std::unique_ptr> wireCol = std::make_unique>(); + + mf::LogInfo("ChannelROIToWire") << "ChannelROIToWire, looking for ChannelROI data at " << channelLabel.encode(); + + // Read in the collection of full length deconvolved waveforms + const std::vector& channelVec = evt.getProduct>(channelLabel); + + mf::LogInfo("ChannelROIToWire") << "--> Recovered ChannelROI data, size: " << channelVec.size(); + + if (!channelVec.empty()) + { + // Reserve the room for the output + wireCol->reserve(channelVec.size()); + + // Loop through the input ChannelROI collection + for(const auto& channelROI : channelVec) + { + // Recover the channel and the view + raw::ChannelID_t channel = channelROI.Channel(); + geo::View_t view = fChannelMapAlg->View(channel); + float ADCScaleFactor = channelROI.ADCScaleFactor(); + + // Create an ROI vector for output + recob::Wire::RegionsOfInterest_t ROIVec; + + // Loop through the ROIs for this channel + const recob::ChannelROI::RegionsOfInterest_t& channelROIs = channelROI.SignalROI(); + + for(const auto& range : channelROIs.get_ranges()) + { + size_t startTick = range.begin_index(); + + std::vector dataVec(range.data().size()); + + for(size_t binIdx = 0; binIdx < range.data().size(); binIdx++) dataVec[binIdx] = std::round(range.data()[binIdx] * ADCScaleFactor); + + ROIVec.add_range(startTick, std::move(dataVec)); + } + + wireCol->push_back(recob::WireCreator(std::move(ROIVec),channel,view).move()); + } + + mf::LogInfo("ChannelROIToWire") << "--> Outputting Wire data, size: " << wireCol->size() << " with instance name: " << instanceName; + + // Time to stroe everything + if(wireCol->empty()) mf::LogWarning("ChannelROIToWire") << "No wires made for this event."; + } + + evt.put(std::move(wireCol), instanceName); + } + + fEventCount++; + + return; +} // produce + +} // end namespace caldata diff --git a/sbncode/HitFinder/WireToChannelROI_module.cc b/sbncode/HitFinder/WireToChannelROI_module.cc new file mode 100644 index 000000000..9f0a5214d --- /dev/null +++ b/sbncode/HitFinder/WireToChannelROI_module.cc @@ -0,0 +1,182 @@ +//////////////////////////////////////////////////////////////////////// +// +// WireToChannelROI class - Convert recob::Wire to recob::ChannelROI +// +// usher@slac.stanford.edu +// +//////////////////////////////////////////////////////////////////////// + +// C/C++ standard libraries +#include +#include +#include // std::pair<> +#include // std::unique_ptr<> + +// framework libraries +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "canvas/Utilities/Exception.h" +#include "canvas/Utilities/InputTag.h" + +// LArSoft libraries +#include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t +#include "larcore/Geometry/WireReadout.h" +#include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom() +#include "larcorealg/CoreUtils/zip.h" +#include "lardataobj/RecoBase/Wire.h" + +#include "sbnobj/ICARUS/TPC/ChannelROI.h" +#include "sbnobj/Common/Utilities/ChannelROICreator.h" + +///creation of calibrated signals on wires +namespace caldata { + +class WireToChannelROI : public art::EDProducer +{ +public: +// create calibrated signals on wires. this class runs +// an fft to remove the electronics shaping. + explicit WireToChannelROI(fhicl::ParameterSet const& pset); + void produce(art::Event& evt); + void beginJob(); + void endJob(); + void reconfigure(fhicl::ParameterSet const& p); +private: + + std::vector fWireModuleLabelVec; ///< vector of modules that made digits + std::vector fOutInstanceLabelVec; ///< The output instance labels to apply + bool fDiagnosticOutput; ///< secret diagnostics flag + size_t fEventCount; ///< count of event processed + + const geo::WireReadoutGeom* fChannelMapAlg = &art::ServiceHandle()->Get(); + +}; // class WireToChannelROI + +DEFINE_ART_MODULE(WireToChannelROI) + +//------------------------------------------------- +WireToChannelROI::WireToChannelROI(fhicl::ParameterSet const& pset) : EDProducer{pset} +{ + this->reconfigure(pset); + + for(const auto& wireLabel : fOutInstanceLabelVec) + { + produces>(wireLabel); + } +} + +////////////////////////////////////////////////////// +void WireToChannelROI::reconfigure(fhicl::ParameterSet const& pset) +{ + // Recover the parameters + fWireModuleLabelVec = pset.get>("WireModuleLabelVec", std::vector()={"decon1droi"}); + fOutInstanceLabelVec = pset.get> ("OutInstanceLabelVec", {"PHYSCRATEDATA"}); + fDiagnosticOutput = pset.get< bool >("DiagnosticOutput", false); + + if (fWireModuleLabelVec.size() != fOutInstanceLabelVec.size()) + { + throw art::Exception(art::errors::Configuration) << " Configured " << fOutInstanceLabelVec.size() + << " instance names (`OutInstanceLabelVec`) for " << fWireModuleLabelVec.size() + << " input products (`WireModuleLabelVec`)\n"; + } + + return; +} + +//------------------------------------------------- +void WireToChannelROI::beginJob() +{ + fEventCount = 0; +} // beginJob + +////////////////////////////////////////////////////// +void WireToChannelROI::endJob() +{ +} + +////////////////////////////////////////////////////// +void WireToChannelROI::produce(art::Event& evt) +{ + float ADCScaleFactor(recob::ChannelROI::defADCScaleFactor); + + // We need to loop through the list of Wire data we have been given + // This construct from Gianluca Petrillo who invented it and should be given all credit for it! + for(auto const& [wireLabel, instanceName] : util::zip(fWireModuleLabelVec, fOutInstanceLabelVec)) + { + // make a collection of Wires + std::unique_ptr> channelROICol = std::make_unique>(); + + mf::LogInfo("WireToChannelROI") << "WireToChannelROI, looking for Wire data at " << wireLabel.encode(); + + // Read in the collection of full length deconvolved waveforms + const std::vector& wireVec = evt.getProduct>(wireLabel); + + mf::LogInfo("WireToChannelROI") << "--> Recovered Wire data, size: " << wireVec.size(); + + if (!wireVec.empty()) + { + // Reserve the room for the output + channelROICol->reserve(wireVec.size()); + + // Loop through the input ChannelROI collection + for(const auto& wire : wireVec) + { + // Recover the channel and the view + raw::ChannelID_t channel = wire.Channel(); + + // Create an ROI vector for output + recob::ChannelROI::RegionsOfInterest_t ROIVec; + + // Return the entire waveform (zero padded) so we can find maximum range + std::vector fullWaveform = wire.Signal(); + + std::pair::const_iterator,std::vector::const_iterator> minMaxPair = std::minmax_element(fullWaveform.begin(),fullWaveform.end()); + + float maxValue = std::max(-*minMaxPair.first,*minMaxPair.second); + + ADCScaleFactor = std::max(std::min(float(512.),static_cast(std::numeric_limits::max())/maxValue),float(8.)); + + // Loop through the ROIs for this channel + const recob::Wire::RegionsOfInterest_t& wireROIs = wire.SignalROI(); + + for(const auto& range : wireROIs.get_ranges()) + { + size_t startTick = range.begin_index(); + + std::vector dataVec(range.data().size()); + + for(size_t binIdx = 0; binIdx < range.data().size(); binIdx++) + { + short int scaledIntADCVal = + std::min(std::max(std::round(range.data()[binIdx] * ADCScaleFactor),static_cast(std::numeric_limits::min())), + static_cast(std::numeric_limits::max())); + + dataVec[binIdx] = scaledIntADCVal; + } + + ROIVec.add_range(startTick, std::move(dataVec)); + } + + channelROICol->push_back(recob::ChannelROICreator(std::move(ROIVec),channel,ADCScaleFactor).move()); + } + + mf::LogInfo("WireToChannelROI") << "--> Outputting ChannelROI data, size: " << channelROICol->size() << " with instance name: " << instanceName; + + // Time to stroe everything + if(channelROICol->empty()) mf::LogWarning("WireToChannelROI") << "No wires made for this event."; + } + + evt.put(std::move(channelROICol), instanceName); + } + + fEventCount++; + + return; +} // produce + +} // end namespace caldata diff --git a/sbncode/HitFinder/wirechannelroiconverters_sbn.fcl b/sbncode/HitFinder/wirechannelroiconverters_sbn.fcl new file mode 100644 index 000000000..a79623b16 --- /dev/null +++ b/sbncode/HitFinder/wirechannelroiconverters_sbn.fcl @@ -0,0 +1,30 @@ +// from larreco/RecoAlg: +#include "hitalgorithms.fcl" +#include "hitfindermodules.fcl" + +BEGIN_PROLOG + +# This defines a version of the Gauss Hit Finder that uses as input ChannelROIs instead of Wire +# In principle all default parameters remain the same. + +channelroitowire: +{ + module_type: "ChannelROIToWire" + WireModuleLabelVec: [" "] + OutInstanceLabelVec: [" "] + DiagnosticOutput: false +} + +wiretochannelroi: +{ + module_type: "WireToChannelROI" + WireModuleLabelVec: [" "] + OutInstanceLabelVec: [" "] + DiagnosticOutput: false +} + +# Define sbn versions +channelroitowire_sbn: @local::channelroitowire +wiretochannelroi_sbn: @local::wiretochannelroi + +END_PROLOG From 09836792d6c4a43740b164a1b8bff04377aac264 Mon Sep 17 00:00:00 2001 From: Tracy Usher Date: Tue, 22 Apr 2025 13:28:53 -0700 Subject: [PATCH 072/367] Moving the "HitCreator" here... should not have been in sbnobj. Also note this version creates regular recob::Hit objects. --- .../HitFinderUtilities/CMakeLists.txt | 21 + .../HitFinderUtilities/HitCreator.cxx | 638 ++++++++++ .../HitFinder/HitFinderUtilities/HitCreator.h | 1062 +++++++++++++++++ 3 files changed, 1721 insertions(+) create mode 100644 sbncode/HitFinder/HitFinderUtilities/CMakeLists.txt create mode 100644 sbncode/HitFinder/HitFinderUtilities/HitCreator.cxx create mode 100644 sbncode/HitFinder/HitFinderUtilities/HitCreator.h diff --git a/sbncode/HitFinder/HitFinderUtilities/CMakeLists.txt b/sbncode/HitFinder/HitFinderUtilities/CMakeLists.txt new file mode 100644 index 000000000..2e9266b58 --- /dev/null +++ b/sbncode/HitFinder/HitFinderUtilities/CMakeLists.txt @@ -0,0 +1,21 @@ +cet_make_library( + SOURCE + HitCreator.cxx + LIBRARIES + cetlib_except::cetlib_except + messagefacility::MF_MessageLogger + sbnobj::ICARUS_TPC + larcore::Geometry_Geometry_service + larcorealg::Geometry + lardata::ArtDataHelper + lardataobj::AnalysisBase + art::Framework_Core + art::Framework_Principal + art::Framework_Services_Registry + art::Persistency_Common + art::Persistency_Provenance + art::Utilities + ) + +install_headers() +install_source() diff --git a/sbncode/HitFinder/HitFinderUtilities/HitCreator.cxx b/sbncode/HitFinder/HitFinderUtilities/HitCreator.cxx new file mode 100644 index 000000000..76f9833ae --- /dev/null +++ b/sbncode/HitFinder/HitFinderUtilities/HitCreator.cxx @@ -0,0 +1,638 @@ +/** **************************************************************************** + * @file HitCreator.cxx + * @brief Helper functions to create a hit from ChannelROIs - implementation file + * @date April 20, 2025 + * @author usher@slac.stanford.edu + * @see Hit.h HitCreator.h + * + * ****************************************************************************/ + +// declaration header +#include "sbncode/HitFinder/HitFinderUtilities/HitCreator.h" + +// C/C++ standard library +#include // std::accumulate(), std::max() +#include +#include // std::numeric_limits<> +#include // std::move() + +// art libraries +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "canvas/Persistency/Common/FindOneP.h" +#include "canvas/Utilities/Exception.h" + +// LArSoft libraries +#include "larcore/Geometry/WireReadout.h" +#include "lardata/Utilities/MakeIndex.h" + +namespace { + + /// Erases the content of an association + template + void ClearAssociations(art::Assns& assns) + { + art::Assns empty; + assns.swap(empty); + } // ClearAssociations() + +} // local namespace + +/// Reconstruction base classes +namespace sbn { + + //**************************************************************************** + //*** HitCreator + //---------------------------------------------------------------------- + HitCreator::HitCreator(raw::RawDigit const& digits, + geo::WireID const& wireID, + raw::TDCtick_t start_tick, + raw::TDCtick_t end_tick, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof) + : hit(digits.Channel(), + start_tick, + end_tick, + peak_time, + sigma_peak_time, + rms, + peak_amplitude, + sigma_peak_amplitude, + ROIsummedADC, + HitsummedADC, + hit_integral, + hit_sigma_integral, + multiplicity, + local_index, + goodness_of_fit, + dof, + art::ServiceHandle()->Get().View(digits.Channel()), + art::ServiceHandle()->Get().SignalType(digits.Channel()), + wireID) + {} // HitCreator::HitCreator(RawDigit) + + //---------------------------------------------------------------------- + HitCreator::HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + raw::TDCtick_t start_tick, + raw::TDCtick_t end_tick, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof) + : hit(wire.Channel(), + start_tick, + end_tick, + peak_time, + sigma_peak_time, + rms, + peak_amplitude, + sigma_peak_amplitude, + ROIsummedADC, + HitsummedADC, + hit_integral, + hit_sigma_integral, + multiplicity, + local_index, + goodness_of_fit, + dof, + art::ServiceHandle()->Get().View(wire.Channel()), + art::ServiceHandle()->Get().SignalType(wire.Channel()), + wireID) + {} // HitCreator::HitCreator(Wire) + + //---------------------------------------------------------------------- + HitCreator::HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + raw::TDCtick_t start_tick, + raw::TDCtick_t end_tick, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof) + : HitCreator(wire, + wireID, + start_tick, + end_tick, + rms, + peak_time, + sigma_peak_time, + peak_amplitude, + sigma_peak_amplitude, + hit_integral, + hit_sigma_integral, + std::accumulate(wire.SignalROI().begin() + start_tick, + wire.SignalROI().begin() + end_tick, + 0.), // sum of ADC counts between start_tick and end_tic + std::accumulate( + wire.SignalROI().begin() + start_tick, + wire.SignalROI().begin() + end_tick, + 0.), // sum of ADC counts between start_tick and end_tick TO BE MODIFIED IF HIT HAS TO BE CONSIDERED + multiplicity, + local_index, + goodness_of_fit, + dof) + {} // HitCreator::HitCreator(Wire; no summed ADC) + + //---------------------------------------------------------------------- + HitCreator::HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof, + RegionOfInterest_t const& signal) + : HitCreator(wire, + wireID, + signal.begin_index(), + signal.end_index(), + rms, + peak_time, + sigma_peak_time, + peak_amplitude, + sigma_peak_amplitude, + hit_integral, + hit_sigma_integral, + ROIsummedADC, + HitsummedADC, + multiplicity, + local_index, + goodness_of_fit, + dof) + {} // HitCreator::HitCreator(Wire; RoI) + + //---------------------------------------------------------------------- + HitCreator::HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof, + size_t iSignalRoI) + : HitCreator(wire, + wireID, + rms, + peak_time, + sigma_peak_time, + peak_amplitude, + sigma_peak_amplitude, + hit_integral, + hit_sigma_integral, + ROIsummedADC, + HitsummedADC, + multiplicity, + local_index, + goodness_of_fit, + dof, + wire.SignalROI().range(iSignalRoI)) + {} // HitCreator::HitCreator(Wire; RoI index) + + HitCreator::HitCreator(recob::Hit const& from) : hit(from) {} + + // Need to do this way since we don't have friendship for the wireID + HitCreator::HitCreator(recob::Hit const& from, geo::WireID const& wireID) + : hit(from.Channel(), + from.StartTick(), + from.EndTick(), + from.PeakTime(), + from.SigmaPeakTime(), + from.RMS(), + from.PeakAmplitude(), + from.SigmaPeakAmplitude(), + from.ROISummedADC(), + from.HitSummedADC(), + from.Integral(), + from.SigmaIntegral(), + from.Multiplicity(), + from.LocalIndex(), + from.GoodnessOfFit(), + from.DegreesOfFreedom(), + art::ServiceHandle()->Get().View(from.Channel()), + art::ServiceHandle()->Get().SignalType(from.Channel()), + wireID) + { } // HitCreator::HitCreator(new wire ID) + + //**************************************************************************** + //*** HitAndAssociationsWriterBase + //---------------------------------------------------------------------- + HitAndAssociationsWriterBase::HitAndAssociationsWriterBase(art::Event& event, + std::string instance_name, + bool doWireAssns, + bool doRawDigitAssns) + : prod_instance(instance_name) + , hits() + , WireAssns(doWireAssns ? new art::Assns : nullptr) + , RawDigitAssns(doRawDigitAssns ? new art::Assns : nullptr) + , event(&event) + , hitPtrMaker(*(this->event), prod_instance) + {} // HitAndAssociationsWriterBase::HitAndAssociationsWriterBase() + + //------------------------------------------------------------------------------ + void HitAndAssociationsWriterBase::declare_products(art::ProducesCollector& collector, + std::string instance_name /* = "" */, + bool doWireAssns /* = true */, + bool doRawDigitAssns /* = true */ + ) + { + collector.produces>(instance_name); + + // declare the other products we are creating (if any) + if (doWireAssns) { collector.produces>(instance_name); } + if (doRawDigitAssns) { + collector.produces>(instance_name); + } + } // HitAndAssociationsWriterBase::declare_products() + + //------------------------------------------------------------------------------ + void HitAndAssociationsWriterBase::put_into() + { + assert(event); + if (hits) event->put(std::move(hits), prod_instance); + if (WireAssns) event->put(std::move(WireAssns), prod_instance); + if (RawDigitAssns) event->put(std::move(RawDigitAssns), prod_instance); + } // HitAndAssociationsWriterBase::put_into() + + //**************************************************************************** + //*** HitCollectionCreator + //---------------------------------------------------------------------- + HitCollectionCreator::HitCollectionCreator(art::Event& event, + std::string instance_name /* = "" */, + bool doWireAssns /* = true */, + bool doRawDigitAssns /* = true */ + ) + : HitAndAssociationsWriterBase(event, instance_name, doWireAssns, doRawDigitAssns) + { + hits.reset(new std::vector); + } // HitCollectionCreator::HitCollectionCreator() + + //---------------------------------------------------------------------- + void HitCollectionCreator::emplace_back(recob::Hit&& hit, + art::Ptr const& wire, + art::Ptr const& digits) + { + + // add the hit to the collection + hits->emplace_back(std::move(hit)); + + CreateAssociationsToLastHit(wire, digits); + } // HitCollectionCreator::emplace_back(Hit&&) + + //---------------------------------------------------------------------- + void HitCollectionCreator::emplace_back(recob::Hit const& hit, + art::Ptr const& wire, + art::Ptr const& digits) + { + + // add the hit to the collection + hits->push_back(hit); + + CreateAssociationsToLastHit(wire, digits); + } // HitCollectionCreator::emplace_back(Hit) + + //---------------------------------------------------------------------- + void HitCollectionCreator::put_into() + { + if (!hits) { + throw art::Exception(art::errors::LogicError) + << "HitCollectionCreator is trying to put into the event" + " a hit collection that was never created!\n"; + } + HitAndAssociationsWriterBase::put_into(); + } // HitCollectionCreator::put_into() + + //---------------------------------------------------------------------- + void HitCollectionCreator::CreateAssociationsToLastHit(art::Ptr const& wire, + art::Ptr const& digits) + { + // if no association is required, we are done + if (!WireAssns && !RawDigitAssns) return; + + // art pointer to the hit we just created + HitPtr_t hit_ptr(CreatePtrToLastHit()); + + // association with wires + if (WireAssns && wire.isNonnull()) + WireAssns->addSingle(wire, hit_ptr); // if it fails, it throws + + // association with wires + if (RawDigitAssns && digits.isNonnull()) + RawDigitAssns->addSingle(digits, hit_ptr); // if it fails, it throws + + } // HitCollectionCreator::CreateAssociationsToLastHit() + + //**************************************************************************** + //*** HitCollectionAssociator + //---------------------------------------------------------------------- + HitCollectionAssociator::HitCollectionAssociator(art::Event& event, + std::string instance_name, + art::InputTag const& WireModuleLabel, + art::InputTag const& RawDigitModuleLabel) + : HitAndAssociationsWriterBase(event, + instance_name, + WireModuleLabel != "", + RawDigitModuleLabel != "") + , wires_label(WireModuleLabel) + , digits_label(RawDigitModuleLabel) + { + hits.reset(new std::vector); + } // HitCollectionAssociator::HitCollectionAssociator() + + //---------------------------------------------------------------------- + sbn::HitCollectionAssociator::HitCollectionAssociator(art::Event& event, + std::string instance_name, + art::InputTag const& WireModuleLabel, + bool doRawDigitAssns /* = false */ + ) + : HitAndAssociationsWriterBase(event, instance_name, WireModuleLabel != "", doRawDigitAssns) + , wires_label(WireModuleLabel) + , digits_label() + { + if (RawDigitAssns && !WireAssns) { + throw art::Exception(art::errors::LogicError) + << "HitCollectionAssociator can't create hit <--> raw digit" + " associations through wires, without wires!\n"; + } + hits.reset(new std::vector); + } // HitCollectionAssociator::HitCollectionAssociator() + + //---------------------------------------------------------------------- + void HitCollectionAssociator::use_hits(std::unique_ptr>&& srchits) + { + hits = std::move(srchits); + } // HitCollectionAssociator::use_hits() + + //---------------------------------------------------------------------- + void HitCollectionAssociator::put_into() + { + prepare_associations(); + HitAndAssociationsWriterBase::put_into(); + } // HitCollectionAssociator::put_into() + + //---------------------------------------------------------------------- + void HitCollectionAssociator::prepare_associations(std::vector const& srchits) + { + if (!RawDigitAssns && !WireAssns) return; // no associations needed + assert(event); + + // we make the associations anew + if (RawDigitAssns) ClearAssociations(*RawDigitAssns); + if (WireAssns) ClearAssociations(*WireAssns); + + // the following is true is we want associations with digits + // but we don't know where digits are; in that case, we try to use wires + const bool bUseWiresForDigits = RawDigitAssns && (digits_label == ""); + + if (WireAssns || bUseWiresForDigits) { + // do we use wires for digit associations too? + + // get the wire collection + art::ValidHandle> hWires = + event->getValidHandle>(wires_label); + + // fill a map of wire index vs. channel number + std::vector WireMap = util::MakeIndex(*hWires, std::mem_fn(&recob::ChannelROI::Channel)); + + // use raw rigit - wire association, assuming they have been produced + // by the same producer as the wire and with the same instance name; + // we don't check whether the data product is found, but the following + // code will have FindOneP throw if that was not the case + // (that's what we would do here anyway, maybe with a better message...) + std::unique_ptr> WireToDigit; + if (bUseWiresForDigits) { + WireToDigit.reset(new art::FindOneP(hWires, *event, wires_label)); + } + + // add associations, hit by hit: + for (size_t iHit = 0; iHit < srchits.size(); ++iHit) { + + // find the channel + size_t iChannel = size_t(srchits[iHit].Channel()); // forcibly converted + + // find the wire associated to that channel + size_t iWire = std::numeric_limits::max(); + if (iChannel < WireMap.size()) iWire = WireMap[iChannel]; + if (iWire == std::numeric_limits::max()) { + throw art::Exception(art::errors::LogicError) + << "No wire associated to channel #" << iChannel << " whence hit #" << iHit + << " comes!\n"; + } // if no channel + + // make the association with wires + if (WireAssns) { + art::Ptr wire(hWires, iWire); + WireAssns->addSingle(wire, CreatePtr(iHit)); + } + + if (bUseWiresForDigits) { + // find the digit associated to that channel + art::Ptr const& digit = WireToDigit->at(iWire); + if (digit.isNull()) { + throw art::Exception(art::errors::LogicError) + << "No raw digit associated to channel #" << iChannel << " whence hit #" << iHit + << " comes!\n"; + } // if no channel + + // make the association + RawDigitAssns->addSingle(digit, CreatePtr(iHit)); + } // if create digit associations through wires + } // for hit + + } // if wire associations + + if (RawDigitAssns && !bUseWiresForDigits) { + // get the digit collection + art::ValidHandle> hDigits = + event->getValidHandle>(digits_label); + + // fill a map of wire index vs. channel number + std::vector DigitMap = + util::MakeIndex(*hDigits, std::mem_fn(&raw::RawDigit::Channel)); + + // add associations, hit by hit: + for (size_t iHit = 0; iHit < srchits.size(); ++iHit) { + + // find the channel + size_t iChannel = size_t(srchits[iHit].Channel()); // forcibly converted + + // find the digit associated to that channel + size_t iDigit = std::numeric_limits::max(); + if (iChannel < DigitMap.size()) iDigit = DigitMap[iChannel]; + if (iDigit == std::numeric_limits::max()) { + throw art::Exception(art::errors::LogicError) + << "No raw digit associated to channel #" << iChannel << " whence hit #" << iHit + << " comes!\n"; + } // if no channel + + // make the association + art::Ptr digit(hDigits, iDigit); + RawDigitAssns->addSingle(digit, CreatePtr(iHit)); + + } // for hit + } // if we have rawdigit label + + } // HitCollectionAssociator::put_into() + + //**************************************************************************** + //*** HitRefinerAssociator + //---------------------------------------------------------------------- + HitRefinerAssociator::HitRefinerAssociator(art::Event& event, + art::InputTag const& HitModuleLabel, + std::string instance_name /* = "" */, + bool doWireAssns /* = true */, + bool doRawDigitAssns /* = true */ + ) + : HitAndAssociationsWriterBase(event, instance_name, doWireAssns, doRawDigitAssns) + , hits_label(HitModuleLabel) + { + hits.reset(new std::vector); + } // HitRefinerAssociator::HitRefinerAssociator() + + //---------------------------------------------------------------------- + void HitRefinerAssociator::use_hits(std::unique_ptr>&& srchits) + { + hits = std::move(srchits); + } // HitRefinerAssociator::use_hits() + + //---------------------------------------------------------------------- + void HitRefinerAssociator::put_into() + { + prepare_associations(); + HitAndAssociationsWriterBase::put_into(); + } // HitRefinerAssociator::put_into() + + //---------------------------------------------------------------------- + void HitRefinerAssociator::prepare_associations(std::vector const& srchits) + { + if (!RawDigitAssns && !WireAssns) return; // no associations needed + assert(event); + + // we make the associations anew + if (RawDigitAssns) ClearAssociations(*RawDigitAssns); + + // read the hits; this is going to hurt performances... + // no solution to that until there is a way to have a lazy read + art::ValidHandle> hHits = + event->getValidHandle>(hits_label); + + // now get the associations + if (WireAssns) { + // we make the associations anew + ClearAssociations(*WireAssns); + + // find the associations between the hits and the wires + art::FindOneP HitToWire(hHits, *event, hits_label); + if (!HitToWire.isValid()) { + throw art::Exception(art::errors::ProductNotFound) + << "Can't find the associations between hits and wires produced by '" << hits_label + << "'!\n"; + } // if no association + + // fill a map of wire vs. channel number + std::vector> WireMap; + for (size_t iAssn = 0; iAssn < HitToWire.size(); ++iAssn) { + art::Ptr wire = HitToWire.at(iAssn); + if (wire.isNull()) continue; + size_t channelID = (size_t)wire->Channel(); + if (WireMap.size() <= channelID) // expand the map of necessary + WireMap.resize(std::max(channelID + 1, 2 * WireMap.size()), {}); + WireMap[channelID] = std::move(wire); + } // for + + // now go through all the hits... + for (size_t iHit = 0; iHit < srchits.size(); ++iHit) { + recob::Hit const& hit = srchits[iHit]; + size_t channelID = (size_t)hit.Channel(); + + // no association if there is no wire to associate with + if ((channelID >= WireMap.size()) || !WireMap[channelID]) continue; + + // create an association using the same wire pointer + WireAssns->addSingle(WireMap[channelID], CreatePtr(iHit)); + } // for hits + } // if wire associations + + // now get the associations + if (RawDigitAssns) { + // we make the associations anew + ClearAssociations(*RawDigitAssns); + + // find the associations between the hits and the raw digits + art::FindOneP HitToDigits(hHits, *event, hits_label); + if (!HitToDigits.isValid()) { + throw art::Exception(art::errors::ProductNotFound) + << "Can't find the associations between hits and raw digits" + << " produced by '" << hits_label << "'!\n"; + } // if no association + + // fill a map of digits vs. channel number + std::vector> DigitMap; + for (size_t iAssn = 0; iAssn < HitToDigits.size(); ++iAssn) { + art::Ptr digits = HitToDigits.at(iAssn); + if (digits.isNull()) continue; + size_t channelID = (size_t)digits->Channel(); + if (DigitMap.size() <= channelID) // expand the map of necessary + DigitMap.resize(std::max(channelID + 1, 2 * DigitMap.size()), {}); + DigitMap[channelID] = std::move(digits); + } // for + + // now go through all the hits... + for (size_t iHit = 0; iHit < srchits.size(); ++iHit) { + recob::Hit const& hit = srchits[iHit]; + size_t channelID = (size_t)hit.Channel(); + + // no association if there is no digits to associate with + if ((channelID >= DigitMap.size()) || !DigitMap[channelID]) continue; + + // create an association using the same digits pointer + RawDigitAssns->addSingle(DigitMap[channelID], CreatePtr(iHit)); + } // for hits + } // if digit associations + + } // HitRefinerAssociator::put_into() + +} // namespace recob diff --git a/sbncode/HitFinder/HitFinderUtilities/HitCreator.h b/sbncode/HitFinder/HitFinderUtilities/HitCreator.h new file mode 100644 index 000000000..658fc1a9b --- /dev/null +++ b/sbncode/HitFinder/HitFinderUtilities/HitCreator.h @@ -0,0 +1,1062 @@ +/** **************************************************************************** + * @file HitCreator.h + * @brief Helper functions to create a hit from ChannelROIs + * @date April 20, 2025 + * @author Tracy Usher (usher@slac.stanford.edu) + * @see Hit.h HitCreator.cxx + * + * ****************************************************************************/ + +#ifndef SBN_ARTDATAHELPERS_HITCREATOR_H +#define SBN_ARTDATAHELPERS_HITCREATOR_H + +// LArSoft libraries +#include "lardataobj/RawData/RawDigit.h" +#include "lardataobj/RecoBase/Hit.h" +#include "sbnobj/ICARUS/TPC/ChannelROI.h" + +// framework libraries +#include "art/Framework/Core/ProducesCollector.h" +#include "art/Persistency/Common/PtrMaker.h" +#include "canvas/Persistency/Common/Assns.h" +#include "canvas/Persistency/Common/Ptr.h" +#include "canvas/Utilities/Exception.h" +#include "canvas/Utilities/InputTag.h" + +// C/C++ standard library +#include +#include // std::move() +#include + +namespace geo { + struct WireID; +} +namespace raw { + class RawDigit; +} +namespace art { + class ProducesCollector; + class Event; +} + +/// Reconstruction base classes +namespace sbn { + + /** ************************************************************************** + * @brief Class managing the creation of a new `recob::Hit` object. + * + * In order to be as simple as possible (Plain Old Data), data products like + * `recob::Hit` need to be stripped of most of their functions, including the + * ability to communicate whether a value we try to store is invalid + * (that would require a art::Exception` -- art -- or at least a message on + * the screen -- MessageFacility) and the ability to read things from event, + * services (e.g. geometry) etc. + * + * A Creator is a class that creates a temporary data product, and at the + * end it yields it to the caller for storage. + * This last step should be by move construction, although a copy method is + * also provided. + * + * An example of creating a `recob::Hit` object (assuming all the relevant + * variables have been assigned proper values): + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * recob::HitCreator hit( + * wire, wireID, + * start_tick, end_tick, rms, + * peak_time, sigma_peak_time, peak_amplitude, sigma_peak_amplitude, + * hit_integral, hit_sigma_integral, summedADC, + * multiplicity, local_index, goodness_of_fit, dof + * ); + * hit.push_back(hit.move()); // hit content is not valid any more + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This is a one-step creation object: the hit is constructed at the same + * time the HitCreator is, and no facility is offered to modify the + * constructed hit, or to create another one. + * + * The constructors currently provided are: + * 1. from RawDigit (extracts channel, view and signal type [CVS] thanks to + * geometry) + * 2. from `recob::ChannelROI`, [CVS] + * 3. from `recob::ChannelROI`, [CVS], `summedADC` is automatically computed from + * wire + * 4. from `recob::ChannelROI`, [CVS], start and stop time from a region of interest + * 5. from `recob::ChannelROI`, [CVS], start and stop time from index of region of + * interest + */ + class HitCreator { + public: + /// Type of one region of interest. + using RegionOfInterest_t = recob::ChannelROI::RegionsOfInterest_f::datarange_t; + + // destructor, copy and move constructor and assignment as default + + /** + * @brief Constructor: extracts some information from raw digit. + * @param digits a pointer to a `raw::RawDigit` (for channel, view, signal + * type) + * @param wireID ID of the wire the hit is on + * @param start_tick first tick in the region the hit was extracted from + * @param end_tick first tick after the region the hit was extracted from + * @param rms RMS of the signal hit, in TDC time units + * @param peak_time time at peak of the signal, in TDC time units + * @param sigma_peak_time uncertainty on time at peak, in TDC time units + * @param peak_amplitude amplitude of the signal at peak, in ADC units + * @param sigma_peak_amplitude uncertainty on amplitude at peak + * @param hit_integral total charge integrated under the hit signal + * @param hit_sigma_integral uncertainty on the total hit charge + * @param ROIsummedADC total ADC count in the region assigned to the hit ROI + * @param HitsummedADC total ADC count in the region assigned to the hit HIT + * @param multiplicity number of hits in the region it was extracted from + * @param local_index index of this hit in the region it was extracted + * from + * @param goodness_of_fit quality parameter for the hit + * @param dof degrees of freedom in the definition of the hit shape + * + * The information used from the raw digit is the channel ID; view and + * signal type are obtained from geometry. + */ + HitCreator(raw::RawDigit const& digits, + geo::WireID const& wireID, + raw::TDCtick_t start_tick, + raw::TDCtick_t end_tick, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof); + + /** + * @brief Constructor: extracts some information from wire. + * @param wire a pointer to a `recob::ChannelROI` (for channel, view, signal + * type) + * @param wireID ID of the wire the hit is on + * @param start_tick first tick in the region the hit was extracted from + * @param end_tick first tick after the region the hit was extracted from + * @param rms RMS of the signal hit, in TDC time units + * @param peak_time time at peak of the signal, in TDC time units + * @param sigma_peak_time uncertainty on time at peak, in TDC time units + * @param peak_amplitude amplitude of the signal at peak, in ADC units + * @param sigma_peak_amplitude uncertainty on amplitude at peak + * @param hit_integral total charge integrated under the hit signal + * @param hit_sigma_integral uncertainty on the total hit charge + * @param ROIsummedADC total ADC count in the region assigned to the hit ROI + * @param HitsummedADC total ADC count in the region assigned to the hit Hit + * @param multiplicity number of hits in the region it was extracted from + * @param local_index index of this hit in the region it was extracted + * from + * @param goodness_of_fit quality parameter for the hit + * @param dof degrees of freedom in the definition of the hit shape + * + * The information used from the wire are the channel ID and view; + * the signal type is obtained from geometry. + */ + HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + raw::TDCtick_t start_tick, + raw::TDCtick_t end_tick, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof); + + /** + * @brief Constructor: computes sum of ADC from wire. + * @param wire a pointer to a `recob::ChannelROI` (for channel, view, signal + * type) + * @param wireID ID of the wire the hit is on + * @param start_tick first tick in the region the hit was extracted from + * @param end_tick first tick after the region the hit was extracted from + * @param rms RMS of the signal hit, in TDC time units + * @param peak_time time at peak of the signal, in TDC time units + * @param sigma_peak_time uncertainty on time at peak, in TDC time units + * @param peak_amplitude amplitude of the signal at peak, in ADC units + * @param sigma_peak_amplitude uncertainty on amplitude at peak + * @param hit_integral total charge integrated under the hit signal + * @param hit_sigma_integral uncertainty on the total hit charge + * @param multiplicity number of hits in the region it was extracted from + * @param local_index index of this hit in the region it was extracted from + * @param goodness_of_fit quality parameter for the hit + * @param dof degrees of freedom in the definition of the hit shape + * + * The information used from the wire are the channel ID, view; + * the signal type is obtained from geometry. + * + * The sum of ADC counts is automatically computed over the whole range + * of the wire signal between `start_tick` and `end_tick` + * (the latter excluded). + */ + HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + raw::TDCtick_t start_tick, + raw::TDCtick_t end_tick, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof); + + /** + * @brief Constructor: uses region of interest specified by index. + * @param wire a pointer to a `recob::ChannelROI` (for channel, view, signal + * type) + * @param wireID ID of the wire the hit is on + * @param rms RMS of the signal hit, in TDC time units + * @param peak_time time at peak of the signal, in TDC time units + * @param sigma_peak_time uncertainty on time at peak, in TDC time units + * @param peak_amplitude amplitude of the signal at peak, in ADC units + * @param sigma_peak_amplitude uncertainty on amplitude at peak + * @param hit_integral total charge integrated under the hit signal + * @param hit_sigma_integral uncertainty on the total hit charge + * @param ROIsummedADC total ADC count in the region assigned to the hit ROI + * @param HitsummedADC total ADC count in the region assigned to the hit Hit + * @param multiplicity number of hits in the region it was extracted from + * @param local_index index of this hit in the region it was extracted + * from + * @param goodness_of_fit quality parameter for the hit + * @param dof degrees of freedom in the definition of the hit shape + * @param signal the signal region the hit was extracted from + * + * The information used from the wire are the channel ID, view + * and the region of interest; the signal type is obtained from + * geometry. + * + * Signal start and end ticks are extracted from the region of interest. + */ + HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof, + RegionOfInterest_t const& signal); + + /** + * @brief Constructor: uses region of interest specified by index. + * @param wire a pointer to a `recob::ChannelROI` (for channel, view, signal + * type) + * @param wireID ID of the wire the hit is on + * @param rms RMS of the signal hit, in TDC time units + * @param peak_time time at peak of the signal, in TDC time units + * @param sigma_peak_time uncertainty on time at peak, in TDC time units + * @param peak_amplitude amplitude of the signal at peak, in ADC units + * @param sigma_peak_amplitude uncertainty on amplitude at peak + * @param hit_integral total charge integrated under the hit signal + * @param hit_sigma_integral uncertainty on the total hit charge + * @param ROI summedADC total ADC count in the region assigned to the hit ROI + * @param Hit summedADC total ADC count in the region assigned to the hit Hit + * @param multiplicity number of hits in the region it was extracted from + * @param local_index index of this hit in the region it was extracted from + * @param goodness_of_fit quality parameter for the hit + * @param dof degrees of freedom in the definition of the hit shape + * @param iSignalRoI index in the wire of the signal region the hit was + * extracted from + * + * The information used from the wire are the channel ID, view + * and the region of interest; the signal type is obtained from + * geometry. + * + * Signal start and end ticks are extracted from the region of interest. + */ + HitCreator(recob::ChannelROI const& wire, + geo::WireID const& wireID, + float rms, + float peak_time, + float sigma_peak_time, + float peak_amplitude, + float sigma_peak_amplitude, + float hit_integral, + float hit_sigma_integral, + float ROIsummedADC, + float HitsummedADC, + short int multiplicity, + short int local_index, + float goodness_of_fit, + int dof, + size_t iSignalRoI); + + /** + * @brief Constructor: copies from an existing hit. + * @param from the original hit + */ + HitCreator(recob::Hit const& from); + + /** + * @brief Constructor: copies from an existing hit, changing wire ID. + * @param from the original hit + * @param wireID ID of the new wire the hit is on + */ + HitCreator(recob::Hit const& from, geo::WireID const& wireID); + + /** + * @brief Prepares the constructed hit to be moved away. + * @return a right-value reference to the constructed hit + * + * Despite the name, no move happens in this function. + * Move takes place in the caller code as proper; for example: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * // be hit a HitCreator instance: + * std::vector Hits; + * hit.move(); // nothing happens + * Hits.push_back(hit.move()); // here the copy happens + * recob::Hit single_hit(hit.move()); // wrong! hit is empty now + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + recob::Hit&& move() { return std::move(hit); } + + /** + * @brief Returns the constructed wire + * @return a constant reference to the constructed wire + * + * Despite the name, no copy happens in this function. + * Copy takes place in the caller code as proper; for example: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * // be Hit a HitCreator instance: + * std::vector Hits; + * hit.copy(); // nothing happens + * Hits.push_back(hit.copy()); // here a copy happens + * recob::Hit single_hit(hit.copy()); // hit is copied again + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + recob::Hit const& copy() const { return hit; } + + protected: + recob::Hit hit; ///< Local instance of the hit being constructed. + + }; // class HitCreator + + /** ************************************************************************** + * @brief Base class handling a collection of hits and its associations. + * + * Instead of creating a collection of hits, one for its association with + * wires and one for its association with raw digits, one can use a class + * derived from this one: + * - `HitCollectionCreator`: push new hits one by one + * - `HitCollectionAssociator`: push a complete collection of hits + * - `HitRefinerAssociator`: push a complete collection of hits deriving their + * associations from other hits + * Using `put_into()` will transfer into the event the data. + * + * The typical usage is to have the constructor of the module call the static + * function + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * HitAndAssociationsWriterBase::declare_products(*this); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * (this example declares a collection with empty instance name and that we + * want associations to both wires and raw digits), and then in `produce()`: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * HitAndAssociationsWriterDerived hcol(*this, event); + * + * // ... fill hcol in the proper way ... + * + * hcol.put_into(); // calls art::Event::put() + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + class HitAndAssociationsWriterBase { + public: + // no public constructor: use one of the derived classes! + // destructor, copy and move constructors and assignment are default + + /// Returns the number of hits currently in the collection. + size_t size() const { return hits ? hits->size() : 0; } + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + * + * @deprecated Use the version with no arguments instead. + */ + void put_into(art::Event&) { put_into(); } + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + */ + void put_into(); + + /// Returns a read-only reference to the current list of hits. + std::vector const& peek() const { return *hits; } + + /** + * @brief Declares the hit products we are going to fill. + * @tparam ModuleType type of producing module (`EDProducer` or `EDFilter`) + * @param producer the module producing the data products + * @param instance_name name of the instance for all data products + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * This declaration must be given in the constructor of producer. + * It is equivalent to manually declare the relevant among these products: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * produces>(prod_instance); + * produces>(prod_instance); + * produces>(prod_instance); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * in the producer constructor. + * All the data products (hit collection and associations) will have the + * specified product instance name. + */ + static void declare_products(art::ProducesCollector& collector, + std::string instance_name = "", + bool doWireAssns = true, + bool doRawDigitAssns = true); + + protected: + using HitPtr_t = art::Ptr; ///< Type of art pointer to Hit. + + std::string prod_instance; ///< Tame of the instance for data products. + + /// Collection of hits. + std::unique_ptr> hits; + /// Associations with wires. + std::unique_ptr> WireAssns; + /// Associations with raw digits. + std::unique_ptr> RawDigitAssns; + + art::Event* event = nullptr; ///< Pointer to the event we are using. + + art::PtrMaker hitPtrMaker; ///< Tool to create hit pointers, + + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param instance_name name of the instance for all data products + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * All the data products (hit collection and associations) will have the + * specified product instance name. + */ + HitAndAssociationsWriterBase(art::Event& event, + std::string instance_name, + bool doWireAssns, + bool doRawDigitAssns); + + /// Creates an art pointer to the hit with the specified index. + HitPtr_t CreatePtr(size_t index) const { return hitPtrMaker(index); } + + }; // class HitAndAssociationsWriterBase + + /** ************************************************************************** + * @brief A class handling a collection of hits and its associations. + * + * Instead of creating a collection of hits, one for its association with + * wires and one for its association with raw digits, one can push hits into + * this object, and then move it into the event. + */ + class HitCollectionCreator : public HitAndAssociationsWriterBase { + public: + /// @name Constructors + /// @{ + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param instance_name name of the instance for all data products + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * All the data products (hit collection and associations) will have the + * specified product instance name. + */ + HitCollectionCreator(art::Event& event, + std::string instance_name = "", + bool doWireAssns = true, + bool doRawDigitAssns = true); + + /** + * @brief Constructor: no product instance name. + * @param event the event the products are going to be put into + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + */ + HitCollectionCreator(art::Event& event, bool doWireAssns, bool doRawDigitAssns) + : HitCollectionCreator(event, "", doWireAssns, doRawDigitAssns) + {} + + /// @} + + // destructor, copy and move constructors and assignment are default + + /// @name Addition of hits + /// @{ + /** + * @brief Adds the specified hit to the data collection. + * @param hit the hit that will be moved into the collection + * @param wire art pointer to the wire to be associated to this hit + * @param digits art pointer to the raw digits to be associated to this hit + * + * After this call, hit will be invalid. + * If a art pointer is not valid, that association will not be stored. + */ + void emplace_back(recob::Hit&& hit, + art::Ptr const& wire = art::Ptr(), + art::Ptr const& digits = art::Ptr()); + + /** + * @brief Adds the specified hit to the data collection. + * @param hit the hit that will be copied into the collection + * @param wire art pointer to the wire to be associated to this hit + * @param digits art pointer to the raw digits to be associated to this hit + * + * If a art pointer is not valid, that association will not be stored. + */ + void emplace_back(recob::Hit const& hit, + art::Ptr const& wire = art::Ptr(), + art::Ptr const& digits = art::Ptr()); + + /** + * @brief Adds the specified hit to the data collection. + * @param hit the HitCreator object containing the hit + * @param wire art pointer to the wire to be associated to this hit + * @param digits art pointer to the raw digits to be associated to this hit + * + * After this call, the hit creator will be empty. + * If a art pointer is not valid, that association will not be stored. + */ + void emplace_back(HitCreator&& hit, + art::Ptr const& wire = art::Ptr(), + art::Ptr const& digits = art::Ptr()) + { + emplace_back(hit.move(), wire, digits); + } + + /** + * @brief Adds the specified hit to the data collection. + * @param hit the hit that will be moved into the collection + * @param digits art pointer to the raw digits to be associated to this hit + * + * After this call, hit will be invalid. + * If the digit pointer is not valid, its association will not be stored. + */ + void emplace_back(recob::Hit&& hit, art::Ptr const& digits) + { + emplace_back(std::move(hit), art::Ptr(), digits); + } + + /** + * @brief Adds the specified hit to the data collection. + * @param hit the HitCreator object containing the hit + * @param digits art pointer to the raw digits to be associated to this hit + * + * After this call, the hit creator will be empty. + * If the digit pointer is not valid, its association will not be stored. + */ + void emplace_back(HitCreator&& hit, art::Ptr const& digits) + { + emplace_back(std::move(hit), art::Ptr(), digits); + } + + /** + * @brief Adds the specified hit to the data collection. + * @param hit the HitCreator object containing the hit + * @param digits art pointer to the raw digits to be associated to this hit + * + * If the digit pointer is not valid, its association will not be stored. + */ + void emplace_back(HitCreator const& hit, art::Ptr const& digits) + { + emplace_back(std::move(hit.copy()), art::Ptr(), digits); + } + /// @} + + /// Returns the number of hits currently in the collection. + size_t size() const { return hits->size(); } + + /// Prepares the collection to host at least `new_size` hits. + void reserve(size_t new_size) + { + if (hits) hits->reserve(new_size); + } + + /** + * @brief Moves the data into an event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + * + * @deprecated Use the version with no arguments instead. + */ + void put_into(art::Event&) { put_into(); } + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + */ + void put_into(); + + /// Returns a read-only reference to the current list of hits. + std::vector const& peek() const { return *hits; } + + protected: + using HitPtr_t = HitAndAssociationsWriterBase::HitPtr_t; + + /// Creates an art pointer to the hit with the last index. + HitPtr_t CreatePtrToLastHit() const + { + return hits->empty() ? HitPtr_t() : CreatePtr(hits->size() - 1); + } + + /// Creates associations between the last hit and the specified pointers. + void CreateAssociationsToLastHit(art::Ptr const& wire, + art::Ptr const& digits); + + }; // class HitCollectionCreator + + /** ************************************************************************** + * @brief A class handling a collection of hits and its associations. + * + * Use this object if you already have a collection of `recob::Hit` and you + * simply want the hits associated to the wire and digit with the same + * channel. + */ + class HitCollectionAssociator : public HitAndAssociationsWriterBase { + public: + /// @name Constructors + /// @{ + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param instance_name name of the instance for all data products + * @param WireModuleLabel label of the module used to create wires + * @param RawDigitModuleLabel label of the module used to create raw digits + * + * All the data products (hit collection and associations) will have the + * specified product instance name. + * + * If a label is empty, the corresponding association will not be produced. + */ + HitCollectionAssociator(art::Event& event, + std::string instance_name, + art::InputTag const& WireModuleLabel, + art::InputTag const& RawDigitModuleLabel); + + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param WireModuleLabel label of the module used to create wires + * @param RawDigitModuleLabel label of the module used to create raw digits + * + * All the data products (hit collection and associations) will have a + * default, empty product instance name. + * + * If a label is empty, the corresponding association will not be produced. + */ + HitCollectionAssociator(art::Event& event, + art::InputTag const& WireModuleLabel, + art::InputTag const& RawDigitModuleLabel) + : HitCollectionAssociator(event, "", WireModuleLabel, RawDigitModuleLabel) + {} + + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param instance_name name of the instance for all data products + * @param WireModuleLabel label of the module used to create wires + * @param doRawDigitAssns whether to write associations with raw digits + * + * All the data products (hit collection and associations) will have the + * specified product instance name. + * + * The raw digit association is built out of their existing associations + * with wires, rather than by directly using the raw digits data product. + */ + HitCollectionAssociator(art::Event& event, + std::string instance_name, + art::InputTag const& WireModuleLabel, + bool doRawDigitAssns); + + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param WireModuleLabel label of the module used to create wires + * @param doRawDigitAssns whether to write associations with raw digits + * + * All the data products (hit collection and associations) will have the + * default, empty product instance name. + * + * The raw digit association is built out of their existing associations + * with wires, rather than by directly using the raw digits data product. + */ + HitCollectionAssociator(art::Event& event, + art::InputTag const& WireModuleLabel, + bool doRawDigitAssns) + : HitCollectionAssociator(event, "", WireModuleLabel, doRawDigitAssns) + {} + + /// @} + + // destructor, copy and move constructors and assignment are default + + /** + * @brief Uses the specified collection as data product. + * @param srchits the collection to be used as data product + * + * The very same collection is put into the event. + * This object will temporary own the collection until the hits are put into + * the event. + * If there were previous hits in the object, they are lost. + */ + void use_hits(std::unique_ptr>&& srchits); + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + * + * @deprecated Use the version with no arguments instead. + */ + void put_into(art::Event&) { put_into(); } + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + */ + void put_into(); + + protected: + /// Label of the collection of wires to associate. + art::InputTag wires_label; + /// Label of raw digits collection to associate. + art::InputTag digits_label; + + /// Finds out the associations for the specified hits. + void prepare_associations(std::vector const& srchits); + + /// Finds out the associations for the current hits. + void prepare_associations() { prepare_associations(*hits); } + + }; // class HitCollectionAssociator + + /** ************************************************************************** + * @brief A class handling a collection of hits and its associations. + * + * Use this object if you already have a `recob::Hit` data product and + * another collection that is going to become a data product, and you + * simply want the new hits associated to the wire and digit with the same + * channel. + * No hit-to-hit association is attempted (that would be, incidentally, not + * supported by art): the data product is used to get all the associated + * wires and digits, then they are associated to the new hits by channel ID. + * If a channel is not available, a warning is produced. If different hits + * on the same channel are associated to different wires or raw digits, an + * exception is thrown. + */ + class HitRefinerAssociator : public HitAndAssociationsWriterBase { + public: + /// @name Constructors + /// @{ + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param HitModuleLabel label of the module used to create hits + * @param instance_name name of the instance for all data products + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * All the data products (hit collection and associations) will have the + * specified product instance name. + */ + HitRefinerAssociator(art::Event& event, + art::InputTag const& HitModuleLabel, + std::string instance_name = "", + bool doWireAssns = true, + bool doRawDigitAssns = true); + + /** + * @brief Constructor: sets instance name and whether to build associations. + * @param event the event the products are going to be put into + * @param HitModuleLabel label of the module used to create hits + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * All the data products (hit collection and associations) will have an + * empty product instance name. + */ + HitRefinerAssociator(art::Event& event, + art::InputTag const& HitModuleLabel, + bool doWireAssns, + bool doRawDigitAssns = true) + : HitRefinerAssociator(event, HitModuleLabel, "", doWireAssns, doRawDigitAssns) + {} + + /// @} + + // destructor, copy and move constructors and assignment are default + + /** + * @brief Uses the specified collection as data product. + * @param srchits the collection to be used as data product + * + * The very same collection is put into the event. + * This object will temporary own the collection until the hits are put into + * the event. + * If there were previous hits in the object, they are lost. + */ + void use_hits(std::unique_ptr>&& srchits); + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + * + * @deprecated Use the version with no arguments instead. + * + */ + void put_into(art::Event&) { put_into(); } + + /** + * @brief Moves the data into the event. + * + * The calling module must have already declared the production of these + * products with the proper instance name. + * After the move, the collections in this object are empty. + */ + void put_into(); + + protected: + art::InputTag hits_label; ///< Label of the collection of hits. + + /// Finds out the associations for the specified hits. + void prepare_associations(std::vector const& srchits); + + /// Finds out the associations for the current hits. + void prepare_associations() { prepare_associations(*hits); } + + }; // class HitRefinerAssociator + + // --------------------------------------------------------------------------- + /** + * @brief A helper to centralise creation of a hit collection data product. + * @tparam Writer writer class to manage + * @tparam ModuleType owning module: `art::EDProducer` or `art::EDFilter` + * + * This class adds an indirection layer to the model relying on + * `HitAndAssociationsWriter`. In that one, two different steps are required, + * one in the constructor of the module, where data products are declared, and + * one in the place where hits are actually assembled. + * These two steps need consistent setup, but they are separate and + * formally independent. The "manager" approach consists of an object + * performing the first step directly, and delivering an already configured + * object for the second step. + * + * An example of usage in a module: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * class MyHitProducer: public art::EDProducer { + * + * recob::HitAndAssociationsWriterManager + * hitCollCreator; + * + * public: + * + * MyHitProducer(fhicl::ParameterSet const& pset) + * : EDProducer{pset} + * , hitCollCreator(*this, pset.get("instanceName", "")) + * {} + * + * void produce(art::Event& event) + * { + * auto hitCollWriter = hitCollCreator.collectionWriter(event); + * + * for (recob::ChannelROI const& wire: Wires) { + * // create hits... + * hitCollWriter.emplace_back(hit, wire, digit); + * } + * hitCollWriter.put_into(); + * } + * + * }; // class MyHitProducer + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + template + class HitAndAssociationsWriterManager { + + public: + using Writer_t = Writer; ///< Type of managed hit collection writer. + + /** + * @brief Constructor: does not declare anything. + * + * This constructor does not declare products. Calling `declare_products()` + * explicitly is then required in the module constructor. + * + */ + HitAndAssociationsWriterManager() = default; + + /** + * @brief Declares the hit products we are going to fill. + * @param collector the module this manager is bound to + * @param instanceName name of the instance for all data products + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * This constructor calls `declareProducts()`. + */ + HitAndAssociationsWriterManager(art::ProducesCollector& collector, + std::string instanceName = "", + bool doWireAssns = true, + bool doRawDigitAssns = true); + + /** + * @brief Declares the hit products we are going to fill. + * @param collector the module this manager is bound to + * @param instanceName name of the instance for all data products + * @param doWireAssns whether to enable associations to wires + * @param doRawDigitAssns whether to enable associations to raw digits + * + * This declaration must be made in the constructor of producer. + * It is equivalent to manually declare the relevant among these products: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * produces>(prod_instance); + * produces>(prod_instance); + * produces>(prod_instance); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * in the producer constructor. + * All the data products (hit collection and associations) will have the + * specified product instance name. + */ + void declareProducts(art::ProducesCollector& collector, + std::string instanceName = "", + bool doWireAssns = true, + bool doRawDigitAssns = true); + + /// Returns a new writer already configured. + Writer_t collectionWriter(art::Event& event) const; + + /// Returns the configured product instance name. + std::string instanceName() const { return prodInstance; } + + /// Returns whether the class is fully configured. + bool ready() const noexcept { return collector_p != nullptr; } + + protected: + art::ProducesCollector* collector_p = nullptr; ///< Collector this manager is bound to. + + std::string prodInstance; ///< Tame of the instance for data products. + + /// Whether we produce hit-digit associations. + bool hasRawDigitAssns = true; + + /// Whether we produce hit-wire associations. + bool hasWireAssns = true; + + }; // class HitAndAssociationsWriterManager + + /// A manager for `recob::HitCollectionCreator` writer class. + using HitCollectionCreatorManager = HitAndAssociationsWriterManager; + +} // namespace sbn + +//------------------------------------------------------------------------------ +//--- template implementation +//------------------------------------------------------------------------------ +//--- recob::HitAndAssociationsWriterBase +//--- +//------------------------------------------------------------------------------ +//--- recob::HitAndAssociationsWriterManager +//--- +template +sbn::HitAndAssociationsWriterManager::HitAndAssociationsWriterManager( + art::ProducesCollector& collector, + std::string instanceName /* = "" */, + bool doWireAssns /* = true */, + bool doRawDigitAssns /* = true */ +) +{ + declareProducts(collector, instanceName, doWireAssns, doRawDigitAssns); +} // recob::HitAndAssociationsWriterManager::HitAndAssociationsWriterManager() + +//------------------------------------------------------------------------------ +template +void sbn::HitAndAssociationsWriterManager::declareProducts( + art::ProducesCollector& collector, + std::string instanceName /* = "" */, + bool doWireAssns /* = true */, + bool doRawDigitAssns /* = true */ +) +{ + if (collector_p) { + // this means you already called to declaredProducts() + // or used the wrong constructor (which did that for you): + throw art::Exception(art::errors::LogicError) + << "HitAndAssociationsWriter<> has already declared its products."; + } + collector_p = &collector; + prodInstance = instanceName; + hasWireAssns = doWireAssns; + hasRawDigitAssns = doRawDigitAssns; + HitAndAssociationsWriterBase::declare_products( + collector, prodInstance, hasWireAssns, hasRawDigitAssns); +} // recob::HitAndAssociationsWriterManager::declareProducts() + +//------------------------------------------------------------------------------ +template +typename sbn::HitAndAssociationsWriterManager::Writer_t +sbn::HitAndAssociationsWriterManager::collectionWriter(art::Event& event) const +{ + if (!collector_p) { + // this means you forgot to code a call to declaredProducts() + // or used the wrong constructor: + throw art::Exception(art::errors::LogicError) + << "HitAndAssociationsWriter<>::collectionWriter() called" + " before products are declared."; + } + return {event, prodInstance, hasWireAssns, hasRawDigitAssns}; +} // recob::HitAndAssociationsWriterManager::collectionWriter() + +//------------------------------------------------------------------------------ + +#endif // LARDATA_ARTDATAHELPERS_HITCREATOR_H From 4c39d747e5b01f3f9d795fc555eb089dbc5518ef Mon Sep 17 00:00:00 2001 From: Tracy Usher Date: Tue, 22 Apr 2025 13:30:03 -0700 Subject: [PATCH 073/367] Modify to output recob::Hit objects --- sbncode/HitFinder/CMakeLists.txt | 6 +++++- sbncode/HitFinder/GaussHitFinderSBN_module.cc | 12 ++++++------ sbncode/HitFinder/hitfindermodules_sbn.fcl | 14 -------------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/sbncode/HitFinder/CMakeLists.txt b/sbncode/HitFinder/CMakeLists.txt index 4961f4dcd..1d4870cef 100644 --- a/sbncode/HitFinder/CMakeLists.txt +++ b/sbncode/HitFinder/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(HitFinderUtilities) art_make_library( LIBRARIES @@ -21,6 +22,7 @@ set( MODULE_LIBRARIES larreco::RecoAlg sbnobj::ICARUS_TPC sbnobj::Common_Utilities + sbncode::HitFinder_HitFinderUtilities art::Framework_Core art::Framework_Principal art::Framework_Services_Registry @@ -46,7 +48,9 @@ cet_build_plugin(GaussHitFinderSBN art::module larreco::CandidateHitFinderTool larreco::PeakFitterTool ) - +cet_build_plugin(ChannelROIToWire art::module LIBRARIES ${MODULE_LIBRARIES}) +cet_build_plugin(WireToChannelROI art::module LIBRARIES ${MODULE_LIBRARIES}) + install_headers() install_fhicl() diff --git a/sbncode/HitFinder/GaussHitFinderSBN_module.cc b/sbncode/HitFinder/GaussHitFinderSBN_module.cc index 7dfe59334..c0a91cc91 100644 --- a/sbncode/HitFinder/GaussHitFinderSBN_module.cc +++ b/sbncode/HitFinder/GaussHitFinderSBN_module.cc @@ -44,10 +44,10 @@ #include "larcore/Geometry/WireReadout.h" #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t #include "larreco/HitFinder/HitFilterAlg.h" +#include "lardataobj/RecoBase/Hit.h" #include "sbnobj/ICARUS/TPC/ChannelROI.h" -#include "sbnobj/Common/Utilities//HitCreator.h" -#include "sbnobj/ICARUS/TPC/Hit.h" +#include "sbncode/HitFinder/HitFinderUtilities/HitCreator.h" #include "larreco/HitFinder/HitFinderTools/ICandidateHitFinder.h" #include "larreco/HitFinder/HitFinderTools/IPeakFitter.h" @@ -238,7 +238,7 @@ namespace hit { //store in a thread safe way struct hitstruct { - sbn::Hit hit_tbb; + recob::Hit hit_tbb; art::Ptr channelROI_tbb; }; @@ -436,7 +436,7 @@ namespace hit { int numHits(0); // Make a container for what will be the filtered collection - std::vector filteredHitVec; + std::vector filteredHitVec; float nextpeak(0); float prevpeak(0); @@ -560,7 +560,7 @@ namespace hit { if (filteredHitCol) filteredHitVec.push_back(hitcreator.copy()); - const sbn::Hit hit(hitcreator.move()); + const recob::Hit hit(hitcreator.move()); // This loop will store ALL hits hitstruct tmp{std::move(hit), channelROI}; @@ -598,7 +598,7 @@ namespace hit { // Find where the pulse heights drop below threshold float threshold(fPulseRatioCuts.at(plane)); - std::vector::iterator smallHitItr = + std::vector::iterator smallHitItr = std::find_if(filteredHitVec.begin(), filteredHitVec.end(), [largestPH, threshold](const auto& hit) { diff --git a/sbncode/HitFinder/hitfindermodules_sbn.fcl b/sbncode/HitFinder/hitfindermodules_sbn.fcl index 6d7d55478..868e5a2b8 100644 --- a/sbncode/HitFinder/hitfindermodules_sbn.fcl +++ b/sbncode/HitFinder/hitfindermodules_sbn.fcl @@ -51,18 +51,4 @@ gauss_hitfinder: # Define sbn version of gaushit finder gausshit_sbn: @local::gauss_hitfinder -# Now set parameters for the GaussHitFinderSBN -# Note these are "default" for ICARUS and will move to a fcl file in icaruscode -gausshit_sbn.PeakFitter.MinWidth: 1 -gausshit_sbn.PeakFitter.FloatBaseline: false -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane0: @local::candhitfinder_standard -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane0.Plane: 0 -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane0.RoiThreshold: 9. -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane1: @local::candhitfinder_standard -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane1.Plane: 1 -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane1.RoiThreshold: 9.5 -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane2: @local::candhitfinder_standard -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane2.Plane: 2 -gausshit_sbn.HitFinderToolVec.CandidateHitsPlane2.RoiThreshold: 9. - END_PROLOG From 2026deda2373be622210af48aed72de32fa1fab0 Mon Sep 17 00:00:00 2001 From: Tracy Usher Date: Wed, 23 Apr 2025 08:29:51 -0700 Subject: [PATCH 074/367] float to short conversion --- sbncode/HitFinder/WireToChannelROI_module.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sbncode/HitFinder/WireToChannelROI_module.cc b/sbncode/HitFinder/WireToChannelROI_module.cc index 9f0a5214d..d8f5062ac 100644 --- a/sbncode/HitFinder/WireToChannelROI_module.cc +++ b/sbncode/HitFinder/WireToChannelROI_module.cc @@ -50,6 +50,7 @@ class WireToChannelROI : public art::EDProducer std::vector fWireModuleLabelVec; ///< vector of modules that made digits std::vector fOutInstanceLabelVec; ///< The output instance labels to apply + short int fMaxADCScaleFactor; ///< Maximum scale factor to apply bool fDiagnosticOutput; ///< secret diagnostics flag size_t fEventCount; ///< count of event processed @@ -76,6 +77,7 @@ void WireToChannelROI::reconfigure(fhicl::ParameterSet const& pset) // Recover the parameters fWireModuleLabelVec = pset.get>("WireModuleLabelVec", std::vector()={"decon1droi"}); fOutInstanceLabelVec = pset.get> ("OutInstanceLabelVec", {"PHYSCRATEDATA"}); + fMaxADCScaleFactor = pset.get("MaxADCScaleFactor", 512); fDiagnosticOutput = pset.get< bool >("DiagnosticOutput", false); if (fWireModuleLabelVec.size() != fOutInstanceLabelVec.size()) @@ -102,8 +104,6 @@ void WireToChannelROI::endJob() ////////////////////////////////////////////////////// void WireToChannelROI::produce(art::Event& evt) { - float ADCScaleFactor(recob::ChannelROI::defADCScaleFactor); - // We need to loop through the list of Wire data we have been given // This construct from Gianluca Petrillo who invented it and should be given all credit for it! for(auto const& [wireLabel, instanceName] : util::zip(fWireModuleLabelVec, fOutInstanceLabelVec)) @@ -126,6 +126,8 @@ void WireToChannelROI::produce(art::Event& evt) // Loop through the input ChannelROI collection for(const auto& wire : wireVec) { + short int ADCScaleFactor(recob::ChannelROI::defADCScaleFactor); + // Recover the channel and the view raw::ChannelID_t channel = wire.Channel(); @@ -139,7 +141,7 @@ void WireToChannelROI::produce(art::Event& evt) float maxValue = std::max(-*minMaxPair.first,*minMaxPair.second); - ADCScaleFactor = std::max(std::min(float(512.),static_cast(std::numeric_limits::max())/maxValue),float(8.)); + ADCScaleFactor = std::max(short(std::round(std::min(float(fMaxADCScaleFactor),static_cast(std::numeric_limits::max())/maxValue))),ADCScaleFactor); // Loop through the ROIs for this channel const recob::Wire::RegionsOfInterest_t& wireROIs = wire.SignalROI(); From 319e1a9e275de672d0c1db3583d663ff52ff2166 Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Wed, 23 Apr 2025 14:30:13 -0500 Subject: [PATCH 075/367] Include SimEnergyDepositLites in simedep filter. --- .../DetSim/FilterSimEnergyDeposits_module.cc | 27 +++++++++++++++++++ sbncode/DetSim/fcl/icarus_simedepfilter.fcl | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/sbncode/DetSim/FilterSimEnergyDeposits_module.cc b/sbncode/DetSim/FilterSimEnergyDeposits_module.cc index ffb45d6e3..087c7ae96 100644 --- a/sbncode/DetSim/FilterSimEnergyDeposits_module.cc +++ b/sbncode/DetSim/FilterSimEnergyDeposits_module.cc @@ -18,6 +18,7 @@ #include "larcorealg/Geometry/BoxBoundedGeo.h" #include "lardataobj/Simulation/SimEnergyDeposit.h" +#include "lardataobj/Simulation/SimEnergyDepositLite.h" #include @@ -43,6 +44,7 @@ class FilterSimEnergyDeposits : public art::EDProducer { // Declare member data here. art::InputTag fInitSimEnergyDepositLabel; + art::InputTag fInitSimEnergyDepositLiteLabel; geo::BoxBoundedGeo fBox; static constexpr auto kModuleName = "FilterSimEnergyDeposit"; double ShiftX(double z) const; @@ -56,6 +58,7 @@ class FilterSimEnergyDeposits : public art::EDProducer { FilterSimEnergyDeposits::FilterSimEnergyDeposits(fhicl::ParameterSet const& p) : EDProducer{p} , fInitSimEnergyDepositLabel{p.get("InitSimEnergyDepositLabel", "undefined")} + , fInitSimEnergyDepositLiteLabel{p.get("InitSimEnergyDepositLiteLabel", "undefined")} , fBox{p.get("P1_X"), p.get("P2_X"), p.get("P1_Y"), p.get("P2_Y"), p.get("P1_Z"), p.get("P2_Z")} @@ -66,6 +69,9 @@ FilterSimEnergyDeposits::FilterSimEnergyDeposits(fhicl::ParameterSet const& p) // Call appropriate produces<>() functions here. // Call appropriate consumes<>() for any products to be retrieved by this module. produces>(); + + + if (fInitSimEnergyDepositLiteLabel != "undefined") { produces>(); } } @@ -126,6 +132,27 @@ void FilterSimEnergyDeposits::produce(art::Event& e) origID)); } e.put(std::move(pSimEDeps)); + + // also futz with the SimEnergyDepositLite's if configured to + if (fInitSimEnergyDepositLiteLabel == "undefined") return; + + auto const& simEDepLites = + e.getProduct>(fInitSimEnergyDepositLiteLabel); + auto pSimEDepLites = std::make_unique>(); + pSimEDepLites->reserve(simEDepLites.size()); + + for (auto const& inSimEDepLite : simEDepLites) { + geo::Point_t middlePos = inSimEDepLite.Position(); + if(fBox.ContainsPosition(middlePos)) + continue; + double energy = inSimEDepLite.Energy(); + double middleTime = inSimEDepLite.Time(); + int ID = inSimEDepLite.TrackID(); + + pSimEDepLites->emplace_back(energy, middlePos, middleTime, ID); + } + + e.put(std::move(pSimEDepLites)); } DEFINE_ART_MODULE(FilterSimEnergyDeposits) diff --git a/sbncode/DetSim/fcl/icarus_simedepfilter.fcl b/sbncode/DetSim/fcl/icarus_simedepfilter.fcl index 124a50981..e56b2db8b 100644 --- a/sbncode/DetSim/fcl/icarus_simedepfilter.fcl +++ b/sbncode/DetSim/fcl/icarus_simedepfilter.fcl @@ -3,6 +3,7 @@ BEGIN_PROLOG simedepfilter_ind1gap: { module_type: "FilterSimEnergyDeposits" InitSimEnergyDepositLabel: "ionization" + InitSimEnergyDepositLiteLabel: "sedlite" P1_X: -400 #cm, create a box that spans the full x,y range. Not super-precise. P1_Y: -200 #cm, create a box that spans the full x,y range. Not super-precise. P1_Z: -2 #cm, one edge of the filtered gap based on the 37 mm total size of the wire gap @@ -16,4 +17,4 @@ simedepfilter_ind1gap: { } -END_PROLOG \ No newline at end of file +END_PROLOG From ca8a96eb4c5971c2ee96e8f17c5b33bd49ddc4ff Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Thu, 24 Apr 2025 16:34:25 +0200 Subject: [PATCH 076/367] This commit introduces CRTT0Tagging for ICARUS into the CAFs, enabling the usage of CRTT0Tagged tracks for analysis and out of time cosmic rejection --- sbncode/CAFMaker/CAFMakerParams.h | 8 +++++++- sbncode/CAFMaker/CAFMaker_module.cc | 22 ++++++++++++++++++++-- sbncode/CAFMaker/FillReco.cxx | 10 ++++++++++ sbncode/CAFMaker/FillReco.h | 2 ++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index dab095902..61c415b03 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -275,7 +275,13 @@ namespace caf Atom CRTHitMatchLabel { Name("CRTHitMatchLabel"), Comment("Base label of track to CRT hit matching producer."), - "pandoraTrackCRTHit" + "CRTT0Tagging" + }; + + Atom CRTHitMatchInfoLabel { + Name("CRTHitMatchInfoLabel"), + Comment("Base label of additional information on track to CRT hit matching producer."), + "CRTT0Tagging" }; Atom CRTTrackMatchLabel { diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 32013baca..2b9e066c2 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1926,9 +1926,21 @@ void CAFMaker::produce(art::Event& evt) noexcept { // NOTE: The sbn::crt::CRTHit is associated to the T0. It's a bit awkward to // access that here, so we do it per-track (see code where fmCRTHitMatch is accessed below) + + // note: in the ICARUS case we do not need a slice_tag_stuff for CRTHitMatch as it is + // common to East and West + /* art::FindManyP fmCRTHitMatch = FindManyPStrict(slcTracks, evt, fParams.CRTHitMatchLabel() + slice_tag_suff); + */ + art::FindManyP fmCRTHitMatch = + FindManyPStrict(slcTracks, evt, + fParams.CRTHitMatchLabel()); + + art::FindManyP fmCRTHitMatchInfo = + FindManyPStrict(slcTracks, evt, + fParams.CRTHitMatchInfoLabel()); // TODO: also save the sbn::crt::CRTTrack in the matching so that CAFMaker has access to it art::FindManyP fmCRTTrackMatch = @@ -2167,14 +2179,20 @@ void CAFMaker::produce(art::Event& evt) noexcept { fParams.TrackHitFillRRStartCut(), fParams.TrackHitFillRREndCut(), dprop, trk); } + if (fmCRTHitMatch.isValid() && fDet == kICARUS) { art::FindManyP CRTT02Hit = FindManyPStrict - (fmCRTHitMatch.at(iPart), evt, fParams.CRTHitMatchLabel() + slice_tag_suff); + (fmCRTHitMatch.at(iPart), evt, fParams.CRTHitMatchLabel()); std::vector> crthitmatch; if (CRTT02Hit.isValid() && CRTT02Hit.size() == 1) crthitmatch = CRTT02Hit.at(0); - FillTrackCRTHit(fmCRTHitMatch.at(iPart), crthitmatch, fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, trk); + std::vector> crthittagginginfo; + if(CRTT02Hit.isValid() && CRTT02Hit.size() == 1){ + crthittagginginfo = fmCRTHitMatchInfo.at(iPart); + } + + FillTrackCRTHit(fmCRTHitMatch.at(iPart), crthitmatch, crthittagginginfo, fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, trk); } // NOTE: SEE TODO AT fmCRTTrackMatch if (fmCRTTrackMatch.isValid() && fDet == kICARUS) { diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 59d8e69f3..2e71822cc 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -548,6 +548,7 @@ namespace caf void FillTrackCRTHit(const std::vector> &t0match, const std::vector> &hitmatch, + const std::vector> &hitmatchinfo, bool use_ts0, int64_t CRT_T0_reference_time, // ns, signed double CRT_T1_reference_time, // us @@ -557,7 +558,16 @@ namespace caf if (t0match.size()) { assert(t0match.size() == 1); srtrack.crthit.distance = t0match[0]->fTriggerConfidence; + srtrack.crthit.region = t0match[0]->fID; + srtrack.crthit.sys = t0match[0]->fTriggerBits; + srtrack.crthit.deltaX = hitmatchinfo[0]->DeltaX; + srtrack.crthit.deltaY = hitmatchinfo[0]->DeltaY; + srtrack.crthit.deltaZ = hitmatchinfo[0]->DeltaZ; + srtrack.crthit.crossX = hitmatchinfo[0]->CrossX; + srtrack.crthit.crossY = hitmatchinfo[0]->CrossY; + srtrack.crthit.crossZ = hitmatchinfo[0]->CrossZ; srtrack.crthit.hit.time = t0match[0]->fTime / 1e3; /* ns -> us */ + srtrack.crthit.hit.plane = t0match[0]->fID; } if (hitmatch.size()) { FillCRTHit(*hitmatch[0], use_ts0, CRT_T0_reference_time, CRT_T1_reference_time, srtrack.crthit.hit, allowEmpty); diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index c6df1ab39..c6d3fdfc8 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -40,6 +40,7 @@ #include "sbnobj/SBND/CRT/CRTSpacePoint.hh" #include "sbnobj/SBND/CRT/CRTTrack.hh" #include "sbnobj/Common/CRT/CRTPMTMatching.hh" +#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" #include "nusimdata/SimulationBase/MCParticle.h" #include "nusimdata/SimulationBase/MCTruth.h" @@ -132,6 +133,7 @@ namespace caf void FillTrackCRTHit(const std::vector> &t0match, const std::vector> &hitmatch, + const std::vector> &hitmatchinfo, bool use_ts0, int64_t CRT_T0_reference_time, // ns, signed double CRT_T1_reference_time, // us From afe40cda2cabe2bed82cfb17063e4972faff7d45 Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Thu, 24 Apr 2025 17:18:11 +0200 Subject: [PATCH 077/367] Addressed a request from Gray that correctly pointed out it could break withcout a check on the hitmatchinfo size --- sbncode/CAFMaker/FillReco.cxx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 2e71822cc..447c839ca 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -559,13 +559,15 @@ namespace caf assert(t0match.size() == 1); srtrack.crthit.distance = t0match[0]->fTriggerConfidence; srtrack.crthit.region = t0match[0]->fID; - srtrack.crthit.sys = t0match[0]->fTriggerBits; - srtrack.crthit.deltaX = hitmatchinfo[0]->DeltaX; - srtrack.crthit.deltaY = hitmatchinfo[0]->DeltaY; - srtrack.crthit.deltaZ = hitmatchinfo[0]->DeltaZ; - srtrack.crthit.crossX = hitmatchinfo[0]->CrossX; - srtrack.crthit.crossY = hitmatchinfo[0]->CrossY; - srtrack.crthit.crossZ = hitmatchinfo[0]->CrossZ; + srtrack.crthit.sys = t0match[0]->fTriggerBits; + if(hitmatchinfo.size() == 1){ + srtrack.crthit.deltaX = hitmatchinfo[0]->DeltaX; + srtrack.crthit.deltaY = hitmatchinfo[0]->DeltaY; + srtrack.crthit.deltaZ = hitmatchinfo[0]->DeltaZ; + srtrack.crthit.crossX = hitmatchinfo[0]->CrossX; + srtrack.crthit.crossY = hitmatchinfo[0]->CrossY; + srtrack.crthit.crossZ = hitmatchinfo[0]->CrossZ; + } srtrack.crthit.hit.time = t0match[0]->fTime / 1e3; /* ns -> us */ srtrack.crthit.hit.plane = t0match[0]->fID; } From 9b443ee15d9f81a3bbd3d26359453ecbc24d81b6 Mon Sep 17 00:00:00 2001 From: gputnam Date: Thu, 24 Apr 2025 10:21:53 -0500 Subject: [PATCH 078/367] Clarify OverrideRealData comment. Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMakerParams.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index dab095902..ba84fb398 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -46,7 +46,7 @@ namespace caf }; Atom OverrideRealData { Name("OverrideRealData"), - Comment("Whether to ignore things aimed at real data -- e.g. if instead the event in an overlay"), false + Comment("when true, some algorithms (e.g. PoT count) treat events as MC rather than real data -- e.g. set it if the event is an overlay"), false }; Atom PrescaleFactor { Name("PrescaleFactor"), From 7b0737d65eb5c63cc5518ae9cc241cfc2ca4b9da Mon Sep 17 00:00:00 2001 From: gputnam Date: Thu, 24 Apr 2025 10:22:49 -0500 Subject: [PATCH 079/367] Idiomatic isRealData Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 32013baca..80e099102 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1274,7 +1274,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { bool const firstInFile = (fIndexInFile++ == 0); // is this event real data? -- BH: if fOverrideRealData, treat it as MC. Otherwise, get the info from the art event. - bool isRealData = ( fOverrideRealData ? false : evt.isRealData() ); + bool isRealData = !fOverrideRealData && evt.isRealData(); std::unique_ptr> srcol( new std::vector); From 92ee59df234b16925a36b76542ad3cfdd43a9f06 Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Mon, 28 Apr 2025 17:04:24 +0200 Subject: [PATCH 080/367] This commit addresses requests from the reviewers. --- sbncode/CAFMaker/CAFMakerParams.h | 2 +- sbncode/CAFMaker/CAFMaker_module.cc | 8 ++++---- sbncode/CAFMaker/FillReco.cxx | 7 +++++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 61c415b03..cc11b200e 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -275,7 +275,7 @@ namespace caf Atom CRTHitMatchLabel { Name("CRTHitMatchLabel"), Comment("Base label of track to CRT hit matching producer."), - "CRTT0Tagging" + "pandoraTrackCRTHit" }; Atom CRTHitMatchInfoLabel { diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 2b9e066c2..020fa8aa9 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -101,6 +101,7 @@ #include "nusimdata/SimulationBase/MCNeutrino.h" #include "nusimdata/SimulationBase/GTruth.h" +#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" #include "sbnobj/Common/EventGen/MeVPrtl/MeVPrtlTruth.h" #include "sbnobj/Common/Reco/RangeP.h" #include "sbnobj/Common/SBNEventWeight/EventWeightMap.h" @@ -1927,7 +1928,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { // NOTE: The sbn::crt::CRTHit is associated to the T0. It's a bit awkward to // access that here, so we do it per-track (see code where fmCRTHitMatch is accessed below) - // note: in the ICARUS case we do not need a slice_tag_stuff for CRTHitMatch as it is + // note: in the ICARUS case we do not need a slice_tag_suff for CRTHitMatch as it is // common to East and West /* art::FindManyP fmCRTHitMatch = @@ -2185,12 +2186,11 @@ void CAFMaker::produce(art::Event& evt) noexcept { (fmCRTHitMatch.at(iPart), evt, fParams.CRTHitMatchLabel()); std::vector> crthitmatch; - if (CRTT02Hit.isValid() && CRTT02Hit.size() == 1) crthitmatch = CRTT02Hit.at(0); - std::vector> crthittagginginfo; if(CRTT02Hit.isValid() && CRTT02Hit.size() == 1){ + crthitmatch = CRTT02Hit.at(0); crthittagginginfo = fmCRTHitMatchInfo.at(iPart); - } + } FillTrackCRTHit(fmCRTHitMatch.at(iPart), crthitmatch, crthittagginginfo, fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, trk); } diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 447c839ca..df80d757b 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -546,6 +546,7 @@ namespace caf //...................................................................... + void FillTrackCRTHit(const std::vector> &t0match, const std::vector> &hitmatch, const std::vector> &hitmatchinfo, @@ -555,6 +556,12 @@ namespace caf caf::SRTrack &srtrack, bool allowEmpty) { + // Francesco Poppi: In the current implementation, hitmatch and hitmatchinfo are + // vectors of pointers, but currently they are vector of size 1. + // The reason behind the current implementation is that we only store the + // best CRT candidate in the selection, eventually, we can store a vector + // of "good" candidates and fill additional infos for all of them. + // This is a TODO. if (t0match.size()) { assert(t0match.size() == 1); srtrack.crthit.distance = t0match[0]->fTriggerConfidence; From c4ed95613ad8d4724d6230348b149af738f5ca5f Mon Sep 17 00:00:00 2001 From: kjplows Date: Mon, 28 Apr 2025 15:38:48 -0500 Subject: [PATCH 081/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3463744c6..3c226693b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.04.08 LANGUAGES CXX) +project(sbncode VERSION 10.05.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 7f73d7985..d74e30d9b 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v10_05_00 - -sbnalg v10_04_08 - +sbnalg v10_05_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From e86e34e23016baf535ee1c033f8a495c955d7c0f Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Tue, 29 Apr 2025 19:36:15 +0200 Subject: [PATCH 082/367] removed outdated comment. --- sbncode/CAFMaker/CAFMaker_module.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 020fa8aa9..a5eea86bd 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1928,13 +1928,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { // NOTE: The sbn::crt::CRTHit is associated to the T0. It's a bit awkward to // access that here, so we do it per-track (see code where fmCRTHitMatch is accessed below) - // note: in the ICARUS case we do not need a slice_tag_suff for CRTHitMatch as it is - // common to East and West - /* - art::FindManyP fmCRTHitMatch = - FindManyPStrict(slcTracks, evt, - fParams.CRTHitMatchLabel() + slice_tag_suff); - */ art::FindManyP fmCRTHitMatch = FindManyPStrict(slcTracks, evt, fParams.CRTHitMatchLabel()); From 63e2505dc56afec6d481eeeca87d83e271ad329b Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Wed, 30 Apr 2025 16:32:54 -0500 Subject: [PATCH 083/367] Apply ADCScaleFactor correctly. --- sbncode/HitFinder/ChannelROIToWire_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/HitFinder/ChannelROIToWire_module.cc b/sbncode/HitFinder/ChannelROIToWire_module.cc index 243d5a744..42d304537 100644 --- a/sbncode/HitFinder/ChannelROIToWire_module.cc +++ b/sbncode/HitFinder/ChannelROIToWire_module.cc @@ -141,7 +141,7 @@ void ChannelROIToWire::produce(art::Event& evt) std::vector dataVec(range.data().size()); - for(size_t binIdx = 0; binIdx < range.data().size(); binIdx++) dataVec[binIdx] = std::round(range.data()[binIdx] * ADCScaleFactor); + for(size_t binIdx = 0; binIdx < range.data().size(); binIdx++) dataVec[binIdx] = std::round(range.data()[binIdx] / ADCScaleFactor); ROIVec.add_range(startTick, std::move(dataVec)); } From 177d4672815312c345344bfc104303747176736c Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 1 May 2025 12:26:04 -0500 Subject: [PATCH 084/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c226693b..ecef5790a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.05.00 LANGUAGES CXX) +project(sbncode VERSION 10.06.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index d74e30d9b..7e62556fe 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_05_00 - -sbnalg v10_05_00 - +larsoft v10_06_00 - +sbnalg v10_06_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From 0b5ad313d5a7cb64f0d6fded578cdceac887b05c Mon Sep 17 00:00:00 2001 From: Giuseppe Cerati Date: Tue, 6 May 2025 12:02:17 -0500 Subject: [PATCH 085/367] address BH comments --- sbncode/CAFMaker/CAFMaker_module.cc | 1 + sbncode/CAFMaker/FillReco.cxx | 31 ++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 0e8b88482..74f08272a 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -96,6 +96,7 @@ #include "lardataobj/RecoBase/Shower.h" #include "lardataobj/RecoBase/MCSFitResult.h" #include "lardataobj/RecoBase/Cluster.h" +#include "lardataobj/AnalysisBase/MVAOutput.h" #include "nusimdata/SimulationBase/MCFlux.h" #include "nusimdata/SimulationBase/MCTruth.h" diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 1224a10da..7dab1547d 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -978,10 +978,6 @@ namespace caf bool allowEmpty) { - auto arg_max = [](std::vector const& vec) { - return std::distance(vec.begin(), std::max_element(vec.begin(), vec.end())); - }; - // the nugraph elements are ordered the same as the sliceHitsMap std::vector mappedhits; for (auto& hit : pfpHits) { @@ -996,20 +992,23 @@ namespace caf std::vector ng2sempfpcounts(5,0); size_t ng2bkgpfpcount = 0; for (size_t pos : mappedhits) { - auto scores = ngSemanticResult.at(pos); - std::vector ng2semscores; - for (size_t i=0;isize();i++) ng2semscores.push_back(scores->at(i)); - size_t sem_label = arg_max(ng2semscores); - ng2sempfpcounts[sem_label]++; auto bkgscore = ngFilterResult.at(pos); - if (bkgscore->at(0)<0.5) ng2bkgpfpcount++; + if (bkgscore->at(0)<0.5) { + ng2bkgpfpcount++; + } else { + auto scores = ngSemanticResult.at(pos); + std::vector ng2semscores; + for (size_t i=0;isize();i++) ng2semscores.push_back(scores->at(i)); + size_t sem_label = std::distance(ng2semscores.begin(), std::max_element(ng2semscores.begin(), ng2semscores.end()));//arg_max(ng2semscores); + ng2sempfpcounts[sem_label]++; + } } - srpfp.ng_sem_cat = arg_max(ng2sempfpcounts); - srpfp.ng_mip_frac = float(ng2sempfpcounts[0])/pfpHits.size(); - srpfp.ng_hip_frac = float(ng2sempfpcounts[1])/pfpHits.size(); - srpfp.ng_shr_frac = float(ng2sempfpcounts[2])/pfpHits.size(); - srpfp.ng_mhl_frac = float(ng2sempfpcounts[3])/pfpHits.size(); - srpfp.ng_dif_frac = float(ng2sempfpcounts[4])/pfpHits.size(); + srpfp.ng_sem_cat = std::distance(ng2sempfpcounts.begin(), std::max_element(ng2sempfpcounts.begin(), ng2sempfpcounts.end()));//arg_max(ng2sempfpcounts); + srpfp.ng_mip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[0])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ng_hip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[1])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ng_shr_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[2])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ng_mhl_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[3])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ng_dif_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[4])/(pfpHits.size()-ng2bkgpfpcount) : -1.); srpfp.ng_bkg_frac = float(ng2bkgpfpcount)/pfpHits.size(); } else { srpfp.ng_sem_cat = -1; From cb3e4a3bb6b7fbdeac3e18294d853bd911f68702 Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Wed, 7 May 2025 20:18:43 +0200 Subject: [PATCH 086/367] fixed an issues where a .cc file was included, instead of a .h --- sbncode/Calibration/TrackCaloSkimmer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index c35f9ecd5..7cc2b91ee 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -61,8 +61,8 @@ #include "larsim/MCCheater/ParticleInventoryService.h" #include "sbnobj/Common/Calibration/TrackCaloSkimmerObj.h" -#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.cc" -#include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.cc" +#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.h" +#include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.h" #include "ITCSSelectionTool.h" From d4847d57956e1a8aec35f5a9e062f9a1f0796f32 Mon Sep 17 00:00:00 2001 From: Francesco Poppi Date: Wed, 7 May 2025 20:25:52 +0200 Subject: [PATCH 087/367] typo .h instead of .hh --- sbncode/Calibration/TrackCaloSkimmer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index 7cc2b91ee..f9fb1930e 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -61,8 +61,8 @@ #include "larsim/MCCheater/ParticleInventoryService.h" #include "sbnobj/Common/Calibration/TrackCaloSkimmerObj.h" -#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.h" -#include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.h" +#include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" +#include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.hh" #include "ITCSSelectionTool.h" From b36ce76b7d5f5d255902eb2d1a924b8167c00b52 Mon Sep 17 00:00:00 2001 From: Giuseppe Cerati Date: Wed, 7 May 2025 13:27:30 -0500 Subject: [PATCH 088/367] fix typo --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillReco.cxx | 2 +- sbncode/CAFMaker/FillReco.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 74f08272a..948181bf2 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2150,7 +2150,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { } if (ng2_slice_hit_map_handle[producer].isValid()) { - FillPPFNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp); + FillPFPNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp); } if (!thisTrack.empty()) { // it has a track! diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 0979d93fe..33b435fd9 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -970,7 +970,7 @@ namespace caf srpfp.cnnscore.nclusters = cnnscore->nClusters; } - void FillPPFNuGraph(const std::vector &sliceHitsMap, + void FillPFPNuGraph(const std::vector &sliceHitsMap, const std::vector>> &ngFilterResult, const std::vector>> &ngSemanticResult, const std::vector> &pfpHits, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 5482077f1..45cf2ea2b 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -137,7 +137,7 @@ namespace caf caf::SRPFP& srpfp, bool allowEmpty = false); - void FillPPFNuGraph(const std::vector &sliceHitsMap, + void FillPFPNuGraph(const std::vector &sliceHitsMap, const std::vector>> &ngFilterResult, const std::vector>> &ngSemanticResult, const std::vector> &pfpHits, From 0157111590797da7ce620909cebab78653bce80b Mon Sep 17 00:00:00 2001 From: Giuseppe Cerati Date: Wed, 7 May 2025 19:00:19 -0500 Subject: [PATCH 089/367] address GP's comments --- sbncode/CAFMaker/FillReco.cxx | 38 +++++++++++++++++------------------ sbncode/CAFMaker/FillReco.h | 20 ++++++++++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 33b435fd9..0106aaf61 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -12,6 +12,7 @@ namespace caf { + const float ng_filter_cut = 0.5; //...................................................................... bool SelectSlice(const caf::SRSlice &slice, bool cut_clear_cosmic) { @@ -544,7 +545,6 @@ namespace caf } } - void FillSliceNuGraph(const std::vector> &inputHits, const std::vector &sliceHitsMap, const std::vector>> &ngFilterResult, @@ -559,7 +559,7 @@ namespace caf unsigned int npass = 0; for ( unsigned int i = 0; i < nHits; i++ ) { - if (ngFilterResult.at(i)->at(0)>0.5) npass++; + if (ngFilterResult.at(i)->at(0)>=ng_filter_cut) npass++; } slice.ng_filt_pass_frac = float(npass)/nHits; } @@ -992,32 +992,32 @@ namespace caf std::vector ng2sempfpcounts(5,0); size_t ng2bkgpfpcount = 0; for (size_t pos : mappedhits) { - auto bkgscore = ngFilterResult.at(pos); - if (bkgscore->at(0)<0.5) { + auto const& bkgscore = ngFilterResult.at(pos); + if (bkgscore->at(0) ng2semscores; for (size_t i=0;isize();i++) ng2semscores.push_back(scores->at(i)); size_t sem_label = std::distance(ng2semscores.begin(), std::max_element(ng2semscores.begin(), ng2semscores.end()));//arg_max(ng2semscores); ng2sempfpcounts[sem_label]++; } } - srpfp.ng_sem_cat = std::distance(ng2sempfpcounts.begin(), std::max_element(ng2sempfpcounts.begin(), ng2sempfpcounts.end()));//arg_max(ng2sempfpcounts); - srpfp.ng_mip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[0])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ng_hip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[1])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ng_shr_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[2])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ng_mhl_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[3])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ng_dif_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[4])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ng_bkg_frac = float(ng2bkgpfpcount)/pfpHits.size(); + srpfp.ngscore.sem_cat = SRNuGraphScore::NuGraphCategory(std::distance(ng2sempfpcounts.begin(), std::max_element(ng2sempfpcounts.begin(), ng2sempfpcounts.end())));//arg_max(ng2sempfpcounts); + srpfp.ngscore.mip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[0])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ngscore.hip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[1])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ngscore.shr_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[2])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ngscore.mhl_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[3])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ngscore.dif_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[4])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + srpfp.ngscore.bkg_frac = float(ng2bkgpfpcount)/pfpHits.size(); } else { - srpfp.ng_sem_cat = -1; - srpfp.ng_mip_frac = -1.; - srpfp.ng_hip_frac = -1.; - srpfp.ng_shr_frac = -1.; - srpfp.ng_mhl_frac = -1.; - srpfp.ng_dif_frac = -1.; - srpfp.ng_bkg_frac = -1.; + srpfp.ngscore.sem_cat = SRNuGraphScore::NuGraphCategory::Unset; + srpfp.ngscore.mip_frac = -1.; + srpfp.ngscore.hip_frac = -1.; + srpfp.ngscore.shr_frac = -1.; + srpfp.ngscore.mhl_frac = -1.; + srpfp.ngscore.dif_frac = -1.; + srpfp.ngscore.bkg_frac = -1.; } } diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 45cf2ea2b..efe582756 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -105,6 +105,16 @@ namespace caf const std::vector> &inputPoints, caf::SRSlice &slice); + /** + * @brief Fills the results from NuGraph at slice level + * @param inputHits (pointers to) the hits associated to the slice + * @param sliceHitsMap maps position of hits in collection input to NuGraph (slice only) to the one input to Pandora (all gaus hits) + * @param ngFilterResult NuGraph filter result, for each hit + * @param ngSemanticResult NuGraph semnatic result, for each hit (MIP track, HIP, shower, Michel electron, diffuse activity) + * @param[out] slice the destination slice object + * + * Hits with filter value (`ngFilterResult`) lower than `ng_filter_cut` are counted as background. + */ void FillSliceNuGraph(const std::vector> &inputHits, const std::vector &sliceHitsMap, const std::vector>> &ngFilterResult, @@ -137,6 +147,16 @@ namespace caf caf::SRPFP& srpfp, bool allowEmpty = false); + /** + * @brief Fills the results from NuGraph at slice level + * @param sliceHitsMap maps position of hits in collection input to NuGraph (slice only) to the one input to Pandora (all gaus hits) + * @param ngFilterResult NuGraph filter result, for each hit + * @param ngSemanticResult NuGraph semnatic result, for each hit (MIP track, HIP, shower, Michel electron, diffuse activity) + * @param pfpHits Vector of hits associated to the PFParticle + * @param[out] srpfp the destination PFParticle object + * + * Hits with filter value (`ngFilterResult`) lower than `ng_filter_cut` are counted as background. + */ void FillPFPNuGraph(const std::vector &sliceHitsMap, const std::vector>> &ngFilterResult, const std::vector>> &ngSemanticResult, From cae5b11869ac295ad72061d4cd4de77fcd81744c Mon Sep 17 00:00:00 2001 From: Giuseppe Cerati Date: Wed, 7 May 2025 19:22:29 -0500 Subject: [PATCH 090/367] address GP's comments --- sbncode/CAFMaker/FillReco.cxx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d01cb1d91..d81cb5890 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -1058,11 +1058,12 @@ namespace caf } } srpfp.ngscore.sem_cat = SRNuGraphScore::NuGraphCategory(std::distance(ng2sempfpcounts.begin(), std::max_element(ng2sempfpcounts.begin(), ng2sempfpcounts.end())));//arg_max(ng2sempfpcounts); - srpfp.ngscore.mip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[0])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ngscore.hip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[1])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ngscore.shr_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[2])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ngscore.mhl_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[3])/(pfpHits.size()-ng2bkgpfpcount) : -1.); - srpfp.ngscore.dif_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[4])/(pfpHits.size()-ng2bkgpfpcount) : -1.); + size_t nonBkgHits = (pfpHits.size() > ng2bkgpfpcount ? pfpHits.size()-ng2bkgpfpcount : 0); + srpfp.ngscore.mip_frac = (nonBkgHits>0 ? float(ng2sempfpcounts[0])/nonBkgHits : -1.); + srpfp.ngscore.hip_frac = (nonBkgHits>0 ? float(ng2sempfpcounts[1])/nonBkgHits : -1.); + srpfp.ngscore.shr_frac = (nonBkgHits>0 ? float(ng2sempfpcounts[2])/nonBkgHits : -1.); + srpfp.ngscore.mhl_frac = (nonBkgHits>0 ? float(ng2sempfpcounts[3])/nonBkgHits : -1.); + srpfp.ngscore.dif_frac = (nonBkgHits>0 ? float(ng2sempfpcounts[4])/nonBkgHits : -1.); srpfp.ngscore.bkg_frac = float(ng2bkgpfpcount)/pfpHits.size(); } else { srpfp.ngscore.sem_cat = SRNuGraphScore::NuGraphCategory::Unset; From 4630c4466bb201380cb8ccfad93777de357ae11c Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 8 May 2025 04:57:56 -0500 Subject: [PATCH 091/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecef5790a..8591bc48b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.06.00 LANGUAGES CXX) +project(sbncode VERSION 10.06.00.01 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 7e62556fe..e479198df 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v10_06_00 - -sbnalg v10_06_00 - +sbnalg v10_06_00_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From a0442281b318a78250046bd034f005630e26f7ab Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Mon, 2 Jun 2025 19:00:57 -0500 Subject: [PATCH 092/367] read PMTBeamSignal into the CAFMaker to be passed to FillICARUSOpFlash --- sbncode/CAFMaker/CAFMakerParams.h | 6 ++++++ sbncode/CAFMaker/CAFMaker_module.cc | 15 +++++++++++++-- sbncode/CAFMaker/CMakeLists.txt | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 253f0d4c2..572bb5545 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -374,6 +374,12 @@ namespace caf "OpFlash" }; + Atom PMTBeamSignalLabel { + Name("PMTBeamSignalLabel"), + Comment("Label for special PMT beam timing signals used to build the beam bunch structure"), + "beamTiming:RWM" + }; + Atom CRTSimT0Offset { Name("CRTSimT0Offset"), Comment("start of beam gate/simulation time in the simulated CRT clock"), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 48da84e8f..31212aec0 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1669,6 +1669,10 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector srflashes; if(fDet == kICARUS) { + //Get all of the special PMT Beam Signals (to use as an opFlash reference time below) + art::Handle> PMTBeamSignal_handle; + GetByLabelStrict(evt, fParams.PMTBeamSignalLabel(), PMTBeamSignal_handle); + for (const std::string& pandora_tag_suffix : pandora_tag_suffixes) { art::Handle> flashes_handle; GetByLabelStrict(evt, fParams.OpFlashLabel() + pandora_tag_suffix, flashes_handle); @@ -1676,7 +1680,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (flashes_handle.isValid()) { const std::vector &opflashes = *flashes_handle; int cryostat = ( pandora_tag_suffix.find("W") != std::string::npos ) ? 1 : 0; - + // get associated OpHits for each OpFlash art::FindMany findManyHits(flashes_handle, evt, fParams.OpFlashLabel() + pandora_tag_suffix); @@ -1686,7 +1690,14 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector const& ophits = findManyHits.at(iflash); srflashes.emplace_back(); - FillICARUSOpFlash(flash, ophits, cryostat, srflashes.back()); + if(PMTBeamSignal_handle.isValid() && isRealData){ + const std::vector &pmtbeamsignals = *PMTBeamSignal_handle; + FillICARUSOpFlash(flash, ophits, cryostat, pmtbeamsignals, srflashes.back()); + } + else{ + const std::vector pmtbeamsignals; + FillICARUSOpFlash(flash, ophits, cryostat, pmtbeamsignals, srflashes.back()); + } iflash++; } } diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 76c3903d4..4cae127e2 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -35,6 +35,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_CRT sbnobj::Common_Reco sbnobj::Common_Analysis + sbnobj::Common_PMT_Data sbnobj::SBND_CRT lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service From 505cdc88702a885e9f64c756ad5a521b6a26521f Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Mon, 2 Jun 2025 19:06:33 -0500 Subject: [PATCH 093/367] within FillICARUSOpFlash, reconstruct the flash time w.r.t. RWM time using information stored in PMTBeamSignal --- sbncode/CAFMaker/FillReco.cxx | 6 ++++++ sbncode/CAFMaker/FillReco.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d81cb5890..75c46cea5 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -183,6 +183,7 @@ namespace caf void FillICARUSOpFlash(const recob::OpFlash &flash, std::vector const& hits, int cryo, + std::vector RWMTimes, caf::SROpFlash &srflash, bool allowEmpty) { @@ -192,11 +193,16 @@ namespace caf srflash.timewidth = flash.TimeWidth(); double firstTime = std::numeric_limits::max(); + std::map startmap, risemap; for(const auto& hit: hits){ double const hitTime = hit->HasStartTime()? hit->StartTime(): hit->PeakTime(); if (firstTime > hitTime) firstTime = hitTime; + if (!RWMTimes.empty()) + sbn::timing::SelectFirstOpHitByTime(hit,startmap,risemap); } + srflash.rwmtime = getFlashBunchTime(risemap, RWMTimes); + std::cout << "Flash at Time " << flash.Time() << " has " << startmap.size() << " opHit channels, flashTime_rwm = " << srflash.rwmtime << " \n"; srflash.firsttime = firstTime; srflash.cryo = cryo; // 0 in SBND, 0/1 for E/W in ICARUS diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 6e8ecf292..4b24b4a98 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -42,6 +42,7 @@ #include "sbnobj/SBND/CRT/CRTTrack.hh" #include "sbnobj/Common/CRT/CRTPMTMatching.hh" #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" +#include "sbnobj/Common/PMT/Data/PMTBeamSignal.hh" #include "nusimdata/SimulationBase/MCParticle.h" #include "nusimdata/SimulationBase/MCTruth.h" @@ -256,6 +257,7 @@ namespace caf void FillICARUSOpFlash(const recob::OpFlash &flash, std::vector const& hits, int cryo, + std::vector RWMTimes, caf::SROpFlash &srflash, bool allowEmpty = false); From 9aa0be95ae6243b768c7099dc5a622faeedd431a Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Mon, 2 Jun 2025 19:07:29 -0500 Subject: [PATCH 094/367] remove cout statement --- sbncode/CAFMaker/FillReco.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 75c46cea5..0d69d594b 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -202,7 +202,6 @@ namespace caf sbn::timing::SelectFirstOpHitByTime(hit,startmap,risemap); } srflash.rwmtime = getFlashBunchTime(risemap, RWMTimes); - std::cout << "Flash at Time " << flash.Time() << " has " << startmap.size() << " opHit channels, flashTime_rwm = " << srflash.rwmtime << " \n"; srflash.firsttime = firstTime; srflash.cryo = cryo; // 0 in SBND, 0/1 for E/W in ICARUS From a492b433631af51e140042bae88e8aa7667f2cc6 Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Thu, 5 Jun 2025 14:17:32 -0500 Subject: [PATCH 095/367] remove startmap from SelectFirstOpHitByTime as it is not needed --- sbncode/CAFMaker/FillReco.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 0d69d594b..cb3dc5f6c 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -193,13 +193,13 @@ namespace caf srflash.timewidth = flash.TimeWidth(); double firstTime = std::numeric_limits::max(); - std::map startmap, risemap; + std::map risemap; for(const auto& hit: hits){ double const hitTime = hit->HasStartTime()? hit->StartTime(): hit->PeakTime(); if (firstTime > hitTime) firstTime = hitTime; if (!RWMTimes.empty()) - sbn::timing::SelectFirstOpHitByTime(hit,startmap,risemap); + sbn::timing::SelectFirstOpHitByTime(hit,risemap); } srflash.rwmtime = getFlashBunchTime(risemap, RWMTimes); srflash.firsttime = firstTime; From 0f63559060a95327629ecc23a7844cb256e5513c Mon Sep 17 00:00:00 2001 From: Anna Heggestuen Date: Thu, 5 Jun 2025 14:33:47 -0500 Subject: [PATCH 096/367] use GetByLabelIfExists for PMTBeamSignalLabel --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 31212aec0..b2cdb15f8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1671,7 +1671,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { { //Get all of the special PMT Beam Signals (to use as an opFlash reference time below) art::Handle> PMTBeamSignal_handle; - GetByLabelStrict(evt, fParams.PMTBeamSignalLabel(), PMTBeamSignal_handle); + GetByLabelIfExists(evt, fParams.PMTBeamSignalLabel(), PMTBeamSignal_handle); for (const std::string& pandora_tag_suffix : pandora_tag_suffixes) { art::Handle> flashes_handle; From 7d0e890c48ada68f1fd48a33aeaca49712aa47c4 Mon Sep 17 00:00:00 2001 From: Harry Hausner <56450208+hausnerh@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:02:33 -0500 Subject: [PATCH 097/367] Add new devices to BNB Info --- .../BNBRetriever/BNBRetriever_module.cc | 30 +++++++++++++++++++ sbncode/CAFMaker/FillExposure.cxx | 10 +++++++ 2 files changed, 40 insertions(+) diff --git a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc index 2265d0e2c..903d52873 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBRetriever/BNBRetriever_module.cc @@ -663,6 +663,8 @@ sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo double LM875A = 0; // units R/s double LM875B = 0; // units R/s double LM875C = 0; // units R/s + double HP873 = 0; // units mm + double VP873 = 0; // units mm double HP875 = 0; // units mm double VP875 = 0; // units mm double HPTG1 = 0; // units mm @@ -671,6 +673,14 @@ sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo double VPTG2 = 0; // units mm double BTJT2 = 0; // units Deg C double THCURR = 0; // units kiloAmps + double M875HS = 0; // units mm + double M875VS = 0; // units mm + double M875HM = 0; // units mm + double M875VM = 0; // units mm + double M876HS = 0; // units mm + double M876VS = 0; // units mm + double M876HM = 0; // units mm + double M876VM = 0; // units mm double TOR860_time = 0; // units s @@ -683,6 +693,8 @@ sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo try{bfp->GetNamedData(time, "E:LM875A",&LM875A);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:HP873",&HP873);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:VP873",&VP873);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -691,6 +703,14 @@ sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M875HS",&M875HS);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M875VS",&M875VS);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M875HM",&M875HM);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M875VM",&M875VM);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M876HS",&M876HS);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M876VS",&M876VS);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M876HM",&M876HM);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{bfp->GetNamedData(time, "E:M876VM",&M876VM);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} //crunch the times unsigned long int time_closest_int = (int) TOR860_time; @@ -703,6 +723,8 @@ sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo beamInfo.LM875A = LM875A; beamInfo.LM875B = LM875B; beamInfo.LM875C = LM875C; + beamInfo.HP873 = HP873; + beamInfo.VP873 = VP873; beamInfo.HP875 = HP875; beamInfo.VP875 = VP875; beamInfo.HPTG1 = HPTG1; @@ -711,6 +733,14 @@ sbn::BNBSpillInfo sbn::BNBRetriever::makeBNBSpillInfo beamInfo.VPTG2 = VPTG2; beamInfo.BTJT2 = BTJT2; beamInfo.THCURR = THCURR; + beamInfo.M875HS = M875HS; + beamInfo.M875VS = M875VS; + beamInfo.M875HM = M875HM; + beamInfo.M875VM = M875VM; + beamInfo.M876HS = M876HS; + beamInfo.M876VS = M876VS; + beamInfo.M876HM = M876HM; + beamInfo.M876VM = M876VM; beamInfo.spill_time_s = time_closest_int; beamInfo.spill_time_ns = time_closest_ns; diff --git a/sbncode/CAFMaker/FillExposure.cxx b/sbncode/CAFMaker/FillExposure.cxx index 01dd11b80..a4bc81494 100644 --- a/sbncode/CAFMaker/FillExposure.cxx +++ b/sbncode/CAFMaker/FillExposure.cxx @@ -15,6 +15,8 @@ namespace caf single_store.LM875A = info.LM875A; single_store.LM875B = info.LM875B; single_store.LM875C = info.LM875C; + single_store.HP873 = info.HP873; + single_store.VP873 = info.VP873; single_store.HP875 = info.HP875; single_store.VP875 = info.VP875; single_store.HPTG1 = info.HPTG1; @@ -23,6 +25,14 @@ namespace caf single_store.VPTG2 = info.VPTG2; single_store.BTJT2 = info.BTJT2; single_store.THCURR = info.THCURR; + single_store.M875HS = info.M875HS; + single_store.M875VS = info.M875VS; + single_store.M875HM = info.M875HM; + single_store.M875VM = info.M875VM; + single_store.M876HS = info.M876HS; + single_store.M876VS = info.M876VS; + single_store.M876HM = info.M876HM; + single_store.M876VM = info.M876VM; single_store.M875BB = info.M875BB; single_store.M876BB = info.M876BB; single_store.MMBTBB = info.MMBTBB; From 742d78c940b43d67420c0c7b87a683d6773f373b Mon Sep 17 00:00:00 2001 From: jzennamo Date: Wed, 2 Jul 2025 15:50:28 -0500 Subject: [PATCH 098/367] need to edit ref --- .../BNBEXTRetriever/BNBEXTRetriever_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc index 1b7c79dd5..14ea73741 100644 --- a/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/BNBEXTRetriever/BNBEXTRetriever_module.cc @@ -173,7 +173,7 @@ void sbn::BNBEXTRetriever::endSubRun(art::SubRun& sr) std::cout << "FAILED! " << std::endl; // probably want to throw an exception here - for(auto ExtInfo : fOutExtInfos){ + for(auto &ExtInfo : fOutExtInfos){ ExtInfo.gates_since_last_trigger *= scale_factor; From d141dc324520bf206bb7100939802aa534124a47 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 7 Jul 2025 17:04:49 -0500 Subject: [PATCH 099/367] Initial working build stage --- sbncode/BeamSpillInfoRetriever/CMakeLists.txt | 18 +- .../SBNDBNBRetriever/CMakeLists.txt | 1 + .../SBNDBNBRetriever_module.cc | 21 +- .../SBNDBNBZEROBIASRetriever_module.cc | 10 +- .../BeamSpillInfoRetriever/SBNDPOTTools.cpp | 42 +- sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h | 2 +- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 589 ++++++++++++++++++ sbncode/BeamSpillInfoRetriever/getFOM.h | 37 ++ .../job/sbndbnbdefaults.fcl | 3 + 9 files changed, 717 insertions(+), 6 deletions(-) create mode 100644 sbncode/BeamSpillInfoRetriever/getFOM.cpp create mode 100644 sbncode/BeamSpillInfoRetriever/getFOM.h diff --git a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt index 3fcd2f930..cd7b625d1 100644 --- a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt @@ -15,6 +15,7 @@ art_make_library(LIBRARIES Boost::system SOURCE MWRData.cpp ) + art_make_library( LIBRARIES art::Persistency_Common @@ -26,11 +27,24 @@ art_make_library( sbnobj::Common_POTAccounting sbn_MWRData larcorealg::CoreUtils - - LIBRARY_NAME sbn_SBNDPOTTools + + LIBRARY_NAME sbn_SBNDPOTTools SOURCE SBNDPOTTools.cpp ) +art_make_library( + LIBRARIES + art::Persistency_Common + art::Utilities + ROOT::Hist + ROOT::Spectrum + ROOT::MathCore + ROOT::Tree + + LIBRARY_NAME sbn_getFOM + SOURCE getFOM.cpp +) + install_headers() install_fhicl() install_source() diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt index ea89ae916..ca297fcdd 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt @@ -4,6 +4,7 @@ find_package(ifdh_art) cet_build_plugin(SBNDBNBRetriever art::module LIBRARIES sbn_SBNDPOTTools + sbn_getFOM ) install_headers() diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 5e709c2b0..9536c3d61 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -9,6 +9,9 @@ #include "messagefacility/MessageLogger/MessageLogger.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" #include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" +//#include "sbncode/BeamSpillInfoRetriever/getFOM.cpp" +#include "sbncode/BeamSpillInfoRetriever/getFOM.h" + namespace sbn { class SBNDBNBRetriever; @@ -35,7 +38,10 @@ class sbn::SBNDBNBRetriever : public art::EDProducer { double fBESOffset; std::string fDeviceUsedForTiming; std::unique_ptr bfp; + std::unique_ptr offsets; + std::unique_ptr vp873; std::unique_ptr bfp_mwr; + sbn::MWRData mwrdata; art::ServiceHandle ifbeam_handle; static constexpr double MWRtoroidDelay = -0.035; ///< the same time point is measured _t_ by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] @@ -62,6 +68,12 @@ sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); TotalBeamSpills = 0; + vp873 = ifbeam_handle->getBeamFolder(params.get("VP873Bundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + vp873->set_epsilon(0.02); + + offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + offsets->set_epsilon(600); + } void sbn::SBNDBNBRetriever::produce(art::Event & e) @@ -210,7 +222,14 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( }//end loop over MWR devices - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp); + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); + + double spillFOM = sbn::getFOM(spillInfo); + + spillInfo.FOM = spillFOM; + + std::cout << spillInfo.HP875 << "," < bfp; + std::unique_ptr offsets; + std::unique_ptr vp873; std::unique_ptr bfp_mwr; sbn::MWRData mwrdata; art::ServiceHandle ifbeam_handle; @@ -61,6 +63,12 @@ sbn::SBNDBNBZEROBIASRetriever::SBNDBNBZEROBIASRetriever(fhicl::ParameterSet cons bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); + vp873 = ifbeam_handle->getBeamFolder(params.get("VP873Bundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + vp873->set_epsilon(0.02); + + offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + offsets->set_epsilon(600); + TotalBeamSpills = 0; produces< std::vector< sbn::BNBSpillInfo >, art::InEvent >(); produces< std::vector< sbn::BNBSpillInfo >, art::InSubRun >(); @@ -217,7 +225,7 @@ void sbn::SBNDBNBZEROBIASRetriever::matchMultiWireData( }//end loop over MWR times }//end loop over MWR devices - sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp); + sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); beamInfos.push_back(std::move(spillInfo)); // We do not write these to the art::Events because diff --git a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp b/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp index 9acb26ab2..79d257cca 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.cpp @@ -65,7 +65,7 @@ namespace sbn{ // Collect device information to make BNBSpillInfo object. Used in // ICARUS and SBND modules. sbn::BNBSpillInfo makeBNBSpillInfo - (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR, std::unique_ptr const& bfp) + (art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR, std::unique_ptr const& bfp, const std::unique_ptr & offsets,const std::unique_ptr & vp873) { auto const& [ MWR_times, unpacked_MWR ] = MWRdata; // alias @@ -87,8 +87,19 @@ namespace sbn{ double BTJT2 = 0; // units Deg C double THCURR = 0; // units kiloAmps + + double VP873 = 0; //units mm; not in the first IFBeam query bunch + double HP875Offset =0;//units mm; make a another separate IFBeam query bunch for offsets + double VP875Offset =0;//units mm + double VP873Offset =0;//units mm + double HPTG1Offset =0;//units mm + double HPTG2Offset =0;//units mm + double VPTG1Offset =0;//units mm + double VPTG2Offset =0;//units mm + double TOR860_time = 0; // units s + // Here we request all the devices // since sometimes devices fail to report we'll // allow each to throw an exception but still move forward @@ -107,6 +118,21 @@ namespace sbn{ try{bfp->GetNamedData(time, "E:VPTG2",&VPTG2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:BTJT2",&BTJT2);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:THCURR",&THCURR);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + + + try{bfp->GetNamedData(time, "E:VP873",&VP873);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + try{offsets->GetNamedData(time, "E_VP873S",&VP873Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{offsets->GetNamedData(time, "E_HP875S",&HP875Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{offsets->GetNamedData(time, "E_VP875S",&VP875Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{offsets->GetNamedData(time, "E_HPTG1S",&HPTG1Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{offsets->GetNamedData(time, "E_HPTG2S",&HPTG2Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{offsets->GetNamedData(time, "E_VPTG1S",&VPTG1Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{offsets->GetNamedData(time, "E_VPTG2S",&VPTG2Offset);}catch (WebAPIException &we) {mf::LogDebug("SBNDBNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + + + //crunch the times unsigned long int time_closest_int = (int) TOR860_time; @@ -129,6 +155,16 @@ namespace sbn{ beamInfo.THCURR = THCURR; beamInfo.spill_time_s = time_closest_int; beamInfo.spill_time_ns = time_closest_ns; + beamInfo.VP873 = VP873; + beamInfo.VP873Offset = VP873Offset; + beamInfo.HP875Offset = HP875Offset; + beamInfo.VP875Offset = VP875Offset; + beamInfo.HPTG1Offset = HPTG1Offset; + beamInfo.HPTG2Offset = HPTG2Offset; + beamInfo.VPTG1Offset = VPTG1Offset; + beamInfo.VPTG2Offset = VPTG2Offset; + + for(auto const& MWRdata: unpacked_MWR){ std::ignore = MWRdata; @@ -331,4 +367,8 @@ namespace sbn{ return { std::move(MWR_times), std::move(unpacked_MWR) }; } + } + + + diff --git a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h b/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h index 46d16c709..a43b09691 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h +++ b/sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h @@ -36,7 +36,7 @@ namespace sbn{ double extractTDCTimeStamp(art::Handle > cont_frags); bool BrokenClock(double time, std::unique_ptr const& bfp); MWRdata_t extractSpillTimes(TriggerInfo_t const& triggerInfo, std::unique_ptr const& bfp, std::unique_ptr const& bfp_mwr, double fTimePad, double MWRtoroidDelay, sbn::MWRData mwrdata ); - sbn::BNBSpillInfo makeBNBSpillInfo(art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR, std::unique_ptr const& bfp); + sbn::BNBSpillInfo makeBNBSpillInfo(art::EventID const& eventID, double time, MWRdata_t const& MWRdata, std::vector const& matched_MWR, std::unique_ptr const& bfp, std::unique_ptr const& offsets, std::unique_ptr const& vp873); } #endif diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp new file mode 100644 index 000000000..75684caa2 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -0,0 +1,589 @@ +#include "getFOM.h" +#include +#include +#include "TH1D.h" +#include "TF1.h" + +using namespace std; + + +namespace sbn { + + float getFOM(BNBSpillInfo & spill ) + //float getFOM2( const ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings, bool useAutoTune) + { + double fom=0; + + + + + + // ========================================= I believe all of this can be replaced with the BNBSpillInfo which I fill already ============================================ + + + + + + + + double hp875_offset= spill.HP875Offset; + double vp875_offset= spill.VP875Offset; + double hptg1_offset= spill.HPTG1Offset; + double vptg1_offset= spill.VPTG1Offset; + double hptg2_offset= spill.HPTG2Offset; + double vptg2_offset= spill.VPTG2Offset; + + + //int useHTG = bnb::kTG1; + //int useVTG = bnb::kTG1; + + int useHTG = 1; + int useVTG = 1; + + + //if(useAutoTune){ + // bnb::bnbOffsets data = settings.getData(); + // hp875_offset = data.hp875; + // vp875_offset = data.vp875; + // hptg1_offset = data.hptg1; + // vptg1_offset = data.vptg1; + // hptg2_offset = data.hptg2; + // vptg2_offset = data.vptg2; + //useHTG = settings.getHTG(); + //useVTG = settings.getVTG(); + //} + + + + //double hptg2_offset= +0.79; + //double vptg2_offset= +1.02; + double hp875_zpos= 202.116104; + double vp875_zpos= 202.3193205; + double hptg1_zpos= 204.833267; + double vptg1_zpos= 204.629608; + double hptg2_zpos= 205.240662; + double vptg2_zpos= 205.036835; + double target_center_zpos= 206.870895; + double p875x[]={0.431857, 0.158077, 0.00303551}; + double p875y[]={0.279128, 0.337048, 0}; + double p876x[]={0.166172, 0.30999, -0.00630299}; + double p876y[]={0.13425, 0.580862, 0}; + + + std::vector tor860; + std::vector tor875; + std::vector hp875; + std::vector vp875; + std::vector hptg1; + std::vector vptg1; + std::vector hptg2; + std::vector vptg2; + + std::vector mw875(spill.M875BB.begin(), spill.M875BB.end()); + std::vector mw876(spill.M876BB.begin(), spill.M876BB.end()); + std::vector mwtgt(spill.MMBTBB.begin(), spill.MMBTBB.end()); + + //std::vector mw875 = spill.M875BB; + //std::vector mw876 = spill.M876BB; + //std::vector mwtgt = spill.MMBTBB; + + tor860.push_back(spill.TOR860); + tor875.push_back(spill.TOR875); + hp875.push_back(spill.HP875); + vp875.push_back(spill.VP875); + hptg1.push_back(spill.HPTG1); + vptg1.push_back(spill.VPTG1); + hptg2.push_back(spill.HPTG2); + vptg2.push_back(spill.VPTG2); + + /* + for(auto& bdata : bd) { // get toroid, BPM, and multiwire data + if(bdata.getDeviceName().find("E:TOR860") != std::string::npos) { // get E:TOR860 reading + tor860 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:TOR875") != std::string::npos) { // get E:TOR875 reading + tor875 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:HP875") != std::string::npos) { // get E:HP875 reading + hp875 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:VP875") != std::string::npos) { // get E:VP875 reading + vp875 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:HPTG1") != std::string::npos) { // get E:HPTG1 reading + hptg1 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:VPTG1") != std::string::npos) { // get E:VPTG1 reading + vptg1 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:HPTG2") != std::string::npos) { // get E:HPTG1 reading + hptg2 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:VPTG2") != std::string::npos) { // get E:VPTG1 reading + vptg2 = bdata.getData(); + continue; + } else if(bdata.getDeviceName().find("E:M875BB") != std::string::npos) { // get horizontal and vertical target multiwire reading + mw875.resize(96); + for (int ii=0;ii<96;ii++) + mw875[ii]=bdata.getData()[ii]; + continue; + } else if(bdata.getDeviceName().find("E:M876BB") != std::string::npos) { // get horizontal and vertical target multiwire reading + mw876.resize(96); + for (int ii=0;ii<96;ii++) + mw876[ii]=bdata.getData()[ii]; + continue; + } else if(bdata.getDeviceName().find("E:MMBTBB") != std::string::npos) { // get horizontal and vertical target multiwire reading + mwtgt.resize(96); + for (int ii=0;ii<96;ii++) + mwtgt[ii]=bdata.getData()[ii]; + continue; + } + } + */ + + double tor; + if (tor860.size()>0) + tor=tor860[0]; + else if (tor875.size()>0) + tor=tor875[0]; + else + return -1; + + + + + // ==================================================================== Replace with BNBSpillInfo ==================================================================================== + + + + + + //when creating ntuples for pot counting script the variables are filled with -999 + //this could create a difference when passing events with FOM>1 since + //events with missing BPM data would get FOM=2, while events with BPM set to -999 will get FOM=0 + //bad or missing MWR data gets FOM 4 in either case + if (hptg2.size()==0) hptg2.push_back(-999); + if (hptg1.size()==0) hptg1.push_back(-999); + if (hp875.size()==0) hp875.push_back(-999); + if (vptg2.size()==0) vptg2.push_back(-999); + if (vptg1.size()==0) vptg1.push_back(-999); + if (vp875.size()==0) vp875.push_back(-999); + double horang,horpos; + //if(useHTG == bnb::kTG1){ + if(useHTG == 1){ + if (hptg1.size()>0 && hp875.size()>0) { + horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); + horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + } else if (hptg2.size()>0 && hp875.size()>0) { + horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); + horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + } else { + //missing horizontal BPM data + return 2; + } + } + //else if(useHTG == bnb::kTG2){ + else if(useHTG == 0){ + if (hptg2.size()>0 && hp875.size()>0) { + horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); + horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + } else if (hptg1.size()>0 && hp875.size()>0) { + horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); + horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + } else { + //missing horizontal BPM data + return 2; + } + } + else { return 2; } + double verang,verpos; + if(useVTG == 1){ + //if(useVTG == bnb::kTG1){ + if (vptg1.size()>0 && vp875.size()>0) { + verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); + verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + } else if (vptg2.size()>0 && vp875.size()>0) { + verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); + verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + } else { + //missing vertical BPM data + return 3; + } + } + else if(useVTG == 0){ + //else if(useVTG == bnb::kTG2){ + if (vptg2.size()>0 && vp875.size()>0) { + verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); + verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + } else if (vptg1.size()>0 && vp875.size()>0) { + verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); + verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + } else { + //missing vertical BPM data + return 3; + } + } + else { return 3; } + horang=atan(horang); + verang=atan(verang); + double xx,yy,sx,sy,chi2x,chi2y; + double tgtsx, tgtsy; + bool good_tgt=false; + bool good_876=false; + bool good_875=false; + if (mwtgt.size()>0) { + //if (bh.getSeconds()<1463677200 && mwtgt.size()>0) { + //target multiwire started failing after May 20 2016 (1463677200) + //skip this if data from when tgt multiwire was already dead + processBNBprofile(&mwtgt[0], xx, sx,chi2x); + processBNBprofile(&mwtgt[48], yy, sy, chi2y); + if (sx>0.5 && sx<10 && sy>0.3 && sy<10 && chi2x<20 && chi2y<20 && mwtgt.size()>0) { + tgtsx=sx; + tgtsy=sy; + good_tgt=true; + } + } + if (!good_tgt && mw876.size()>0) { + processBNBprofile(&mw876[0], xx,sx,chi2x); + processBNBprofile(&mw876[48], yy,sy,chi2y); + double tgtsx876=p876x[0]+p876x[1]*sx+p876x[2]*sx*sx; + double tgtsy876=p876y[0]+p876y[1]*sy+p876y[2]*sy*sy; + if (tgtsx876>0.5 && tgtsx876<10 && tgtsy876>0.3 && tgtsy876<10 && chi2x<20 && chi2y<20) { + tgtsx=tgtsx876; + tgtsy=tgtsy876; + good_876=true; + } + } + if (!good_tgt && !good_876 && mw875.size()>0){ + processBNBprofile(&mw875[0], xx,sx,chi2x); + processBNBprofile(&mw875[48], yy,sy,chi2y); + double tgtsx875=p875x[0]+p875x[1]*sx+p875x[2]*sx*sx; + double tgtsy875=p875y[0]+p875y[1]*sy+p875y[2]*sy*sy; + if (tgtsx875>0.5 && tgtsx875<10 && tgtsy875>0.3 && tgtsy875<10 && chi2x<20 && chi2y<20) { + tgtsx=tgtsx875; + tgtsy=tgtsy875; + good_875=true; + } + } + if (!good_tgt && !good_876 && !good_875) { + //failed getting multiwire data + return 4; + } + fom=1-pow(10,sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy)); + + return fom; + } + + /* + bmd::autoTunes bmd::cacheAutoTuneHistory() + { + bmd::autoTunes history; + bnb::bnbAutoTune item; + // run1-3 parameters + item.setEntry(202435254, 132, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); + history.push_back(item); + // run4a (misaligned beam) + item.setEntry(203988466, 174, 315, bnb::bnbOffsets{-3.4, 1.48, 0.46, -1., -1., 1.84}, bnb::kTG1, bnb::kTG2); + history.push_back(item); + item.setEntry(204211306, 174, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + // run4b-4d parameters (same as run1-3) + item.setEntry(215107286, 410, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); + history.push_back(item); + // item.setEntry(232368446, 268, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // item.setEntry(232368986, 268, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); + // history.push_back(item); + // before run 5 + item.setEntry(247063273, 276, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + // run5a parameters used on Nov 4th + item.setEntry(247501553, 130, 317, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, -3.15}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + // parameters being tested in the autotune from Nov5th - Nov 10th (not used because not parameters not reflected in BPM readings) + // item.setEntry(247573532, 305, 318, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, -0.03}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // item.setEntry(247576952, 304, 319, bnb::bnbOffsets{-3.4, 1.48, -1., -0.03, 1.07, -1.}, bnb::kTG2, bnb::kTG1); + // history.push_back(item); + // item.setEntry(247577492, 304, 320, bnb::bnbOffsets{-3.4, 1.48, -1., -3.15, 1.07, -1.}, bnb::kTG2, bnb::kTG1); + // history.push_back(item); + // item.setEntry(247587752, 304, 322, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 0.}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // item.setEntry(248020832, 304, 320, bnb::bnbOffsets{-3.4, 1.48, -1., -3.15, 1.07, -1.}, bnb::kTG2, bnb::kTG1); + // history.push_back(item); + // item.setEntry(248458772, 304, 322, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 0.}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // later run5 data (after target scan) + item.setEntry(248792844, 573, 323, bnb::bnbOffsets{-1.20, 1.30, -1., -1., -0.4, 0.1}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + return history; +} + + +bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const ub_BeamHeader& bh) +{ + if(*(history.end()-1) <= bh) return *(history.end()-1); + if(*(history.begin()) >= bh) return *(history.begin()); + for(auto it = history.begin(); it != history.end()-1; ++it){ + auto curr = *it; + auto following = *(it+1); + if((curr <= bh) && (following > bh)) return curr; + } + bnb::bnbAutoTune ret = bnb::bnbAutoTune(); + return ret; +} + +bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const raw::BeamInfo& bi) +{ + if(*(history.end()-1) <= bi) return *(history.end()-1); + if(*(history.begin()) >= bi) return *(history.begin()); + for(auto it = history.begin(); it != history.end()-1; ++it){ + auto curr = *it; + auto following = *(it+1); + if((curr <= bi) && (following > bi)) return curr; + } + bnb::bnbAutoTune ret = bnb::bnbAutoTune(); + return ret; +} + +bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t utctstamp) +{ + if(*(history.end()-1) <= utctstamp) return *(history.end()-1); + if(*(history.begin()) >= utctstamp) return *(history.begin()); + for(auto it = history.begin(); it != history.end()-1; ++it){ + auto curr = *it; + auto following = *(it+1); + if((curr <= utctstamp) && (following > utctstamp)) return curr; + } + bnb::bnbAutoTune ret = bnb::bnbAutoTune(); + return ret; +} +*/ + + void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2) + { + /* + function takes multiwire data as input (48 channels horizontal or vertical, + finds the min and max + finds the first and last bin where amplitude is greater than 20% + fits the peak between first and last bin with gaussian (assuming 2% relative errors) + returns: + x - mean position from the fit + sx - sigma x from the fit + chi2 - chi2/NDF for the gaussian fit + */ + double minx=0; + double maxx=0; + for (unsigned int i=0;i<48;i++) { + minx=std::min(-mwdata[i],minx); + maxx=std::max(-mwdata[i],maxx); + } + int first_x=-1; + int last_x=-1; + static int entry = 1; + TH1D* hProf=new TH1D("hProf"+TString(std::to_string(entry)),"",48,-12,12); + for (unsigned int i=0;i<48;i++) { + hProf->SetBinContent(i+1,-mwdata[i]-minx); + if (-mwdata[i]-minx > (maxx-minx)*0.2 && first_x==-1) first_x=i; + if (-mwdata[i]-minx > (maxx-minx)*0.2) last_x=i+1; + hProf->SetBinError(i+1,(maxx-minx)*0.02); + } + if (hProf->GetSumOfWeights()>0) { + hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); + x =hProf->GetFunction("gaus")->GetParameter(1); + sx =hProf->GetFunction("gaus")->GetParameter(2); + chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); + } else { + x=99999; + sx=99999; + chi2=99999; + } + entry += 1; + } + + + double calcFOM(double horpos, double horang, double verpos, double verang, double ppp, double tgtsx, double tgtsy) + { + //code from MiniBooNE AnalysisFramework with the addition of scaling the beam profile to match tgtsx, tgtsy + //form DQ_BeamLine_twiss_init.F + double bx = 4.68; + double ax = 0.0389; + double gx = (1+ax*ax)/bx; + double nx = 0.0958; + double npx = -0.0286; + double by = 59.12; + double ay = 2.4159; + double gy = (1+ay*ay)/by; + double ny = 0.4577; + double npy = -0.0271; + //from DQ_BeamLine_make_tgt_fom2.F + double ex = 0.1775E-06 + 0.1827E-07*ppp; + double ey = 0.1382E-06 + 0.2608E-08*ppp; + double dp = 0.4485E-03 + 0.6100E-04*ppp; + double tex = ex; + double tey = ey; + double tdp = dp; + //from DQ_BeamLine_beam_init.F + double sigma1[6][6]={{0}}; + double centroid1[6]={0}; + centroid1[0] = horpos; + centroid1[1] = horang; + centroid1[2] = verpos; + centroid1[3] = verang; + centroid1[4] = 0.0; + centroid1[5] = 0.0; + sigma1[5][5] = tdp*tdp; + sigma1[0][0] = tex*bx+ nx*nx *tdp*tdp; + sigma1[0][1] = -tex*ax+ nx*npx*tdp*tdp; + sigma1[1][1] = tex*gx+npx*npx*tdp*tdp; + sigma1[0][5] = nx*tdp*tdp; + sigma1[1][5] = npx*tdp*tdp; + sigma1[1][0] = sigma1[0][1]; + sigma1[5][0] = sigma1[0][5]; + sigma1[5][1] = sigma1[1][5]; + sigma1[2][2] = tey*by+ny*ny*tdp*tdp; + sigma1[2][3] = -tey*ay+ny*npy*tdp*tdp; + sigma1[3][3] = tey*gy+npy*npy*tdp*tdp; + sigma1[2][5] = ny*tdp*tdp; + sigma1[3][5] = npy*tdp*tdp; + sigma1[3][2] = sigma1[2][3]; + sigma1[5][2] = sigma1[2][5]; + sigma1[5][3] = sigma1[3][5]; + double begtocnt[6][6]={ + { 0.65954, 0.43311, 0.00321, 0.10786, 0.00000, 1.97230}, + { 0.13047, 1.60192, 0.00034, 0.00512, 0.00000, 1.96723}, + {-0.00287, -0.03677, -0.35277, -4.68056, 0.00000, 0.68525}, + {-0.00089, -0.00430, -0.17722, -5.18616, 0.00000, 0.32300}, + {-0.00104, 0.00232, -0.00001, -0.00224, 1.00000, -0.00450}, + { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000} + }; + double cnttoups[6][6]={{0}}; + double cnttodns[6][6]={{0}}; + double identity[6][6]={{0}}; + double begtoups[6][6]={{0}}; + double begtodns[6][6]={{0}}; + for (int i=0;i<6;i++) { + for (int j=0;j<6;j++) { + if (i==j) { + cnttoups[i][j] = 1.0; + cnttodns[i][j] = 1.0; + identity[i][j] = 1.0; + } else { + cnttoups[i][j] = 0.0; + cnttodns[i][j] = 0.0; + identity[i][j] = 0.0; + } + } + } + cnttoups[0][1] = -0.35710; + cnttoups[2][3] = -0.35710; + cnttodns[0][1] = +0.35710; + cnttodns[2][3] = +0.35710; + for (int i=0;i<6;i++) { + for (int j=0;j<6;j++) { + for (int k=0;k<6;k++) { + begtoups[i][k] = begtoups[i][k] + cnttoups[i][j]*begtocnt[j][k]; + begtodns[i][k] = begtodns[i][k] + cnttodns[i][j]*begtocnt[j][k]; + } + } + } + //swim to upstream of target + double cx, cy, sx, sy, rho; + sbn::swimBNB(centroid1,sigma1, + cnttoups, begtoups, + cx, cy, sx, sy, rho); + double scalex=tgtsx/sx; + double scaley=tgtsy/sy; + double fom_a=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + //swim to center of target + sbn::swimBNB(centroid1,sigma1, + identity, begtocnt, + cx, cy, sx, sy, rho); + double fom_b=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + //swim to downstream of target + sbn::swimBNB(centroid1,sigma1, + cnttodns, begtodns, + cx, cy, sx, sy, rho); + double fom_c=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + // add a guard for double precision + if(fom_a <= -10000. || fom_b <= -10000. || fom_c <= -10000) return -10000.; + double fom2=fom_a*0.6347 + + fom_b*0.2812 + + fom_c*0.0841; + return fom2; + } + + void swimBNB(const double centroid1[6], const double sigma1[6][6], + const double xferc[6][6], const double xfers[6][6], + double &cx, double& cy, double &sx, double &sy, double &rho) + { + //centroid + double centroid2[6]={0}; + for (int i=0;i<6;i++) { + for (int j=0;j<6;j++) { + centroid2[i] = centroid2[i] + xferc[i][j]*centroid1[j]; + } + } + cx = centroid2[0]; + cy = centroid2[2]; + //sigma + double sigma2[6][6]={{0}}; + for (int i = 0; i<6;i++) { + for (int j = 0;j<6;j++) { + for (int k = 0;k<6;k++) { + for (int m = 0;m<6;m++) { + sigma2[i][m] = sigma2[i][m] + + xfers[i][j]*sigma1[j][k]*xfers[m][k]; + } + } + } + } + //get beam sigma + sx = sqrt(sigma2[0][0])*1000.0; + sy = sqrt(sigma2[2][2])*1000.0; + rho = sigma2[0][2]/sqrt(sigma2[0][0]*sigma2[2][2]); + // cout<<"Swim "<= 1.) return -10000.; + return log10(1-sum); + } + +} diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.h b/sbncode/BeamSpillInfoRetriever/getFOM.h new file mode 100644 index 000000000..090ec3a3b --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/getFOM.h @@ -0,0 +1,37 @@ +#ifndef _GETFOM_H +#define _GETFOM_H + +//#include "datatypes/ub_BeamHeader.h" +//#include "datatypes/ub_BeamData.h" +//#include "lardataobj/RawData/BeamInfo.h" +#include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" +//#include "bnbAutoTune.h" +#include +#include "TMath.h" +#include "TH1.h" +#include "TGraph.h" +//#include "TH1D.h" +//#include "TF1.h" + + + + +namespace sbn +{ + //typedef std::vector autoTunes; + //float getFOM2(std::string beam, const gov::fnal::uboone::datatypes::ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings = bnb::bnbAutoTune(), bool useAutoTune=true); + float getFOM(BNBSpillInfo& spill); + + /* autoTunes cacheAutoTuneHistory(); */ + /* bnb::bnbAutoTune getSettings(const autoTunes& history, const gov::fnal::uboone::datatypes::ub_BeamHeader& bh); */ + /* bnb::bnbAutoTune getSettings(const autoTunes& history, const raw::BeamInfo& bi); */ + /* bnb::bnbAutoTune getSettings(const autoTunes& history, const uint64_t utctstamp); */ + double calcFOM(double horpos,double horang,double verpos,double verang,double tor,double tgtsx,double tgtsy); + void swimBNB(const double centroid1[6], const double sigma1[6][6], + const double xferc[6][6], const double xfers[6][6], + double &cx, double& cy, double &sx, double &sy, double &rho); + double func_intbivar(const double cx, const double cy, const double sx, const double sy, const double rho ); + void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2); + +} +#endif diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl index 26327a100..51cd8565a 100644 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl @@ -8,6 +8,9 @@ sbndbnbspillinfo: { URL: "" #Default URL having issues Nov 21 2024, used this instead https://dbdata3vm.fnal.gov:9443/ifbeam Bundle: "BoosterNeutrinoBeam_read" MultiWireBundle: "BNBMultiWire" + VP873Bundle: "BNB_monitor" + OffsetBundle: "BNB_BPM_settings" + TimeWindow: "700" #seconds MWR_TimeWindow: "3601" #seconds DeviceUsedForTiming: "E:TOR860" From 047e5d5312fb714a7e0d4308d249a1588a63a7d8 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 14 Jul 2025 10:39:42 -0500 Subject: [PATCH 100/367] First working FOM values --- .../SBNDBNBRetriever_module.cc | 14 ++- .../BeamSpillInfoRetriever/SBNDPOTTools.cpp | 10 ++- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 85 +++++++++++++++++-- 3 files changed, 98 insertions(+), 11 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 9536c3d61..9022f09a5 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -11,6 +11,7 @@ #include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" //#include "sbncode/BeamSpillInfoRetriever/getFOM.cpp" #include "sbncode/BeamSpillInfoRetriever/getFOM.h" +#include namespace sbn { @@ -223,12 +224,19 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( }//end loop over MWR devices sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); - + double spillFOM = sbn::getFOM(spillInfo); - + spillInfo.FOM = spillFOM; + std::cout << "Figure of Merit: " << spillFOM << std::endl; + + std::ofstream outfile("FOM.txt", std::ios::app); + outfile << spillInfo.FOM << std::endl; + outfile.close(); + + - std::cout << spillInfo.HP875 << "," < #include "TH1D.h" #include "TF1.h" +#include +#include +#include "TCanvas.h" + using namespace std; namespace sbn { + + bool onePlot = true; float getFOM(BNBSpillInfo & spill ) //float getFOM2( const ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings, bool useAutoTune) @@ -37,8 +43,8 @@ namespace sbn { //int useHTG = bnb::kTG1; //int useVTG = bnb::kTG1; - int useHTG = 1; - int useVTG = 1; + int useHTG = 0; + int useVTG = 0; //if(useAutoTune){ @@ -83,6 +89,37 @@ namespace sbn { std::vector mw876(spill.M876BB.begin(), spill.M876BB.end()); std::vector mwtgt(spill.MMBTBB.begin(), spill.MMBTBB.end()); + //std::cout << "MWR 875 Size: " << mw875.size() << " | MWR876 Size: " << mw876.size() << " | MWTGT Size: " << mwtgt.size() << std::endl; + //for (size_t m =0; m< mw875.size() ; m++){ + //std::cout << "MWR 875: " << mw875[m] << " | MWR876: " << mw876[m] << " | MWTGT: " << mwtgt[m] << std::endl; + //} + + /* + if (onePlot){ + TH1D* MWRx =new TH1D("MWRx","MWRx",48,-12,12); + TCanvas *c1 = new TCanvas("c1", "c1", 800, 600); + + TH1D* MWRy =new TH1D("MWRy","MWRy",48,-12,12); + TCanvas *c2 = new TCanvas("c2", "c2", 800, 600); + + + for(int w =0 ; w< 48; w++){ + MWRx->SetBinContent(w+1, -mw875[w]); + MWRx->SetBinContent(w+1, -mw875[w+48]); + } + + c1->cd(); + MWRx->Draw("HIST"); + c1->Draw(); + + c2->cd(); + MWRy->Draw("HIST"); + c2->Draw(); + + onePlot =false; + } + */ + //std::vector mw875 = spill.M875BB; //std::vector mw876 = spill.M876BB; //std::vector mwtgt = spill.MMBTBB; @@ -96,6 +133,11 @@ namespace sbn { hptg2.push_back(spill.HPTG2); vptg2.push_back(spill.VPTG2); + + + //std::cout << spill.HP875 << "," <Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); x =hProf->GetFunction("gaus")->GetParameter(1); sx =hProf->GetFunction("gaus")->GetParameter(2); + //std::cout << "sx value: " << sx << std::endl; + // if ( sx > 50.){ + // for (size_t m =0; m< 48 ; m++){ + // std::cout << "Bad MWData: " << mwdata[m] << std::endl; + // } + //} + chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); } else { x=99999; @@ -404,6 +456,9 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t double calcFOM(double horpos, double horang, double verpos, double verang, double ppp, double tgtsx, double tgtsy) { + ppp = ppp / pow(10,12); + + //code from MiniBooNE AnalysisFramework with the addition of scaling the beam profile to match tgtsx, tgtsy //form DQ_BeamLine_twiss_init.F double bx = 4.68; @@ -449,6 +504,15 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t sigma1[3][2] = sigma1[2][3]; sigma1[5][2] = sigma1[2][5]; sigma1[5][3] = sigma1[3][5]; + + + + for (int fi =0; fi <6; fi++){ + for(int la =0; la<6; la++){ + //std::cout << "sigma1[" << fi << "][" << la << "] = " << sigma1[fi][la] << " | ppp: " << ppp << std::endl; + } + } + double begtocnt[6][6]={ { 0.65954, 0.43311, 0.00321, 0.10786, 0.00000, 1.97230}, { 0.13047, 1.60192, 0.00034, 0.00512, 0.00000, 1.96723}, @@ -494,18 +558,22 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t cx, cy, sx, sy, rho); double scalex=tgtsx/sx; double scaley=tgtsy/sy; + //std::cout << "Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << std::endl; double fom_a=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); //swim to center of target sbn::swimBNB(centroid1,sigma1, identity, begtocnt, cx, cy, sx, sy, rho); double fom_b=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + //std::cout << "After Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << " | rho: " << rho << std::endl; //swim to downstream of target sbn::swimBNB(centroid1,sigma1, cnttodns, begtodns, cx, cy, sx, sy, rho); double fom_c=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); // add a guard for double precision + //std::cout << "Foma,b,c: " << fom_a << ", " << fom_b << ", " << fom_c << std::endl; + if(fom_a <= -10000. || fom_b <= -10000. || fom_c <= -10000) return -10000.; double fom2=fom_a*0.6347 + fom_b*0.2812 + @@ -532,8 +600,8 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t for (int j = 0;j<6;j++) { for (int k = 0;k<6;k++) { for (int m = 0;m<6;m++) { - sigma2[i][m] = sigma2[i][m] + - xfers[i][j]*sigma1[j][k]*xfers[m][k]; + sigma2[i][m] = sigma2[i][m] + xfers[i][j]*sigma1[j][k]*xfers[m][k]; + //std::cout << "sigma2: " << sigma2[i][m] << " = " << sigma2[i][m]<< " + " << xfers[i][j] << " * " << sigma1[j][k] << " * " << xfers[m][k] << std::endl; } } } @@ -542,13 +610,14 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t sx = sqrt(sigma2[0][0])*1000.0; sy = sqrt(sigma2[2][2])*1000.0; rho = sigma2[0][2]/sqrt(sigma2[0][0]*sigma2[2][2]); - // cout<<"Swim "<= 1.) return -10000.; return log10(1-sum); From 038834a3c0ea46b685d5e053181a0ede8b5bfdfa Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Tue, 15 Jul 2025 11:44:55 -0500 Subject: [PATCH 101/367] Update sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl Co-authored-by: Gianluca Petrillo --- sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl index 68984021a..546179ec4 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl @@ -38,7 +38,7 @@ physics: { outputs: { out1: { module_type: RootOutput - fileName: "%ifb_%tc_icarusbnbinfo.root" + fileName: "%ifb_%tc_bnbinfo.root" dataTier: "raw" compressionLevel: 1 } From a9c323b44aff4722d52d907f4852a055444fece0 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Tue, 15 Jul 2025 11:45:08 -0500 Subject: [PATCH 102/367] Update sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl Co-authored-by: Gianluca Petrillo --- sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl index 546179ec4..dbacd75d5 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl @@ -31,7 +31,7 @@ physics: { icarusbnbinfo: @local::icarusbnbspillinfo } - simulate: [icarusbnbinfo ] + simulate: [ bnbinfo ] stream1: [ out1 ] } From 4169593ab60a21108e7fef98476224c7283eff3d Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Tue, 15 Jul 2025 11:45:21 -0500 Subject: [PATCH 103/367] Update sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl Co-authored-by: Gianluca Petrillo --- sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl index dbacd75d5..d5e4ffe0f 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl @@ -28,7 +28,7 @@ source: { physics: { producers: { - icarusbnbinfo: @local::icarusbnbspillinfo + bnbinfo: @local::icarusbnbspillinfo } simulate: [ bnbinfo ] From 519c73514707ebdd497b48cb60470dc88674168c Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Tue, 15 Jul 2025 11:45:31 -0500 Subject: [PATCH 104/367] Update sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl Co-authored-by: Gianluca Petrillo --- sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl index d5e4ffe0f..495b3543b 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_icarusbnbinfo_sbn.fcl @@ -1,6 +1,6 @@ #include "icarusbnbspillinfo.fcl" -process_name: ICARUSBNBInfoGen +process_name: BNBInfoGen services:{ From 30b70f993d7e30b95cbb9f7cac78b53a5166f8d7 Mon Sep 17 00:00:00 2001 From: NathanielERowe Date: Tue, 15 Jul 2025 12:18:46 -0500 Subject: [PATCH 105/367] unify sbnd fcls with icarus --- .../BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl | 8 ++++---- .../BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl index ca85d36af..88201c999 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl @@ -1,6 +1,6 @@ #include "sbndbnbdefaults.fcl" -process_name: SBNDBNBEXTInfoGen +process_name: BNBEXTInfoGen services:{ @@ -27,10 +27,10 @@ source: { physics: { producers: { - sbndbnbextinfo: @local::sbndbnbspillinfo + bnbextinfo: @local::sbndbnbspillinfo } - simulate: [sbndbnbextinfo ] + simulate: [bnbextinfo ] stream1: [ out1 ] } @@ -39,7 +39,7 @@ physics.producers.sbndbnbextinfo.module_type: "SBNDBNBEXTRetriever" outputs: { out1: { module_type: RootOutput - fileName: "%ifb_%tc_sbndbnbextinfo.root" + fileName: "%ifb_%tc_bnbextinfo.root" dataTier: "raw" compressionLevel: 1 } diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl index 66756c41b..4f8505cb1 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl @@ -1,6 +1,6 @@ #include "sbndbnbdefaults.fcl" -process_name: SBNDBNBInfoGen +process_name: BNBInfoGen services:{ @@ -28,9 +28,9 @@ source: { physics: { producers: { - sbndbnbinfo: @local::sbndbnbspillinfo + bnbinfo: @local::sbndbnbspillinfo } - simulate: [sbndbnbinfo ] + simulate: [bnbinfo ] stream1: [ out1 ] } @@ -39,7 +39,7 @@ physics.producers.sbndbnbinfo.module_type: "SBNDBNBRetriever" outputs: { out1: { module_type: RootOutput - fileName: "%ifb_%tc_sbndbnbinfo.root" + fileName: "%ifb_%tc_bnbinfo.root" dataTier: "raw" compressionLevel: 1 } From 44571ab564e06bf868cba487d390f5b237f2efd1 Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 18 Jul 2025 12:06:19 -0500 Subject: [PATCH 106/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8591bc48b..eaf37a802 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.06.00.01 LANGUAGES CXX) +project(sbncode VERSION 10.06.00.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index e479198df..7324a153e 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_06_00 - -sbnalg v10_06_00_01 - +larsoft v10_06_00_01 - +sbnalg v10_06_00_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From 32643ef2f8c27a552385cfa4fad43f44af73d29b Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 18 Jul 2025 13:20:31 -0500 Subject: [PATCH 107/367] Undo erroneous deletion of line 101 --- sbncode/DetSim/FilterSimEnergyDeposits_module.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/DetSim/FilterSimEnergyDeposits_module.cc b/sbncode/DetSim/FilterSimEnergyDeposits_module.cc index f5f07630d..bfcd191dd 100644 --- a/sbncode/DetSim/FilterSimEnergyDeposits_module.cc +++ b/sbncode/DetSim/FilterSimEnergyDeposits_module.cc @@ -105,6 +105,7 @@ void FilterSimEnergyDeposits::produce(art::Event& e) const int numelectrons = sedep.NumElectrons(); const double syratio = sedep.ScintYieldRatio(); const double energy = sedep.Energy(); + geo::Point_t start = sedep.Start(); geo::Point_t end = sedep.End(); if (TPC) { auto const& wireReadout = art::ServiceHandle()->Get(); From f5e0e89bf3cab4d1d45911e8d64f2329c937a8ad Mon Sep 17 00:00:00 2001 From: kjplows Date: Mon, 21 Jul 2025 18:02:30 -0500 Subject: [PATCH 108/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eaf37a802..176b4d3c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.06.00.02 LANGUAGES CXX) +project(sbncode VERSION 10.06.00.03 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 7324a153e..efa661c7b 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v10_06_00_01 - -sbnalg v10_06_00_02 - +sbnalg v10_06_00_03 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From 2f82fea79e85d4680b67b17a2e55d341ce0ab20c Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Wed, 23 Jul 2025 10:27:00 +0200 Subject: [PATCH 109/367] CAFMaker changes to accomodate for Pandora track/shower discrimination changes --- sbncode/CAFMaker/FillReco.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index f47265c1e..b3b479695 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -918,8 +918,8 @@ namespace caf // Pfo Characterisation features srpfp.pfochar.setDefault(); - CopyPropertyIfSet(propertiesMap, "LArThreeDChargeFeatureTool_EndFraction", srpfp.pfochar.chgendfrac); - CopyPropertyIfSet(propertiesMap, "LArThreeDChargeFeatureTool_FractionalSpread", srpfp.pfochar.chgfracspread); + CopyPropertyIfSet(propertiesMap, "LArThreeDChargeFeatureTool_ICARUS_EndFraction", srpfp.pfochar.chgendfrac); + CopyPropertyIfSet(propertiesMap, "LArThreeDChargeFeatureTool_ICARUS_FractionalSpread", srpfp.pfochar.chgfracspread); CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_DiffStraightLineMean", srpfp.pfochar.linfitdiff); CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_Length", srpfp.pfochar.linfitlen); CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_MaxFitGapLength", srpfp.pfochar.linfitgaplen); @@ -928,9 +928,9 @@ namespace caf CopyPropertyIfSet(propertiesMap, "LArThreeDPCAFeatureTool_SecondaryPCARatio", srpfp.pfochar.pca2ratio); CopyPropertyIfSet(propertiesMap, "LArThreeDPCAFeatureTool_TertiaryPCARatio", srpfp.pfochar.pca3ratio); CopyPropertyIfSet(propertiesMap, "LArThreeDVertexDistanceFeatureTool_VertexDistance", srpfp.pfochar.vtxdist); - CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_HaloTotalRatio", srpfp.pfochar.halototratio); - CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_Concentration", srpfp.pfochar.concentration); - CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_Conicalness", srpfp.pfochar.conicalness); + CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_ICARUS_HaloTotalRatio", srpfp.pfochar.halototratio); + CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_ICARUS_Concentration", srpfp.pfochar.concentration); + CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_ICARUS_Conicalness", srpfp.pfochar.conicalness); } if (t0) { srpfp.t0 = t0->Time() / 1e3; /* ns -> us */ From 6ab4aff6f7fc718d13f558532d3e5467afe42be6 Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Thu, 24 Jul 2025 07:21:57 -0500 Subject: [PATCH 110/367] fixing dependencies --- ups/product_deps | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/ups/product_deps b/ups/product_deps index 9dfd1799f..467fe7bf5 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -248,19 +248,19 @@ libdir fq_dir lib # cetmodules), an entry for cetmodules is required. # # * It is an error for more than one non-( == "-default-") - entry to match for a given product. +# entry to match for a given product. # #################################### product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_06_00 - -sbnalg v10_06_00_01 - +larsoft v10_06_00_01 - +sbnalg v10_06_00_03 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - nusystematics v1_05_07 - -geant4reweight v01_20_08 - +geant4reweight v01_20_11 - cetmodules v3_24_01 - only_for_build end_product_list #################################### @@ -316,12 +316,11 @@ end_product_list # case it is optional. # #################################### - -qualifier larsoft sbnalg sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics notes -c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug -nq- -c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof -nq- -e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug -nq- -e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof -nq- +qualifier larsoft sbnalg sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics geant4reweight notes +c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug c14:debug:s131 -nq- +c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof c14:prof:s131 -nq- +e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug e26:debug:s131 -nq- +e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof e26:prof:s131 -nq- end_qualifier_list #################################### From e506332515b8bcb452ee53d1d1fce0e4aa38abc6 Mon Sep 17 00:00:00 2001 From: Jack Smedley Date: Tue, 22 Jul 2025 14:06:10 -0500 Subject: [PATCH 111/367] Testing the switch from multisim to multisigma --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 19 ++++++++++++++++++- .../jobs/geant4/eventweight_geant4_sbn.fcl | 14 ++++++++++---- .../geant4/neutron_reweight_parameters.fcl | 9 +++++++++ .../geant4/proton_reweight_parameters.fcl | 8 ++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 16d684f72..2a551eab6 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -61,7 +61,8 @@ class Geant4WeightCalc : public WeightCalc { CLHEP::RandGaussQ* fGaussRandom; //!< Random number generator fhicl::ParameterSet fMaterial; //!< Detector material, i.e. LAr // std::map fParticles; //!< Particles to reweight - unsigned fNsims; //!< Number of multisims + unsigned fNsims; //!< Number of universes (multisim mode) + unsigned fNsigmas; //!< Number of sigmas (multisigma mode) int fPdg; //!< PDG value for particles that a given weight calculator should apply to. Note that for now this module can only handle weights for one particle species at a time. // float fXSUncertainty; //!< Flat cross section uncertainty G4ReweighterFactory fRWFactory; //!< Base class to handle all Geant4Reweighters @@ -115,6 +116,7 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, std::string FracsFileName = pset.get< std::string >( "fracsfile" ); std::vector< fhicl::ParameterSet > FitParSets = pset.get< std::vector< fhicl::ParameterSet > >("parameters"); fNsims = pset.get ("number_of_multisims", 0); + fNsigmas = pset.get ("number_of_sigmas", 0); fPdg = pset.get ("pdg_to_reweight"); fMaterial = pset.get ("material"); fDebug = pset.get ("debug",false); @@ -171,6 +173,7 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, std::vector FitParSigmas; std::map theNominals; + std::cout << "Configuring parameter: " << GetFullName() << " with mode: " << mode << std::endl; fParameterSet.Configure(GetFullName(), mode, fNsims); for (size_t i_parset=0; i_parset tmp_vals(theNominals); + tmp_vals[FitParNames.at(i_parset)] = FitParNominals.at(i_parset) + i_sigma*FitParSigmas.at(i_parset); + UniverseVals.push_back(tmp_vals); + } // ened loop over sigmas + } // end loop over parsets (i) + } // multisigma + else{ // Anything else mode: Set parameters to user-defined nominal value UniverseVals.push_back(theNominals); diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index 6711f56d5..f4eeab56f 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -61,8 +61,10 @@ sbn_eventweight_geant4: { material: @local::LAr random_seed: 60 parameters: @local::ProtonParameters - mode: multisim - number_of_multisims: 1000 + mode: multisigma + number_of_sigmas: 3 + #mode: multisim + #number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" makeoutputtree: true pdg_to_reweight: 2212 @@ -74,8 +76,10 @@ sbn_eventweight_geant4: { material: @local::LAr random_seed: 60 parameters: @local::NeutronParameters - mode: multisim - number_of_multisims: 1000 + mode: multisigma + number_of_sigmas: 3 + #mode: multisim + #number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" makeoutputtree: true pdg_to_reweight: 2112 @@ -87,6 +91,7 @@ sbn_eventweight_geant4: { material: @local::LAr random_seed: 60 parameters: @local::KPlusParameters + #mode: pm1sigma mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" @@ -100,6 +105,7 @@ sbn_eventweight_geant4: { material: @local::LAr random_seed: 60 parameters: @local::KMinusParameters + #mode: pm1sigma mode: multisim number_of_multisims: 1000 fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" diff --git a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl index a5c462d84..b0a3e782a 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl @@ -15,7 +15,16 @@ NeutronParameters: [ Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 + }, + + { + Name: "fNeutronTotal" + Cut: "total" + Range: [10.0, 2005.00] + Nominal: 1.0 + Sigma: 0.2 } + ] END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl index 13113db75..8bdc9435b 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl @@ -17,6 +17,14 @@ ProtonParameters: [ Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 + }, + + { + Name: "fProtonTotal" + Cut: "total" + Range: [10., 2005.] + Nominal: 1 + Sigma: 0.2 } ] From f7cc3d8fe995eafff5aeb35739956f6deb9f26f0 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Fri, 25 Jul 2025 08:57:18 -0500 Subject: [PATCH 112/367] Ensure CRT T0 usage in calibration ntuples is direction aware --- sbncode/Calibration/TrackCaloSkimmer_module.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 047f2d019..5fc33ab4d 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -1140,15 +1140,10 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, fTrack->start.x = track.Start().X(); fTrack->end.x = track.End().X(); } else if (t0Info.hasT0CRTTrack) { + int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); - // Comment from Francesco: I am not sure of the below formula. - // SBND has two TPCs with a common cathode like ICARUS, the driftvelocity - // returns the absolute value, but the displacement (basically the + below) - // depends on the TPC, in one case is + and in the other is negative. - // In this way the displacement is always in the same direction, working for - // one TPC, but not for the other. - fTrack->start.x = track.Start().X() + driftv*t0Info.t0CRTTrack*1e-3; - fTrack->end.x = track.End().X() + driftv*t0Info.t0CRTTrack*1e-3; + fTrack->start.x = track.Start().X() + driftDir*driftv*t0Info.t0CRTTrack*1e-3; + fTrack->end.x = track.End().X() + driftDir*driftv*t0Info.t0CRTTrack*1e-3; } else if (t0Info.hasT0CRTHit){ // If the track does not have a a Pandora T0, the tracks will always be either on the left or (ex Or) right of the cathode. int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); From 90cb1273a672507feed9867d3dd48fe557fc5c0f Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 28 Jul 2025 18:33:04 -0500 Subject: [PATCH 113/367] Working SBND FOM with uBooNE, only for BNB+Light --- .../SBNDBNBRetriever_module.cc | 2 +- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 2 +- sbncode/BeamSpillInfoRetriever/getUbooneFOM.C | 804 ++++++++++++++++++ 3 files changed, 806 insertions(+), 2 deletions(-) create mode 100644 sbncode/BeamSpillInfoRetriever/getUbooneFOM.C diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 9022f09a5..559d66e0a 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -231,7 +231,7 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( std::cout << "Figure of Merit: " << spillFOM << std::endl; std::ofstream outfile("FOM.txt", std::ios::app); - outfile << spillInfo.FOM << std::endl; + outfile << spillInfo.FOM << std::endl; outfile.close(); diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index a541c7c59..ccc11963d 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -457,7 +457,7 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t double calcFOM(double horpos, double horang, double verpos, double verang, double ppp, double tgtsx, double tgtsy) { ppp = ppp / pow(10,12); - + //code from MiniBooNE AnalysisFramework with the addition of scaling the beam profile to match tgtsx, tgtsy //form DQ_BeamLine_twiss_init.F diff --git a/sbncode/BeamSpillInfoRetriever/getUbooneFOM.C b/sbncode/BeamSpillInfoRetriever/getUbooneFOM.C new file mode 100644 index 000000000..22c5b8929 --- /dev/null +++ b/sbncode/BeamSpillInfoRetriever/getUbooneFOM.C @@ -0,0 +1,804 @@ +#include "getFOM.h" +#include +#include +#include "TH1D.h" +#include "TF1.h" +#include +#include +#include "TCanvas.h" + + +using namespace std; + + +//namespace sbn { + void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2) + { + /* + function takes multiwire data as input (48 channels horizontal or vertical, + finds the min and max + finds the first and last bin where amplitude is greater than 20% + fits the peak between first and last bin with gaussian (assuming 2% relative errors) + returns: + x - mean position from the fit + sx - sigma x from the fit + chi2 - chi2/NDF for the gaussian fit + */ + double minx=0; + double maxx=0; + for (unsigned int i=0;i<48;i++) { + minx=std::min(-mwdata[i],minx); + maxx=std::max(-mwdata[i],maxx); + } + int first_x=-1; + int last_x=-1; + static int entry = 1; + TH1D* hProf=new TH1D("hProf"+TString(std::to_string(entry)),"",48,-12,12); + for (unsigned int i=0;i<48;i++) { + hProf->SetBinContent(i+1,-mwdata[i]-minx); + if (-mwdata[i]-minx > (maxx-minx)*0.2 && first_x==-1) first_x=i; + if (-mwdata[i]-minx > (maxx-minx)*0.2) last_x=i+1; + hProf->SetBinError(i+1,(maxx-minx)*0.02); + } + if (hProf->GetSumOfWeights()>0) { + hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); + x =hProf->GetFunction("gaus")->GetParameter(1); + sx =hProf->GetFunction("gaus")->GetParameter(2); + //std::cout << "sx value: " << sx << std::endl; + // if ( sx > 50.){ + // for (size_t m =0; m< 48 ; m++){ + // std::cout << "Bad MWData: " << mwdata[m] << std::endl; + // } + //} + + chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); + } else { + x=99999; + sx=99999; + chi2=99999; + } + entry += 1; + } + + + double calcFOM(double horpos, double horang, double verpos, double verang, double ppp, double tgtsx, double tgtsy) + { + //ppp = ppp / pow(10,12); + + + //code from MiniBooNE AnalysisFramework with the addition of scaling the beam profile to match tgtsx, tgtsy + //form DQ_BeamLine_twiss_init.F + double bx = 4.68; + double ax = 0.0389; + double gx = (1+ax*ax)/bx; + double nx = 0.0958; + double npx = -0.0286; + double by = 59.12; + double ay = 2.4159; + double gy = (1+ay*ay)/by; + double ny = 0.4577; + double npy = -0.0271; + //from DQ_BeamLine_make_tgt_fom2.F + double ex = 0.1775E-06 + 0.1827E-07*ppp; + double ey = 0.1382E-06 + 0.2608E-08*ppp; + double dp = 0.4485E-03 + 0.6100E-04*ppp; + double tex = ex; + double tey = ey; + double tdp = dp; + //from DQ_BeamLine_beam_init.F + double sigma1[6][6]={{0}}; + double centroid1[6]={0}; + centroid1[0] = horpos; + centroid1[1] = horang; + centroid1[2] = verpos; + centroid1[3] = verang; + centroid1[4] = 0.0; + centroid1[5] = 0.0; + sigma1[5][5] = tdp*tdp; + sigma1[0][0] = tex*bx+ nx*nx *tdp*tdp; + sigma1[0][1] = -tex*ax+ nx*npx*tdp*tdp; + sigma1[1][1] = tex*gx+npx*npx*tdp*tdp; + sigma1[0][5] = nx*tdp*tdp; + sigma1[1][5] = npx*tdp*tdp; + sigma1[1][0] = sigma1[0][1]; + sigma1[5][0] = sigma1[0][5]; + sigma1[5][1] = sigma1[1][5]; + sigma1[2][2] = tey*by+ny*ny*tdp*tdp; + sigma1[2][3] = -tey*ay+ny*npy*tdp*tdp; + sigma1[3][3] = tey*gy+npy*npy*tdp*tdp; + sigma1[2][5] = ny*tdp*tdp; + sigma1[3][5] = npy*tdp*tdp; + sigma1[3][2] = sigma1[2][3]; + sigma1[5][2] = sigma1[2][5]; + sigma1[5][3] = sigma1[3][5]; + + + + for (int fi =0; fi <6; fi++){ + for(int la =0; la<6; la++){ + //std::cout << "sigma1[" << fi << "][" << la << "] = " << sigma1[fi][la] << " | ppp: " << ppp << std::endl; + } + } + + double begtocnt[6][6]={ + { 0.65954, 0.43311, 0.00321, 0.10786, 0.00000, 1.97230}, + { 0.13047, 1.60192, 0.00034, 0.00512, 0.00000, 1.96723}, + {-0.00287, -0.03677, -0.35277, -4.68056, 0.00000, 0.68525}, + {-0.00089, -0.00430, -0.17722, -5.18616, 0.00000, 0.32300}, + {-0.00104, 0.00232, -0.00001, -0.00224, 1.00000, -0.00450}, + { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000} + }; + double cnttoups[6][6]={{0}}; + double cnttodns[6][6]={{0}}; + double identity[6][6]={{0}}; + double begtoups[6][6]={{0}}; + double begtodns[6][6]={{0}}; + for (int i=0;i<6;i++) { + for (int j=0;j<6;j++) { + if (i==j) { + cnttoups[i][j] = 1.0; + cnttodns[i][j] = 1.0; + identity[i][j] = 1.0; + } else { + cnttoups[i][j] = 0.0; + cnttodns[i][j] = 0.0; + identity[i][j] = 0.0; + } + } + } + cnttoups[0][1] = -0.35710; + cnttoups[2][3] = -0.35710; + cnttodns[0][1] = +0.35710; + cnttodns[2][3] = +0.35710; + for (int i=0;i<6;i++) { + for (int j=0;j<6;j++) { + for (int k=0;k<6;k++) { + begtoups[i][k] = begtoups[i][k] + cnttoups[i][j]*begtocnt[j][k]; + begtodns[i][k] = begtodns[i][k] + cnttodns[i][j]*begtocnt[j][k]; + } + } + } + //swim to upstream of target + double cx, cy, sx, sy, rho; + sbn::swimBNB(centroid1,sigma1, + cnttoups, begtoups, + cx, cy, sx, sy, rho); + double scalex=tgtsx/sx; + double scaley=tgtsy/sy; + //std::cout << "Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << std::endl; + double fom_a=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + //swim to center of target + sbn::swimBNB(centroid1,sigma1, + identity, begtocnt, + cx, cy, sx, sy, rho); + double fom_b=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + //std::cout << "After Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << " | rho: " << rho << std::endl; + //swim to downstream of target + sbn::swimBNB(centroid1,sigma1, + cnttodns, begtodns, + cx, cy, sx, sy, rho); + double fom_c=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); + // add a guard for double precision + //std::cout << "Foma,b,c: " << fom_a << ", " << fom_b << ", " << fom_c << std::endl; + + if(fom_a <= -10000. || fom_b <= -10000. || fom_c <= -10000) return -10000.; + double fom2=fom_a*0.6347 + + fom_b*0.2812 + + fom_c*0.0841; + return fom2; + } + + void swimBNB(const double centroid1[6], const double sigma1[6][6], + const double xferc[6][6], const double xfers[6][6], + double &cx, double& cy, double &sx, double &sy, double &rho) + { + //centroid + double centroid2[6]={0}; + for (int i=0;i<6;i++) { + for (int j=0;j<6;j++) { + centroid2[i] = centroid2[i] + xferc[i][j]*centroid1[j]; + } + } + cx = centroid2[0]; + cy = centroid2[2]; + //sigma + double sigma2[6][6]={{0}}; + for (int i = 0; i<6;i++) { + for (int j = 0;j<6;j++) { + for (int k = 0;k<6;k++) { + for (int m = 0;m<6;m++) { + sigma2[i][m] = sigma2[i][m] + xfers[i][j]*sigma1[j][k]*xfers[m][k]; + //std::cout << "sigma2: " << sigma2[i][m] << " = " << sigma2[i][m]<< " + " << xfers[i][j] << " * " << sigma1[j][k] << " * " << xfers[m][k] << std::endl; + } + } + } + } + //get beam sigma + sx = sqrt(sigma2[0][0])*1000.0; + sy = sqrt(sigma2[2][2])*1000.0; + rho = sigma2[0][2]/sqrt(sigma2[0][0]*sigma2[2][2]); + //cout<<"Swim "<= 1.) return -10000.; + return log10(1-sum); + } + + + + + + + + + + + + bool onePlot = true; + void getUbooneFOM() + //float getFOM(BNBSpillInfo & spill ) + //float getFOM2( const ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings, bool useAutoTune) + { + gStyle->SetOptStat(0); + + double fom=0; + //TFile* f = TFile::Open("/exp/sbnd/app/users/maxd/BNBQualityCut/ubooneData/pnfs/pnfs/uboone/persistent/uboonebeam/beam_data/bnb_data/00/01/47/68/beamdata_00014768.root", "READ"); + TFile* f = TFile::Open("/exp/sbnd/app/users/maxd/BNBQualityCut/ubooneData/pnfs/uboone/persistent/uboonebeam/beam_data/bnb_data/00/02/57/44/beamdata_00025744.root", "READ"); + + if (!f || f->IsZombie()) { + std::cerr << "Error opening file.root\n"; + return; + } + + // Get the TTree named "bnb" + TTree* tree = (TTree*)f->Get("bnb"); + if (!tree) { + std::cerr << "TTree 'bnb' not found in file.root\n"; + return; + } + + std::map hp875_offset_map; + std::map vp875_offset_map; + std::map hptg1_offset_map; + std::map hptg2_offset_map; + std::map vptg1_offset_map; + std::map vptg2_offset_map; + + //hp875_offset = hp875_offset_map[]; + + + //Other run 5 autotune offsets -3.4, 1.48, -1., -1., 1.07, -3.15 + // double hp875_offset= -3.4; + // double vp875_offset= 1.48; + // double hptg1_offset= -1.0; + // double vptg1_offset= -1.0; + // //double hptg2_offset= -1.0; + // //double vptg2_offset= -1.0; + // double hptg2_offset= 1.07; + // double vptg2_offset= -3.15; + + + + + + //Run 5 autotune values + // double hp875_offset= -1.2; + // double vp875_offset= 1.3; + // double hptg1_offset= -1.0; + // double vptg1_offset= -1.0; + // //double hptg2_offset= -1.0; + // //double vptg2_offset= -1.0; + // double hptg2_offset= -0.4; + // double vptg2_offset= 0.1; + + + + //From IFBeam for Run 25744 + // double hp875_offset= -1.3359030485153198; + // double vp875_offset= 1.3375698328018188; + // double hptg1_offset= -0.1474824994802475; + // double vptg1_offset= -0.24208535254001617; + // //double hptg2_offset= -1.0; + // //double vptg2_offset= -1.0; + // double hptg2_offset= -0.5022110939025879; + // double vptg2_offset= 0.12833189964294434; + + //Previous hardcoded values + double hp875_offset= -3.40271; + double vp875_offset= +1.47511; + double hptg1_offset= +0.457014; + double vptg1_offset= +0.38914; + //double hptg2_offset= -1.0; + //double vptg2_offset= -1.0; + //double hptg2_offset= +0.8; + //double vptg2_offset= +1.0; + double hptg2_offset= +0.79; + double vptg2_offset= +1.02; + + // double hp875_offset= -2.2; + // double vp875_offset= +1.7; + // double hptg1_offset= -0.2; + // double vptg1_offset= +0.38; + // //double hptg2_offset= -1.0; + // //double vptg2_offset= -1.0; + // double hptg2_offset= +0.5; + // double vptg2_offset= +1.0; + + + + + + + // double hp875_offset= spill.HP875Offset; + // double vp875_offset= spill.VP875Offset; + // double hptg1_offset= spill.HPTG1Offset; + // double vptg1_offset= spill.VPTG1Offset; + // double hptg2_offset= spill.HPTG2Offset; + // double vptg2_offset= spill.VPTG2Offset; + + + //int useHTG = bnb::kTG1; + //int useVTG = bnb::kTG1; + + int useHTG = 0; + int useVTG = 0; + + + //if(useAutoTune){ + // bnb::bnbOffsets data = settings.getData(); + // hp875_offset = data.hp875; + // vp875_offset = data.vp875; + // hptg1_offset = data.hptg1; + // vptg1_offset = data.vptg1; + // hptg2_offset = data.hptg2; + // vptg2_offset = data.vptg2; + //useHTG = settings.getHTG(); + //useVTG = settings.getVTG(); + //} + + + + + double hp875_zpos= 202.116104; + double vp875_zpos= 202.3193205; + double hptg1_zpos= 204.833267; + double vptg1_zpos= 204.629608; + double hptg2_zpos= 205.240662; + double vptg2_zpos= 205.036835; + double target_center_zpos= 206.870895; + double p875x[]={0.431857, 0.158077, 0.00303551}; + double p875y[]={0.279128, 0.337048, 0}; + double p876x[]={0.166172, 0.30999, -0.00630299}; + double p876y[]={0.13425, 0.580862, 0}; + + + double tor860; + double tor875; + double hp875; + double vp875; + double hptg1; + double vptg1; + double hptg2; + double vptg2; + float fom2; + Long64_t tstamp; + + //std::vector mw875;// = nullptr; + //std::vector mw876;// = nullptr; + //std::vector mwtgt;// = nullptr; + double mw875[96]; + double mw876[96]; + double mwtgt[96]; + + tree->SetBranchAddress("tor860", &tor860); + tree->SetBranchAddress("tor875", &tor875); + tree->SetBranchAddress("hp875", &hp875); + tree->SetBranchAddress("vp875", &vp875); + tree->SetBranchAddress("hptg1", &hptg1); + tree->SetBranchAddress("vptg1", &vptg1); + tree->SetBranchAddress("hptg2", &hptg2); + tree->SetBranchAddress("vptg2", &vptg2); + tree->SetBranchAddress("fom2", &fom2); + tree->SetBranchAddress("m875bb", &mw875); + tree->SetBranchAddress("m876bb", &mw876); + tree->SetBranchAddress("mmbtbb", &mwtgt); + tree->SetBranchAddress("tstamp", &tstamp); + + //std::cout << "MWR 875 Size: " << mw875.size() << " | MWR876 Size: " << mw876.size() << " | MWTGT Size: " << mwtgt.size() << std::endl; + //for (size_t m =0; m< mw875.size() ; m++){ + //std::cout << "MWR 875: " << mw875[m] << " | MWR876: " << mw876[m] << " | MWTGT: " << mwtgt[m] << std::endl; + //} + + /* + if (onePlot){ + TH1D* MWRx =new TH1D("MWRx","MWRx",48,-12,12); + TCanvas *c1 = new TCanvas("c1", "c1", 800, 600); + + TH1D* MWRy =new TH1D("MWRy","MWRy",48,-12,12); + TCanvas *c2 = new TCanvas("c2", "c2", 800, 600); + + + for(int w =0 ; w< 48; w++){ + MWRx->SetBinContent(w+1, -mw875[w]); + MWRx->SetBinContent(w+1, -mw875[w+48]); + } + + c1->cd(); + MWRx->Draw("HIST"); + c1->Draw(); + + c2->cd(); + MWRy->Draw("HIST"); + c2->Draw(); + + onePlot =false; + } + */ + + //std::vector mw875 = spill.M875BB; + //std::vector mw876 = spill.M876BB; + //std::vector mwtgt = spill.MMBTBB; + + // tor860.push_back(spill.TOR860); + // tor875.push_back(spill.TOR875); + // hp875.push_back(spill.HP875); + // vp875.push_back(spill.VP875); + // hptg1.push_back(spill.HPTG1); + // vptg1.push_back(spill.VPTG1); + // hptg2.push_back(spill.HPTG2); + // vptg2.push_back(spill.VPTG2); + + + + //std::cout << spill.HP875 << "," <0) + // tor=tor860[0]; + // else if (tor875.size()>0) + // tor=tor875[0]; + // else + // return; + + + + + // ==================================================================== Replace with BNBSpillInfo ==================================================================================== + + TCanvas* c1 = new TCanvas("c1", "c1", 800,600); + TH1D* calcFOMhist = new TH1D("CalcFOMHist", "Calculated FOM Histogram; FOM; Entries", 100, 0.0 , 5.0); + TCanvas* c2 = new TCanvas("c2", "c2", 800,600); + //TH2D* FOMvfom2 = new TH2D("FOMvfom2", "FOM vs fom2; FOM; fom2", 100, 0. , 1.0, 100, 0., 1.0); + TH2D* FOMvfom2 = new TH2D("FOMvfom2", "FOM vs fom2; FOM; fom2", 100, 0.95 , 1.0, 100, 0.95, 1.0); + Long64_t firstTS=0; Long64_t lastTS =0; + + Long64_t nentries = tree->GetEntries(); + for (Long64_t i = 0; i < nentries; ++i) { + tree->GetEntry(i); + //std::cout << "Entry " << i << ": fom2 = " << fom2 << " | " << mw876.size() << std::endl;; + double tor = tor860; + if (i==0) firstTS = tstamp; + if (i == nentries-1) lastTS = tstamp; + fom=0; + if ( hptg1 <0.0){ + fom =-2; + // hp875_offset = bad_hp875_offset; + // vp875_offset = bad_vp875_offset; + // hptg1_offset = bad_hptg1_offset; + // vptg1_offset = bad_vptg1_offset; + // hptg2_offset = bad_hptg2_offset; + // vptg2_offset = bad_vptg2_offset; + } + //when creating ntuples for pot counting script the variables are filled with -999 + //this could create a difference when passing events with FOM>1 since + //events with missing BPM data would get FOM=2, while events with BPM set to -999 will get FOM=0 + //bad or missing MWR data gets FOM 4 in either case + // if (hptg2.size()==0) hptg2.push_back(-999); + // if (hptg1.size()==0) hptg1.push_back(-999); + // if (hp875.size()==0) hp875.push_back(-999); + // if (vptg2.size()==0) vptg2.push_back(-999); + // if (vptg1.size()==0) vptg1.push_back(-999); + // if (vp875.size()==0) vp875.push_back(-999); + double horang,horpos; + //if(useHTG == bnb::kTG1){ + if(useHTG == 1){ + // if (hptg1.size()>0 && hp875.size()>0) { + // horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); + // horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + // } else if (hptg2.size()>0 && hp875.size()>0) { + // horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); + // horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + // } else { + // //missing horizontal BPM data + // return; + // } + } + //else if(useHTG == bnb::kTG2){ + + else if(useHTG == 0){ + if (hptg2 != -999 && hp875!=-999) { + horang=((hptg2-hptg2_offset)-(hp875-hp875_offset))/(hptg2_zpos-hp875_zpos); + horpos=(hp875-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + } else if (hptg1!=-999 && hp875 !=-999) { + horang=((hptg1-hptg1_offset)-(hp875-hp875_offset))/(hptg1_zpos-hp875_zpos); + horpos=(hp875-hp875_offset)+horang*(target_center_zpos-hp875_zpos); + } else { + //missing horizontal BPM data + fom=-1; + } + } + + double verang,verpos; + if(useVTG == 1){ + //if(useVTG == bnb::kTG1){ + // if (vptg1.size()>0 && vp875.size()>0) { + // verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); + // verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + // } else if (vptg2.size()>0 && vp875.size()>0) { + // verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); + // verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + // } else { + // //missing vertical BPM data + // return; + // } + } + else if(useVTG == 0){ + //else if(useVTG == bnb::kTG2){ + if (vptg2!=-999 && vp875!=-999) { + verang=((vptg2-vptg2_offset)-(vp875-vp875_offset))/(vptg2_zpos-vp875_zpos); + verpos=(vp875-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + } else if (vptg1!=-999 && vp875!=-999) { + verang=((vptg1-vptg1_offset)-(vp875-vp875_offset))/(vptg1_zpos-vp875_zpos); + verpos=(vp875-vp875_offset)+verang*(target_center_zpos-vp875_zpos); + } else { + fom=-1; + } + } + + horang=atan(horang); + verang=atan(verang); + double xx,yy,sx,sy,chi2x,chi2y; + double tgtsx, tgtsy; + bool good_tgt=false; + bool good_876=false; + bool good_875=false; + if (true){ //mwtgt.size()>0) { + //if (bh.getSeconds()<1463677200 && mwtgt.size()>0) { + //target multiwire started failing after May 20 2016 (1463677200) + //skip this if data from when tgt multiwire was already dead + processBNBprofile(&mwtgt[0], xx, sx,chi2x); + processBNBprofile(&mwtgt[48], yy, sy, chi2y); + if (sx>0.5 && sx<10 && sy>0.3 && sy<10 && chi2x<20 && chi2y<20 ){ //&& mwtgt.size()>0) { + tgtsx=sx; + tgtsy=sy; + good_tgt=true; + } + } + if (!good_tgt){// && mw876.size()>0) { + processBNBprofile(&mw876[0], xx,sx,chi2x); + processBNBprofile(&mw876[48], yy,sy,chi2y); + double tgtsx876=p876x[0]+p876x[1]*sx+p876x[2]*sx*sx; + double tgtsy876=p876y[0]+p876y[1]*sy+p876y[2]*sy*sy; + if (tgtsx876>0.5 && tgtsx876<10 && tgtsy876>0.3 && tgtsy876<10 && chi2x<20 && chi2y<20) { + tgtsx=tgtsx876; + tgtsy=tgtsy876; + good_876=true; + } + } + if (!good_tgt && !good_876 ){ // && mw875.size()>0){ + processBNBprofile(&mw875[0], xx,sx,chi2x); + processBNBprofile(&mw875[48], yy,sy,chi2y); + double tgtsx875=p875x[0]+p875x[1]*sx+p875x[2]*sx*sx; + double tgtsy875=p875y[0]+p875y[1]*sy+p875y[2]*sy*sy; + if (tgtsx875>0.5 && tgtsx875<10 && tgtsy875>0.3 && tgtsy875<10 && chi2x<20 && chi2y<20) { + tgtsx=tgtsx875; + tgtsy=tgtsy875; + good_875=true; + } + } + if (!good_tgt && !good_876 && !good_875) { + //failed getting multiwire data + fom=4; + } + //std::cout << "FOM before power: " << sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy) << ", " << horpos << ", " << horang << ", " << verpos << ", " << verang << ", " << tor << ", " << tgtsx << ", " << tgtsy<< std::endl; + + //std::cout << "Tgtsx: " << tgtsx << " | Tgtsy: " << tgtsy << std::endl; + if(fom==0) fom=1-pow(10,sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy)); + + + //std::cout <Fill(fom); + FOMvfom2->Fill(fom, fom2); + + //if ( fom-fom2 > 0.01) { + if (fom !=0 && fom!=4 && fom - fom2 < 0.002 && fom-fom2 > -0.002) { + std::cout <cd(); + calcFOMhist->Draw("HIST"); + + c2->cd(); + FOMvfom2->Draw("colz"); + + } + + /* + bmd::autoTunes bmd::cacheAutoTuneHistory() + { + bmd::autoTunes history; + bnb::bnbAutoTune item; + // run1-3 parameters + item.setEntry(202435254, 132, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); + history.push_back(item); + // run4a (misaligned beam) + item.setEntry(203988466, 174, 315, bnb::bnbOffsets{-3.4, 1.48, 0.46, -1., -1., 1.84}, bnb::kTG1, bnb::kTG2); + history.push_back(item); + item.setEntry(204211306, 174, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + // run4b-4d parameters (same as run1-3) + item.setEntry(215107286, 410, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); + history.push_back(item); + // item.setEntry(232368446, 268, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // item.setEntry(232368986, 268, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); + // history.push_back(item); + // before run 5 + item.setEntry(247063273, 276, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + // run5a parameters used on Nov 4th + item.setEntry(247501553, 130, 317, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, -3.15}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + // parameters being tested in the autotune from Nov5th - Nov 10th (not used because not parameters not reflected in BPM readings) + // item.setEntry(247573532, 305, 318, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, -0.03}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // item.setEntry(247576952, 304, 319, bnb::bnbOffsets{-3.4, 1.48, -1., -0.03, 1.07, -1.}, bnb::kTG2, bnb::kTG1); + // history.push_back(item); + // item.setEntry(247577492, 304, 320, bnb::bnbOffsets{-3.4, 1.48, -1., -3.15, 1.07, -1.}, bnb::kTG2, bnb::kTG1); + // history.push_back(item); + // item.setEntry(247587752, 304, 322, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 0.}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // item.setEntry(248020832, 304, 320, bnb::bnbOffsets{-3.4, 1.48, -1., -3.15, 1.07, -1.}, bnb::kTG2, bnb::kTG1); + // history.push_back(item); + // item.setEntry(248458772, 304, 322, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 0.}, bnb::kTG2, bnb::kTG2); + // history.push_back(item); + // later run5 data (after target scan) + item.setEntry(248792844, 573, 323, bnb::bnbOffsets{-1.20, 1.30, -1., -1., -0.4, 0.1}, bnb::kTG2, bnb::kTG2); + history.push_back(item); + return history; +} + + +bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const ub_BeamHeader& bh) +{ + if(*(history.end()-1) <= bh) return *(history.end()-1); + if(*(history.begin()) >= bh) return *(history.begin()); + for(auto it = history.begin(); it != history.end()-1; ++it){ + auto curr = *it; + auto following = *(it+1); + if((curr <= bh) && (following > bh)) return curr; + } + bnb::bnbAutoTune ret = bnb::bnbAutoTune(); + return ret; +} + +bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const raw::BeamInfo& bi) +{ + if(*(history.end()-1) <= bi) return *(history.end()-1); + if(*(history.begin()) >= bi) return *(history.begin()); + for(auto it = history.begin(); it != history.end()-1; ++it){ + auto curr = *it; + auto following = *(it+1); + if((curr <= bi) && (following > bi)) return curr; + } + bnb::bnbAutoTune ret = bnb::bnbAutoTune(); + return ret; +} + +bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t utctstamp) +{ + if(*(history.end()-1) <= utctstamp) return *(history.end()-1); + if(*(history.begin()) >= utctstamp) return *(history.begin()); + for(auto it = history.begin(); it != history.end()-1; ++it){ + auto curr = *it; + auto following = *(it+1); + if((curr <= utctstamp) && (following > utctstamp)) return curr; + } + bnb::bnbAutoTune ret = bnb::bnbAutoTune(); + return ret; +} +*/ +//} From c486b2943a98dfa8ab3961835deea252aaa5267c Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Wed, 30 Jul 2025 09:36:46 -0500 Subject: [PATCH 114/367] clean up configurations to only keep cases that have implementations in geant4reweight --- .../jobs/geant4/eventweight_geant4_sbn.fcl | 38 +++++++++---------- .../geant4/kminus_reweight_parameters.fcl | 16 +++----- .../jobs/geant4/kplus_reweight_parameters.fcl | 16 +++----- .../geant4/neutron_reweight_parameters.fcl | 21 ++-------- .../geant4/piminus_reweight_parameters.fcl | 11 +----- .../geant4/piplus_reweight_parameters.fcl | 13 ++----- .../geant4/proton_reweight_parameters.fcl | 22 ++--------- 7 files changed, 39 insertions(+), 98 deletions(-) diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index f4eeab56f..af11d7ea5 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -61,11 +61,11 @@ sbn_eventweight_geant4: { material: @local::LAr random_seed: 60 parameters: @local::ProtonParameters - mode: multisigma - number_of_sigmas: 3 - #mode: multisim - #number_of_multisims: 1000 - fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + #mode: multisigma + #number_of_sigmas: 3 + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: 2212 debug: true @@ -74,13 +74,13 @@ sbn_eventweight_geant4: { reinteractions_neutron: { type: Geant4 material: @local::LAr - random_seed: 60 + random_seed: 61 parameters: @local::NeutronParameters - mode: multisigma - number_of_sigmas: 3 - #mode: multisim - #number_of_multisims: 1000 - fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + #mode: multisigma + #number_of_sigmas: 3 + mode: multisim + number_of_multisims: 1000 + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: 2112 debug: true @@ -89,12 +89,12 @@ sbn_eventweight_geant4: { reinteractions_kplus: { type: Geant4 material: @local::LAr - random_seed: 60 + random_seed: 62 parameters: @local::KPlusParameters #mode: pm1sigma mode: multisim number_of_multisims: 1000 - fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: 321 debug: true @@ -103,12 +103,12 @@ sbn_eventweight_geant4: { reinteractions_kminus: { type: Geant4 material: @local::LAr - random_seed: 60 + random_seed: 63 parameters: @local::KMinusParameters #mode: pm1sigma mode: multisim number_of_multisims: 1000 - fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" + fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: -321 debug: true @@ -116,8 +116,6 @@ sbn_eventweight_geant4: { } -# reinteractions_neutron - ### # Reweighting parameters should be defined as # @@ -139,15 +137,15 @@ sbn_eventweight_geant4: { # "nominal" value in that case, just the set value) # - Sigma defines the 1-sigma range for multisims and unisims. Currently the # code can only accept a single value for sigma, giving symmetric -# uncertainty bounds: nominal-sigma and nominal+sigma +# uncertainty bounds: nominal-sigma and nominal+sigma +# [Only in use for fitting purposes, instead range defined through input files - Jul 2025] # - Cut must be one of the following: -# "reac" <- total inelastic scattering cross section +# "total" <- total scattering cross section, pulled from Geant4 # "abs" <- absorption cross section (pi+ and pi- only at the moment -- Oct 2019) # "cex" <- charge exchange cross section (pi+ and pi- only at the moment -- Oct 2019) # "dcex" <- double charge exchange cross section (pi+ and pi- only at the moment -- Oct 2019) # "prod" <- pion production cross section (pi+ and pi- only at the moment -- Oct 2019) # "inel" <- quasi-elastic inelastic scattering cross section (pi+ and pi- only at the moment -- Oct 2019) -# "elast" <- total elastic scattering cross section # - Name can be anything you like (but should uniquely identify that parameter/ # variation) ### diff --git a/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl index 3713f0183..ac330892e 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/kminus_reweight_parameters.fcl @@ -1,18 +1,12 @@ BEGIN_PROLOG -KMinusParameters: [ - { - Name: "fKMinusReac" - Cut: "reac" - Range: [10., 2005.] - Nominal: 1 - Sigma: 0.2 - }, +## KMinus available process keys: "total" +KMinusParameters: [ { - Name: "fKMinusElast" - Cut: "elast" - Range: [10.0, 2005.00] + Name: "fKMinusTotal" + Cut: "total" + Range: [10.0, 2005.0] Nominal: 1.0 Sigma: 0.2 } diff --git a/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl index b426eb6bd..08ec5e9f2 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/kplus_reweight_parameters.fcl @@ -1,18 +1,12 @@ BEGIN_PROLOG -KPlusParameters: [ - { - Name: "fKPlusReac" - Cut: "reac" - Range: [10., 2005.] - Nominal: 1 - Sigma: 0.2 - }, +## KPlus available process keys: "total" +KPlusParameters: [ { - Name: "fKPlusElast" - Cut: "elast" - Range: [10.0, 2005.00] + Name: "fKPlusTotal" + Cut: "total" + Range: [10.0, 2005.0] Nominal: 1.0 Sigma: 0.2 } diff --git a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl index b0a3e782a..f33d5e030 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl @@ -1,30 +1,15 @@ BEGIN_PROLOG -NeutronParameters: [ - { - Name: "fNeutronReac" - Cut: "reac" - Range: [10., 2005.] - Nominal: 1 - Sigma: 0.2 - }, - - { - Name: "fNeutronElast" - Cut: "elast" - Range: [10.0, 2005.00] - Nominal: 1.0 - Sigma: 0.2 - }, +## Neutron available process keys: "total" +NeutronParameters: [ { Name: "fNeutronTotal" Cut: "total" - Range: [10.0, 2005.00] + Range: [10.0, 2005.0] Nominal: 1.0 Sigma: 0.2 } - ] END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl index b64756415..3bf335877 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl @@ -1,6 +1,6 @@ BEGIN_PROLOG -# From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 +## PiMinus available process keys: "abs", "cex", "prod", "dcex", "inel" PiMinusParameters: [ { @@ -52,15 +52,8 @@ PiMinusParameters: [ Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 - }, - - { - Name: "fPiMinusElast" - Cut: "elast" - Range: [10.0, 2005.00] - Nominal: 1.0 - Sigma: 0.2 } + ] END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl index c9cfc3e23..9524a28fd 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl @@ -1,13 +1,13 @@ BEGIN_PROLOG -# From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 +## PiPlus available process keys: "abs", "cex", "prod", "dcex", "inel" PiPlusParameters: [ { Name: "fPiPlusReacLow" Cut: "reac" Range: [10., 200.] - Nominal: 1 + Nominal: 1.0 Sigma: 0.2 } , { @@ -52,15 +52,8 @@ PiPlusParameters: [ Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 - }, - - { - Name: "fPiPlusElast" - Cut: "elast" - Range: [10.0, 2005.00] - Nominal: 1.0 - Sigma: 0.2 } + ] END_PROLOG diff --git a/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl index 8bdc9435b..3dd017d93 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/proton_reweight_parameters.fcl @@ -1,29 +1,13 @@ BEGIN_PROLOG -# From MicroBooNE, ubsim UBOONE_SUITE_v08_00_00_69 +## Proton available process keys: "total" ProtonParameters: [ - { - Name: "fProtonReac" - Cut: "reac" - Range: [10., 2005.] - Nominal: 1 - Sigma: 0.2 - }, - - { - Name: "fProtonElast" - Cut: "elast" - Range: [10.0, 2005.00] - Nominal: 1.0 - Sigma: 0.2 - }, - { Name: "fProtonTotal" Cut: "total" - Range: [10., 2005.] - Nominal: 1 + Range: [10.0, 2005.0] + Nominal: 1.0 Sigma: 0.2 } ] From 70bf4195bbcc5ea482ddca83fc78dff24c84d08b Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Wed, 30 Jul 2025 10:35:11 -0500 Subject: [PATCH 115/367] adding missing particle masses --- .../SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 2a551eab6..56afd66a8 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -300,7 +300,11 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { double mass = 0.; if( TMath::Abs(p_PDG) == 211 ) mass = 139.57; + else if ( p_PDG == 111 ) mass = 134.9768; else if( p_PDG == 2212 ) mass = 938.28; + else if ( p_PDG == 2112 ) mass = 939.565; + else if ( TMath::Abs(p_PDG) == 321) mass = 493.677; + else if ( p_PDG == 311) mass = 497.61; // We only want to record weights for one type of particle (defined by fPDG from the fcl file), so skip other particles if (p_PDG == fPdg){ From f37272b9f4c193d1bb80329876d48a88cff2b3f8 Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 30 Jul 2025 15:36:57 -0500 Subject: [PATCH 116/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 176b4d3c9..6d2f8b3ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.06.00.03 LANGUAGES CXX) +project(sbncode VERSION 10.06.00.04 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index efa661c7b..4d5dd8cb9 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_06_00_01 - +larsoft v10_06_00_02 - sbnalg v10_06_00_03 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - From be583420cad0ccc231e6b5b3e9f062df3958eb00 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Thu, 31 Jul 2025 05:24:11 -0500 Subject: [PATCH 117/367] Add CRTSpacePoint tagging (SBND) to calib ntuples and document score & shift for all CRT matchings --- sbncode/Calibration/TrackCaloSkimmer.h | 6 + .../Calibration/TrackCaloSkimmer_module.cc | 104 +++++++++++++----- 2 files changed, 84 insertions(+), 26 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index f9fb1930e..d50c532b3 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -63,6 +63,8 @@ #include "sbnobj/Common/Calibration/TrackCaloSkimmerObj.h" #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" #include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.hh" +#include "sbnobj/SBND/CRT/CRTTrack.hh" +#include "sbnobj/SBND/CRT/CRTSpacePoint.hh" #include "ITCSSelectionTool.h" @@ -98,9 +100,12 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { double t0Pandora; double t0CRTTrack; double t0CRTHit; + double t0CRTSpacePoint; bool hasT0Pandora; bool hasT0CRTTrack; bool hasT0CRTHit; + bool hasT0CRTSpacePoint; + double crtMatchingScore; }; // Internal data struct @@ -192,6 +197,7 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { art::InputTag fPFPT0producer; art::InputTag fCRTTrackT0producer; art::InputTag fCRTHitT0producer; + art::InputTag fCRTSpacePointT0producer; art::InputTag fCALOproducer; art::InputTag fTRKproducer; art::InputTag fTRKHMproducer; diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 5fc33ab4d..1d68006e6 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -11,7 +11,6 @@ //////////////////////////////////////////////////////////////////////// #include "TrackCaloSkimmer.h" -#include "sbnobj/SBND/CRT/CRTTrack.hh" #include "art/Utilities/make_tool.h" @@ -70,6 +69,7 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) fPFPproducer = p.get< art::InputTag > ("PFPproducer","pandoraGausCryo0"); fPFPT0producer = p.get< art::InputTag > ("PFPT0producer", "pandoraGausCryo0"); fCRTTrackT0producer = p.get< art::InputTag >("CRTTrackT0producer", "crttrackmatching"); + fCRTSpacePointT0producer = p.get< art::InputTag >("CRTSpacePointT0producer", "crtspacepointmatching"); fCRTHitT0producer = p.get< art::InputTag >("CRTHitT0producer", "CRTT0Tagging"); fCALOproducer = p.get< art::InputTag > ("CALOproducer"); @@ -231,6 +231,8 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) // // Tracks (SBND style) art::FindManyP fmT0CRTTrack(tracks, e, fCRTTrackT0producer); + // SpacePoints (SBND style) + art::FindManyP fmT0CRTSpacePoint(tracks, e, fCRTSpacePointT0producer); // Hits (ICARUS style) art::FindManyP fmT0CRTHit(tracks, e, fCRTHitT0producer); @@ -345,8 +347,9 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } // Collect T0s - bool hasT0 = false, hasPFPT0 = false, hasCRTTrackT0 = false, hasCRTHitT0 = false; + bool hasT0 = false, hasPFPT0 = false, hasCRTTrackT0 = false, hasCRTHitT0 = false, hasCRTSpacePointT0 = false; int whicht0 = -1; + float crtMatchingScore = std::numeric_limits::signaling_NaN(); double t0PFP = std::numeric_limits::signaling_NaN(); if (fmT0PFP.isValid() && fmT0PFP.at(p_pfp.key()).size()) { @@ -356,12 +359,23 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } double t0CRTTrack = std::numeric_limits::signaling_NaN(); + double t0CRTTrackScore = std::numeric_limits::signaling_NaN(); if (fmT0CRTTrack.isValid() && fmT0CRTTrack.at(trkPtr.key()).size()) { t0CRTTrack = fmT0CRTTrack.data(trkPtr.key()).at(0)->Time(); + t0CRTTrackScore = fmT0CRTTrack.data(trkPtr.key()).at(0)->TriggerConfidence(); hasCRTTrackT0 = true; } + double t0CRTSpacePoint = std::numeric_limits::signaling_NaN(); + double t0CRTSpacePointScore = std::numeric_limits::signaling_NaN(); + if (fmT0CRTSpacePoint.isValid() && fmT0CRTSpacePoint.at(trkPtr.key()).size()) { + t0CRTSpacePoint = fmT0CRTSpacePoint.data(trkPtr.key()).at(0)->Time(); + t0CRTSpacePointScore = fmT0CRTSpacePoint.data(trkPtr.key()).at(0)->TriggerConfidence(); + hasCRTSpacePointT0 = true; + } + double t0CRTHit = std::numeric_limits::signaling_NaN(); + double t0CRTHitScore = std::numeric_limits::signaling_NaN(); if (fIncludeCRTHitTagging && fmT0CRTHit.isValid() && fmT0CRTHit.at(trkPtr.key()).size()) { const sbn::crt::CRTHitT0TaggingInfo &tag = *fmCRTHitT0TaggingInfo.at(trkPtr.key()).at(0); double time = fmT0CRTHit.at(trkPtr.key()).at(0)->Time(); @@ -384,23 +398,41 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) if (!crtHitSysRejected && !crtHitDistanceRejected) { t0CRTHit = time; + t0CRTHitScore = tag.Distance; hasCRTHitT0 = true; } } - T0TimingInfo thisTrackTimingInfo = {t0PFP, t0CRTTrack, t0CRTHit, hasPFPT0, hasCRTTrackT0, hasCRTHitT0}; - hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0; - // "whicht0" should reflect the T0 used for the reconstruction of the drift coordinate. - if(!hasT0) whicht0 = -1 ; + if(!hasT0) whicht0 = -1; // In this way, if a track is T0 tagged from PFP and CRT tagged, which T0 reflects the PFP Tag. - else if (hasPFPT0) whicht0 = 0 ; - else if (hasCRTTrackT0) whicht0 = 1 ; - else if (hasCRTHitT0) whicht0 = 2 ; + else if (hasPFPT0) whicht0 = 0; + else if (hasCRTTrackT0) + { + whicht0 = 1; + crtMatchingScore = t0CRTTrackScore; + } + else if (hasCRTHitT0) + { + whicht0 = 2; + crtMatchingScore = t0CRTHitScore; + } + else if (hasCRTSpacePointT0) + { + whicht0 = 3; + crtMatchingScore = t0CRTSpacePointScore; + } + + T0TimingInfo thisTrackTimingInfo = {t0PFP, t0CRTTrack, t0CRTHit, t0CRTSpacePoint, hasPFPT0, hasCRTTrackT0, hasCRTHitT0, hasCRTSpacePointT0, crtMatchingScore}; + hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0 || hasCRTSpacePointT0; if (fRequireT0 && !hasT0) continue; - if (fVerbose) std::cout << "Processing new track! ID: " << trkPtr->ID() << " time: " << t0PFP << " timeCRTTrack: " << t0CRTTrack << " timeCRTHit "<ID() << "\n" + << "\tPandora time: " << t0PFP << "\n" + << "\tCRTTrack (SBND) time: " << t0CRTTrack << "\n" + << "\tCRTHit (ICARUS) time: " << t0CRTHit << "\n" + << "\tCRTSpacePoint (SBND) time: " << t0CRTSpacePoint << std::endl; // Reset the track object *fTrack = sbn::TrackInfo(); @@ -1124,6 +1156,8 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, fTrack->t0PFP = t0Info.t0Pandora; fTrack->t0CRTTrack = t0Info.t0CRTTrack; fTrack->t0CRTHit = t0Info.t0CRTHit; + fTrack->t0CRTSpacePoint = t0Info.t0CRTSpacePoint; + fTrack->crtMatchingScore = t0Info.crtMatchingScore; fTrack->id = track.ID(); fTrack->clear_cosmic_muon = pfp.Parent() == recob::PFParticle::kPFParticlePrimary; @@ -1135,22 +1169,40 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, fTrack->dir.x = track.StartDirection().X(); fTrack->dir.y = track.StartDirection().Y(); fTrack->dir.z = track.StartDirection().Z(); - //If track is only CRTt0 tagged, undo the assumed trigger correction - if (t0Info.hasT0Pandora) { - fTrack->start.x = track.Start().X(); - fTrack->end.x = track.End().X(); - } else if (t0Info.hasT0CRTTrack) { - int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); - const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); - fTrack->start.x = track.Start().X() + driftDir*driftv*t0Info.t0CRTTrack*1e-3; - fTrack->end.x = track.End().X() + driftDir*driftv*t0Info.t0CRTTrack*1e-3; - } else if (t0Info.hasT0CRTHit){ - // If the track does not have a a Pandora T0, the tracks will always be either on the left or (ex Or) right of the cathode. - int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); - const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); - fTrack->start.x = track.Start().X() + driftDir*driftv*t0Info.t0CRTHit*1e-3; - fTrack->end.x = track.End().X() + driftDir*driftv*t0Info.t0CRTHit*1e-3; - } + + if(t0Info.hasT0Pandora) + { + fTrack->start.x = track.Start().X(); + fTrack->end.x = track.End().X(); + } + else + { + // If CRT T0 tagged we can shift the x positions appropriately + int driftDir = geo->TPC(hits[0]->WireID()).DriftDir().X(); + const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); + + if(t0Info.hasT0CRTTrack) + { + const double xshift = driftDir*driftv*t0Info.t0CRTTrack*1e-3; + fTrack->start.x = track.Start().X() + xshift; + fTrack->end.x = track.End().X() + xshift; + fTrack->xShiftCRT = xshift; + } + else if(t0Info.hasT0CRTHit) + { + const double xshift = driftDir*driftv*t0Info.t0CRTHit*1e-3; + fTrack->start.x = track.Start().X() + xshift; + fTrack->end.x = track.End().X() + xshift; + fTrack->xShiftCRT = xshift; + } + else if(t0Info.hasT0CRTSpacePoint) + { + const double xshift = driftDir*driftv*t0Info.t0CRTSpacePoint*1e-3; + fTrack->start.x = track.Start().X() + xshift; + fTrack->end.x = track.End().X() + xshift; + fTrack->xShiftCRT = xshift; + } + } if (hits.size() > 0) { fTrack->cryostat = hits[0]->WireID().Cryostat; From 817cac509acfd85ac076a715e23343636928c956 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Thu, 31 Jul 2025 06:04:43 -0500 Subject: [PATCH 118/367] Add xshifts for hits and spacepoints --- sbncode/Calibration/TrackCaloSkimmer.h | 3 +- .../Calibration/TrackCaloSkimmer_module.cc | 39 +++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index d50c532b3..c69d8589d 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -183,7 +183,8 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { const geo::WireReadoutGeom *wireReadout, const detinfo::DetectorClocksData &dclock, const cheat::BackTrackerService *bt_serv, - const detinfo::DetectorPropertiesData &dprop); + const detinfo::DetectorPropertiesData &dprop, + const float &xshift); void FillTrackCRTHitInfo(const std::vector> &tag); // helpers diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 1d68006e6..777276226 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -1210,7 +1210,7 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, // Fill each hit for (unsigned i_hit = 0; i_hit < hits.size(); i_hit++) { - sbn::TrackHitInfo hinfo = MakeHit(*hits[i_hit], hits[i_hit].key(), *thms[i_hit], track, t0Info, sps[i_hit], calo, geo, wireReadout, clock_data, bt_serv, dprop); + sbn::TrackHitInfo hinfo = MakeHit(*hits[i_hit], hits[i_hit].key(), *thms[i_hit], track, t0Info, sps[i_hit], calo, geo, wireReadout, clock_data, bt_serv, dprop, fTrack->xShiftCRT); if (hinfo.h.plane == 0) { fTrack->hits0.push_back(hinfo); } @@ -1377,7 +1377,8 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, const geo::WireReadoutGeom *wireReadout, const detinfo::DetectorClocksData &dclock, const cheat::BackTrackerService *bt_serv, - const detinfo::DetectorPropertiesData &dprop) { + const detinfo::DetectorPropertiesData &dprop, + const float &xshift) { // TrackHitInfo to save sbn::TrackHitInfo hinfo; @@ -1452,13 +1453,29 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, } } - // This is needed to reconstrut drift coordinate using a different Time - int driftDir = geo->TPC(hit.WireID()).DriftDir().X(); - const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); - double anodeDistance = std::numeric_limits::signaling_NaN(); - if(t0Info.hasT0CRTHit) anodeDistance = (hit.PeakTime()-dclock.Time2Tick(dclock.TriggerTime())-t0Info.t0CRTHit*1e-3/dclock.TPCClock().TickPeriod())*dclock.TPCClock().TickPeriod()*driftv; - double wirePlaneX = wireReadout->Plane(geo::PlaneID(hit.WireID().Cryostat, hit.WireID().TPC, hit.WireID().Plane)).GetCenter().X(); - double recoX = wirePlaneX - driftDir*anodeDistance; + // If T0 provided CRT then we should appropriately shift the drift position (already done for pandora T0) + double recoX = std::numeric_limits::signaling_NaN(); + + if(!t0Info.hasT0Pandora && (t0Info.hasT0CRTTrack || t0Info.hasT0CRTHit || t0Info.hasT0CRTSpacePoint)) + { + int driftDir = geo->TPC(hit.WireID()).DriftDir().X(); + const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); + + double time = std::numeric_limits::signaling_NaN(); + + if(t0Info.hasT0CRTTrack) + time = t0Info.t0CRTTrack*1e-3; + else if(t0Info.hasT0CRTHit) + time = t0Info.t0CRTHit*1e-3; + else if(t0Info.hasT0CRTSpacePoint) + time = t0Info.t0CRTSpacePoint*1e-3; + + double anodeDistance = (hit.PeakTime()-dclock.Time2Tick(dclock.TriggerTime())-time/dclock.TPCClock().TickPeriod())*dclock.TPCClock().TickPeriod()*driftv; + double wirePlaneX = wireReadout->Plane(geo::PlaneID(hit.WireID().Cryostat, hit.WireID().TPC, hit.WireID().Plane)).GetCenter().X(); + + recoX = wirePlaneX - driftDir*anodeDistance; + } + // Information from the TrackHitMeta bool badhit = (thm.Index() == std::numeric_limits::max()) || (!trk.HasValidPoint(thm.Index())); @@ -1471,7 +1488,7 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, // The tp X coordinate is reconstructed only if it does not have a PandoraT0. hinfo.tp.x = loc.X(); - if(t0Info.hasT0CRTHit && !t0Info.hasT0Pandora && !isnan(hinfo.tp.x)) hinfo.tp.x = recoX; + if((t0Info.hasT0CRTTrack || t0Info.hasT0CRTHit || t0Info.hasT0CRTSpacePoint) && !t0Info.hasT0Pandora && !isnan(hinfo.tp.x)) hinfo.tp.x = recoX; hinfo.tp.y = loc.Y(); hinfo.tp.z = loc.Z(); @@ -1503,7 +1520,7 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, if (sp) { hinfo.h.sp.x = sp->position().x(); // If the track has a Pandora T0, do not displace, track is already reconstructed at the correct position - if(t0Info.hasT0CRTHit && !t0Info.hasT0Pandora) hinfo.h.sp.x = sp->position().x() + driftDir*driftv*t0Info.t0CRTHit*1e-3; + if((t0Info.hasT0CRTTrack || t0Info.hasT0CRTHit || t0Info.hasT0CRTSpacePoint) && !t0Info.hasT0Pandora) hinfo.h.sp.x = sp->position().x() + xshift; hinfo.h.sp.y = sp->position().y(); hinfo.h.sp.z = sp->position().z(); hinfo.h.hasSP = true; From 25d087663de3450bf7aee11a194385e80e100f10 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Thu, 31 Jul 2025 18:38:35 +0200 Subject: [PATCH 119/367] refactored code to allow for configurable BDT tool names --- sbncode/CAFMaker/CAFMakerParams.h | 86 +++++++++++++++++++++++++++++ sbncode/CAFMaker/CAFMaker_module.cc | 17 +++++- sbncode/CAFMaker/FillReco.cxx | 27 ++++----- sbncode/CAFMaker/FillReco.h | 19 ++++++- 4 files changed, 134 insertions(+), 15 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index d05eb8b9b..d735fb5a1 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -424,6 +424,92 @@ namespace caf 25. }; + struct PFOCharLabels_t { + Atom EndFractionName { + Name("EndFractionName"), + Comment("Provide the tool name for the EndFraction BDT variable."), + "LArThreeDChargeFeatureTool_EndFraction" + }; + + Atom FractionalSpreadName { + Name("FractionalSpreadName"), + Comment("Provide the tool name for the FractionalSpread BDT variable."), + "LArThreeDChargeFeatureTool_FractionalSpread" + }; + + Atom DiffStraightLineMeanName { + Name("DiffStraightLineMeanName"), + Comment("Provide the tool name for the DiffStraightLineMean BDT variable."), + "LArThreeDChargeFeatureTool_DiffStraightLineMean" + }; + + Atom LengthName { + Name("LengthName"), + Comment("Provide the tool name for the Length BDT variable."), + "LArThreeDChargeFeatureTool_Length" + }; + + Atom MaxFitGapLengthName { + Name("MaxFitGapLengthName"), + Comment("Provide the tool name for the MaxFitGapLength BDT variable."), + "LArThreeDChargeFeatureTool_MaxFitGapLength" + }; + + Atom SlidingLinearFitRMSName { + Name("SlidingLinearFitRMSName"), + Comment("Provide the tool name for the SlidingLinearFitRMS BDT variable."), + "LArThreeDChargeFeatureTool_SlidingLinearFitRMS" + }; + + Atom AngleDiffName { + Name("AngleDiffName"), + Comment("Provide the tool name for the AngleDiff BDT variable."), + "LArThreeDChargeFeatureTool_AngleDiff" + }; + + Atom SecondaryPCARatioName { + Name("SecondaryPCARatioName"), + Comment("Provide the tool name for the SecondaryPCARatio BDT variable."), + "LArThreeDChargeFeatureTool_SecondaryPCARatio" + }; + + Atom TertiaryPCARatioName { + Name("TertiaryPCARatioName"), + Comment("Provide the tool name for the TertiaryPCARatio BDT variable."), + "LArThreeDChargeFeatureTool_TertiaryPCARatio" + }; + + Atom VertexDistanceName { + Name("VertexDistanceName"), + Comment("Provide the tool name for the VertexDistance BDT variable."), + "LArThreeDChargeFeatureTool_VertexDistanceName" + }; + + Atom HaloTotalRatioName { + Name("HaloTotalRatioName"), + Comment("Provide the tool name for the HaloTotalRatio BDT variable."), + "LArThreeDChargeFeatureTool_HaloTotalRatioName" + }; + + Atom ConcentrationName { + Name("ConcentrationName"), + Comment("Provide the tool name for the Concentration BDT variable."), + "LArThreeDChargeFeatureTool_Concentration" + + }; + + Atom ConicalnessName { + Name("ConicalnessName"), + Comment("Provide the tool name for the Conicalness BDT variable."), + "LArThreeDChargeFeatureTool_Conicalness" + }; + }; + + Table PFOCharLabels { + Name("PFOCharLabels"), + Comment("Provide tool names for the Pandora track/shower discrimination BDT variables.") + }; + Atom ReferencePMTFromTriggerToBeam { Name("ReferencePMTFromTriggerToBeam"), Comment("Whether to switch the reference time of PMT reco from 'trigger' to 'beam spill' time."), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 2728b395f..7dbc3adc8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2098,7 +2098,22 @@ void CAFMaker::produce(art::Event& evt) noexcept { } const larpandoraobj::PFParticleMetadata *pfpMeta = (fmPFPMeta.at(iPart).empty()) ? NULL : fmPFPMeta.at(iPart).at(0).get(); - FillPFPVars(thisParticle, primary, pfpMeta, thisPFPT0, pfp); + const caf::PFOCharLabelsStruct pfoCharLabels { + fParams.PFOCharLabels().EndFractionName(), + fParams.PFOCharLabels().FractionalSpreadName(), + fParams.PFOCharLabels().DiffStraightLineMeanName(), + fParams.PFOCharLabels().LengthName(), + fParams.PFOCharLabels().MaxFitGapLengthName(), + fParams.PFOCharLabels().SlidingLinearFitRMSName(), + fParams.PFOCharLabels().AngleDiffName(), + fParams.PFOCharLabels().SecondaryPCARatioName(), + fParams.PFOCharLabels().TertiaryPCARatioName(), + fParams.PFOCharLabels().VertexDistanceName(), + fParams.PFOCharLabels().HaloTotalRatioName(), + fParams.PFOCharLabels().ConcentrationName(), + fParams.PFOCharLabels().ConicalnessName() + }; + FillPFPVars(thisParticle, primary, pfpMeta, thisPFPT0, pfp, pfoCharLabels); if (fmCNNScores.isValid()) { const sbn::PFPCNNScore *cnnScores = fmCNNScores.at(iPart).at(0).get(); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index b3b479695..258a4b6fe 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -895,6 +895,7 @@ namespace caf const larpandoraobj::PFParticleMetadata *pfpMeta, const art::Ptr t0, caf::SRPFP& srpfp, + const PFOCharLabelsStruct& pfoCharLabels, bool allowEmpty) { srpfp.id = particle.Self(); @@ -918,19 +919,19 @@ namespace caf // Pfo Characterisation features srpfp.pfochar.setDefault(); - CopyPropertyIfSet(propertiesMap, "LArThreeDChargeFeatureTool_ICARUS_EndFraction", srpfp.pfochar.chgendfrac); - CopyPropertyIfSet(propertiesMap, "LArThreeDChargeFeatureTool_ICARUS_FractionalSpread", srpfp.pfochar.chgfracspread); - CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_DiffStraightLineMean", srpfp.pfochar.linfitdiff); - CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_Length", srpfp.pfochar.linfitlen); - CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_MaxFitGapLength", srpfp.pfochar.linfitgaplen); - CopyPropertyIfSet(propertiesMap, "LArThreeDLinearFitFeatureTool_SlidingLinearFitRMS", srpfp.pfochar.linfitrms); - CopyPropertyIfSet(propertiesMap, "LArThreeDOpeningAngleFeatureTool_AngleDiff", srpfp.pfochar.openanglediff); - CopyPropertyIfSet(propertiesMap, "LArThreeDPCAFeatureTool_SecondaryPCARatio", srpfp.pfochar.pca2ratio); - CopyPropertyIfSet(propertiesMap, "LArThreeDPCAFeatureTool_TertiaryPCARatio", srpfp.pfochar.pca3ratio); - CopyPropertyIfSet(propertiesMap, "LArThreeDVertexDistanceFeatureTool_VertexDistance", srpfp.pfochar.vtxdist); - CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_ICARUS_HaloTotalRatio", srpfp.pfochar.halototratio); - CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_ICARUS_Concentration", srpfp.pfochar.concentration); - CopyPropertyIfSet(propertiesMap, "LArConeChargeFeatureTool_ICARUS_Conicalness", srpfp.pfochar.conicalness); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.EndFractionName, srpfp.pfochar.chgendfrac); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.FractionalSpreadName, srpfp.pfochar.chgfracspread); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.DiffStraightLineMeanName, srpfp.pfochar.linfitdiff); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.LengthName, srpfp.pfochar.linfitlen); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.MaxFitGapLengthName, srpfp.pfochar.linfitgaplen); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.SlidingLinearFitRMSName, srpfp.pfochar.linfitrms); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.AngleDiffName, srpfp.pfochar.openanglediff); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.SecondaryPCARatioName, srpfp.pfochar.pca2ratio); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.TertiaryPCARatioName, srpfp.pfochar.pca3ratio); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.VertexDistanceName, srpfp.pfochar.vtxdist); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.HaloTotalRatioName, srpfp.pfochar.halototratio); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.ConcentrationName, srpfp.pfochar.concentration); + CopyPropertyIfSet(propertiesMap, pfoCharLabels.ConicalnessName, srpfp.pfochar.conicalness); } if (t0) { srpfp.t0 = t0->Time() / 1e3; /* ns -> us */ diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index c6df1ab39..766d0ab09 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -118,12 +118,29 @@ namespace caf caf::SRHit& srhit, bool allowEmpty = false); + struct PFOCharLabelsStruct { + std::string EndFractionName; + std::string FractionalSpreadName; + std::string DiffStraightLineMeanName; + std::string LengthName; + std::string MaxFitGapLengthName; + std::string SlidingLinearFitRMSName; + std::string AngleDiffName; + std::string SecondaryPCARatioName; + std::string TertiaryPCARatioName; + std::string VertexDistanceName; + std::string HaloTotalRatioName; + std::string ConcentrationName; + std::string ConicalnessName; + }; + void FillPFPVars(const recob::PFParticle &particle, const recob::PFParticle *primary, const larpandoraobj::PFParticleMetadata *pfpMeta, const art::Ptr t0, caf::SRPFP& srpfp, - bool allowEmpty= false); + const PFOCharLabelsStruct& pfoCharLabels, + bool allowEmpty = false); void FillCNNScores(const recob::PFParticle &particle, const sbn::PFPCNNScore *cnnscore, From 33845ea196995a575fdf376bbd19511308e55c20 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Fri, 1 Aug 2025 01:01:45 +0200 Subject: [PATCH 120/367] moved changes to fhicl::OptionalTable --- sbncode/CAFMaker/CAFMakerParams.h | 3 ++- sbncode/CAFMaker/CAFMaker_module.cc | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index d735fb5a1..83b15fb8b 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -16,6 +16,7 @@ namespace caf template using Atom = fhicl::Atom; template using Sequence = fhicl::Sequence; template using Table = fhicl::Table; + template using OptionalTable = fhicl::OptionalTable; using Comment = fhicl::Comment; using Name = fhicl::Name; using string = std::string; @@ -505,7 +506,7 @@ namespace caf }; }; - Table PFOCharLabels { + OptionalTable PFOCharLabels { Name("PFOCharLabels"), Comment("Provide tool names for the Pandora track/shower discrimination BDT variables.") }; diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7dbc3adc8..f1187f917 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2098,20 +2098,22 @@ void CAFMaker::produce(art::Event& evt) noexcept { } const larpandoraobj::PFParticleMetadata *pfpMeta = (fmPFPMeta.at(iPart).empty()) ? NULL : fmPFPMeta.at(iPart).at(0).get(); + caf::CAFMakerParams::PFOCharLabels_t const& pfoCharParams + = fParams.PFOCharLabels().value_or(caf::CAFMakerParams::PFOCharLabels_t{}); const caf::PFOCharLabelsStruct pfoCharLabels { - fParams.PFOCharLabels().EndFractionName(), - fParams.PFOCharLabels().FractionalSpreadName(), - fParams.PFOCharLabels().DiffStraightLineMeanName(), - fParams.PFOCharLabels().LengthName(), - fParams.PFOCharLabels().MaxFitGapLengthName(), - fParams.PFOCharLabels().SlidingLinearFitRMSName(), - fParams.PFOCharLabels().AngleDiffName(), - fParams.PFOCharLabels().SecondaryPCARatioName(), - fParams.PFOCharLabels().TertiaryPCARatioName(), - fParams.PFOCharLabels().VertexDistanceName(), - fParams.PFOCharLabels().HaloTotalRatioName(), - fParams.PFOCharLabels().ConcentrationName(), - fParams.PFOCharLabels().ConicalnessName() + pfoCharParams.EndFractionName(), + pfoCharParams.FractionalSpreadName(), + pfoCharParams.DiffStraightLineMeanName(), + pfoCharParams.LengthName(), + pfoCharParams.MaxFitGapLengthName(), + pfoCharParams.SlidingLinearFitRMSName(), + pfoCharParams.AngleDiffName(), + pfoCharParams.SecondaryPCARatioName(), + pfoCharParams.TertiaryPCARatioName(), + pfoCharParams.VertexDistanceName(), + pfoCharParams.HaloTotalRatioName(), + pfoCharParams.ConcentrationName(), + pfoCharParams.ConicalnessName() }; FillPFPVars(thisParticle, primary, pfpMeta, thisPFPT0, pfp, pfoCharLabels); From e8e6c98592655be3e47c347d0b5ad308e1ec69fc Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Fri, 1 Aug 2025 04:40:52 -0500 Subject: [PATCH 121/367] Move definition of hasT0 --- sbncode/Calibration/TrackCaloSkimmer_module.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 777276226..1baff7ea6 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -403,6 +403,8 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } } + hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0 || hasCRTSpacePointT0; + // "whicht0" should reflect the T0 used for the reconstruction of the drift coordinate. if(!hasT0) whicht0 = -1; // In this way, if a track is T0 tagged from PFP and CRT tagged, which T0 reflects the PFP Tag. @@ -424,7 +426,6 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) } T0TimingInfo thisTrackTimingInfo = {t0PFP, t0CRTTrack, t0CRTHit, t0CRTSpacePoint, hasPFPT0, hasCRTTrackT0, hasCRTHitT0, hasCRTSpacePointT0, crtMatchingScore}; - hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0 || hasCRTSpacePointT0; if (fRequireT0 && !hasT0) continue; From 081b5ba89ffea13de4d2a2055b7027b736e92d16 Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Mon, 4 Aug 2025 15:12:38 -0500 Subject: [PATCH 122/367] adding neutron threshold and cleaning up configurations --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 5 +++-- .../jobs/geant4/eventweight_geant4_sbn.fcl | 1 - .../jobs/geant4/neutron_reweight_parameters.fcl | 2 +- .../jobs/geant4/piminus_reweight_parameters.fcl | 12 ++++-------- .../jobs/geant4/piplus_reweight_parameters.fcl | 12 ++++-------- 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 56afd66a8..1889e9c90 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -186,6 +186,8 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, FitParNominals.push_back(theNominal); FitParSigmas.push_back(theSigma); + if (fDebug) std::cout << "Name: " << theName << ", Nominal: " << theNominal << ", Sigma: " << theSigma << std::endl; + theNominals[theName] = theNominal; fParameterSet.AddParameter(theName, theSigma); @@ -514,8 +516,7 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { } std::cout << std::endl; } - - } // if ( ( TMath::Abs(p_PDG) == 211 || p_PDG == 2212 ) ) + } if (fMakeOutputTrees) fOutTree_Particle->Fill(); } // loop over mcparticles (i) if (fMakeOutputTrees) fOutTree_MCTruth->Fill(); diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index af11d7ea5..081964d3f 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -138,7 +138,6 @@ sbn_eventweight_geant4: { # - Sigma defines the 1-sigma range for multisims and unisims. Currently the # code can only accept a single value for sigma, giving symmetric # uncertainty bounds: nominal-sigma and nominal+sigma -# [Only in use for fitting purposes, instead range defined through input files - Jul 2025] # - Cut must be one of the following: # "total" <- total scattering cross section, pulled from Geant4 # "abs" <- absorption cross section (pi+ and pi- only at the moment -- Oct 2019) diff --git a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl index f33d5e030..65743db98 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/neutron_reweight_parameters.fcl @@ -6,7 +6,7 @@ NeutronParameters: [ { Name: "fNeutronTotal" Cut: "total" - Range: [10.0, 2005.0] + Range: [100.0, 2005.0] Nominal: 1.0 Sigma: 0.2 } diff --git a/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl index 3bf335877..fb27aeed4 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/piminus_reweight_parameters.fcl @@ -4,15 +4,15 @@ BEGIN_PROLOG PiMinusParameters: [ { - Name: "fPiMinusReacLow" - Cut: "reac" + Name: "fPiMinusInelLow" + Cut: "inel" Range: [10., 200.] Nominal: 1 Sigma: 0.2 } , { - Name: "fPiMinusReacHigh" - Cut: "reac" + Name: "fPiMinusInelHigh" + Cut: "inel" Range: [700., 2005.] Nominal: 1.0 Sigma: 0.2 @@ -21,7 +21,6 @@ PiMinusParameters: [ { Name: "fPiMinusAbs" Cut: "abs" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 @@ -30,7 +29,6 @@ PiMinusParameters: [ { Name: "fPiMinusCex" Cut: "cex" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 @@ -39,7 +37,6 @@ PiMinusParameters: [ { Name: "fPiMinusDCex" Cut: "dcex" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 @@ -48,7 +45,6 @@ PiMinusParameters: [ { Name: "fPiMinusPiProd" Cut: "prod" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 diff --git a/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl b/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl index 9524a28fd..4aeaeb96d 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/piplus_reweight_parameters.fcl @@ -4,15 +4,15 @@ BEGIN_PROLOG PiPlusParameters: [ { - Name: "fPiPlusReacLow" - Cut: "reac" + Name: "fPiPlusInelLow" + Cut: "inel" Range: [10., 200.] Nominal: 1.0 Sigma: 0.2 } , { - Name: "fPiPlusReacHigh" - Cut: "reac" + Name: "fPiPlusInelHigh" + Cut: "inel" Range: [700., 2005.] Nominal: 1.0 Sigma: 0.2 @@ -21,7 +21,6 @@ PiPlusParameters: [ { Name: "fPiPlusAbs" Cut: "abs" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 @@ -30,7 +29,6 @@ PiPlusParameters: [ { Name: "fPiPlusCex" Cut: "cex" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 @@ -39,7 +37,6 @@ PiPlusParameters: [ { Name: "fPiPlusDCex" Cut: "dcex" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 @@ -48,7 +45,6 @@ PiPlusParameters: [ { Name: "fPiPlusPiProd" Cut: "prod" - # Range: [200.0, 700.00] Range: [10.0, 2005.00] Nominal: 1.0 Sigma: 0.2 From 83479a0eca91984f1e89faccd7cf71bd15a90b6e Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Mon, 4 Aug 2025 15:35:22 -0500 Subject: [PATCH 123/367] disable debug mode by default --- .../jobs/geant4/eventweight_geant4_sbn.fcl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl index 081964d3f..2431af89d 100644 --- a/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl +++ b/sbncode/SBNEventWeight/jobs/geant4/eventweight_geant4_sbn.fcl @@ -40,7 +40,7 @@ sbn_eventweight_geant4: { fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piplus.root" makeoutputtree: true pdg_to_reweight: 211 - debug: true + debug: false } reinteractions_piminus: { @@ -53,7 +53,7 @@ sbn_eventweight_geant4: { fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_piminus.root" makeoutputtree: true pdg_to_reweight: -211 - debug: true + debug: false } reinteractions_proton: { @@ -68,7 +68,7 @@ sbn_eventweight_geant4: { fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: 2212 - debug: true + debug: false } reinteractions_neutron: { @@ -83,7 +83,7 @@ sbn_eventweight_geant4: { fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: 2112 - debug: true + debug: false } reinteractions_kplus: { @@ -97,7 +97,7 @@ sbn_eventweight_geant4: { fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: 321 - debug: true + debug: false } reinteractions_kminus: { @@ -111,7 +111,7 @@ sbn_eventweight_geant4: { fracsfile: "$SBNDATA_DIR/systematics/reint/g4_fracs_proton.root" # dummy file, cross section pulled directly from Geant4 makeoutputtree: true pdg_to_reweight: -321 - debug: true + debug: false } } From 324917856a09bffa309c06ca26bfb3fd5c50ff7e Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 5 Aug 2025 15:04:07 -0500 Subject: [PATCH 124/367] Removed comments, and added functionality to Zero Bias stream --- .../SBNDBNBRetriever_module.cc | 13 +- .../SBNDBNBZEROBIASRetriever/CMakeLists.txt | 1 + .../SBNDBNBZEROBIASRetriever_module.cc | 4 + sbncode/BeamSpillInfoRetriever/getFOM.cpp | 263 ++---------------- 4 files changed, 24 insertions(+), 257 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 559d66e0a..6681b91eb 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -226,19 +226,8 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); double spillFOM = sbn::getFOM(spillInfo); - spillInfo.FOM = spillFOM; - std::cout << "Figure of Merit: " << spillFOM << std::endl; - - std::ofstream outfile("FOM.txt", std::ios::app); - outfile << spillInfo.FOM << std::endl; - outfile.close(); - - - - //std::cout << spillInfo.HP875 << "," < #include @@ -16,21 +24,8 @@ namespace sbn { bool onePlot = true; float getFOM(BNBSpillInfo & spill ) - //float getFOM2( const ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings, bool useAutoTune) { double fom=0; - - - - - - // ========================================= I believe all of this can be replaced with the BNBSpillInfo which I fill already ============================================ - - - - - - double hp875_offset= spill.HP875Offset; double vp875_offset= spill.VP875Offset; @@ -38,31 +33,11 @@ namespace sbn { double vptg1_offset= spill.VPTG1Offset; double hptg2_offset= spill.HPTG2Offset; double vptg2_offset= spill.VPTG2Offset; - - - //int useHTG = bnb::kTG1; - //int useVTG = bnb::kTG1; - + + //Decides which position monitor to check first int useHTG = 0; int useVTG = 0; - - //if(useAutoTune){ - // bnb::bnbOffsets data = settings.getData(); - // hp875_offset = data.hp875; - // vp875_offset = data.vp875; - // hptg1_offset = data.hptg1; - // vptg1_offset = data.vptg1; - // hptg2_offset = data.hptg2; - // vptg2_offset = data.vptg2; - //useHTG = settings.getHTG(); - //useVTG = settings.getVTG(); - //} - - - - //double hptg2_offset= +0.79; - //double vptg2_offset= +1.02; double hp875_zpos= 202.116104; double vp875_zpos= 202.3193205; double hptg1_zpos= 204.833267; @@ -89,40 +64,6 @@ namespace sbn { std::vector mw876(spill.M876BB.begin(), spill.M876BB.end()); std::vector mwtgt(spill.MMBTBB.begin(), spill.MMBTBB.end()); - //std::cout << "MWR 875 Size: " << mw875.size() << " | MWR876 Size: " << mw876.size() << " | MWTGT Size: " << mwtgt.size() << std::endl; - //for (size_t m =0; m< mw875.size() ; m++){ - //std::cout << "MWR 875: " << mw875[m] << " | MWR876: " << mw876[m] << " | MWTGT: " << mwtgt[m] << std::endl; - //} - - /* - if (onePlot){ - TH1D* MWRx =new TH1D("MWRx","MWRx",48,-12,12); - TCanvas *c1 = new TCanvas("c1", "c1", 800, 600); - - TH1D* MWRy =new TH1D("MWRy","MWRy",48,-12,12); - TCanvas *c2 = new TCanvas("c2", "c2", 800, 600); - - - for(int w =0 ; w< 48; w++){ - MWRx->SetBinContent(w+1, -mw875[w]); - MWRx->SetBinContent(w+1, -mw875[w+48]); - } - - c1->cd(); - MWRx->Draw("HIST"); - c1->Draw(); - - c2->cd(); - MWRy->Draw("HIST"); - c2->Draw(); - - onePlot =false; - } - */ - - //std::vector mw875 = spill.M875BB; - //std::vector mw876 = spill.M876BB; - //std::vector mwtgt = spill.MMBTBB; tor860.push_back(spill.TOR860); tor875.push_back(spill.TOR875); @@ -133,56 +74,6 @@ namespace sbn { hptg2.push_back(spill.HPTG2); vptg2.push_back(spill.VPTG2); - - - //std::cout << spill.HP875 << "," <0) tor=tor860[0]; @@ -190,15 +81,7 @@ namespace sbn { tor=tor875[0]; else return -1; - - - - - // ==================================================================== Replace with BNBSpillInfo ==================================================================================== - - - - + //when creating ntuples for pot counting script the variables are filled with -999 //this could create a difference when passing events with FOM>1 since @@ -211,7 +94,6 @@ namespace sbn { if (vptg1.size()==0) vptg1.push_back(-999); if (vp875.size()==0) vp875.push_back(-999); double horang,horpos; - //if(useHTG == bnb::kTG1){ if(useHTG == 1){ if (hptg1.size()>0 && hp875.size()>0) { horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); @@ -224,7 +106,6 @@ namespace sbn { return 2; } } - //else if(useHTG == bnb::kTG2){ else if(useHTG == 0){ if (hptg2.size()>0 && hp875.size()>0) { horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); @@ -240,7 +121,6 @@ namespace sbn { else { return 2; } double verang,verpos; if(useVTG == 1){ - //if(useVTG == bnb::kTG1){ if (vptg1.size()>0 && vp875.size()>0) { verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); @@ -253,7 +133,6 @@ namespace sbn { } } else if(useVTG == 0){ - //else if(useVTG == bnb::kTG2){ if (vptg2.size()>0 && vp875.size()>0) { verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); @@ -311,100 +190,13 @@ namespace sbn { //failed getting multiwire data return 4; } - //std::cout << "FOM before power: " << sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy) << ", " << horpos << ", " << horang << ", " << verpos << ", " << verang << ", " << tor << ", " << tgtsx << ", " << tgtsy<< std::endl; - //std::cout << "Tgtsx: " << tgtsx << " | Tgtsy: " << tgtsy << std::endl; fom=1-pow(10,sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy)); - //std::cout << "FOM: " <= bh) return *(history.begin()); - for(auto it = history.begin(); it != history.end()-1; ++it){ - auto curr = *it; - auto following = *(it+1); - if((curr <= bh) && (following > bh)) return curr; - } - bnb::bnbAutoTune ret = bnb::bnbAutoTune(); - return ret; -} - -bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const raw::BeamInfo& bi) -{ - if(*(history.end()-1) <= bi) return *(history.end()-1); - if(*(history.begin()) >= bi) return *(history.begin()); - for(auto it = history.begin(); it != history.end()-1; ++it){ - auto curr = *it; - auto following = *(it+1); - if((curr <= bi) && (following > bi)) return curr; - } - bnb::bnbAutoTune ret = bnb::bnbAutoTune(); - return ret; -} - -bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t utctstamp) -{ - if(*(history.end()-1) <= utctstamp) return *(history.end()-1); - if(*(history.begin()) >= utctstamp) return *(history.begin()); - for(auto it = history.begin(); it != history.end()-1; ++it){ - auto curr = *it; - auto following = *(it+1); - if((curr <= utctstamp) && (following > utctstamp)) return curr; - } - bnb::bnbAutoTune ret = bnb::bnbAutoTune(); - return ret; -} -*/ - void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2) { /* @@ -437,12 +229,6 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); x =hProf->GetFunction("gaus")->GetParameter(1); sx =hProf->GetFunction("gaus")->GetParameter(2); - //std::cout << "sx value: " << sx << std::endl; - // if ( sx > 50.){ - // for (size_t m =0; m< 48 ; m++){ - // std::cout << "Bad MWData: " << mwdata[m] << std::endl; - // } - //} chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); } else { @@ -506,13 +292,6 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t sigma1[5][3] = sigma1[3][5]; - - for (int fi =0; fi <6; fi++){ - for(int la =0; la<6; la++){ - //std::cout << "sigma1[" << fi << "][" << la << "] = " << sigma1[fi][la] << " | ppp: " << ppp << std::endl; - } - } - double begtocnt[6][6]={ { 0.65954, 0.43311, 0.00321, 0.10786, 0.00000, 1.97230}, { 0.13047, 1.60192, 0.00034, 0.00512, 0.00000, 1.96723}, @@ -558,22 +337,19 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t cx, cy, sx, sy, rho); double scalex=tgtsx/sx; double scaley=tgtsy/sy; - //std::cout << "Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << std::endl; double fom_a=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); //swim to center of target sbn::swimBNB(centroid1,sigma1, identity, begtocnt, cx, cy, sx, sy, rho); double fom_b=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); - //std::cout << "After Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << " | rho: " << rho << std::endl; //swim to downstream of target sbn::swimBNB(centroid1,sigma1, cnttodns, begtodns, cx, cy, sx, sy, rho); double fom_c=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); // add a guard for double precision - //std::cout << "Foma,b,c: " << fom_a << ", " << fom_b << ", " << fom_c << std::endl; - + if(fom_a <= -10000. || fom_b <= -10000. || fom_c <= -10000) return -10000.; double fom2=fom_a*0.6347 + fom_b*0.2812 + @@ -601,7 +377,6 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t for (int k = 0;k<6;k++) { for (int m = 0;m<6;m++) { sigma2[i][m] = sigma2[i][m] + xfers[i][j]*sigma1[j][k]*xfers[m][k]; - //std::cout << "sigma2: " << sigma2[i][m] << " = " << sigma2[i][m]<< " + " << xfers[i][j] << " * " << sigma1[j][k] << " * " << xfers[m][k] << std::endl; } } } @@ -610,14 +385,12 @@ bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t sx = sqrt(sigma2[0][0])*1000.0; sy = sqrt(sigma2[2][2])*1000.0; rho = sigma2[0][2]/sqrt(sigma2[0][0]*sigma2[2][2]); - //cout<<"Swim "<= 1.) return -10000.; From 34c65fedee46cf5fd107974db6551a4686a4def0 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 5 Aug 2025 15:22:41 -0500 Subject: [PATCH 125/367] Updated CAFMaker --- sbncode/CAFMaker/FillExposure.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sbncode/CAFMaker/FillExposure.cxx b/sbncode/CAFMaker/FillExposure.cxx index 01dd11b80..ef3ca60df 100644 --- a/sbncode/CAFMaker/FillExposure.cxx +++ b/sbncode/CAFMaker/FillExposure.cxx @@ -21,6 +21,14 @@ namespace caf single_store.VPTG1 = info.VPTG1; single_store.HPTG2 = info.HPTG2; single_store.VPTG2 = info.VPTG2; + single_store.FOM = info.FOM; + single_store.VP873 = info.VP873; + single_store.VP875Offset = info.VP875Offset; + single_store.HP875Offset = info.HP875Offset; + single_store.VPTG1Offset = info.VPTG1Offset; + single_store.HPTG1Offset = info.HPTG1Offset; + single_store.VPTG2Offset = info.VPTG2Offset; + single_store.HPTG2Offset = info.HPTG2Offset; single_store.BTJT2 = info.BTJT2; single_store.THCURR = info.THCURR; single_store.M875BB = info.M875BB; From e22d9a7355f3732c0c40ae3c9af08e3e1b6514cf Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:15:30 -0400 Subject: [PATCH 126/367] Update sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc Co-authored-by: Gianluca Petrillo --- .../SBNDBNBRetriever/SBNDBNBRetriever_module.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 6681b91eb..9b8dbf11f 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -9,7 +9,6 @@ #include "messagefacility/MessageLogger/MessageLogger.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" #include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" -//#include "sbncode/BeamSpillInfoRetriever/getFOM.cpp" #include "sbncode/BeamSpillInfoRetriever/getFOM.h" #include From 35dfbbe70731fff5cef455cc26e229afaffdb064 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:23:34 -0400 Subject: [PATCH 127/367] Update SBNDBNBRetriever_module.cc --- .../SBNDBNBRetriever/SBNDBNBRetriever_module.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 9b8dbf11f..2dbe1d89d 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -62,16 +62,17 @@ sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) fTimePad = params.get("TimePadding"); fBESOffset = params.get("BESOffset"); fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); - bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); + double timeWindow = std::stod(params.get("TimeWindow")) + bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), timeWindow); bfp->set_epsilon(0.02); bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); TotalBeamSpills = 0; - vp873 = ifbeam_handle->getBeamFolder(params.get("VP873Bundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + vp873 = ifbeam_handle->getBeamFolder(params.get("VP873Bundle"), params.get("URL"), timeWindow); vp873->set_epsilon(0.02); - offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), timeWindow); offsets->set_epsilon(600); } From 12322c8d72ed13f00885b87ec8cea23e3326fee5 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:23:54 -0400 Subject: [PATCH 128/367] Update sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc Co-authored-by: Gianluca Petrillo --- .../SBNDBNBRetriever/SBNDBNBRetriever_module.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 2dbe1d89d..64abf0c0f 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -10,7 +10,6 @@ #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" #include "sbncode/BeamSpillInfoRetriever/SBNDPOTTools.h" #include "sbncode/BeamSpillInfoRetriever/getFOM.h" -#include namespace sbn { From f7a7ab2b4ae0698607ae009906b5a049e94134fb Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:24:34 -0400 Subject: [PATCH 129/367] Update sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc Co-authored-by: Gianluca Petrillo --- .../SBNDBNBRetriever/SBNDBNBRetriever_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 64abf0c0f..38d83d586 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -224,7 +224,7 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); - double spillFOM = sbn::getFOM(spillInfo); + double const spillFOM = sbn::getFOM(spillInfo); spillInfo.FOM = spillFOM; beamInfos.push_back(std::move(spillInfo)); From 16a81f85d3965d49b19ddc91a0130dfc724f521d Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:32:16 -0400 Subject: [PATCH 130/367] Update getFOM.h --- sbncode/BeamSpillInfoRetriever/getFOM.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.h b/sbncode/BeamSpillInfoRetriever/getFOM.h index 090ec3a3b..b9a6b5afe 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.h +++ b/sbncode/BeamSpillInfoRetriever/getFOM.h @@ -1,18 +1,7 @@ #ifndef _GETFOM_H #define _GETFOM_H -//#include "datatypes/ub_BeamHeader.h" -//#include "datatypes/ub_BeamData.h" -//#include "lardataobj/RawData/BeamInfo.h" #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" -//#include "bnbAutoTune.h" -#include -#include "TMath.h" -#include "TH1.h" -#include "TGraph.h" -//#include "TH1D.h" -//#include "TF1.h" - From a93fad27af33d28fa370de6948141ca401206ccd Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 12:07:20 -0400 Subject: [PATCH 131/367] Update SBNDBNBRetriever_module.cc --- .../SBNDBNBRetriever/SBNDBNBRetriever_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 38d83d586..b33c9d3f8 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -61,7 +61,7 @@ sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) fTimePad = params.get("TimePadding"); fBESOffset = params.get("BESOffset"); fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); - double timeWindow = std::stod(params.get("TimeWindow")) + double const timeWindow = std::stod(params.get("TimeWindow")) bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), timeWindow); bfp->set_epsilon(0.02); bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); From 828f88c2ba2264ff98f98ab26ae8ff709e5153bc Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 12:21:01 -0400 Subject: [PATCH 132/367] Update getFOM.h --- sbncode/BeamSpillInfoRetriever/getFOM.h | 33 ++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.h b/sbncode/BeamSpillInfoRetriever/getFOM.h index b9a6b5afe..daa3fa3dc 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.h +++ b/sbncode/BeamSpillInfoRetriever/getFOM.h @@ -1,5 +1,10 @@ #ifndef _GETFOM_H #define _GETFOM_H +/** + * @file sbncode/BeamSpillInfoRetriever/getFOM.h + * @brief Beam quality figures of merit. + * @author Max Dubnowski (maxdub@upenn.sas.edu) + */ #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" @@ -7,19 +12,35 @@ namespace sbn { - //typedef std::vector autoTunes; - //float getFOM2(std::string beam, const gov::fnal::uboone::datatypes::ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings = bnb::bnbAutoTune(), bool useAutoTune=true); + /** + * @brief Returns a Figure of Merit on BNB beam quality. + * + * The figure of merit is described in [SBN DocDB 41901](https://sbn-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=41901). + * Inputs the BNBSpillInfo and returns the BNB Quality Metric called FOM, derived from MicroBooNE's FOM + */ float getFOM(BNBSpillInfo& spill); - /* autoTunes cacheAutoTuneHistory(); */ - /* bnb::bnbAutoTune getSettings(const autoTunes& history, const gov::fnal::uboone::datatypes::ub_BeamHeader& bh); */ - /* bnb::bnbAutoTune getSettings(const autoTunes& history, const raw::BeamInfo& bi); */ - /* bnb::bnbAutoTune getSettings(const autoTunes& history, const uint64_t utctstamp); */ + /** + * @brief Inside the getFOM script, takes the positions and angles of the beam and calculates the BNB FOM + */ double calcFOM(double horpos,double horang,double verpos,double verang,double tor,double tgtsx,double tgtsy); + + /** + * @brief Takes in the centroid and sigma of the beam, along with transfer matrices, and will determine the beam's + * 2D gaussian position depending where on the target is being measured. The code "swims" up the target to calculate these + */ void swimBNB(const double centroid1[6], const double sigma1[6][6], const double xferc[6][6], const double xfers[6][6], double &cx, double& cy, double &sx, double &sy, double &rho); + + /** + * @brief Integrates the 2D modelled gaussian beam overlapping with the target, and returns the fraction outside the beam + */ double func_intbivar(const double cx, const double cy, const double sx, const double sy, const double rho ); + + /** + * @brief Inputs the MWR Data and determines the centroid, sigma, and chi2 value of a gaussian fit of the beam + */ void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2); } From 090c4a0e5b8d715ba7f5f541f5e1a303090efcc5 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 12:22:39 -0400 Subject: [PATCH 133/367] Update getFOM.h --- sbncode/BeamSpillInfoRetriever/getFOM.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.h b/sbncode/BeamSpillInfoRetriever/getFOM.h index daa3fa3dc..82f534282 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.h +++ b/sbncode/BeamSpillInfoRetriever/getFOM.h @@ -18,7 +18,7 @@ namespace sbn * The figure of merit is described in [SBN DocDB 41901](https://sbn-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=41901). * Inputs the BNBSpillInfo and returns the BNB Quality Metric called FOM, derived from MicroBooNE's FOM */ - float getFOM(BNBSpillInfo& spill); + float getBNBqualityFOM(BNBSpillInfo& spill); /** * @brief Inside the getFOM script, takes the positions and angles of the beam and calculates the BNB FOM From 94215feb4764a1ffb978a8281de57fed08e434b8 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 12:52:28 -0400 Subject: [PATCH 134/367] Update getFOM.cpp --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 138 ++++++++++------------ 1 file changed, 65 insertions(+), 73 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index a5f147e92..f48be2963 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -1,19 +1,12 @@ -//############################################################################################# -// Script: Figure of Merit for BNB Spills using SBND information adapted from MicroBooNE FOM -// -// Author: Max Dubnowski -// Contact: maxdub@sas.upenn.edu or sbn slack -// -//############################################################################################### - -#include "getFOM.h" -#include +/** + * @file sbncode/BeamSpillInfoRetriever/getFOM.cpp + * @brief Figure of Merit for BNB Spills using SBND information adapted from MicroBooNE FOM + * @author Max Dubnowski (maxdub@sas.upenn.edu or `@Max Dubnowski` on SBN Slack) + */ #include #include "TH1D.h" -#include "TF1.h" +#include "TFitResultPtr.h" #include -#include -#include "TCanvas.h" using namespace std; @@ -23,7 +16,7 @@ namespace sbn { bool onePlot = true; - float getFOM(BNBSpillInfo & spill ) + float getBNBqualityFOM(BNBSpillInfo & spill ) { double fom=0; @@ -37,18 +30,19 @@ namespace sbn { //Decides which position monitor to check first int useHTG = 0; int useVTG = 0; - - double hp875_zpos= 202.116104; - double vp875_zpos= 202.3193205; - double hptg1_zpos= 204.833267; - double vptg1_zpos= 204.629608; - double hptg2_zpos= 205.240662; - double vptg2_zpos= 205.036835; - double target_center_zpos= 206.870895; - double p875x[]={0.431857, 0.158077, 0.00303551}; - double p875y[]={0.279128, 0.337048, 0}; - double p876x[]={0.166172, 0.30999, -0.00630299}; - double p876y[]={0.13425, 0.580862, 0}; + + //Z Position of the monitors in m + double const hp875_zpos= 202.116104; + double const vp875_zpos= 202.3193205; + double const hptg1_zpos= 204.833267; + double const vptg1_zpos= 204.629608; + double const hptg2_zpos= 205.240662; + double const vptg2_zpos= 205.036835; + double const target_center_zpos= 206.870895; + double const p875x[]={0.431857, 0.158077, 0.00303551}; + double const p875y[]={0.279128, 0.337048, 0}; + double const p876x[]={0.166172, 0.30999, -0.00630299}; + double const p876y[]={0.13425, 0.580862, 0}; std::vector tor860; @@ -75,9 +69,9 @@ namespace sbn { vptg2.push_back(spill.VPTG2); double tor; - if (tor860.size()>0) + if (!tor860.empty()) tor=tor860[0]; - else if (tor875.size()>0) + else if (!tor875.empty()) tor=tor875[0]; else return -1; @@ -87,12 +81,12 @@ namespace sbn { //this could create a difference when passing events with FOM>1 since //events with missing BPM data would get FOM=2, while events with BPM set to -999 will get FOM=0 //bad or missing MWR data gets FOM 4 in either case - if (hptg2.size()==0) hptg2.push_back(-999); - if (hptg1.size()==0) hptg1.push_back(-999); - if (hp875.size()==0) hp875.push_back(-999); - if (vptg2.size()==0) vptg2.push_back(-999); - if (vptg1.size()==0) vptg1.push_back(-999); - if (vp875.size()==0) vp875.push_back(-999); + if (hptg2.empty()) hptg2.push_back(-999); + if (hptg1.empty()) hptg1.push_back(-999); + if (hp875.empty()) hp875.push_back(-999); + if (vptg2.empty()) vptg2.push_back(-999); + if (vptg1.empty()) vptg1.push_back(-999); + if (vp875.empty()) vp875.push_back(-999); double horang,horpos; if(useHTG == 1){ if (hptg1.size()>0 && hp875.size()>0) { @@ -152,12 +146,11 @@ namespace sbn { bool good_tgt=false; bool good_876=false; bool good_875=false; + constexpr size_t FirstXMWtgt =0; + constexpr size_t FirstYMWtgt =48; if (mwtgt.size()>0) { - //if (bh.getSeconds()<1463677200 && mwtgt.size()>0) { - //target multiwire started failing after May 20 2016 (1463677200) - //skip this if data from when tgt multiwire was already dead - processBNBprofile(&mwtgt[0], xx, sx,chi2x); - processBNBprofile(&mwtgt[48], yy, sy, chi2y); + processBNBprofile(&mwtgt[FirstXMWtgt], xx, sx,chi2x); + processBNBprofile(&mwtgt[FirstYMWtgt], yy, sy, chi2y); if (sx>0.5 && sx<10 && sy>0.3 && sy<10 && chi2x<20 && chi2y<20 && mwtgt.size()>0) { tgtsx=sx; tgtsy=sy; @@ -165,8 +158,8 @@ namespace sbn { } } if (!good_tgt && mw876.size()>0) { - processBNBprofile(&mw876[0], xx,sx,chi2x); - processBNBprofile(&mw876[48], yy,sy,chi2y); + processBNBprofile(&mw876[FirstXMWtgt], xx,sx,chi2x); + processBNBprofile(&mw876[FirstYMWtgt], yy,sy,chi2y); double tgtsx876=p876x[0]+p876x[1]*sx+p876x[2]*sx*sx; double tgtsy876=p876y[0]+p876y[1]*sy+p876y[2]*sy*sy; if (tgtsx876>0.5 && tgtsx876<10 && tgtsy876>0.3 && tgtsy876<10 && chi2x<20 && chi2y<20) { @@ -176,8 +169,8 @@ namespace sbn { } } if (!good_tgt && !good_876 && mw875.size()>0){ - processBNBprofile(&mw875[0], xx,sx,chi2x); - processBNBprofile(&mw875[48], yy,sy,chi2y); + processBNBprofile(&mw875[FirstXMWtgt], xx,sx,chi2x); + processBNBprofile(&mw875[FirstYMWtgt], yy,sy,chi2y); double tgtsx875=p875x[0]+p875x[1]*sx+p875x[2]*sx*sx; double tgtsy875=p875y[0]+p875y[1]*sy+p875y[2]*sy*sy; if (tgtsx875>0.5 && tgtsx875<10 && tgtsy875>0.3 && tgtsy875<10 && chi2x<20 && chi2y<20) { @@ -196,41 +189,40 @@ namespace sbn { } - +/** + * @brief Extracts statistics from multiwire monitor data. + * @param mwdata pointer to multiwire data (48 channels horizontal or vertical) + * @param[out] x mean position from the fit [mm] + * @param[out] sx σ from the fit [mm] + * @param[out] chi2 χ²/NDF for the Gaussian fit + * + * This function takes multiwire data (`mwdata`), + * finds the min and max, + * finds the first and last bin where amplitude is greater than 20%, + * fits the peak between first and last bin with Gaussian (assuming 2% relative errors) + * and returns the parameters of the fit. + */ void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2) { - /* - function takes multiwire data as input (48 channels horizontal or vertical, - finds the min and max - finds the first and last bin where amplitude is greater than 20% - fits the peak between first and last bin with gaussian (assuming 2% relative errors) - returns: - x - mean position from the fit - sx - sigma x from the fit - chi2 - chi2/NDF for the gaussian fit - */ - double minx=0; - double maxx=0; - for (unsigned int i=0;i<48;i++) { - minx=std::min(-mwdata[i],minx); - maxx=std::max(-mwdata[i],maxx); - } - int first_x=-1; - int last_x=-1; - static int entry = 1; - TH1D* hProf=new TH1D("hProf"+TString(std::to_string(entry)),"",48,-12,12); - for (unsigned int i=0;i<48;i++) { + // values' sign is inverted + double minx = std::min(-*std::max_element(mwdata, mwdata + 48), 0); + double maxx = std::max(-*std::min_element(mwdata, mwdata + 48), 0); + + TH1D hProf("hProfMW","",48,-12.0,12.0); // coverage is 24 cm + double const threshold = (maxx-minx)*0.2; // 20% of the range + double const error = (maxx-minx)*0.02; // 2% of the range + for (unsigned int i=0;i<48;i++) { hProf->SetBinContent(i+1,-mwdata[i]-minx); - if (-mwdata[i]-minx > (maxx-minx)*0.2 && first_x==-1) first_x=i; - if (-mwdata[i]-minx > (maxx-minx)*0.2) last_x=i+1; - hProf->SetBinError(i+1,(maxx-minx)*0.02); + if (-mwdata[i]-minx > threshold && first_x==-1) first_x=i; + if (-mwdata[i]-minx > threshold) last_x=i+1; + hProf->SetBinError(i+1,error); } if (hProf->GetSumOfWeights()>0) { - hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); - x =hProf->GetFunction("gaus")->GetParameter(1); - sx =hProf->GetFunction("gaus")->GetParameter(2); + TFitResultPtr const fit = hProf.Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); + x = fit->Parameter(1); + sx = fit->Parameter(2); + chi2= fit->Chi2() / fit->Ndf(); - chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); } else { x=99999; sx=99999; @@ -242,7 +234,7 @@ namespace sbn { double calcFOM(double horpos, double horang, double verpos, double verang, double ppp, double tgtsx, double tgtsy) { - ppp = ppp / pow(10,12); + ppp /= 1e12; //converts to 10^12 POT //code from MiniBooNE AnalysisFramework with the addition of scaling the beam profile to match tgtsx, tgtsy From 04256b949d6cd0d20c62a8055c5490d34083ef60 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 12:54:58 -0400 Subject: [PATCH 135/367] Update getFOM.h --- sbncode/BeamSpillInfoRetriever/getFOM.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.h b/sbncode/BeamSpillInfoRetriever/getFOM.h index 82f534282..2015ea937 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.h +++ b/sbncode/BeamSpillInfoRetriever/getFOM.h @@ -1,5 +1,6 @@ -#ifndef _GETFOM_H -#define _GETFOM_H +#ifndef SBNCODE_BEAMSPILLRETRIEVER_GETFOM_H +#define SBNCODE_BEAMSPILLRETRIEVER_GETFOM_H + /** * @file sbncode/BeamSpillInfoRetriever/getFOM.h * @brief Beam quality figures of merit. From 65cd616d29e88c1f6c6ffef06fcd5473a48e1bd2 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:16:18 -0400 Subject: [PATCH 136/367] Delete sbncode/BeamSpillInfoRetriever/getUbooneFOM.C --- sbncode/BeamSpillInfoRetriever/getUbooneFOM.C | 804 ------------------ 1 file changed, 804 deletions(-) delete mode 100644 sbncode/BeamSpillInfoRetriever/getUbooneFOM.C diff --git a/sbncode/BeamSpillInfoRetriever/getUbooneFOM.C b/sbncode/BeamSpillInfoRetriever/getUbooneFOM.C deleted file mode 100644 index 22c5b8929..000000000 --- a/sbncode/BeamSpillInfoRetriever/getUbooneFOM.C +++ /dev/null @@ -1,804 +0,0 @@ -#include "getFOM.h" -#include -#include -#include "TH1D.h" -#include "TF1.h" -#include -#include -#include "TCanvas.h" - - -using namespace std; - - -//namespace sbn { - void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2) - { - /* - function takes multiwire data as input (48 channels horizontal or vertical, - finds the min and max - finds the first and last bin where amplitude is greater than 20% - fits the peak between first and last bin with gaussian (assuming 2% relative errors) - returns: - x - mean position from the fit - sx - sigma x from the fit - chi2 - chi2/NDF for the gaussian fit - */ - double minx=0; - double maxx=0; - for (unsigned int i=0;i<48;i++) { - minx=std::min(-mwdata[i],minx); - maxx=std::max(-mwdata[i],maxx); - } - int first_x=-1; - int last_x=-1; - static int entry = 1; - TH1D* hProf=new TH1D("hProf"+TString(std::to_string(entry)),"",48,-12,12); - for (unsigned int i=0;i<48;i++) { - hProf->SetBinContent(i+1,-mwdata[i]-minx); - if (-mwdata[i]-minx > (maxx-minx)*0.2 && first_x==-1) first_x=i; - if (-mwdata[i]-minx > (maxx-minx)*0.2) last_x=i+1; - hProf->SetBinError(i+1,(maxx-minx)*0.02); - } - if (hProf->GetSumOfWeights()>0) { - hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); - x =hProf->GetFunction("gaus")->GetParameter(1); - sx =hProf->GetFunction("gaus")->GetParameter(2); - //std::cout << "sx value: " << sx << std::endl; - // if ( sx > 50.){ - // for (size_t m =0; m< 48 ; m++){ - // std::cout << "Bad MWData: " << mwdata[m] << std::endl; - // } - //} - - chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); - } else { - x=99999; - sx=99999; - chi2=99999; - } - entry += 1; - } - - - double calcFOM(double horpos, double horang, double verpos, double verang, double ppp, double tgtsx, double tgtsy) - { - //ppp = ppp / pow(10,12); - - - //code from MiniBooNE AnalysisFramework with the addition of scaling the beam profile to match tgtsx, tgtsy - //form DQ_BeamLine_twiss_init.F - double bx = 4.68; - double ax = 0.0389; - double gx = (1+ax*ax)/bx; - double nx = 0.0958; - double npx = -0.0286; - double by = 59.12; - double ay = 2.4159; - double gy = (1+ay*ay)/by; - double ny = 0.4577; - double npy = -0.0271; - //from DQ_BeamLine_make_tgt_fom2.F - double ex = 0.1775E-06 + 0.1827E-07*ppp; - double ey = 0.1382E-06 + 0.2608E-08*ppp; - double dp = 0.4485E-03 + 0.6100E-04*ppp; - double tex = ex; - double tey = ey; - double tdp = dp; - //from DQ_BeamLine_beam_init.F - double sigma1[6][6]={{0}}; - double centroid1[6]={0}; - centroid1[0] = horpos; - centroid1[1] = horang; - centroid1[2] = verpos; - centroid1[3] = verang; - centroid1[4] = 0.0; - centroid1[5] = 0.0; - sigma1[5][5] = tdp*tdp; - sigma1[0][0] = tex*bx+ nx*nx *tdp*tdp; - sigma1[0][1] = -tex*ax+ nx*npx*tdp*tdp; - sigma1[1][1] = tex*gx+npx*npx*tdp*tdp; - sigma1[0][5] = nx*tdp*tdp; - sigma1[1][5] = npx*tdp*tdp; - sigma1[1][0] = sigma1[0][1]; - sigma1[5][0] = sigma1[0][5]; - sigma1[5][1] = sigma1[1][5]; - sigma1[2][2] = tey*by+ny*ny*tdp*tdp; - sigma1[2][3] = -tey*ay+ny*npy*tdp*tdp; - sigma1[3][3] = tey*gy+npy*npy*tdp*tdp; - sigma1[2][5] = ny*tdp*tdp; - sigma1[3][5] = npy*tdp*tdp; - sigma1[3][2] = sigma1[2][3]; - sigma1[5][2] = sigma1[2][5]; - sigma1[5][3] = sigma1[3][5]; - - - - for (int fi =0; fi <6; fi++){ - for(int la =0; la<6; la++){ - //std::cout << "sigma1[" << fi << "][" << la << "] = " << sigma1[fi][la] << " | ppp: " << ppp << std::endl; - } - } - - double begtocnt[6][6]={ - { 0.65954, 0.43311, 0.00321, 0.10786, 0.00000, 1.97230}, - { 0.13047, 1.60192, 0.00034, 0.00512, 0.00000, 1.96723}, - {-0.00287, -0.03677, -0.35277, -4.68056, 0.00000, 0.68525}, - {-0.00089, -0.00430, -0.17722, -5.18616, 0.00000, 0.32300}, - {-0.00104, 0.00232, -0.00001, -0.00224, 1.00000, -0.00450}, - { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000} - }; - double cnttoups[6][6]={{0}}; - double cnttodns[6][6]={{0}}; - double identity[6][6]={{0}}; - double begtoups[6][6]={{0}}; - double begtodns[6][6]={{0}}; - for (int i=0;i<6;i++) { - for (int j=0;j<6;j++) { - if (i==j) { - cnttoups[i][j] = 1.0; - cnttodns[i][j] = 1.0; - identity[i][j] = 1.0; - } else { - cnttoups[i][j] = 0.0; - cnttodns[i][j] = 0.0; - identity[i][j] = 0.0; - } - } - } - cnttoups[0][1] = -0.35710; - cnttoups[2][3] = -0.35710; - cnttodns[0][1] = +0.35710; - cnttodns[2][3] = +0.35710; - for (int i=0;i<6;i++) { - for (int j=0;j<6;j++) { - for (int k=0;k<6;k++) { - begtoups[i][k] = begtoups[i][k] + cnttoups[i][j]*begtocnt[j][k]; - begtodns[i][k] = begtodns[i][k] + cnttodns[i][j]*begtocnt[j][k]; - } - } - } - //swim to upstream of target - double cx, cy, sx, sy, rho; - sbn::swimBNB(centroid1,sigma1, - cnttoups, begtoups, - cx, cy, sx, sy, rho); - double scalex=tgtsx/sx; - double scaley=tgtsy/sy; - //std::cout << "Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << std::endl; - double fom_a=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); - //swim to center of target - sbn::swimBNB(centroid1,sigma1, - identity, begtocnt, - cx, cy, sx, sy, rho); - double fom_b=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); - //std::cout << "After Scalex: " << scalex << " | Scaley: " << scaley << " | sx: " << sx << " | sy: " << sy << " | tgtsx: " << tgtsx << " | tgtsy: " << tgtsy << " | rho: " << rho << std::endl; - //swim to downstream of target - sbn::swimBNB(centroid1,sigma1, - cnttodns, begtodns, - cx, cy, sx, sy, rho); - double fom_c=sbn::func_intbivar(cx, cy, sx*scalex, sy*scaley, rho); - // add a guard for double precision - //std::cout << "Foma,b,c: " << fom_a << ", " << fom_b << ", " << fom_c << std::endl; - - if(fom_a <= -10000. || fom_b <= -10000. || fom_c <= -10000) return -10000.; - double fom2=fom_a*0.6347 + - fom_b*0.2812 + - fom_c*0.0841; - return fom2; - } - - void swimBNB(const double centroid1[6], const double sigma1[6][6], - const double xferc[6][6], const double xfers[6][6], - double &cx, double& cy, double &sx, double &sy, double &rho) - { - //centroid - double centroid2[6]={0}; - for (int i=0;i<6;i++) { - for (int j=0;j<6;j++) { - centroid2[i] = centroid2[i] + xferc[i][j]*centroid1[j]; - } - } - cx = centroid2[0]; - cy = centroid2[2]; - //sigma - double sigma2[6][6]={{0}}; - for (int i = 0; i<6;i++) { - for (int j = 0;j<6;j++) { - for (int k = 0;k<6;k++) { - for (int m = 0;m<6;m++) { - sigma2[i][m] = sigma2[i][m] + xfers[i][j]*sigma1[j][k]*xfers[m][k]; - //std::cout << "sigma2: " << sigma2[i][m] << " = " << sigma2[i][m]<< " + " << xfers[i][j] << " * " << sigma1[j][k] << " * " << xfers[m][k] << std::endl; - } - } - } - } - //get beam sigma - sx = sqrt(sigma2[0][0])*1000.0; - sy = sqrt(sigma2[2][2])*1000.0; - rho = sigma2[0][2]/sqrt(sigma2[0][0]*sigma2[2][2]); - //cout<<"Swim "<= 1.) return -10000.; - return log10(1-sum); - } - - - - - - - - - - - - bool onePlot = true; - void getUbooneFOM() - //float getFOM(BNBSpillInfo & spill ) - //float getFOM2( const ub_BeamHeader& bh, const std::vector& bd, const bnb::bnbAutoTune settings, bool useAutoTune) - { - gStyle->SetOptStat(0); - - double fom=0; - //TFile* f = TFile::Open("/exp/sbnd/app/users/maxd/BNBQualityCut/ubooneData/pnfs/pnfs/uboone/persistent/uboonebeam/beam_data/bnb_data/00/01/47/68/beamdata_00014768.root", "READ"); - TFile* f = TFile::Open("/exp/sbnd/app/users/maxd/BNBQualityCut/ubooneData/pnfs/uboone/persistent/uboonebeam/beam_data/bnb_data/00/02/57/44/beamdata_00025744.root", "READ"); - - if (!f || f->IsZombie()) { - std::cerr << "Error opening file.root\n"; - return; - } - - // Get the TTree named "bnb" - TTree* tree = (TTree*)f->Get("bnb"); - if (!tree) { - std::cerr << "TTree 'bnb' not found in file.root\n"; - return; - } - - std::map hp875_offset_map; - std::map vp875_offset_map; - std::map hptg1_offset_map; - std::map hptg2_offset_map; - std::map vptg1_offset_map; - std::map vptg2_offset_map; - - //hp875_offset = hp875_offset_map[]; - - - //Other run 5 autotune offsets -3.4, 1.48, -1., -1., 1.07, -3.15 - // double hp875_offset= -3.4; - // double vp875_offset= 1.48; - // double hptg1_offset= -1.0; - // double vptg1_offset= -1.0; - // //double hptg2_offset= -1.0; - // //double vptg2_offset= -1.0; - // double hptg2_offset= 1.07; - // double vptg2_offset= -3.15; - - - - - - //Run 5 autotune values - // double hp875_offset= -1.2; - // double vp875_offset= 1.3; - // double hptg1_offset= -1.0; - // double vptg1_offset= -1.0; - // //double hptg2_offset= -1.0; - // //double vptg2_offset= -1.0; - // double hptg2_offset= -0.4; - // double vptg2_offset= 0.1; - - - - //From IFBeam for Run 25744 - // double hp875_offset= -1.3359030485153198; - // double vp875_offset= 1.3375698328018188; - // double hptg1_offset= -0.1474824994802475; - // double vptg1_offset= -0.24208535254001617; - // //double hptg2_offset= -1.0; - // //double vptg2_offset= -1.0; - // double hptg2_offset= -0.5022110939025879; - // double vptg2_offset= 0.12833189964294434; - - //Previous hardcoded values - double hp875_offset= -3.40271; - double vp875_offset= +1.47511; - double hptg1_offset= +0.457014; - double vptg1_offset= +0.38914; - //double hptg2_offset= -1.0; - //double vptg2_offset= -1.0; - //double hptg2_offset= +0.8; - //double vptg2_offset= +1.0; - double hptg2_offset= +0.79; - double vptg2_offset= +1.02; - - // double hp875_offset= -2.2; - // double vp875_offset= +1.7; - // double hptg1_offset= -0.2; - // double vptg1_offset= +0.38; - // //double hptg2_offset= -1.0; - // //double vptg2_offset= -1.0; - // double hptg2_offset= +0.5; - // double vptg2_offset= +1.0; - - - - - - - // double hp875_offset= spill.HP875Offset; - // double vp875_offset= spill.VP875Offset; - // double hptg1_offset= spill.HPTG1Offset; - // double vptg1_offset= spill.VPTG1Offset; - // double hptg2_offset= spill.HPTG2Offset; - // double vptg2_offset= spill.VPTG2Offset; - - - //int useHTG = bnb::kTG1; - //int useVTG = bnb::kTG1; - - int useHTG = 0; - int useVTG = 0; - - - //if(useAutoTune){ - // bnb::bnbOffsets data = settings.getData(); - // hp875_offset = data.hp875; - // vp875_offset = data.vp875; - // hptg1_offset = data.hptg1; - // vptg1_offset = data.vptg1; - // hptg2_offset = data.hptg2; - // vptg2_offset = data.vptg2; - //useHTG = settings.getHTG(); - //useVTG = settings.getVTG(); - //} - - - - - double hp875_zpos= 202.116104; - double vp875_zpos= 202.3193205; - double hptg1_zpos= 204.833267; - double vptg1_zpos= 204.629608; - double hptg2_zpos= 205.240662; - double vptg2_zpos= 205.036835; - double target_center_zpos= 206.870895; - double p875x[]={0.431857, 0.158077, 0.00303551}; - double p875y[]={0.279128, 0.337048, 0}; - double p876x[]={0.166172, 0.30999, -0.00630299}; - double p876y[]={0.13425, 0.580862, 0}; - - - double tor860; - double tor875; - double hp875; - double vp875; - double hptg1; - double vptg1; - double hptg2; - double vptg2; - float fom2; - Long64_t tstamp; - - //std::vector mw875;// = nullptr; - //std::vector mw876;// = nullptr; - //std::vector mwtgt;// = nullptr; - double mw875[96]; - double mw876[96]; - double mwtgt[96]; - - tree->SetBranchAddress("tor860", &tor860); - tree->SetBranchAddress("tor875", &tor875); - tree->SetBranchAddress("hp875", &hp875); - tree->SetBranchAddress("vp875", &vp875); - tree->SetBranchAddress("hptg1", &hptg1); - tree->SetBranchAddress("vptg1", &vptg1); - tree->SetBranchAddress("hptg2", &hptg2); - tree->SetBranchAddress("vptg2", &vptg2); - tree->SetBranchAddress("fom2", &fom2); - tree->SetBranchAddress("m875bb", &mw875); - tree->SetBranchAddress("m876bb", &mw876); - tree->SetBranchAddress("mmbtbb", &mwtgt); - tree->SetBranchAddress("tstamp", &tstamp); - - //std::cout << "MWR 875 Size: " << mw875.size() << " | MWR876 Size: " << mw876.size() << " | MWTGT Size: " << mwtgt.size() << std::endl; - //for (size_t m =0; m< mw875.size() ; m++){ - //std::cout << "MWR 875: " << mw875[m] << " | MWR876: " << mw876[m] << " | MWTGT: " << mwtgt[m] << std::endl; - //} - - /* - if (onePlot){ - TH1D* MWRx =new TH1D("MWRx","MWRx",48,-12,12); - TCanvas *c1 = new TCanvas("c1", "c1", 800, 600); - - TH1D* MWRy =new TH1D("MWRy","MWRy",48,-12,12); - TCanvas *c2 = new TCanvas("c2", "c2", 800, 600); - - - for(int w =0 ; w< 48; w++){ - MWRx->SetBinContent(w+1, -mw875[w]); - MWRx->SetBinContent(w+1, -mw875[w+48]); - } - - c1->cd(); - MWRx->Draw("HIST"); - c1->Draw(); - - c2->cd(); - MWRy->Draw("HIST"); - c2->Draw(); - - onePlot =false; - } - */ - - //std::vector mw875 = spill.M875BB; - //std::vector mw876 = spill.M876BB; - //std::vector mwtgt = spill.MMBTBB; - - // tor860.push_back(spill.TOR860); - // tor875.push_back(spill.TOR875); - // hp875.push_back(spill.HP875); - // vp875.push_back(spill.VP875); - // hptg1.push_back(spill.HPTG1); - // vptg1.push_back(spill.VPTG1); - // hptg2.push_back(spill.HPTG2); - // vptg2.push_back(spill.VPTG2); - - - - //std::cout << spill.HP875 << "," <0) - // tor=tor860[0]; - // else if (tor875.size()>0) - // tor=tor875[0]; - // else - // return; - - - - - // ==================================================================== Replace with BNBSpillInfo ==================================================================================== - - TCanvas* c1 = new TCanvas("c1", "c1", 800,600); - TH1D* calcFOMhist = new TH1D("CalcFOMHist", "Calculated FOM Histogram; FOM; Entries", 100, 0.0 , 5.0); - TCanvas* c2 = new TCanvas("c2", "c2", 800,600); - //TH2D* FOMvfom2 = new TH2D("FOMvfom2", "FOM vs fom2; FOM; fom2", 100, 0. , 1.0, 100, 0., 1.0); - TH2D* FOMvfom2 = new TH2D("FOMvfom2", "FOM vs fom2; FOM; fom2", 100, 0.95 , 1.0, 100, 0.95, 1.0); - Long64_t firstTS=0; Long64_t lastTS =0; - - Long64_t nentries = tree->GetEntries(); - for (Long64_t i = 0; i < nentries; ++i) { - tree->GetEntry(i); - //std::cout << "Entry " << i << ": fom2 = " << fom2 << " | " << mw876.size() << std::endl;; - double tor = tor860; - if (i==0) firstTS = tstamp; - if (i == nentries-1) lastTS = tstamp; - fom=0; - if ( hptg1 <0.0){ - fom =-2; - // hp875_offset = bad_hp875_offset; - // vp875_offset = bad_vp875_offset; - // hptg1_offset = bad_hptg1_offset; - // vptg1_offset = bad_vptg1_offset; - // hptg2_offset = bad_hptg2_offset; - // vptg2_offset = bad_vptg2_offset; - } - //when creating ntuples for pot counting script the variables are filled with -999 - //this could create a difference when passing events with FOM>1 since - //events with missing BPM data would get FOM=2, while events with BPM set to -999 will get FOM=0 - //bad or missing MWR data gets FOM 4 in either case - // if (hptg2.size()==0) hptg2.push_back(-999); - // if (hptg1.size()==0) hptg1.push_back(-999); - // if (hp875.size()==0) hp875.push_back(-999); - // if (vptg2.size()==0) vptg2.push_back(-999); - // if (vptg1.size()==0) vptg1.push_back(-999); - // if (vp875.size()==0) vp875.push_back(-999); - double horang,horpos; - //if(useHTG == bnb::kTG1){ - if(useHTG == 1){ - // if (hptg1.size()>0 && hp875.size()>0) { - // horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); - // horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - // } else if (hptg2.size()>0 && hp875.size()>0) { - // horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); - // horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - // } else { - // //missing horizontal BPM data - // return; - // } - } - //else if(useHTG == bnb::kTG2){ - - else if(useHTG == 0){ - if (hptg2 != -999 && hp875!=-999) { - horang=((hptg2-hptg2_offset)-(hp875-hp875_offset))/(hptg2_zpos-hp875_zpos); - horpos=(hp875-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - } else if (hptg1!=-999 && hp875 !=-999) { - horang=((hptg1-hptg1_offset)-(hp875-hp875_offset))/(hptg1_zpos-hp875_zpos); - horpos=(hp875-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - } else { - //missing horizontal BPM data - fom=-1; - } - } - - double verang,verpos; - if(useVTG == 1){ - //if(useVTG == bnb::kTG1){ - // if (vptg1.size()>0 && vp875.size()>0) { - // verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); - // verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - // } else if (vptg2.size()>0 && vp875.size()>0) { - // verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); - // verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - // } else { - // //missing vertical BPM data - // return; - // } - } - else if(useVTG == 0){ - //else if(useVTG == bnb::kTG2){ - if (vptg2!=-999 && vp875!=-999) { - verang=((vptg2-vptg2_offset)-(vp875-vp875_offset))/(vptg2_zpos-vp875_zpos); - verpos=(vp875-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - } else if (vptg1!=-999 && vp875!=-999) { - verang=((vptg1-vptg1_offset)-(vp875-vp875_offset))/(vptg1_zpos-vp875_zpos); - verpos=(vp875-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - } else { - fom=-1; - } - } - - horang=atan(horang); - verang=atan(verang); - double xx,yy,sx,sy,chi2x,chi2y; - double tgtsx, tgtsy; - bool good_tgt=false; - bool good_876=false; - bool good_875=false; - if (true){ //mwtgt.size()>0) { - //if (bh.getSeconds()<1463677200 && mwtgt.size()>0) { - //target multiwire started failing after May 20 2016 (1463677200) - //skip this if data from when tgt multiwire was already dead - processBNBprofile(&mwtgt[0], xx, sx,chi2x); - processBNBprofile(&mwtgt[48], yy, sy, chi2y); - if (sx>0.5 && sx<10 && sy>0.3 && sy<10 && chi2x<20 && chi2y<20 ){ //&& mwtgt.size()>0) { - tgtsx=sx; - tgtsy=sy; - good_tgt=true; - } - } - if (!good_tgt){// && mw876.size()>0) { - processBNBprofile(&mw876[0], xx,sx,chi2x); - processBNBprofile(&mw876[48], yy,sy,chi2y); - double tgtsx876=p876x[0]+p876x[1]*sx+p876x[2]*sx*sx; - double tgtsy876=p876y[0]+p876y[1]*sy+p876y[2]*sy*sy; - if (tgtsx876>0.5 && tgtsx876<10 && tgtsy876>0.3 && tgtsy876<10 && chi2x<20 && chi2y<20) { - tgtsx=tgtsx876; - tgtsy=tgtsy876; - good_876=true; - } - } - if (!good_tgt && !good_876 ){ // && mw875.size()>0){ - processBNBprofile(&mw875[0], xx,sx,chi2x); - processBNBprofile(&mw875[48], yy,sy,chi2y); - double tgtsx875=p875x[0]+p875x[1]*sx+p875x[2]*sx*sx; - double tgtsy875=p875y[0]+p875y[1]*sy+p875y[2]*sy*sy; - if (tgtsx875>0.5 && tgtsx875<10 && tgtsy875>0.3 && tgtsy875<10 && chi2x<20 && chi2y<20) { - tgtsx=tgtsx875; - tgtsy=tgtsy875; - good_875=true; - } - } - if (!good_tgt && !good_876 && !good_875) { - //failed getting multiwire data - fom=4; - } - //std::cout << "FOM before power: " << sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy) << ", " << horpos << ", " << horang << ", " << verpos << ", " << verang << ", " << tor << ", " << tgtsx << ", " << tgtsy<< std::endl; - - //std::cout << "Tgtsx: " << tgtsx << " | Tgtsy: " << tgtsy << std::endl; - if(fom==0) fom=1-pow(10,sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy)); - - - //std::cout <Fill(fom); - FOMvfom2->Fill(fom, fom2); - - //if ( fom-fom2 > 0.01) { - if (fom !=0 && fom!=4 && fom - fom2 < 0.002 && fom-fom2 > -0.002) { - std::cout <cd(); - calcFOMhist->Draw("HIST"); - - c2->cd(); - FOMvfom2->Draw("colz"); - - } - - /* - bmd::autoTunes bmd::cacheAutoTuneHistory() - { - bmd::autoTunes history; - bnb::bnbAutoTune item; - // run1-3 parameters - item.setEntry(202435254, 132, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); - history.push_back(item); - // run4a (misaligned beam) - item.setEntry(203988466, 174, 315, bnb::bnbOffsets{-3.4, 1.48, 0.46, -1., -1., 1.84}, bnb::kTG1, bnb::kTG2); - history.push_back(item); - item.setEntry(204211306, 174, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); - history.push_back(item); - // run4b-4d parameters (same as run1-3) - item.setEntry(215107286, 410, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); - history.push_back(item); - // item.setEntry(232368446, 268, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); - // history.push_back(item); - // item.setEntry(232368986, 268, 313, bnb::bnbOffsets{-3.4, 1.48, 0.46, 0.39, -1., -1.}, bnb::kTG1, bnb::kTG1); - // history.push_back(item); - // before run 5 - item.setEntry(247063273, 276, 316, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 1.84}, bnb::kTG2, bnb::kTG2); - history.push_back(item); - // run5a parameters used on Nov 4th - item.setEntry(247501553, 130, 317, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, -3.15}, bnb::kTG2, bnb::kTG2); - history.push_back(item); - // parameters being tested in the autotune from Nov5th - Nov 10th (not used because not parameters not reflected in BPM readings) - // item.setEntry(247573532, 305, 318, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, -0.03}, bnb::kTG2, bnb::kTG2); - // history.push_back(item); - // item.setEntry(247576952, 304, 319, bnb::bnbOffsets{-3.4, 1.48, -1., -0.03, 1.07, -1.}, bnb::kTG2, bnb::kTG1); - // history.push_back(item); - // item.setEntry(247577492, 304, 320, bnb::bnbOffsets{-3.4, 1.48, -1., -3.15, 1.07, -1.}, bnb::kTG2, bnb::kTG1); - // history.push_back(item); - // item.setEntry(247587752, 304, 322, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 0.}, bnb::kTG2, bnb::kTG2); - // history.push_back(item); - // item.setEntry(248020832, 304, 320, bnb::bnbOffsets{-3.4, 1.48, -1., -3.15, 1.07, -1.}, bnb::kTG2, bnb::kTG1); - // history.push_back(item); - // item.setEntry(248458772, 304, 322, bnb::bnbOffsets{-3.4, 1.48, -1., -1., 1.07, 0.}, bnb::kTG2, bnb::kTG2); - // history.push_back(item); - // later run5 data (after target scan) - item.setEntry(248792844, 573, 323, bnb::bnbOffsets{-1.20, 1.30, -1., -1., -0.4, 0.1}, bnb::kTG2, bnb::kTG2); - history.push_back(item); - return history; -} - - -bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const ub_BeamHeader& bh) -{ - if(*(history.end()-1) <= bh) return *(history.end()-1); - if(*(history.begin()) >= bh) return *(history.begin()); - for(auto it = history.begin(); it != history.end()-1; ++it){ - auto curr = *it; - auto following = *(it+1); - if((curr <= bh) && (following > bh)) return curr; - } - bnb::bnbAutoTune ret = bnb::bnbAutoTune(); - return ret; -} - -bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const raw::BeamInfo& bi) -{ - if(*(history.end()-1) <= bi) return *(history.end()-1); - if(*(history.begin()) >= bi) return *(history.begin()); - for(auto it = history.begin(); it != history.end()-1; ++it){ - auto curr = *it; - auto following = *(it+1); - if((curr <= bi) && (following > bi)) return curr; - } - bnb::bnbAutoTune ret = bnb::bnbAutoTune(); - return ret; -} - -bnb::bnbAutoTune bmd::getSettings(const bmd::autoTunes& history, const uint64_t utctstamp) -{ - if(*(history.end()-1) <= utctstamp) return *(history.end()-1); - if(*(history.begin()) >= utctstamp) return *(history.begin()); - for(auto it = history.begin(); it != history.end()-1; ++it){ - auto curr = *it; - auto following = *(it+1); - if((curr <= utctstamp) && (following > utctstamp)) return curr; - } - bnb::bnbAutoTune ret = bnb::bnbAutoTune(); - return ret; -} -*/ -//} From 0ef25f145318da9c93f14c0fb2f90c0974560520 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:18:41 -0400 Subject: [PATCH 137/367] Update SBNDBNBRetriever_module.cc --- .../SBNDBNBRetriever/SBNDBNBRetriever_module.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index b33c9d3f8..9c516c159 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -223,8 +223,8 @@ int sbn::SBNDBNBRetriever::matchMultiWireData( }//end loop over MWR devices sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); - - double const spillFOM = sbn::getFOM(spillInfo); + + double const spillFOM = sbn::getBNBqualityFOM(spillInfo); spillInfo.FOM = spillFOM; beamInfos.push_back(std::move(spillInfo)); From 2a6d70aed14d486b132028b1e8c8e7620f891fdc Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:20:11 -0400 Subject: [PATCH 138/367] Update SBNDBNBZEROBIASRetriever_module.cc --- .../SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index c7a7919e3..cd30c2a3a 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -227,7 +227,7 @@ void sbn::SBNDBNBZEROBIASRetriever::matchMultiWireData( }//end loop over MWR devices sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); - double spillFOM = sbn::getFOM(spillInfo); + double spillFOM = sbn::getBNBqualityFOM(spillInfo); spillInfo.FOM = spillFOM; beamInfos.push_back(std::move(spillInfo)); From 1fe068280dcf8dcc7d960356747c4de798869ef7 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:22:01 -0400 Subject: [PATCH 139/367] Update SBNDBNBZEROBIASRetriever_module.cc --- .../SBNDBNBZEROBIASRetriever_module.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index cd30c2a3a..3e0fa2446 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -59,15 +59,16 @@ sbn::SBNDBNBZEROBIASRetriever::SBNDBNBZEROBIASRetriever(fhicl::ParameterSet cons fTimePad = params.get("TimePadding"); fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); fBESOffset = params.get("BESOffset"); - bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), std::stod(params.get("TimeWindow"))); + const double timeWindow = std::stod(params.get("TimeWindow")); + bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), timeWindow); bfp->set_epsilon(0.02); bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); bfp_mwr->set_epsilon(0.5); bfp_mwr->setValidWindow(3605); - vp873 = ifbeam_handle->getBeamFolder(params.get("VP873Bundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + vp873 = ifbeam_handle->getBeamFolder(params.get("VP873Bundle"), params.get("URL"), timeWindow); vp873->set_epsilon(0.02); - offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), std::stod(params.get("TimeWindow" ) )); + offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), timeWindow); offsets->set_epsilon(600); TotalBeamSpills = 0; From 649055d92014545c73c99c1f436b585c1877397e Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:41:14 -0400 Subject: [PATCH 140/367] Update getFOM.cpp --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 84 +++++++++-------------- 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index f48be2963..a9885c71c 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -88,57 +88,39 @@ namespace sbn { if (vptg1.empty()) vptg1.push_back(-999); if (vp875.empty()) vp875.push_back(-999); double horang,horpos; - if(useHTG == 1){ - if (hptg1.size()>0 && hp875.size()>0) { - horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); - horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - } else if (hptg2.size()>0 && hp875.size()>0) { - horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); - horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - } else { - //missing horizontal BPM data - return 2; - } - } - else if(useHTG == 0){ - if (hptg2.size()>0 && hp875.size()>0) { - horang=((hptg2[0]-hptg2_offset)-(hp875[0]-hp875_offset))/(hptg2_zpos-hp875_zpos); - horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - } else if (hptg1.size()>0 && hp875.size()>0) { - horang=((hptg1[0]-hptg1_offset)-(hp875[0]-hp875_offset))/(hptg1_zpos-hp875_zpos); - horpos=(hp875[0]-hp875_offset)+horang*(target_center_zpos-hp875_zpos); - } else { - //missing horizontal BPM data - return 2; - } - } - else { return 2; } - double verang,verpos; - if(useVTG == 1){ - if (vptg1.size()>0 && vp875.size()>0) { - verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); - verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - } else if (vptg2.size()>0 && vp875.size()>0) { - verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); - verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - } else { - //missing vertical BPM data - return 3; - } - } - else if(useVTG == 0){ - if (vptg2.size()>0 && vp875.size()>0) { - verang=((vptg2[0]-vptg2_offset)-(vp875[0]-vp875_offset))/(vptg2_zpos-vp875_zpos); - verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - } else if (vptg1.size()>0 && vp875.size()>0) { - verang=((vptg1[0]-vptg1_offset)-(vp875[0]-vp875_offset))/(vptg1_zpos-vp875_zpos); - verpos=(vp875[0]-vp875_offset)+verang*(target_center_zpos-vp875_zpos); - } else { - //missing vertical BPM data - return 3; - } - } - else { return 3; } + + auto interpolate_hp875 = [delta_hp875=(hp875[0]-hp875_offset), hp875_zpos, target_center_zpos] + (double delta_value, double zpos) + { + double const ang = (delta_value-delta_hp875)/(zpos-hp875_zpos); + double const pos = delta_hp875+ang*(target_center_zpos-hp875_zpos); + return std::pair(ang, pos); + }; + + // return 2 when missing essential beam horizontal position data: + if (hp875.empty() || (hptg1.empty() && hptg2.empty())) return 2; + bool const doUseHTG1 = (useHTG == 1) || hptg2.empty(); + auto const [ horang, horpos ] = doUseHTG1? + interpolate_hp875(hptg1[0] - hptg1_offset, hptg1_zpos): + interpolate_hp875(hptg2[0] - hptg2_offset, hptg2_zpos); + + + double verang,verpos; + auto interpolate_vp875 = [delta_vp875=(vp875[0]-vp875_offset), vp875_zpos, target_center_zpos] + (double delta_value, double zpos) + { + double const ang = (delta_value-delta_vp875)/(zpos-vp875_zpos); + double const pos = delta_vp875+ang*(target_center_zpos-vp875_zpos); + return std::pair(ang, pos); + }; + + // return 2 when missing essential beam horizontal position data: + if (vp875.empty() || (vptg1.empty() && vptg2.empty())) return 3; + bool const doUseVTG1 = (useVTG == 1) || vptg2.empty(); + auto const [ verang, verpos ] = doUseVTG1? + interpolate_vp875(vptg1[0] - vptg1_offset, vptg1_zpos): + interpolate_vp875(vptg2[0] - vptg2_offset, vptg2_zpos); + horang=atan(horang); verang=atan(verang); double xx,yy,sx,sy,chi2x,chi2y; From 50fd8cf9d35afdaef06446010a3992d7ee2cb6c2 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:53:14 -0400 Subject: [PATCH 141/367] Update getFOM.cpp --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index a9885c71c..06e0f63c4 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -130,13 +130,14 @@ namespace sbn { bool good_875=false; constexpr size_t FirstXMWtgt =0; constexpr size_t FirstYMWtgt =48; + const double smallSigmaX =0.5, largeSigmaX = 10, smallSigmaY = 0.3, largeSigmaY =10, maxChi2X = 20, maxChi2Y = 20; if (mwtgt.size()>0) { processBNBprofile(&mwtgt[FirstXMWtgt], xx, sx,chi2x); processBNBprofile(&mwtgt[FirstYMWtgt], yy, sy, chi2y); - if (sx>0.5 && sx<10 && sy>0.3 && sy<10 && chi2x<20 && chi2y<20 && mwtgt.size()>0) { - tgtsx=sx; - tgtsy=sy; - good_tgt=true; + if (sx>smallSigmaX && sxsmallSigmaY && sy0) { @@ -144,10 +145,10 @@ namespace sbn { processBNBprofile(&mw876[FirstYMWtgt], yy,sy,chi2y); double tgtsx876=p876x[0]+p876x[1]*sx+p876x[2]*sx*sx; double tgtsy876=p876y[0]+p876y[1]*sy+p876y[2]*sy*sy; - if (tgtsx876>0.5 && tgtsx876<10 && tgtsy876>0.3 && tgtsy876<10 && chi2x<20 && chi2y<20) { - tgtsx=tgtsx876; - tgtsy=tgtsy876; - good_876=true; + if (tgtsx876>smallSigmaX && tgtsx876smallSigmaY && tgtsy8760){ @@ -155,10 +156,10 @@ namespace sbn { processBNBprofile(&mw875[FirstYMWtgt], yy,sy,chi2y); double tgtsx875=p875x[0]+p875x[1]*sx+p875x[2]*sx*sx; double tgtsy875=p875y[0]+p875y[1]*sy+p875y[2]*sy*sy; - if (tgtsx875>0.5 && tgtsx875<10 && tgtsy875>0.3 && tgtsy875<10 && chi2x<20 && chi2y<20) { - tgtsx=tgtsx875; - tgtsy=tgtsy875; - good_875=true; + if (tgtsx875>smallSigmaX && tgtsx875smallSigmaY && tgtsy875 Date: Mon, 11 Aug 2025 08:07:06 -0500 Subject: [PATCH 142/367] Skip shower-type PFPs --- sbncode/Calibration/TrackCaloSkimmer_module.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 1baff7ea6..f6be5ae6f 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -315,6 +315,9 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) for (art::Ptr p_pfp: PFParticleList) { const recob::PFParticle &pfp = *p_pfp; + if(p_pfp->PdgCode() == 11) + continue; + const std::vector> thisTrack = fmTracks.at(p_pfp.key()); if (thisTrack.size() != 1) continue; From c8c130bb177b7586c704bb25631abb9743a9b0c9 Mon Sep 17 00:00:00 2001 From: NathanielERowe Date: Mon, 11 Aug 2025 09:05:17 -0500 Subject: [PATCH 143/367] Missing obj loading for new obj --- sbncode/BeamSpillInfoRetriever/POTTools.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index fabd45662..d9b4948ca 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -134,6 +134,8 @@ namespace sbn::pot{ beamInfo.LM875A = LM875A; beamInfo.LM875B = LM875B; beamInfo.LM875C = LM875C; + beamInfo.HP873 = HP873; + beamInfo.VP873 = VP873; beamInfo.HP875 = HP875; beamInfo.VP875 = VP875; beamInfo.HPTG1 = HPTG1; @@ -142,9 +144,17 @@ namespace sbn::pot{ beamInfo.VPTG2 = VPTG2; beamInfo.BTJT2 = BTJT2; beamInfo.THCURR = THCURR; + beamInfo.M875HS = M875HS; + beamInfo.M875VS = M875VS; + beamInfo.M875HM = M875HM; + beamInfo.M875VM = M875VM; + beamInfo.M876HS = M876HS; + beamInfo.M876VS = M876VS; + beamInfo.M876HM = M876HM; + beamInfo.M876VM = M876VM; beamInfo.spill_time_s = time_closest_int; beamInfo.spill_time_ns = time_closest_ns; - + for(auto const& MWRdata: unpacked_MWR){ std::ignore = MWRdata; assert(!MWRdata.empty()); From f04aa0a1d7b770019964cf6f0e67f5b7c08b6622 Mon Sep 17 00:00:00 2001 From: kjplows Date: Mon, 11 Aug 2025 11:41:07 -0500 Subject: [PATCH 144/367] Updated dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d2f8b3ef..67af6b4fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.06.00.04 LANGUAGES CXX) +project(sbncode VERSION 10.09.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 4d5dd8cb9..07b483f3f 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -252,10 +252,10 @@ libdir fq_dir lib # #################################### product version qual flags -genie_xsec v3_04_00 - +genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_06_00_02 - -sbnalg v10_06_00_03 - +larsoft v10_09_00 - +sbnalg v10_09_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From 7ed606a8b108c5151991b8279f5db052b487484b Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 11 Aug 2025 18:32:09 -0500 Subject: [PATCH 145/367] Testing Changes --- sbncode/BeamSpillInfoRetriever/CMakeLists.txt | 9 +++---- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 27 ++++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt index cd7b625d1..1ba5595c9 100644 --- a/sbncode/BeamSpillInfoRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/CMakeLists.txt @@ -34,12 +34,11 @@ art_make_library( art_make_library( LIBRARIES - art::Persistency_Common - art::Utilities + ROOT::Hist - ROOT::Spectrum - ROOT::MathCore - ROOT::Tree + ROOT::MathCore + sbnobj::Common_POTAccounting + LIBRARY_NAME sbn_getFOM SOURCE getFOM.cpp diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index 06e0f63c4..3e32c3e9c 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -3,9 +3,10 @@ * @brief Figure of Merit for BNB Spills using SBND information adapted from MicroBooNE FOM * @author Max Dubnowski (maxdub@sas.upenn.edu or `@Max Dubnowski` on SBN Slack) */ +#include "sbncode/BeamSpillInfoRetriever/getFOM.h" #include #include "TH1D.h" -#include "TFitResultPtr.h" +#include "TFitResult.h" #include @@ -87,7 +88,7 @@ namespace sbn { if (vptg2.empty()) vptg2.push_back(-999); if (vptg1.empty()) vptg1.push_back(-999); if (vp875.empty()) vp875.push_back(-999); - double horang,horpos; + //double horang,horpos; auto interpolate_hp875 = [delta_hp875=(hp875[0]-hp875_offset), hp875_zpos, target_center_zpos] (double delta_value, double zpos) @@ -105,7 +106,7 @@ namespace sbn { interpolate_hp875(hptg2[0] - hptg2_offset, hptg2_zpos); - double verang,verpos; + //double verang,verpos; auto interpolate_vp875 = [delta_vp875=(vp875[0]-vp875_offset), vp875_zpos, target_center_zpos] (double delta_value, double zpos) { @@ -188,24 +189,24 @@ namespace sbn { void processBNBprofile(const double* mwdata, double &x, double& sx, double& chi2) { // values' sign is inverted - double minx = std::min(-*std::max_element(mwdata, mwdata + 48), 0); - double maxx = std::max(-*std::min_element(mwdata, mwdata + 48), 0); - - TH1D hProf("hProfMW","",48,-12.0,12.0); // coverage is 24 cm - double const threshold = (maxx-minx)*0.2; // 20% of the range - double const error = (maxx-minx)*0.02; // 2% of the range - for (unsigned int i=0;i<48;i++) { + double minx = std::min(-*std::max_element(mwdata, mwdata + 48), 0.0); + double maxx = std::max(-*std::min_element(mwdata, mwdata + 48), 0.0); + int first_x = -1; int last_x = -1; + TH1D* hProf("hProfMW","",48,-12.0,12.0); // coverage is 24 cm + double const threshold = (maxx-minx)*0.2; // 20% of the range + double const error = (maxx-minx)*0.02; // 2% of the range + for (unsigned int i=0;i<48;i++) { hProf->SetBinContent(i+1,-mwdata[i]-minx); - if (-mwdata[i]-minx > threshold && first_x==-1) first_x=i; + if (-mwdata[i]-minx > threshold && first_x==-1) first_x=i; if (-mwdata[i]-minx > threshold) last_x=i+1; hProf->SetBinError(i+1,error); } if (hProf->GetSumOfWeights()>0) { - TFitResultPtr const fit = hProf.Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); + TFitResult const fit = hProf.Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); x = fit->Parameter(1); sx = fit->Parameter(2); chi2= fit->Chi2() / fit->Ndf(); - + } else { x=99999; sx=99999; From 865dea7d36e4f3dfe768f065cda467459bbab6df Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 11 Aug 2025 19:23:30 -0500 Subject: [PATCH 146/367] Fixed errors --- .../SBNDBNBRetriever_module.cc | 2 +- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 18 ++++++++++-------- .../Calculators/BNBFlux/FluxCalcPrep.cxx | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 9c516c159..d4fa877b5 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -61,7 +61,7 @@ sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) fTimePad = params.get("TimePadding"); fBESOffset = params.get("BESOffset"); fDeviceUsedForTiming = params.get("DeviceUsedForTiming"); - double const timeWindow = std::stod(params.get("TimeWindow")) + double const timeWindow = std::stod(params.get("TimeWindow")); bfp = ifbeam_handle->getBeamFolder(params.get("Bundle"), params.get("URL"), timeWindow); bfp->set_epsilon(0.02); bfp_mwr = ifbeam_handle->getBeamFolder(params.get("MultiWireBundle"), params.get("URL"), std::stod(params.get("MWR_TimeWindow"))); diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index 3e32c3e9c..ca75c87ca 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -88,7 +88,7 @@ namespace sbn { if (vptg2.empty()) vptg2.push_back(-999); if (vptg1.empty()) vptg1.push_back(-999); if (vp875.empty()) vp875.push_back(-999); - //double horang,horpos; + double horang; auto interpolate_hp875 = [delta_hp875=(hp875[0]-hp875_offset), hp875_zpos, target_center_zpos] (double delta_value, double zpos) @@ -101,12 +101,12 @@ namespace sbn { // return 2 when missing essential beam horizontal position data: if (hp875.empty() || (hptg1.empty() && hptg2.empty())) return 2; bool const doUseHTG1 = (useHTG == 1) || hptg2.empty(); - auto const [ horang, horpos ] = doUseHTG1? + auto const [ Tanhorang, horpos ] = doUseHTG1? interpolate_hp875(hptg1[0] - hptg1_offset, hptg1_zpos): interpolate_hp875(hptg2[0] - hptg2_offset, hptg2_zpos); - //double verang,verpos; + double verang; auto interpolate_vp875 = [delta_vp875=(vp875[0]-vp875_offset), vp875_zpos, target_center_zpos] (double delta_value, double zpos) { @@ -118,12 +118,12 @@ namespace sbn { // return 2 when missing essential beam horizontal position data: if (vp875.empty() || (vptg1.empty() && vptg2.empty())) return 3; bool const doUseVTG1 = (useVTG == 1) || vptg2.empty(); - auto const [ verang, verpos ] = doUseVTG1? + auto const [ Tanverang, verpos ] = doUseVTG1? interpolate_vp875(vptg1[0] - vptg1_offset, vptg1_zpos): interpolate_vp875(vptg2[0] - vptg2_offset, vptg2_zpos); - horang=atan(horang); - verang=atan(verang); + horang=atan(Tanhorang); + verang=atan(Tanverang); double xx,yy,sx,sy,chi2x,chi2y; double tgtsx, tgtsy; bool good_tgt=false; @@ -192,7 +192,8 @@ namespace sbn { double minx = std::min(-*std::max_element(mwdata, mwdata + 48), 0.0); double maxx = std::max(-*std::min_element(mwdata, mwdata + 48), 0.0); int first_x = -1; int last_x = -1; - TH1D* hProf("hProfMW","",48,-12.0,12.0); // coverage is 24 cm + static int entry = 1; + TH1D* hProf = new TH1D("hProfMW","",48,-12.0,12.0); // coverage is 24 cm double const threshold = (maxx-minx)*0.2; // 20% of the range double const error = (maxx-minx)*0.02; // 2% of the range for (unsigned int i=0;i<48;i++) { @@ -202,7 +203,8 @@ namespace sbn { hProf->SetBinError(i+1,error); } if (hProf->GetSumOfWeights()>0) { - TFitResult const fit = hProf.Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); + TFitResultPtr fitPtr = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); + TFitResult* fit = fitPtr.Get(); x = fit->Parameter(1); sx = fit->Parameter(2); chi2= fit->Chi2() / fit->Ndf(); diff --git a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx index 640a84769..11d693a89 100644 --- a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx +++ b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx @@ -261,7 +261,7 @@ namespace sbn { //Let's make a weights based on the calculator you have requested - if(fParameterSet.fRWType == EventWeightParameterSet::kMultisim){ + if(fParameterSet.fRWType == EventWeightParameterSet::kMultiSim){ for (size_t i=0;isecond[i]; @@ -293,7 +293,7 @@ namespace sbn { return weights;//done, all 1 }// Hadronic parent check - if(fParameterSet.fRWType == EventWeightParameterSet::kMultisim){ + if(fParameterSet.fRWType == EventWeightParameterSet::kMultiSim){ for (unsigned int i = 0; int(weights.size()) < NUni; i++) {//if all weights are 1, no need to calculate weights; std::pair test_weight; From 01bac925e0829150fc6b5948866cfcced90f5a0d Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Tue, 12 Aug 2025 03:43:10 -0500 Subject: [PATCH 147/367] Replace throughgoing selection and add exiting selection as previous --- sbncode/Calibration/CMakeLists.txt | 5 ++ ...CaloSkimmerSelectThroughgoingTrack_tool.cc | 79 +++++++++++++++++++ .../fcl/sbnd/sbnd_trackcalo_skimmer.fcl | 19 ++++- 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index 98059edc5..56b3828a3 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -70,6 +70,11 @@ cet_build_plugin(TrackCaloSkimmerSelectAllTrack art::tool ROOT::X3d ) +cet_build_plugin(TrackCaloSkimmerSelectThroughgoingTrack art::tool + LIBRARIES + larcore::Geometry_Geometry_service +) + cet_build_plugin ( DataSelect art::module LIBRARIES ifdh_art::IFDH_service diff --git a/sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc b/sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc new file mode 100644 index 000000000..87bf6d52b --- /dev/null +++ b/sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc @@ -0,0 +1,79 @@ +#include "art/Utilities/ToolMacros.h" +#include "fhiclcpp/ParameterSet.h" + +#include "larcore/Geometry/Geometry.h" +#include "larcore/CoreUtils/ServiceUtil.h" +#include "larcorealg/Geometry/GeometryCore.h" + +#include "ITCSSelectionTool.h" + +namespace sbn { + + class TrackCaloSkimmerSelectThroughgoingTrack: public ITCSSelectionTool { + public: + + TrackCaloSkimmerSelectThroughgoingTrack(const fhicl::ParameterSet &p); + ~TrackCaloSkimmerSelectThroughgoingTrack() {} + + bool Select(const TrackInfo &t) override; + + private: + double fFVInsetMinX; + double fFVInsetMaxX; + double fFVInsetMinY; + double fFVInsetMaxY; + double fFVInsetMinZ; + double fFVInsetMaxZ; + bool fCheckFiducialX; + + std::vector fTPCVolumes; + geo::BoxBoundedGeo fActiveVolume, fFiducialVolume; + }; + + TrackCaloSkimmerSelectThroughgoingTrack::TrackCaloSkimmerSelectThroughgoingTrack(const fhicl::ParameterSet &p): + ITCSSelectionTool(p), + fFVInsetMinX(p.get("FVInsetMinX")), + fFVInsetMaxX(p.get("FVInsetMaxX")), + fFVInsetMinY(p.get("FVInsetMinY")), + fFVInsetMaxY(p.get("FVInsetMaxY")), + fFVInsetMinZ(p.get("FVInsetMinZ")), + fFVInsetMaxZ(p.get("FVInsetMaxZ")), + fCheckFiducialX(p.get("CheckFiducialX")) + { + const geo::GeometryCore *geometry = lar::providerFrom(); + + for(auto const &cryoid: geometry->Iterate()) + { + for(auto const& TPC : geometry->Iterate(cryoid)) + fTPCVolumes.push_back(TPC.ActiveBoundingBox()); + } + + double XMin = std::min_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MinX() < rhs.MinX(); })->MinX(); + double YMin = std::min_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MinY() < rhs.MinY(); })->MinY(); + double ZMin = std::min_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MinZ() < rhs.MinZ(); })->MinZ(); + + double XMax = std::max_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MaxX() < rhs.MaxX(); })->MaxX(); + double YMax = std::max_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MaxY() < rhs.MaxY(); })->MaxY(); + double ZMax = std::max_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MaxZ() < rhs.MaxZ(); })->MaxZ(); + + fActiveVolume = geo::BoxBoundedGeo(XMin, XMax, YMin, YMax, ZMin, ZMax); + + fFiducialVolume = geo::BoxBoundedGeo(fActiveVolume.MinX() + fFVInsetMinX, fActiveVolume.MaxX() - fFVInsetMaxX, + fActiveVolume.MinY() + fFVInsetMinY, fActiveVolume.MaxY() - fFVInsetMaxY, + fActiveVolume.MinZ() + fFVInsetMinZ, fActiveVolume.MaxZ() - fFVInsetMaxZ); + } + + bool TrackCaloSkimmerSelectThroughgoingTrack::Select(const TrackInfo &t) + { + geo::Point_t start {t.start.x, t.start.y, t.start.z}; + bool start_is_non_fid = fCheckFiducialX ? !fFiducialVolume.ContainsPosition(start) : !fFiducialVolume.ContainsYZ(start.Y(), start.Z()); + + geo::Point_t end {t.end.x, t.end.y, t.end.z}; + bool end_is_non_fid = fCheckFiducialX ? !fFiducialVolume.ContainsPosition(end) : !fFiducialVolume.ContainsYZ(end.Y(), end.Z()); + + return start_is_non_fid && end_is_non_fid; + } + + DEFINE_ART_CLASS_TOOL(TrackCaloSkimmerSelectThroughgoingTrack) + +} diff --git a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl index 8735ed405..03ea2ac2d 100644 --- a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl @@ -56,10 +56,10 @@ stopping_selection: { EndMediandQdxCut: 1600 NumberTimeSamples: 3400 MediandQdxRRMax: 5. - CheckFiducialX: false + CheckFiducialX: true } -throughgoing_selection: { +exiting_selection: { tool_type: TrackCaloSkimmerSelectStoppingTrack Invert: true PreScale: 1 @@ -74,7 +74,7 @@ throughgoing_selection: { EndMediandQdxCut: -1 RequireDownwards: false NumberTimeSamples: 3400 - CheckFiducialX: false + CheckFiducialX: true } a2c_selection: { @@ -82,7 +82,18 @@ a2c_selection: { TickCut: 2500 } +throughgoing_selection: { + tool_type: TrackCaloSkimmerSelectThroughgoingTrack + FVInsetMinX: 5 + FVInsetMaxX: 5 + FVInsetMinY: 5 + FVInsetMaxY: 5 + FVInsetMinZ: 5 + FVInsetMaxZ: 5 + CheckFiducialX: true +} + caloskim_nodigits_goldentracks: @local::caloskim_nodigits -caloskim_nodigits_goldentracks.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection] +caloskim_nodigits_goldentracks.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection, @local::exiting_selection] END_PROLOG From 5acaf5e6f7d97ffa56ae028734d407353f4ea0d4 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Tue, 12 Aug 2025 08:36:05 -0500 Subject: [PATCH 148/367] Add event displays for questionable cases --- sbncode/Calibration/CMakeLists.txt | 1 + sbncode/Calibration/TrackCaloSkimmer.h | 4 ++++ .../Calibration/TrackCaloSkimmer_module.cc | 23 ++++++++++++++++++- .../fcl/sbnd/sbnd_trackcalo_skimmer.fcl | 9 +++++--- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index 56b3828a3..a7a02d450 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -25,6 +25,7 @@ cet_build_plugin( TrackCaloSkimmer art::module sbncode_CAFMaker sbnobj::Common_Calibration_dict larevt::SpaceCharge + sbndcode::CRT_CRTEventDisplay ) cet_build_plugin(TrackCaloSkimmerSelectStoppingTrack art::tool diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index c69d8589d..f55bf8390 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -66,6 +66,8 @@ #include "sbnobj/SBND/CRT/CRTTrack.hh" #include "sbnobj/SBND/CRT/CRTSpacePoint.hh" +#include "sbndcode/CRT/CRTEventDisplay/CRTEventDisplayAlg.h" + #include "ITCSSelectionTool.h" namespace sbn { @@ -240,5 +242,7 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { // Fitting info TFitter fFitExp; TFitter fFitConst; + + sbnd::crt::CRTEventDisplayAlg fCRTEventDisplayAlg; }; #endif diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index f6be5ae6f..68635ff3d 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -64,6 +64,7 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) : EDAnalyzer{p}, fFitExp(2), fFitConst(1) + , fCRTEventDisplayAlg(p.get("CRTEventDisplayAlg")) { // Grab config fPFPproducer = p.get< art::InputTag > ("PFPproducer","pandoraGausCryo0"); @@ -260,6 +261,7 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) // The raw digit list is not sorted, so make it into a map on the WireID std::map> rawdigits; + /* for (const art::Ptr &d: rawdigitlist) { std::vector wids; @@ -279,7 +281,7 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) rawdigits[wids[0]] = d; } - + */ // Collect all hits art::ValidHandle> allhit_handle = e.getValidHandle>(fHITproducer); std::vector> allHits; @@ -296,10 +298,12 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) const cheat::BackTrackerService *bt = NULL; if (simchannels.size()) { + /* art::ServiceHandle bt_serv; id_to_ide_map = caf::PrepSimChannels(simchannels, *wireReadout); id_to_truehit_map = caf::PrepTrueHits(allHits, clock_data, *bt_serv.get()); bt = bt_serv.get(); + */ } // service data @@ -408,6 +412,23 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0 || hasCRTSpacePointT0; + if(hasPFPT0) + { + fCRTEventDisplayAlg.SetPrint(true); + fCRTEventDisplayAlg.SetMinTime(t0PFP - 3e3); + fCRTEventDisplayAlg.SetMaxTime(t0PFP + 3e3); + + auto const clockData = art::ServiceHandle()->DataFor(e); + + if(hasCRTTrackT0) + { + std::cout << t0CRTTrack << std::endl; + fCRTEventDisplayAlg.Draw(clockData, e, Form("/exp/sbnd/data/users/hlay/crt_fall_production_2025/t0_event_displays/good/crtEventDisplayRun%iSubrun%iEvent%iPFP%li", e.run(), e.subRun(), e.event(), p_pfp.key())); + } + else + fCRTEventDisplayAlg.Draw(clockData, e, Form("/exp/sbnd/data/users/hlay/crt_fall_production_2025/t0_event_displays/bad/crtEventDisplayRun%iSubrun%iEvent%iPFP%li", e.run(), e.subRun(), e.event(), p_pfp.key())); + } + continue; // "whicht0" should reflect the T0 used for the reconstruction of the drift coordinate. if(!hasT0) whicht0 = -1; // In this way, if a track is T0 tagged from PFP and CRT tagged, which T0 reflects the PFP Tag. diff --git a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl index 03ea2ac2d..4a333d379 100644 --- a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl @@ -1,3 +1,5 @@ +#include "crteventdisplayalg_sbnd.fcl" + BEGIN_PROLOG caloskim_calorimetry: { @@ -56,7 +58,7 @@ stopping_selection: { EndMediandQdxCut: 1600 NumberTimeSamples: 3400 MediandQdxRRMax: 5. - CheckFiducialX: true + CheckFiducialX: false } exiting_selection: { @@ -74,7 +76,7 @@ exiting_selection: { EndMediandQdxCut: -1 RequireDownwards: false NumberTimeSamples: 3400 - CheckFiducialX: true + CheckFiducialX: false } a2c_selection: { @@ -90,10 +92,11 @@ throughgoing_selection: { FVInsetMaxY: 5 FVInsetMinZ: 5 FVInsetMaxZ: 5 - CheckFiducialX: true + CheckFiducialX: false } caloskim_nodigits_goldentracks: @local::caloskim_nodigits caloskim_nodigits_goldentracks.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection, @local::exiting_selection] +caloskim_nodigits_goldentracks.CRTEventDisplayAlg: @local::crteventdisplayalg_sbnd_temp END_PROLOG From 4b529c4fbd5ee65880c1646ee6c8bdbc485f9953 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Tue, 12 Aug 2025 08:46:59 -0500 Subject: [PATCH 149/367] Revert "Add event displays for questionable cases" This reverts commit 5acaf5e6f7d97ffa56ae028734d407353f4ea0d4. --- sbncode/Calibration/CMakeLists.txt | 1 - sbncode/Calibration/TrackCaloSkimmer.h | 4 ---- .../Calibration/TrackCaloSkimmer_module.cc | 23 +------------------ .../fcl/sbnd/sbnd_trackcalo_skimmer.fcl | 9 +++----- 4 files changed, 4 insertions(+), 33 deletions(-) diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index a7a02d450..56b3828a3 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -25,7 +25,6 @@ cet_build_plugin( TrackCaloSkimmer art::module sbncode_CAFMaker sbnobj::Common_Calibration_dict larevt::SpaceCharge - sbndcode::CRT_CRTEventDisplay ) cet_build_plugin(TrackCaloSkimmerSelectStoppingTrack art::tool diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index f55bf8390..c69d8589d 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -66,8 +66,6 @@ #include "sbnobj/SBND/CRT/CRTTrack.hh" #include "sbnobj/SBND/CRT/CRTSpacePoint.hh" -#include "sbndcode/CRT/CRTEventDisplay/CRTEventDisplayAlg.h" - #include "ITCSSelectionTool.h" namespace sbn { @@ -242,7 +240,5 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { // Fitting info TFitter fFitExp; TFitter fFitConst; - - sbnd::crt::CRTEventDisplayAlg fCRTEventDisplayAlg; }; #endif diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 68635ff3d..f6be5ae6f 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -64,7 +64,6 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) : EDAnalyzer{p}, fFitExp(2), fFitConst(1) - , fCRTEventDisplayAlg(p.get("CRTEventDisplayAlg")) { // Grab config fPFPproducer = p.get< art::InputTag > ("PFPproducer","pandoraGausCryo0"); @@ -261,7 +260,6 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) // The raw digit list is not sorted, so make it into a map on the WireID std::map> rawdigits; - /* for (const art::Ptr &d: rawdigitlist) { std::vector wids; @@ -281,7 +279,7 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) rawdigits[wids[0]] = d; } - */ + // Collect all hits art::ValidHandle> allhit_handle = e.getValidHandle>(fHITproducer); std::vector> allHits; @@ -298,12 +296,10 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) const cheat::BackTrackerService *bt = NULL; if (simchannels.size()) { - /* art::ServiceHandle bt_serv; id_to_ide_map = caf::PrepSimChannels(simchannels, *wireReadout); id_to_truehit_map = caf::PrepTrueHits(allHits, clock_data, *bt_serv.get()); bt = bt_serv.get(); - */ } // service data @@ -412,23 +408,6 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) hasT0 = hasPFPT0 || hasCRTTrackT0 || hasCRTHitT0 || hasCRTSpacePointT0; - if(hasPFPT0) - { - fCRTEventDisplayAlg.SetPrint(true); - fCRTEventDisplayAlg.SetMinTime(t0PFP - 3e3); - fCRTEventDisplayAlg.SetMaxTime(t0PFP + 3e3); - - auto const clockData = art::ServiceHandle()->DataFor(e); - - if(hasCRTTrackT0) - { - std::cout << t0CRTTrack << std::endl; - fCRTEventDisplayAlg.Draw(clockData, e, Form("/exp/sbnd/data/users/hlay/crt_fall_production_2025/t0_event_displays/good/crtEventDisplayRun%iSubrun%iEvent%iPFP%li", e.run(), e.subRun(), e.event(), p_pfp.key())); - } - else - fCRTEventDisplayAlg.Draw(clockData, e, Form("/exp/sbnd/data/users/hlay/crt_fall_production_2025/t0_event_displays/bad/crtEventDisplayRun%iSubrun%iEvent%iPFP%li", e.run(), e.subRun(), e.event(), p_pfp.key())); - } - continue; // "whicht0" should reflect the T0 used for the reconstruction of the drift coordinate. if(!hasT0) whicht0 = -1; // In this way, if a track is T0 tagged from PFP and CRT tagged, which T0 reflects the PFP Tag. diff --git a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl index 4a333d379..03ea2ac2d 100644 --- a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl @@ -1,5 +1,3 @@ -#include "crteventdisplayalg_sbnd.fcl" - BEGIN_PROLOG caloskim_calorimetry: { @@ -58,7 +56,7 @@ stopping_selection: { EndMediandQdxCut: 1600 NumberTimeSamples: 3400 MediandQdxRRMax: 5. - CheckFiducialX: false + CheckFiducialX: true } exiting_selection: { @@ -76,7 +74,7 @@ exiting_selection: { EndMediandQdxCut: -1 RequireDownwards: false NumberTimeSamples: 3400 - CheckFiducialX: false + CheckFiducialX: true } a2c_selection: { @@ -92,11 +90,10 @@ throughgoing_selection: { FVInsetMaxY: 5 FVInsetMinZ: 5 FVInsetMaxZ: 5 - CheckFiducialX: false + CheckFiducialX: true } caloskim_nodigits_goldentracks: @local::caloskim_nodigits caloskim_nodigits_goldentracks.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection, @local::exiting_selection] -caloskim_nodigits_goldentracks.CRTEventDisplayAlg: @local::crteventdisplayalg_sbnd_temp END_PROLOG From 76269d8f44ef37931b28693a50110c10dbff3815 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 12 Aug 2025 10:10:57 -0500 Subject: [PATCH 150/367] UPS Fix --- ups/product_deps | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ups/product_deps b/ups/product_deps index e479198df..07b483f3f 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -252,10 +252,10 @@ libdir fq_dir lib # #################################### product version qual flags -genie_xsec v3_04_00 - +genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_06_00 - -sbnalg v10_06_00_01 - +larsoft v10_09_00 - +sbnalg v10_09_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From cae8a6ede1686de94fa7b6c2c232f0db9003518a Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 12 Aug 2025 12:13:02 -0500 Subject: [PATCH 151/367] Working version --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 37 +++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index ca75c87ca..bd04eeff9 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -6,7 +6,9 @@ #include "sbncode/BeamSpillInfoRetriever/getFOM.h" #include #include "TH1D.h" +#include "TF1.h" #include "TFitResult.h" +#include #include @@ -77,11 +79,13 @@ namespace sbn { else return -1; - - //when creating ntuples for pot counting script the variables are filled with -999 - //this could create a difference when passing events with FOM>1 since - //events with missing BPM data would get FOM=2, while events with BPM set to -999 will get FOM=0 - //bad or missing MWR data gets FOM 4 in either case + /** + * @brief when creating ntuples for pot counting script the variables are filled with -999 + * this could create a difference when passing events with FOM>1 since + * events with missing BPM data would get FOM=2, while events with BPM set to -999 will get FOM=0 + * bad or missing MWR data gets FOM 4 in either case + */ + if (hptg2.empty()) hptg2.push_back(-999); if (hptg1.empty()) hptg1.push_back(-999); if (hp875.empty()) hp875.push_back(-999); @@ -169,6 +173,7 @@ namespace sbn { } fom=1-pow(10,sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy)); + std::cout << fom << std::endl; return fom; } @@ -203,12 +208,24 @@ namespace sbn { hProf->SetBinError(i+1,error); } if (hProf->GetSumOfWeights()>0) { - TFitResultPtr fitPtr = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); - TFitResult* fit = fitPtr.Get(); - x = fit->Parameter(1); - sx = fit->Parameter(2); - chi2= fit->Chi2() / fit->Ndf(); + hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); + x =hProf->GetFunction("gaus")->GetParameter(1); + sx =hProf->GetFunction("gaus")->GetParameter(2); + + chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); + + // TFitResult* const fit = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); + // x = fit->Parameter(1); + // sx = fit->Parameter(2); + // chi2= fit->Chi2() / fit->Ndf(); + //TFitResult * fitPtr = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); + //std::cout << "Fit Result " << fitPtr.fStatus << std::endl; + // TFitResult* fit = fitPtr.Get(); + //x = fitPtr->Parameter(1); + //sx = fitPtr->Parameter(2); + //chi2= fitPtr->Chi2() / fitPtr->Ndf(); + delete hProf; } else { x=99999; sx=99999; From c786fdc9e07d39741922c55c864ad75164b9c492 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Tue, 12 Aug 2025 13:26:17 -0400 Subject: [PATCH 152/367] Update getFOM.cpp --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index bd04eeff9..d5be6b649 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -211,21 +211,8 @@ namespace sbn { hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); x =hProf->GetFunction("gaus")->GetParameter(1); sx =hProf->GetFunction("gaus")->GetParameter(2); - chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); - - // TFitResult* const fit = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); - // x = fit->Parameter(1); - // sx = fit->Parameter(2); - // chi2= fit->Chi2() / fit->Ndf(); - - //TFitResult * fitPtr = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); - //std::cout << "Fit Result " << fitPtr.fStatus << std::endl; - // TFitResult* fit = fitPtr.Get(); - //x = fitPtr->Parameter(1); - //sx = fitPtr->Parameter(2); - //chi2= fitPtr->Chi2() / fitPtr->Ndf(); - delete hProf; + delete hProf; } else { x=99999; sx=99999; From 8ab771ba54228e16c605d5bde607065d08c73ead Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 12 Aug 2025 15:00:29 -0500 Subject: [PATCH 153/367] Working Fit Pointer --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 30 ++++++----------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index bd04eeff9..a8642fad0 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -5,10 +5,8 @@ */ #include "sbncode/BeamSpillInfoRetriever/getFOM.h" #include -#include "TH1D.h" -#include "TF1.h" +#include "TH1D.H" #include "TFitResult.h" -#include #include @@ -173,7 +171,6 @@ namespace sbn { } fom=1-pow(10,sbn::calcFOM(horpos,horang,verpos,verang,tor,tgtsx,tgtsy)); - std::cout << fom << std::endl; return fom; } @@ -207,25 +204,12 @@ namespace sbn { if (-mwdata[i]-minx > threshold) last_x=i+1; hProf->SetBinError(i+1,error); } - if (hProf->GetSumOfWeights()>0) { - hProf->Fit("gaus","Q0","",-12+first_x*0.5,-12+last_x*0.5); - x =hProf->GetFunction("gaus")->GetParameter(1); - sx =hProf->GetFunction("gaus")->GetParameter(2); - - chi2=hProf->GetFunction("gaus")->GetChisquare()/hProf->GetFunction("gaus")->GetNDF(); - - // TFitResult* const fit = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); - // x = fit->Parameter(1); - // sx = fit->Parameter(2); - // chi2= fit->Chi2() / fit->Ndf(); - - //TFitResult * fitPtr = hProf->Fit("gaus","QN","",-12+first_x*0.5,-12+last_x*0.5); - //std::cout << "Fit Result " << fitPtr.fStatus << std::endl; - // TFitResult* fit = fitPtr.Get(); - //x = fitPtr->Parameter(1); - //sx = fitPtr->Parameter(2); - //chi2= fitPtr->Chi2() / fitPtr->Ndf(); - delete hProf; + if (hProf->GetSumOfWeights()>0) { + TFitResultPtr const fit = hProf->Fit("gaus","QNS","",-12+first_x*0.5,-12+last_x*0.5); + x = fit->Parameter(1); + sx = fit->Parameter(2); + chi2= fit->Chi2() / fit->Ndf(); + delete hProf; } else { x=99999; sx=99999; From f8687208a3025120eba677efa5f8a79d68324ad4 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 12 Aug 2025 20:06:49 -0500 Subject: [PATCH 154/367] first commit --- sbncode/CAFMaker/CAFMakerParams.h | 12 ++++++++++++ sbncode/CAFMaker/CAFMaker_module.cc | 25 +++++++++++++++++++++++++ sbncode/CAFMaker/FillReco.cxx | 25 +++++++++++++++++++++++++ sbncode/CAFMaker/FillReco.h | 9 +++++++++ 4 files changed, 71 insertions(+) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 253f0d4c2..2f44fea03 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -338,6 +338,18 @@ namespace caf "crttracks" // sbnd }; + Atom SBNDFrameShiftInfoLabel { + Name("SBNDFrameShiftInfoLabel"), + Comment("Label of sbnd frame shift."), + "reco1" // sbnd + }; + + Atom SBNDTimingInfoLabel { + Name("SBNDTimingInfoLabel"), + Comment("Label of sbnd timing shift."), + "reco1" // sbnd + }; + Atom CRTPMTLabel { Name("CRTPMTLabel"), Comment("Label for the CRTPMT Matched variables from the crtpmt data product"), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 48da84e8f..cb99173a9 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1603,6 +1603,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector srcrttracks; std::vector srcrtspacepoints; std::vector srsbndcrttracks; + std::vector srsbndframeshiftinfo; + std::vector srsbndtiminginfo; if(fDet == kICARUS) { @@ -1651,6 +1653,29 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillSBNDCRTTrack(sbndcrttracks[i], srsbndcrttracks.back()); } } + + art::Handle> sbndframeshiftinfo_handle; + GetByLabelStrict(evt, fParams.SBNDFrameShiftInfoLabel(), sbndframeshiftinfo_handle); + // fill into event + if (sbndframeshiftinfo_handle.isValid()) { + const std::vector &sbndframeshiftinfo = *sbndframeshiftinfo_handle; + for (unsigned i = 0; i < sbndframeshiftinfo.size(); i++) { + srsbndframeshiftinfo.emplace_back(); + FillSBNDFrameShiftInfo(sbndframeshiftinfo[i], srsbndframeshiftinfo.back()); + } + } + + art::Handle> sbndtiminginfo_handle; + GetByLabelStrict(evt, fParams.SBNDTimingInfoLabel(), sbndtiminginfo_handle); + // fill into event + if (sbndtiminginfo_handle.isValid()) { + const std::vector &sbndtiminginfo = *sbndtiminginfo_handle; + for (unsigned i = 0; i < sbndtiminginfo.size(); i++) { + srsbndtiminginfo.emplace_back(); + FillSBNDTimingInfo(sbndtiminginfo[i], srsbndtiminginfo.back()); + } + } + } // Get all of the CRTPMT Matches diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d81cb5890..89b6e378e 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -141,6 +141,31 @@ namespace caf srsbndcrttrack.tof = track.ToF(); } + void FillSBNDFrameShiftInfo(const raw::FrameShiftInfo &frame, + caf::SRSBNDFrameShiftInfo &srsbndframe, + bool allowEmpty) + { + srsbndframe.frameTdcCrtt1 = frame.frameTdcCrtt1; + srsbndframe.frameTdcBes = frame.frameTdcBes; + srsbndframe.frameTdcRwm = frame.frameTdcRwm; + srsbndframe.frameHltCrtt1 = frame.frameHltCrtt1; + srsbndframe.frameHltBeamGate = frame.frameHltBeamGate; + srsbndframe.frameDataToMC = frame.frameDataToMC; + } + + void FillSBNDTimingInfo(const raw::TimingInfo &timing, + caf::SRSBNDTimingInfo &srsbndtiming, + bool allowEmpty) + { + srsbndtiming.tdcCrtt1 = timing.tdcCrtt1; + srsbndtiming.tdcBes = timing.tdcBes; + srsbndtiming.tdcRwm = timing.tdcRwm; + srsbndtiming.tdcEtrig = timing.tdcEtrig; + srsbndtiming.hltCrtt1 = timing.hltCrtt1; + srsbndtiming.hltEtrig = timing.hltEtrig; + srsbndtiming.hltBeamGate = timing.hltBeamGate; + } + void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, caf::SRCRTPMTMatch &srmatch, bool allowEmpty){ diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 6e8ecf292..a301faba5 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -44,6 +44,7 @@ #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" #include "nusimdata/SimulationBase/MCParticle.h" #include "nusimdata/SimulationBase/MCTruth.h" +#include "sbndcode/Timing/SBNDRawTimingObj.h" #include "sbnanaobj/StandardRecord/SRSlice.h" #include "sbnanaobj/StandardRecord/StandardRecord.h" @@ -279,6 +280,14 @@ namespace caf caf::SRPFP& srpfp, bool allowEmpty = false); + void FillSBNDFrameShiftInfo(const raw::FrameShiftInfo &frame, + caf::SRSBNDFrameShiftInfo &srsbndframe, + bool allowEmpty = false); + + void FillSBNDTimingInfo(const raw::TimingInfo &timing, + caf::SRSBNDTimingInfo &srsbndtiming, + bool allowEmpty = false); + template void CopyPropertyIfSet( const std::map& props, const std::string& search, U& value ); } From 1f8d3eee3c4f870f8f195eae88989408c7c2c3a3 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Fri, 15 Aug 2025 12:48:26 -0400 Subject: [PATCH 155/367] Using VP873 instead of VPTG1 Found that VP873 monitor was much more reliable than VPTG1 --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index a8642fad0..3e3839f3d 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -23,20 +23,22 @@ namespace sbn { double hp875_offset= spill.HP875Offset; double vp875_offset= spill.VP875Offset; - double hptg1_offset= spill.HPTG1Offset; - double vptg1_offset= spill.VPTG1Offset; + double vp873_offset= spill.VP873Offset; + double hptg1_offset= spill.HPTG1Offset; + //double vptg1_offset= spill.VPTG1Offset; double hptg2_offset= spill.HPTG2Offset; double vptg2_offset= spill.VPTG2Offset; //Decides which position monitor to check first - int useHTG = 0; - int useVTG = 0; + int useHTG = 1; + int useVTG = 1; //Z Position of the monitors in m double const hp875_zpos= 202.116104; double const vp875_zpos= 202.3193205; - double const hptg1_zpos= 204.833267; - double const vptg1_zpos= 204.629608; + double const vp873_zpos= 191.153656; + double const hptg1_zpos= 204.833267; + //double const vptg1_zpos= 204.629608; double const hptg2_zpos= 205.240662; double const vptg2_zpos= 205.036835; double const target_center_zpos= 206.870895; @@ -50,6 +52,7 @@ namespace sbn { std::vector tor875; std::vector hp875; std::vector vp875; + std::vector vp873; std::vector hptg1; std::vector vptg1; std::vector hptg2; @@ -64,7 +67,8 @@ namespace sbn { tor875.push_back(spill.TOR875); hp875.push_back(spill.HP875); vp875.push_back(spill.VP875); - hptg1.push_back(spill.HPTG1); + vp873.push_back(spill.VP873); + hptg1.push_back(spill.HPTG1); vptg1.push_back(spill.VPTG1); hptg2.push_back(spill.HPTG2); vptg2.push_back(spill.VPTG2); @@ -90,6 +94,7 @@ namespace sbn { if (vptg2.empty()) vptg2.push_back(-999); if (vptg1.empty()) vptg1.push_back(-999); if (vp875.empty()) vp875.push_back(-999); + if (vp873.empty()) vp873.push_back(-999); double horang; auto interpolate_hp875 = [delta_hp875=(hp875[0]-hp875_offset), hp875_zpos, target_center_zpos] @@ -121,7 +126,7 @@ namespace sbn { if (vp875.empty() || (vptg1.empty() && vptg2.empty())) return 3; bool const doUseVTG1 = (useVTG == 1) || vptg2.empty(); auto const [ Tanverang, verpos ] = doUseVTG1? - interpolate_vp875(vptg1[0] - vptg1_offset, vptg1_zpos): + interpolate_vp875(vp873[0] - vp873_offset, vp873_zpos): interpolate_vp875(vptg2[0] - vptg2_offset, vptg2_zpos); horang=atan(Tanhorang); From 654d859e79fb618ed46f5728e01885edacfb917e Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Sat, 16 Aug 2025 13:51:02 -0500 Subject: [PATCH 156/367] Update sbndbnbdefaults.fcl --- sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl index 26327a100..f6a26ca70 100644 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl @@ -6,7 +6,7 @@ sbndbnbspillinfo: { TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away was 0.0333 BESOffset: 0.035 #unit seconds, we expect the BES to be about 35 ms from $1D. Need to adjust search range accordingly. URL: "" #Default URL having issues Nov 21 2024, used this instead https://dbdata3vm.fnal.gov:9443/ifbeam - Bundle: "BoosterNeutrinoBeam_read" + Bundle: "BoosterNeutrinoBeam_read_expanded" MultiWireBundle: "BNBMultiWire" TimeWindow: "700" #seconds MWR_TimeWindow: "3601" #seconds From a25683124a5c5460c92abb1f22842d4820042d19 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Sat, 16 Aug 2025 13:51:20 -0500 Subject: [PATCH 157/367] Update icarusbnbspillinfo.fcl --- sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl index 7c33421f8..16cd24c8b 100644 --- a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl @@ -7,7 +7,7 @@ icarusbnbspillinfo: { TimePadding: 0.0333 #unit seconds, Booster Rep Rate is 15 Hz, so the closest spill could be 66ms away BESOffset: 0.035746 #unit seconds, we expect the BES to be about 35 ms from $1D. Need to adjust search range accordingly. URL: "" #keep this blank and we're good - Bundle: "BoosterNeutrinoBeam_read" + Bundle: "BoosterNeutrinoBeam_read_expanded" MultiWireBundle: "BNBMultiWire" TimeWindow: "700" #seconds MWR_TimeWindow: "3601" #seconds From 6051a113bdf70cc2e82900fdeb25d39c1af75b44 Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Sun, 17 Aug 2025 22:24:16 -0500 Subject: [PATCH 158/367] cleaning up code --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 72 +------------------ 1 file changed, 3 insertions(+), 69 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 1889e9c90..ec9d8cc6e 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -60,11 +60,9 @@ class Geant4WeightCalc : public WeightCalc { std::string fMCTruthProducer; //!< Label for the MCTruth producer CLHEP::RandGaussQ* fGaussRandom; //!< Random number generator fhicl::ParameterSet fMaterial; //!< Detector material, i.e. LAr - // std::map fParticles; //!< Particles to reweight unsigned fNsims; //!< Number of universes (multisim mode) unsigned fNsigmas; //!< Number of sigmas (multisigma mode) int fPdg; //!< PDG value for particles that a given weight calculator should apply to. Note that for now this module can only handle weights for one particle species at a time. - // float fXSUncertainty; //!< Flat cross section uncertainty G4ReweighterFactory fRWFactory; //!< Base class to handle all Geant4Reweighters G4Reweighter *fReweighter; //!< Geant4Reweighter -- this is what provides the weights G4ReweightParameterMaker *fParMaker; @@ -90,10 +88,7 @@ class Geant4WeightCalc : public WeightCalc { int p_nElasticScatters; //!< Variables for by-particle output tree std::vector p_weight; //!< Variables for by-particle output tree - // **IF** I understand correctly, then after commit 11077f2 (el_weight*inel_weight) is returned by GetWeight() - //std::vector p_inel_weight; //!< Variables for by-particle output tree - //std::vector p_elastic_weight; //!< Variables for by-particle output bool fDebug; //!< print debug statements @@ -108,7 +103,6 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, // Get configuration for this function fhicl::ParameterSet const& pset = p.get(GetName()); - // std::cout << pset.GetName() << std::endl; fMCParticleProducer = pset.get("MCParticleProducer", "largeant"); fMCTruthProducer = pset.get("MCTruthProducer", "generator"); fMakeOutputTrees = pset.get< bool >( "makeoutputtree", false ); @@ -144,8 +138,6 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, fOutTree_Particle->Branch("pdg_to_reweight",&fPdg); fOutTree_Particle->Branch("weight",&p_weight); - //fOutTree_Particle->Branch("inelastic_weight",&p_inel_weight); - //fOutTree_Particle->Branch("elastic_weight",&p_elastic_weight); fOutTree_Particle->Branch("track_length",&p_track_length); fOutTree_Particle->Branch("PDG",&p_PDG); fOutTree_Particle->Branch("final_proc",&p_final_proc); @@ -165,7 +157,6 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, fOutTree_MCTruth->Branch("pdg_to_reweight",&fPdg); } - // Read input parameter sets and set up universes size_t n_parsets = FitParSets.size(); std::vector FitParNames; @@ -193,29 +184,7 @@ void Geant4WeightCalc::Configure(fhicl::ParameterSet const& p, fParameterSet.AddParameter(theName, theSigma); } - //DEPRECATED - if (mode=="pm1sigma"){ - // pm1sigma mode: 0 = +1sigma, 1 = -1sigma of a single parameter. All other parameters at nominal - for (size_t i_parset=0; i_parset tmp_vals_p1sigma(theNominals); - std::map tmp_vals_m1sigma(theNominals); - // Now reset the +1sigma and -1sigma values for this parameter set only - tmp_vals_p1sigma[FitParNames.at(i_parset)] = FitParNominals.at(i_parset)+FitParSigmas.at(i_parset); - tmp_vals_m1sigma[FitParNames.at(i_parset)] = FitParNominals.at(i_parset)-FitParSigmas.at(i_parset); - - if (fDebug){ - std::cout << "Universe " << i_parset*2 << ": " << FitParNames.at(i_parset) << " = " << FitParNominals.at(i_parset)+FitParSigmas.at(i_parset) << std::endl; - std::cout << "Universe " << i_parset*2+1 << ": " << FitParNames.at(i_parset) << " = " << FitParNominals.at(i_parset)-FitParSigmas.at(i_parset) << std::endl; - } - - // Finally, add these universes into the vector - UniverseVals.push_back(tmp_vals_p1sigma); - UniverseVals.push_back(tmp_vals_m1sigma); - } // end loop over parsets (i) - } // pm1sigma - - else if (mode=="multisim"){ + if (mode=="multisim"){ // multisim mode: parameter values sample within the given uncertainty for all parameters simultaneously // Loop over universes j for (unsigned j=0; j Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Reset things to be saved in the output tree for fast validation p_weight.clear(); p_weight.resize(fNsims,1.0); - //p_inel_weight.clear(); - //p_inel_weight.resize(fNsims,1.0); - //p_elastic_weight.clear(); - //p_elastic_weight.resize(fNsims,1.0); p_track_length=-9999; p_PDG=-9999; p_final_proc="dummy"; @@ -384,9 +349,6 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { p_nElasticScatters = elastic_indices.size(); for( size_t istep = 1; istep < nSteps; ++istep ){ - // if( istep == trajpoint_PX.size() - 1 && std::find( elastic_indices.begin(), elastic_indices.end(), j ) != elastic_indices.end() ) - // std::cout << "Warning: last step an elastic process" << std::endl; - std::string proc = "default"; if( istep == trajpoint_PX.size() - 1 ) proc = EndProcess; @@ -394,7 +356,6 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { proc = "hadElastic"; } - double deltaX = ( trajpoint_X.at(istep) - trajpoint_X.at(istep-1) ); double deltaY = ( trajpoint_Y.at(istep) - trajpoint_Y.at(istep-1) ); double deltaZ = ( trajpoint_Z.at(istep) - trajpoint_Z.at(istep-1) ); @@ -460,7 +421,7 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // Loop through universes (j) for (size_t j=0; jSetNewVals(UniverseVals.at(j)); @@ -474,37 +435,10 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { // just for the output tree p_weight[j] = w; -/* - // Do the same for elastic weight (should be 1 unless set to non-nominal ) - el_w = fReweighter->GetElasticWeight( &theTraj ); - weight[j] *= std::max((float)0.0,el_w); - - // just for the output tree - p_inel_weight[j] = w; - p_elastic_weight[j] = el_w; - - if (fDebug){ - std::cout << " Universe " << j << ": "; - // std::cout << UniverseVals.at(j) << std::endl; - std::cout << " w = " << w << ", el_w = " << el_w << std::endl; - } -*/ - } // loop through universes (j) if (fDebug){ std::cout << "PDG = " << p_PDG << std::endl; -/* - std::cout << "inel weights by particle: "; - for (unsigned int j=0; j Date: Mon, 18 Aug 2025 08:08:04 -0500 Subject: [PATCH 159/367] Return to original selection setup --- sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl index 03ea2ac2d..253f3517b 100644 --- a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl @@ -56,7 +56,7 @@ stopping_selection: { EndMediandQdxCut: 1600 NumberTimeSamples: 3400 MediandQdxRRMax: 5. - CheckFiducialX: true + CheckFiducialX: false } exiting_selection: { @@ -74,7 +74,7 @@ exiting_selection: { EndMediandQdxCut: -1 RequireDownwards: false NumberTimeSamples: 3400 - CheckFiducialX: true + CheckFiducialX: false } a2c_selection: { @@ -90,10 +90,10 @@ throughgoing_selection: { FVInsetMaxY: 5 FVInsetMinZ: 5 FVInsetMaxZ: 5 - CheckFiducialX: true + CheckFiducialX: false } caloskim_nodigits_goldentracks: @local::caloskim_nodigits -caloskim_nodigits_goldentracks.SelectionTools: [@local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection, @local::exiting_selection] +caloskim_nodigits_goldentracks.SelectionTools: [ @local::stopping_selection, @local::a2c_selection, @local::exiting_selection ] END_PROLOG From ba48279fbbbb1a735f2a4d1c355ce6f229e6c87b Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Tue, 19 Aug 2025 10:09:06 -0500 Subject: [PATCH 160/367] Adding efield and phi into FillTrackPlaneCalo --- sbncode/CAFMaker/FillReco.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index cb3dc5f6c..a0c675e55 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -810,6 +810,8 @@ namespace caf const std::vector &dedx = calo.dEdx(); const std::vector &pitch = calo.TrkPitchVec(); const std::vector &rr = calo.ResidualRange(); + const std::vector &efield = calo.Efield(); + const std::vector &phi = calo.Phi(); const std::vector &xyz = calo.XYZ(); const std::vector &tps = calo.TpIndices(); @@ -831,6 +833,8 @@ namespace caf p.dqdx = dqdx[i]; p.dedx = dedx[i]; p.pitch = pitch[i]; + p.efield = efield[i]; + p.phi = phi[i]; p.x = xyz[i].x(); p.y = xyz[i].y(); p.z = xyz[i].z(); From 3b02294e7eec002a0cfc4eb4f0a0901ca62a0136 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Wed, 20 Aug 2025 15:41:12 +0200 Subject: [PATCH 161/367] fixed default tool names --- sbncode/CAFMaker/CAFMakerParams.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 83b15fb8b..25a758770 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -441,68 +441,68 @@ namespace caf Atom DiffStraightLineMeanName { Name("DiffStraightLineMeanName"), Comment("Provide the tool name for the DiffStraightLineMean BDT variable."), - "LArThreeDChargeFeatureTool_DiffStraightLineMean" + "LArThreeDLinearFitFeatureTool_DiffStraightLineMean" }; Atom LengthName { Name("LengthName"), Comment("Provide the tool name for the Length BDT variable."), - "LArThreeDChargeFeatureTool_Length" + "LArThreeDLinearFitFeatureTool_Length" }; Atom MaxFitGapLengthName { Name("MaxFitGapLengthName"), Comment("Provide the tool name for the MaxFitGapLength BDT variable."), - "LArThreeDChargeFeatureTool_MaxFitGapLength" + "LArThreeDLinearFitFeatureTool_MaxFitGapLength" }; Atom SlidingLinearFitRMSName { Name("SlidingLinearFitRMSName"), Comment("Provide the tool name for the SlidingLinearFitRMS BDT variable."), - "LArThreeDChargeFeatureTool_SlidingLinearFitRMS" + "LArThreeDLinearFitFeatureTool_SlidingLinearFitRMS" }; Atom AngleDiffName { Name("AngleDiffName"), Comment("Provide the tool name for the AngleDiff BDT variable."), - "LArThreeDChargeFeatureTool_AngleDiff" + "LArThreeDOpeningAngleFeatureTool_AngleDiff" }; Atom SecondaryPCARatioName { Name("SecondaryPCARatioName"), Comment("Provide the tool name for the SecondaryPCARatio BDT variable."), - "LArThreeDChargeFeatureTool_SecondaryPCARatio" + "LArThreeDPCAFeatureTool_SecondaryPCARatio" }; Atom TertiaryPCARatioName { Name("TertiaryPCARatioName"), Comment("Provide the tool name for the TertiaryPCARatio BDT variable."), - "LArThreeDChargeFeatureTool_TertiaryPCARatio" + "LArThreeDPCAFeatureTool_TertiaryPCARatio" }; Atom VertexDistanceName { Name("VertexDistanceName"), Comment("Provide the tool name for the VertexDistance BDT variable."), - "LArThreeDChargeFeatureTool_VertexDistanceName" + "LArThreeDVertexDistanceFeatureTool_VertexDistance" }; Atom HaloTotalRatioName { Name("HaloTotalRatioName"), Comment("Provide the tool name for the HaloTotalRatio BDT variable."), - "LArThreeDChargeFeatureTool_HaloTotalRatioName" + "LArConeChargeFeatureTool_HaloTotalRatio" }; Atom ConcentrationName { Name("ConcentrationName"), Comment("Provide the tool name for the Concentration BDT variable."), - "LArThreeDChargeFeatureTool_Concentration" + "LArConeChargeFeatureTool_Concentration" }; Atom ConicalnessName { Name("ConicalnessName"), Comment("Provide the tool name for the Conicalness BDT variable."), - "LArThreeDChargeFeatureTool_Conicalness" + "LArConeChargeFeatureTool_Conicalness" }; }; From 48b347430a68392e23fc9781192109b2fe39f06c Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Thu, 21 Aug 2025 04:10:30 -0500 Subject: [PATCH 162/367] Remove extra tool for PR --- sbncode/Calibration/CMakeLists.txt | 5 -- ...CaloSkimmerSelectThroughgoingTrack_tool.cc | 79 ------------------- .../fcl/sbnd/sbnd_trackcalo_skimmer.fcl | 15 +--- 3 files changed, 2 insertions(+), 97 deletions(-) delete mode 100644 sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index 56b3828a3..98059edc5 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -70,11 +70,6 @@ cet_build_plugin(TrackCaloSkimmerSelectAllTrack art::tool ROOT::X3d ) -cet_build_plugin(TrackCaloSkimmerSelectThroughgoingTrack art::tool - LIBRARIES - larcore::Geometry_Geometry_service -) - cet_build_plugin ( DataSelect art::module LIBRARIES ifdh_art::IFDH_service diff --git a/sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc b/sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc deleted file mode 100644 index 87bf6d52b..000000000 --- a/sbncode/Calibration/TrackCaloSkimmerSelectThroughgoingTrack_tool.cc +++ /dev/null @@ -1,79 +0,0 @@ -#include "art/Utilities/ToolMacros.h" -#include "fhiclcpp/ParameterSet.h" - -#include "larcore/Geometry/Geometry.h" -#include "larcore/CoreUtils/ServiceUtil.h" -#include "larcorealg/Geometry/GeometryCore.h" - -#include "ITCSSelectionTool.h" - -namespace sbn { - - class TrackCaloSkimmerSelectThroughgoingTrack: public ITCSSelectionTool { - public: - - TrackCaloSkimmerSelectThroughgoingTrack(const fhicl::ParameterSet &p); - ~TrackCaloSkimmerSelectThroughgoingTrack() {} - - bool Select(const TrackInfo &t) override; - - private: - double fFVInsetMinX; - double fFVInsetMaxX; - double fFVInsetMinY; - double fFVInsetMaxY; - double fFVInsetMinZ; - double fFVInsetMaxZ; - bool fCheckFiducialX; - - std::vector fTPCVolumes; - geo::BoxBoundedGeo fActiveVolume, fFiducialVolume; - }; - - TrackCaloSkimmerSelectThroughgoingTrack::TrackCaloSkimmerSelectThroughgoingTrack(const fhicl::ParameterSet &p): - ITCSSelectionTool(p), - fFVInsetMinX(p.get("FVInsetMinX")), - fFVInsetMaxX(p.get("FVInsetMaxX")), - fFVInsetMinY(p.get("FVInsetMinY")), - fFVInsetMaxY(p.get("FVInsetMaxY")), - fFVInsetMinZ(p.get("FVInsetMinZ")), - fFVInsetMaxZ(p.get("FVInsetMaxZ")), - fCheckFiducialX(p.get("CheckFiducialX")) - { - const geo::GeometryCore *geometry = lar::providerFrom(); - - for(auto const &cryoid: geometry->Iterate()) - { - for(auto const& TPC : geometry->Iterate(cryoid)) - fTPCVolumes.push_back(TPC.ActiveBoundingBox()); - } - - double XMin = std::min_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MinX() < rhs.MinX(); })->MinX(); - double YMin = std::min_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MinY() < rhs.MinY(); })->MinY(); - double ZMin = std::min_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MinZ() < rhs.MinZ(); })->MinZ(); - - double XMax = std::max_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MaxX() < rhs.MaxX(); })->MaxX(); - double YMax = std::max_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MaxY() < rhs.MaxY(); })->MaxY(); - double ZMax = std::max_element(fTPCVolumes.begin(), fTPCVolumes.end(), [](auto &lhs, auto &rhs) { return lhs.MaxZ() < rhs.MaxZ(); })->MaxZ(); - - fActiveVolume = geo::BoxBoundedGeo(XMin, XMax, YMin, YMax, ZMin, ZMax); - - fFiducialVolume = geo::BoxBoundedGeo(fActiveVolume.MinX() + fFVInsetMinX, fActiveVolume.MaxX() - fFVInsetMaxX, - fActiveVolume.MinY() + fFVInsetMinY, fActiveVolume.MaxY() - fFVInsetMaxY, - fActiveVolume.MinZ() + fFVInsetMinZ, fActiveVolume.MaxZ() - fFVInsetMaxZ); - } - - bool TrackCaloSkimmerSelectThroughgoingTrack::Select(const TrackInfo &t) - { - geo::Point_t start {t.start.x, t.start.y, t.start.z}; - bool start_is_non_fid = fCheckFiducialX ? !fFiducialVolume.ContainsPosition(start) : !fFiducialVolume.ContainsYZ(start.Y(), start.Z()); - - geo::Point_t end {t.end.x, t.end.y, t.end.z}; - bool end_is_non_fid = fCheckFiducialX ? !fFiducialVolume.ContainsPosition(end) : !fFiducialVolume.ContainsYZ(end.Y(), end.Z()); - - return start_is_non_fid && end_is_non_fid; - } - - DEFINE_ART_CLASS_TOOL(TrackCaloSkimmerSelectThroughgoingTrack) - -} diff --git a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl index 253f3517b..b510a231f 100644 --- a/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl +++ b/sbncode/Calibration/fcl/sbnd/sbnd_trackcalo_skimmer.fcl @@ -59,7 +59,7 @@ stopping_selection: { CheckFiducialX: false } -exiting_selection: { +throughgoing_selection: { tool_type: TrackCaloSkimmerSelectStoppingTrack Invert: true PreScale: 1 @@ -82,18 +82,7 @@ a2c_selection: { TickCut: 2500 } -throughgoing_selection: { - tool_type: TrackCaloSkimmerSelectThroughgoingTrack - FVInsetMinX: 5 - FVInsetMaxX: 5 - FVInsetMinY: 5 - FVInsetMaxY: 5 - FVInsetMinZ: 5 - FVInsetMaxZ: 5 - CheckFiducialX: false -} - caloskim_nodigits_goldentracks: @local::caloskim_nodigits -caloskim_nodigits_goldentracks.SelectionTools: [ @local::stopping_selection, @local::a2c_selection, @local::exiting_selection ] +caloskim_nodigits_goldentracks.SelectionTools: [ @local::stopping_selection, @local::a2c_selection, @local::throughgoing_selection ] END_PROLOG From 9313298b44eded616068b9c751cb52c3e1dd5f5f Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Thu, 21 Aug 2025 04:14:49 -0500 Subject: [PATCH 163/367] Sort indentation --- .../Calibration/TrackCaloSkimmer_module.cc | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index f6be5ae6f..6fe70bc1c 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -414,18 +414,18 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) else if (hasPFPT0) whicht0 = 0; else if (hasCRTTrackT0) { - whicht0 = 1; - crtMatchingScore = t0CRTTrackScore; + whicht0 = 1; + crtMatchingScore = t0CRTTrackScore; } else if (hasCRTHitT0) { - whicht0 = 2; - crtMatchingScore = t0CRTHitScore; + whicht0 = 2; + crtMatchingScore = t0CRTHitScore; } else if (hasCRTSpacePointT0) { - whicht0 = 3; - crtMatchingScore = t0CRTSpacePointScore; + whicht0 = 3; + crtMatchingScore = t0CRTSpacePointScore; } T0TimingInfo thisTrackTimingInfo = {t0PFP, t0CRTTrack, t0CRTHit, t0CRTSpacePoint, hasPFPT0, hasCRTTrackT0, hasCRTHitT0, hasCRTSpacePointT0, crtMatchingScore}; @@ -1186,26 +1186,26 @@ void sbn::TrackCaloSkimmer::FillTrack(const recob::Track &track, const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); if(t0Info.hasT0CRTTrack) - { - const double xshift = driftDir*driftv*t0Info.t0CRTTrack*1e-3; - fTrack->start.x = track.Start().X() + xshift; - fTrack->end.x = track.End().X() + xshift; - fTrack->xShiftCRT = xshift; - } + { + const double xshift = driftDir*driftv*t0Info.t0CRTTrack*1e-3; + fTrack->start.x = track.Start().X() + xshift; + fTrack->end.x = track.End().X() + xshift; + fTrack->xShiftCRT = xshift; + } else if(t0Info.hasT0CRTHit) - { - const double xshift = driftDir*driftv*t0Info.t0CRTHit*1e-3; - fTrack->start.x = track.Start().X() + xshift; - fTrack->end.x = track.End().X() + xshift; - fTrack->xShiftCRT = xshift; - } + { + const double xshift = driftDir*driftv*t0Info.t0CRTHit*1e-3; + fTrack->start.x = track.Start().X() + xshift; + fTrack->end.x = track.End().X() + xshift; + fTrack->xShiftCRT = xshift; + } else if(t0Info.hasT0CRTSpacePoint) - { - const double xshift = driftDir*driftv*t0Info.t0CRTSpacePoint*1e-3; - fTrack->start.x = track.Start().X() + xshift; - fTrack->end.x = track.End().X() + xshift; - fTrack->xShiftCRT = xshift; - } + { + const double xshift = driftDir*driftv*t0Info.t0CRTSpacePoint*1e-3; + fTrack->start.x = track.Start().X() + xshift; + fTrack->end.x = track.End().X() + xshift; + fTrack->xShiftCRT = xshift; + } } if (hits.size() > 0) { @@ -1468,11 +1468,11 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, double time = std::numeric_limits::signaling_NaN(); if(t0Info.hasT0CRTTrack) - time = t0Info.t0CRTTrack*1e-3; + time = t0Info.t0CRTTrack*1e-3; else if(t0Info.hasT0CRTHit) - time = t0Info.t0CRTHit*1e-3; + time = t0Info.t0CRTHit*1e-3; else if(t0Info.hasT0CRTSpacePoint) - time = t0Info.t0CRTSpacePoint*1e-3; + time = t0Info.t0CRTSpacePoint*1e-3; double anodeDistance = (hit.PeakTime()-dclock.Time2Tick(dclock.TriggerTime())-time/dclock.TPCClock().TickPeriod())*dclock.TPCClock().TickPeriod()*driftv; double wirePlaneX = wireReadout->Plane(geo::PlaneID(hit.WireID().Cryostat, hit.WireID().TPC, hit.WireID().Plane)).GetCenter().X(); From 5f6b535858cf22e020f1d738787509241b52419e Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Mon, 25 Aug 2025 18:20:37 -0400 Subject: [PATCH 164/367] RESOLVED TH1D.H!!! --- sbncode/BeamSpillInfoRetriever/getFOM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/getFOM.cpp b/sbncode/BeamSpillInfoRetriever/getFOM.cpp index 3e3839f3d..dfd91a02e 100644 --- a/sbncode/BeamSpillInfoRetriever/getFOM.cpp +++ b/sbncode/BeamSpillInfoRetriever/getFOM.cpp @@ -5,7 +5,7 @@ */ #include "sbncode/BeamSpillInfoRetriever/getFOM.h" #include -#include "TH1D.H" +#include "TH1D.h" #include "TFitResult.h" #include From b0dd48bfc485f35f5ba2043c78ba407aa61fee28 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Mon, 25 Aug 2025 19:35:52 -0500 Subject: [PATCH 165/367] correct timing in Caf --- sbncode/CAFMaker/CAFMakerParams.h | 4 +- sbncode/CAFMaker/CAFMaker_module.cc | 65 ++++++++++++++++++++++++++++- sbncode/CAFMaker/FillReco.cxx | 3 +- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 2f44fea03..adc0ae0df 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -341,13 +341,13 @@ namespace caf Atom SBNDFrameShiftInfoLabel { Name("SBNDFrameShiftInfoLabel"), Comment("Label of sbnd frame shift."), - "reco1" // sbnd + "framshift" // sbnd }; Atom SBNDTimingInfoLabel { Name("SBNDTimingInfoLabel"), Comment("Label of sbnd timing shift."), - "reco1" // sbnd + "frameshift" // sbnd }; Atom CRTPMTLabel { diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index cb99173a9..68b3fb529 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -316,6 +316,9 @@ class CAFMaker : public art::EDProducer { void FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time); void FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_time, double CRTT1_reference_time); + void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame); + void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame); + /// Equivalent of FindManyP except a return that is !isValid() prints a /// messsage and aborts if StrictMode is true. template @@ -499,6 +502,41 @@ void CAFMaker::BlindEnergyParameters(StandardRecord* brec) { } } +void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame){ + + //CRT Space Point + for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ + sp.time += SBNDFrame; //ns + } + + //CRT Track + for (SRSBNDCRTTrack &trk: rec.sbnd_crt_tracks){ + trk.time += SBNDFrame; //ns + } + + //CRT Space Point and Track Match + for (SRPFP &pfp: rec.reco.pfp) { + pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; + pfp.trk.crtsbndtrack.track.time += SBNDFrame; + } +} + +void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame){ + + double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us + + //Op Flash + for (SROpFlash &opf: rec.opflashes) { + opf.time += SBNDFrame_us; + opf.firsttime += SBNDFrame_us; + } + + //OpT0 match to slice + for (SRSlice &s: rec.slc) { + s.opt0.time += SBNDFrame_us; + } +} + void CAFMaker::FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time) { // Fix the flashes for (SROpFlash &f: rec.opflashes) { @@ -2382,6 +2420,11 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.nsbnd_crt_tracks = srsbndcrttracks.size(); rec.opflashes = srflashes; rec.nopflashes = srflashes.size(); + rec.sbnd_frames = srsbndframeshiftinfo; + rec.nsbnd_frames = srsbndframeshiftinfo.size(); + rec.sbnd_timings = srsbndtiminginfo; + rec.nsbnd_timings = srsbndtiminginfo.size(); + if (fParams.FillTrueParticles()) { rec.true_particles = true_particles; } @@ -2389,7 +2432,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.crtpmt_matches = srcrtpmtmatches; rec.ncrtpmt_matches = srcrtpmtmatches.size(); - // Fix the Reference time + // ICARUS: Fix the Reference time // // We want MC and Data to have the same reference time. // In MC/LArSoft the "reference time" is canonically defined @@ -2421,6 +2464,26 @@ void CAFMaker::produce(art::Event& evt) noexcept { FixPMTReferenceTimes(rec, PMT_reference_time); // TODO: TPC? + + // SBND: Fix the Reference time (See docdb# ????? and FrameShift module on sbndcode repo) + + if (isRealData & (fDet == kSBND)) + { + mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND" ; + + //Should only be 1 set of frame per event, if not, something is really wrong and nothing should be corrected + if (rec.nsbnd_frames == 1) + { + SRSBNDFrameShiftInfo frame = rec.sbnd_frames.at(0); + + //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match + SBNDShiftCRTReference(rec, frame.frameApplyAtCaf); + + //shift reference frame for PMT objects: opflash, opt0 + SBNDShiftPMTReference(rec, frame.frameApplyAtCaf); + } + + } // Get metadata information for header unsigned int run = evt.run(); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 89b6e378e..29cb2bf5a 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -145,12 +145,13 @@ namespace caf caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty) { + srsbndframe.timingType = frame.timingType; srsbndframe.frameTdcCrtt1 = frame.frameTdcCrtt1; srsbndframe.frameTdcBes = frame.frameTdcBes; srsbndframe.frameTdcRwm = frame.frameTdcRwm; srsbndframe.frameHltCrtt1 = frame.frameHltCrtt1; srsbndframe.frameHltBeamGate = frame.frameHltBeamGate; - srsbndframe.frameDataToMC = frame.frameDataToMC; + srsbndframe.frameApplyAtCaf = frame.frameApplyAtCaf; } void FillSBNDTimingInfo(const raw::TimingInfo &timing, From 4f49aba2eb0be7ec0a15782c6c81d437c2780731 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 26 Aug 2025 15:30:41 -0500 Subject: [PATCH 166/367] add fixes --- sbncode/CAFMaker/CAFMakerParams.h | 2 +- sbncode/CAFMaker/CAFMaker_module.cc | 50 ++++++++++------------------- sbncode/CAFMaker/FillReco.cxx | 1 + 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index adc0ae0df..2ee91d866 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -341,7 +341,7 @@ namespace caf Atom SBNDFrameShiftInfoLabel { Name("SBNDFrameShiftInfoLabel"), Comment("Label of sbnd frame shift."), - "framshift" // sbnd + "frameshift" // sbnd }; Atom SBNDTimingInfoLabel { diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 68b3fb529..0cc74b544 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1641,8 +1641,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector srcrttracks; std::vector srcrtspacepoints; std::vector srsbndcrttracks; - std::vector srsbndframeshiftinfo; - std::vector srsbndtiminginfo; + caf::SRSBNDFrameShiftInfo srsbndframeshiftinfo; + caf::SRSBNDTimingInfo srsbndtiminginfo; if(fDet == kICARUS) { @@ -1691,29 +1691,22 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillSBNDCRTTrack(sbndcrttracks[i], srsbndcrttracks.back()); } } - - art::Handle> sbndframeshiftinfo_handle; + + art::Handle sbndframeshiftinfo_handle; GetByLabelStrict(evt, fParams.SBNDFrameShiftInfoLabel(), sbndframeshiftinfo_handle); // fill into event if (sbndframeshiftinfo_handle.isValid()) { - const std::vector &sbndframeshiftinfo = *sbndframeshiftinfo_handle; - for (unsigned i = 0; i < sbndframeshiftinfo.size(); i++) { - srsbndframeshiftinfo.emplace_back(); - FillSBNDFrameShiftInfo(sbndframeshiftinfo[i], srsbndframeshiftinfo.back()); - } + raw::FrameShiftInfo const& sbndframeshiftinfo(*sbndframeshiftinfo_handle); + FillSBNDFrameShiftInfo(sbndframeshiftinfo, srsbndframeshiftinfo); } - art::Handle> sbndtiminginfo_handle; + art::Handle sbndtiminginfo_handle; GetByLabelStrict(evt, fParams.SBNDTimingInfoLabel(), sbndtiminginfo_handle); // fill into event if (sbndtiminginfo_handle.isValid()) { - const std::vector &sbndtiminginfo = *sbndtiminginfo_handle; - for (unsigned i = 0; i < sbndtiminginfo.size(); i++) { - srsbndtiminginfo.emplace_back(); - FillSBNDTimingInfo(sbndtiminginfo[i], srsbndtiminginfo.back()); - } + raw::TimingInfo const& sbndtiminginfo(*sbndtiminginfo_handle); + FillSBNDTimingInfo(sbndtiminginfo, srsbndtiminginfo); } - } // Get all of the CRTPMT Matches @@ -2421,9 +2414,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.opflashes = srflashes; rec.nopflashes = srflashes.size(); rec.sbnd_frames = srsbndframeshiftinfo; - rec.nsbnd_frames = srsbndframeshiftinfo.size(); rec.sbnd_timings = srsbndtiminginfo; - rec.nsbnd_timings = srsbndtiminginfo.size(); if (fParams.FillTrueParticles()) { rec.true_particles = true_particles; @@ -2465,24 +2456,17 @@ void CAFMaker::produce(art::Event& evt) noexcept { // TODO: TPC? - // SBND: Fix the Reference time (See docdb# ????? and FrameShift module on sbndcode repo) - + // SBND: Fix the Reference time in data depending on the stream (See FrameShift module on sbndcode repo) if (isRealData & (fDet == kSBND)) { - mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND" ; - - //Should only be 1 set of frame per event, if not, something is really wrong and nothing should be corrected - if (rec.nsbnd_frames == 1) - { - SRSBNDFrameShiftInfo frame = rec.sbnd_frames.at(0); - - //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match - SBNDShiftCRTReference(rec, frame.frameApplyAtCaf); - - //shift reference frame for PMT objects: opflash, opt0 - SBNDShiftPMTReference(rec, frame.frameApplyAtCaf); - } + mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" + << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; + + //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match + SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + //shift reference frame for PMT objects: opflash, opt0 + SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); } // Get metadata information for header diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 29cb2bf5a..15356240e 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -158,6 +158,7 @@ namespace caf caf::SRSBNDTimingInfo &srsbndtiming, bool allowEmpty) { + srsbndtiming.rawDAQHeaderTimestamp = timing.rawDAQHeaderTimestamp; srsbndtiming.tdcCrtt1 = timing.tdcCrtt1; srsbndtiming.tdcBes = timing.tdcBes; srsbndtiming.tdcRwm = timing.tdcRwm; From ce919163e2ec245bd6e3e65bc3aa7f6d0b9b66ed Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Wed, 27 Aug 2025 23:56:33 -0500 Subject: [PATCH 167/367] undo frame shift for crt matched --- sbncode/CAFMaker/CAFMaker_module.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 0cc74b544..5965e0e2a 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -514,11 +514,11 @@ void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame){ trk.time += SBNDFrame; //ns } - //CRT Space Point and Track Match - for (SRPFP &pfp: rec.reco.pfp) { - pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; - pfp.trk.crtsbndtrack.track.time += SBNDFrame; - } + //TODO: CRT Space Point and Track Match + //for (SRPFP &pfp: rec.reco.pfp) { + // pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; + // pfp.trk.crtsbndtrack.track.time += SBNDFrame; + //} } void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame){ From 40d50a15de35aa9a9d47d8cf4cf7a0ed573d0384 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Fri, 29 Aug 2025 17:27:29 -0500 Subject: [PATCH 168/367] move products from sbndcode to sbnobj --- sbncode/CAFMaker/CAFMaker_module.cc | 10 +++++---- sbncode/CAFMaker/CMakeLists.txt | 1 + sbncode/CAFMaker/FillReco.cxx | 34 ++++++++++++++--------------- sbncode/CAFMaker/FillReco.h | 8 ++++--- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 5965e0e2a..870c813be 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -118,6 +118,8 @@ #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" +#include "sbnobj/SBND/Timing/TimingInfo.hh" +#include "sbnobj/SBND/Timing/FrameShiftInfo.hh" // GENIE #include "Framework/EventGen/EventRecord.h" @@ -1692,19 +1694,19 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } - art::Handle sbndframeshiftinfo_handle; + art::Handle sbndframeshiftinfo_handle; GetByLabelStrict(evt, fParams.SBNDFrameShiftInfoLabel(), sbndframeshiftinfo_handle); // fill into event if (sbndframeshiftinfo_handle.isValid()) { - raw::FrameShiftInfo const& sbndframeshiftinfo(*sbndframeshiftinfo_handle); + sbnd::timing::FrameShiftInfo const& sbndframeshiftinfo(*sbndframeshiftinfo_handle); FillSBNDFrameShiftInfo(sbndframeshiftinfo, srsbndframeshiftinfo); } - art::Handle sbndtiminginfo_handle; + art::Handle sbndtiminginfo_handle; GetByLabelStrict(evt, fParams.SBNDTimingInfoLabel(), sbndtiminginfo_handle); // fill into event if (sbndtiminginfo_handle.isValid()) { - raw::TimingInfo const& sbndtiminginfo(*sbndtiminginfo_handle); + sbnd::timing::TimingInfo const& sbndtiminginfo(*sbndtiminginfo_handle); FillSBNDTimingInfo(sbndtiminginfo, srsbndtiminginfo); } } diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 76c3903d4..c141efa72 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -36,6 +36,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_Reco sbnobj::Common_Analysis sbnobj::SBND_CRT + sbnobj::SBND_Timing lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 15356240e..94d1f3c9d 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -141,31 +141,31 @@ namespace caf srsbndcrttrack.tof = track.ToF(); } - void FillSBNDFrameShiftInfo(const raw::FrameShiftInfo &frame, + void FillSBNDFrameShiftInfo(const sbnd::timing::FrameShiftInfo &frame, caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty) { - srsbndframe.timingType = frame.timingType; - srsbndframe.frameTdcCrtt1 = frame.frameTdcCrtt1; - srsbndframe.frameTdcBes = frame.frameTdcBes; - srsbndframe.frameTdcRwm = frame.frameTdcRwm; - srsbndframe.frameHltCrtt1 = frame.frameHltCrtt1; - srsbndframe.frameHltBeamGate = frame.frameHltBeamGate; - srsbndframe.frameApplyAtCaf = frame.frameApplyAtCaf; + srsbndframe.timingType = frame.TimingType(); + srsbndframe.frameTdcCrtt1 = frame.FrameTdcCrtt1(); + srsbndframe.frameTdcBes = frame.FrameTdcBes(); + srsbndframe.frameTdcRwm = frame.FrameTdcRwm(); + srsbndframe.frameHltCrtt1 = frame.FrameHltCrtt1(); + srsbndframe.frameHltBeamGate = frame.FrameHltBeamGate(); + srsbndframe.frameApplyAtCaf = frame.FrameApplyAtCaf(); } - void FillSBNDTimingInfo(const raw::TimingInfo &timing, + void FillSBNDTimingInfo(const sbnd::timing::TimingInfo &timing, caf::SRSBNDTimingInfo &srsbndtiming, bool allowEmpty) { - srsbndtiming.rawDAQHeaderTimestamp = timing.rawDAQHeaderTimestamp; - srsbndtiming.tdcCrtt1 = timing.tdcCrtt1; - srsbndtiming.tdcBes = timing.tdcBes; - srsbndtiming.tdcRwm = timing.tdcRwm; - srsbndtiming.tdcEtrig = timing.tdcEtrig; - srsbndtiming.hltCrtt1 = timing.hltCrtt1; - srsbndtiming.hltEtrig = timing.hltEtrig; - srsbndtiming.hltBeamGate = timing.hltBeamGate; + srsbndtiming.rawDAQHeaderTimestamp = timing.RawDAQHeaderTimestamp(); + srsbndtiming.tdcCrtt1 = timing.TdcCrtt1(); + srsbndtiming.tdcBes = timing.TdcBes(); + srsbndtiming.tdcRwm = timing.TdcRwm(); + srsbndtiming.tdcEtrig = timing.TdcEtrig(); + srsbndtiming.hltCrtt1 = timing.HltCrtt1(); + srsbndtiming.hltEtrig = timing.HltEtrig(); + srsbndtiming.hltBeamGate = timing.HltBeamGate(); } void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index a301faba5..a79d0185d 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -42,9 +42,11 @@ #include "sbnobj/SBND/CRT/CRTTrack.hh" #include "sbnobj/Common/CRT/CRTPMTMatching.hh" #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" +#include "sbnobj/SBND/Timing/TimingInfo.hh" +#include "sbnobj/SBND/Timing/FrameShiftInfo.hh" + #include "nusimdata/SimulationBase/MCParticle.h" #include "nusimdata/SimulationBase/MCTruth.h" -#include "sbndcode/Timing/SBNDRawTimingObj.h" #include "sbnanaobj/StandardRecord/SRSlice.h" #include "sbnanaobj/StandardRecord/StandardRecord.h" @@ -280,11 +282,11 @@ namespace caf caf::SRPFP& srpfp, bool allowEmpty = false); - void FillSBNDFrameShiftInfo(const raw::FrameShiftInfo &frame, + void FillSBNDFrameShiftInfo(const sbnd::timing::FrameShiftInfo &frame, caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty = false); - void FillSBNDTimingInfo(const raw::TimingInfo &timing, + void FillSBNDTimingInfo(const sbnd::timing::TimingInfo &timing, caf::SRSBNDTimingInfo &srsbndtiming, bool allowEmpty = false); From bfa229c54ace5895c1850649c2b396f18adaa88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Tue, 2 Sep 2025 08:56:57 -0500 Subject: [PATCH 169/367] Add tpcpmt bfm score and chi2 to CAF files --- sbncode/CAFMaker/FillReco.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d81cb5890..a05150126 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -1127,6 +1127,8 @@ namespace caf slice.barycenterFM.deltaZ_Trigger = matchInfo->deltaZ_Trigger; slice.barycenterFM.deltaY_Trigger = matchInfo->deltaY_Trigger; slice.barycenterFM.radius_Trigger = matchInfo->radius_Trigger; + slice.barycenterFM.score = matchInfo->score; + slice.barycenterFM.chi2 = matchInfo->chi2; } } From a4116c1b978eaa9c6295f63d07faf6dfeb68c04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Tue, 2 Sep 2025 10:49:47 -0500 Subject: [PATCH 170/367] Add CorrectedOpFlash to CAF information --- sbncode/CAFMaker/CAFMakerParams.h | 6 ++++++ sbncode/CAFMaker/CAFMaker_module.cc | 15 +++++++++++++-- sbncode/CAFMaker/CMakeLists.txt | 1 + sbncode/CAFMaker/FillReco.cxx | 17 +++++++++++++++++ sbncode/CAFMaker/FillReco.h | 4 ++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 253f0d4c2..daedf5bef 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -350,6 +350,12 @@ namespace caf "" //Empty by default, configured in icaruscode cafmaker_defs }; + Atom CorrectedOpFlashLabel { + Name("CorrectedOpFlashLabel"), + Comment("Label of CorrectedOpFlash containing tpc-corrected flash time."), + "" + }; + Atom NuGraphSliceHitLabel { Name("NuGraphSliceHitLabel"), Comment("Label of NuGraph slice hit map."), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 48da84e8f..af1502db8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1828,6 +1828,15 @@ void CAFMaker::produce(art::Event& evt) noexcept { const sbn::TPCPMTBarycenterMatch *barycenterMatch = foTPCPMTBarycenterMatch.isValid()? foTPCPMTBarycenterMatch.at(0).get(): nullptr; + + art::FindManyP fmCorrectedOpFlash = + FindManyPStrict(sliceList, evt, + fParams.CorrectedOpFlashLabel() + slice_tag_suff); + std::vector> slcCorrectedOpFlash; + if (fmCorrectedOpFlash.isValid()) + slcCorrectedOpFlash = fmCorrectedOpFlash.at(0); + + art::FindOneP foCVNResult = FindOnePStrict(sliceList, evt, fParams.CVNLabel() + slice_tag_suff); @@ -2083,6 +2092,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillSliceOpT0Finder(slcOpT0, recslc); FillSliceBarycenter(slcHits, slcSpacePoints, recslc); FillTPCPMTBarycenterMatch(barycenterMatch, recslc); + FillCorrectedOpFlashTiming(slcCorrectedOpFlash, recslc); FillCVNScores(cvnResult, recslc); // select slice @@ -2429,6 +2439,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.hdr.ismc = !isRealData; rec.hdr.det = fDet; rec.hdr.fno = fFileNumber; + if(fFirstInSubRun) { rec.hdr.nbnbinfo = fBNBInfo.size(); @@ -2469,13 +2480,13 @@ void CAFMaker::produce(art::Event& evt) noexcept { else { std::cout << "Did not find this event in the spill info map." << std::endl; } - + if(fRecTree){ // Save the standard-record StandardRecord* prec = &rec; + fRecTree->SetBranchAddress("rec", &prec); fRecTree->Fill(); - if(fFlatTree){ fFlatRecord->Clear(); fFlatRecord->Fill(rec); diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 76c3903d4..65cf746cb 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -36,6 +36,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_Reco sbnobj::Common_Analysis sbnobj::SBND_CRT + sbnobj::SBND_OpFlashTiming lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d81cb5890..848c4129f 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -263,6 +263,23 @@ namespace caf } } + + void FillCorrectedOpFlashTiming(const std::vector> &slcCorrectedOpFlash, + caf::SRSlice& slice) + { + slice.correctedOpFlash.setDefault(); + if ( slcCorrectedOpFlash.empty()==false ) { + const sbnd::OpFlashTiming::CorrectedOpFlashTiming &_correctedOpFlash = *slcCorrectedOpFlash[0]; + //TODO: use the score of the match to fill the information accordingly + slice.correctedOpFlash.OpFlashT0 = _correctedOpFlash.OpFlashT0; + slice.correctedOpFlash.UpstreamTime_lightonly = _correctedOpFlash.UpstreamTime_lightonly; + slice.correctedOpFlash.UpstreamTime_tpczcorr = _correctedOpFlash.UpstreamTime_tpczcorr; + slice.correctedOpFlash.UpstreamTime_propcorr = _correctedOpFlash.UpstreamTime_propcorr; + slice.correctedOpFlash.UpstreamTime_propcorr_tpczcorr = _correctedOpFlash.UpstreamTime_propcorr_tpczcorr; + } + } + + std::vector double_to_float_vector(const std::vector& v) { std::vector ret; diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 6e8ecf292..3cb5ed0c3 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -40,6 +40,7 @@ #include "sbnobj/Common/CRT/CRTTrack.hh" #include "sbnobj/SBND/CRT/CRTSpacePoint.hh" #include "sbnobj/SBND/CRT/CRTTrack.hh" +#include "sbnobj/SBND/OpFlashTiming/CorrectedOpFlashTiming.h" #include "sbnobj/Common/CRT/CRTPMTMatching.hh" #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" #include "nusimdata/SimulationBase/MCParticle.h" @@ -272,6 +273,9 @@ namespace caf void FillTPCPMTBarycenterMatch(const sbn::TPCPMTBarycenterMatch *matchInfo, caf::SRSlice& slice); + void FillCorrectedOpFlashTiming(const std::vector> &slcCorrectedOpFlash, + caf::SRSlice& slice); + void FillCVNScores(const lcvn::Result *cvnResult, caf::SRSlice& slice); From 0539cd1a27d42d19262cb9d9e19fd262bd843408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Tue, 2 Sep 2025 11:15:21 -0500 Subject: [PATCH 171/367] Fix bug with correctedopflash attribute --- sbncode/CAFMaker/FillReco.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 848c4129f..97b6eae31 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -274,7 +274,6 @@ namespace caf slice.correctedOpFlash.OpFlashT0 = _correctedOpFlash.OpFlashT0; slice.correctedOpFlash.UpstreamTime_lightonly = _correctedOpFlash.UpstreamTime_lightonly; slice.correctedOpFlash.UpstreamTime_tpczcorr = _correctedOpFlash.UpstreamTime_tpczcorr; - slice.correctedOpFlash.UpstreamTime_propcorr = _correctedOpFlash.UpstreamTime_propcorr; slice.correctedOpFlash.UpstreamTime_propcorr_tpczcorr = _correctedOpFlash.UpstreamTime_propcorr_tpczcorr; } } From 6e7264ec854be6eb01dd4c4a4abef40732b1b34a Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Thu, 4 Sep 2025 09:37:43 -0500 Subject: [PATCH 172/367] converting phi to radian from degree --- sbncode/CAFMaker/FillReco.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index a0c675e55..ae363dd61 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -834,7 +834,7 @@ namespace caf p.dedx = dedx[i]; p.pitch = pitch[i]; p.efield = efield[i]; - p.phi = phi[i]; + p.phi = phi[i] * M_PI / 180.; // converting to radian since calo.Phi() is in degree p.x = xyz[i].x(); p.y = xyz[i].y(); p.z = xyz[i].z(); From c95e4da5040d8e7eb82088f638cdec5d29bd1793 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 2 Sep 2025 14:30:14 -0500 Subject: [PATCH 173/367] address comments --- sbncode/CAFMaker/CAFMaker_module.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 870c813be..3ae6d18db 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -318,8 +318,8 @@ class CAFMaker : public art::EDProducer { void FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time); void FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_time, double CRTT1_reference_time); - void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame); - void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame); + void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const; + void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const; /// Equivalent of FindManyP except a return that is !isValid() prints a /// messsage and aborts if StrictMode is true. @@ -504,7 +504,7 @@ void CAFMaker::BlindEnergyParameters(StandardRecord* brec) { } } -void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame){ +void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { //CRT Space Point for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ @@ -523,7 +523,7 @@ void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame){ //} } -void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame){ +void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us @@ -2416,7 +2416,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.opflashes = srflashes; rec.nopflashes = srflashes.size(); rec.sbnd_frames = srsbndframeshiftinfo; - rec.sbnd_timings = srsbndtiminginfo; + rec.sbnd_timings = srsbndtiminginfo; if (fParams.FillTrueParticles()) { rec.true_particles = true_particles; @@ -2425,7 +2425,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.crtpmt_matches = srcrtpmtmatches; rec.ncrtpmt_matches = srcrtpmtmatches.size(); - // ICARUS: Fix the Reference time + // Move the reference time of reconstructed objects from trigger time to beam spill/beam gate opening time. // // We want MC and Data to have the same reference time. // In MC/LArSoft the "reference time" is canonically defined @@ -2442,6 +2442,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { // filled with the default values, which are set to the numerical limits of double. // In this case, we should set the PMT_reference_time to 0. + // ICARUS: Fix the Reference time const bool hasValidTriggerTime = srtrigger.global_trigger_det_time > (std::numeric_limits::min() + std::numeric_limits::epsilon()) && @@ -2458,8 +2459,11 @@ void CAFMaker::produce(art::Event& evt) noexcept { // TODO: TPC? - // SBND: Fix the Reference time in data depending on the stream (See FrameShift module on sbndcode repo) - if (isRealData & (fDet == kSBND)) + // SBND: Fix the Reference time in data depending on the stream i + // For more information, see: + // https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 + + if (isRealData && (fDet == kSBND) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)) { mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; @@ -2754,7 +2758,6 @@ void CAFMaker::endJob() { if(fParams.CreateBlindedCAF() && fFlatFilep) AddMetadataToFile(fFlatFilep, metamap); } - } // end namespace caf DEFINE_ART_MODULE(caf::CAFMaker) //////////////////////////////////////////////////////////////////////// From e545454555a0f1aee81555fcbbf3f74771bc3e90 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 2 Sep 2025 15:56:27 -0500 Subject: [PATCH 174/367] initialise empty label --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 3ae6d18db..57b45b948 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2459,7 +2459,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { // TODO: TPC? - // SBND: Fix the Reference time in data depending on the stream i + // SBND: Fix the Reference time in data depending on the stream // For more information, see: // https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 From 2f079d4905aac0cd56f593cf50bad328d9430b1d Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 2 Sep 2025 16:04:41 -0500 Subject: [PATCH 175/367] remove label --- sbncode/CAFMaker/CAFMakerParams.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 2ee91d866..28d2d6d66 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -341,13 +341,13 @@ namespace caf Atom SBNDFrameShiftInfoLabel { Name("SBNDFrameShiftInfoLabel"), Comment("Label of sbnd frame shift."), - "frameshift" // sbnd + "" // sbnd }; Atom SBNDTimingInfoLabel { Name("SBNDTimingInfoLabel"), Comment("Label of sbnd timing shift."), - "frameshift" // sbnd + "" // sbnd }; Atom CRTPMTLabel { From 691681d1399aaa89d9248039707c1af139b905fc Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 2 Sep 2025 16:24:05 -0500 Subject: [PATCH 176/367] catching NaN cases and 0 --- sbncode/CAFMaker/CAFMaker_module.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 57b45b948..ff5d9b869 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -506,6 +506,7 @@ void CAFMaker::BlindEnergyParameters(StandardRecord* brec) { void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { + std::cout << "hellooooo PMT " << std::endl; //CRT Space Point for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ sp.time += SBNDFrame; //ns @@ -524,7 +525,7 @@ void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) cons } void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { - + std::cout << "hellooooo PMT " << std::endl; double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us //Op Flash @@ -2463,16 +2464,18 @@ void CAFMaker::produce(art::Event& evt) noexcept { // For more information, see: // https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 - if (isRealData && (fDet == kSBND) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)) + if (isRealData && (fDet == kSBND)) { - mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" - << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; - - //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match - SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + if ((rec.sbnd_frames.frameApplyAtCaf != kSignalingNaN) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ + mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" + << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; + + //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match + SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - //shift reference frame for PMT objects: opflash, opt0 - SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + //shift reference frame for PMT objects: opflash, opt0 + SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + } } // Get metadata information for header From e489c77b637bdf3490e4ec1ea0f702b41751c0a6 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 2 Sep 2025 16:25:58 -0500 Subject: [PATCH 177/367] remove test comments --- sbncode/CAFMaker/CAFMaker_module.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index ff5d9b869..772d3a949 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -506,7 +506,6 @@ void CAFMaker::BlindEnergyParameters(StandardRecord* brec) { void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { - std::cout << "hellooooo PMT " << std::endl; //CRT Space Point for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ sp.time += SBNDFrame; //ns @@ -525,7 +524,7 @@ void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) cons } void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { - std::cout << "hellooooo PMT " << std::endl; + double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us //Op Flash From ee536944bad5588c75226752f7527b543a230d97 Mon Sep 17 00:00:00 2001 From: VCLanNguyen <74775793+VCLanNguyen@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:07:46 -0700 Subject: [PATCH 178/367] Update sbncode/CAFMaker/CAFMaker_module.cc with the correct Nan Check Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 772d3a949..8d6fcc7eb 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2465,7 +2465,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (isRealData && (fDet == kSBND)) { - if ((rec.sbnd_frames.frameApplyAtCaf != kSignalingNaN) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ + if (!std::isnan(rec.sbnd_frames.frameApplyAtCaf) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; From 0cddf8860257ccb25c80e50f7046ada413358a53 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Wed, 3 Sep 2025 20:12:23 -0500 Subject: [PATCH 179/367] Fill SRTrigger --- sbncode/CAFMaker/CAFMaker_module.cc | 4 ++++ sbncode/CAFMaker/FillTrigger.cxx | 9 +++++++++ sbncode/CAFMaker/FillTrigger.h | 2 ++ 3 files changed, 15 insertions(+) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 8d6fcc7eb..e1f257f57 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2465,6 +2465,10 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (isRealData && (fDet == kSBND)) { + // Fill trigger info + FillTriggerSBND(srsbndtiminginfo, srtrigger); + + // Shift timing reference frame if (!std::isnan(rec.sbnd_frames.frameApplyAtCaf) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 009deccef..8bf82c02c 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -35,4 +35,13 @@ namespace caf // TODO: fill others? } + void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo){ + + triggerInfo.global_trigger_time = timingInfo.hltEtrig; + triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; + + double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; + triggerInfo.trigger_within_gate = diff_ts; + } + } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index b83c2e9f0..ea1aab7eb 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -4,6 +4,7 @@ #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Trigger/BeamBits.h" #include "sbnanaobj/StandardRecord/SRTrigger.h" +#include "sbnanaobj/StandardRecord/SRSBNDTimingInfo.h" #include "lardataobj/RawData/TriggerData.h" #include @@ -18,6 +19,7 @@ namespace caf void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo); + void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo); } #endif From e2c16b64d7dc0de841b7a822a49df3859fd52c7d Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Thu, 4 Sep 2025 12:18:04 -0500 Subject: [PATCH 180/367] fix trk-mathced CRT --- sbncode/CAFMaker/CAFMaker_module.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index e1f257f57..7fd5222fb 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -517,10 +517,13 @@ void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) cons } //TODO: CRT Space Point and Track Match - //for (SRPFP &pfp: rec.reco.pfp) { - // pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; - // pfp.trk.crtsbndtrack.track.time += SBNDFrame; - //} + for (SRSlice &slc: rec.slc){ + for (SRPFP &pfp: slc.reco.pfp){ + if(!std::isnan(pfp.trk.crtspacepoint.score)) pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; + + if(!std::isnan(pfp.trk.crtsbndtrack.score)) pfp.trk.crtsbndtrack.track.time += SBNDFrame; + } + } } void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { From d8d033774aca1d4374c32ac13ea13ae06be84f6a Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:47:41 -0500 Subject: [PATCH 181/367] Add find_package for eigen --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 67af6b4fe..b95562203 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ cet_report_compiler_flags(REPORT_THRESHOLD VERBOSE) # these are minimum required versions, not the actual product versions find_package( art REQUIRED ) +find_package( Eigen3 REQUIRED) find_package( messagefacility REQUIRED ) find_package( art_root_io REQUIRED ) find_package( nusimdata REQUIRED ) From a28d0d65b0754b6e3e6fc9b58e29369e233a9337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Mon, 8 Sep 2025 11:20:00 -0500 Subject: [PATCH 182/367] Change corrected opflash to reco folder --- sbncode/CAFMaker/CAFMaker_module.cc | 7 ++++--- sbncode/CAFMaker/CMakeLists.txt | 1 - sbncode/CAFMaker/FillReco.cxx | 6 ++++-- sbncode/CAFMaker/FillReco.h | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index af1502db8..9ce254817 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -118,6 +118,7 @@ #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" +#include "sbnobj/Common/Reco/CorrectedOpFlashTiming.h" // GENIE #include "Framework/EventGen/EventRecord.h" @@ -1829,10 +1830,10 @@ void CAFMaker::produce(art::Event& evt) noexcept { = foTPCPMTBarycenterMatch.isValid()? foTPCPMTBarycenterMatch.at(0).get(): nullptr; - art::FindManyP fmCorrectedOpFlash = - FindManyPStrict(sliceList, evt, + art::FindManyP fmCorrectedOpFlash = + FindManyPStrict(sliceList, evt, fParams.CorrectedOpFlashLabel() + slice_tag_suff); - std::vector> slcCorrectedOpFlash; + std::vector> slcCorrectedOpFlash; if (fmCorrectedOpFlash.isValid()) slcCorrectedOpFlash = fmCorrectedOpFlash.at(0); diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 65cf746cb..76c3903d4 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -36,7 +36,6 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_Reco sbnobj::Common_Analysis sbnobj::SBND_CRT - sbnobj::SBND_OpFlashTiming lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 97b6eae31..a711e1b58 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -264,17 +264,19 @@ namespace caf } - void FillCorrectedOpFlashTiming(const std::vector> &slcCorrectedOpFlash, + void FillCorrectedOpFlashTiming(const std::vector> &slcCorrectedOpFlash, caf::SRSlice& slice) { slice.correctedOpFlash.setDefault(); if ( slcCorrectedOpFlash.empty()==false ) { - const sbnd::OpFlashTiming::CorrectedOpFlashTiming &_correctedOpFlash = *slcCorrectedOpFlash[0]; + const sbn::CorrectedOpFlashTiming &_correctedOpFlash = *slcCorrectedOpFlash[0]; //TODO: use the score of the match to fill the information accordingly slice.correctedOpFlash.OpFlashT0 = _correctedOpFlash.OpFlashT0; slice.correctedOpFlash.UpstreamTime_lightonly = _correctedOpFlash.UpstreamTime_lightonly; slice.correctedOpFlash.UpstreamTime_tpczcorr = _correctedOpFlash.UpstreamTime_tpczcorr; slice.correctedOpFlash.UpstreamTime_propcorr_tpczcorr = _correctedOpFlash.UpstreamTime_propcorr_tpczcorr; + slice.correctedOpFlash.FMScore = _correctedOpFlash.FMScore; + slice.correctedOpFlash.SliceNuScore = _correctedOpFlash.SliceNuScore; } } diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 3cb5ed0c3..ef1e2964b 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -36,11 +36,11 @@ #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" #include "sbnobj/Common/Reco/TPCPMTBarycenterMatch.h" +#include "sbnobj/Common/Reco/CorrectedOpFlashTiming.h" #include "sbnobj/Common/CRT/CRTHit.hh" #include "sbnobj/Common/CRT/CRTTrack.hh" #include "sbnobj/SBND/CRT/CRTSpacePoint.hh" #include "sbnobj/SBND/CRT/CRTTrack.hh" -#include "sbnobj/SBND/OpFlashTiming/CorrectedOpFlashTiming.h" #include "sbnobj/Common/CRT/CRTPMTMatching.hh" #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" #include "nusimdata/SimulationBase/MCParticle.h" @@ -273,7 +273,7 @@ namespace caf void FillTPCPMTBarycenterMatch(const sbn::TPCPMTBarycenterMatch *matchInfo, caf::SRSlice& slice); - void FillCorrectedOpFlashTiming(const std::vector> &slcCorrectedOpFlash, + void FillCorrectedOpFlashTiming(const std::vector> &slcCorrectedOpFlash, caf::SRSlice& slice); void FillCVNScores(const lcvn::Result *cvnResult, From b256c77f82b6aa6bb2bcfd6011f5cc956667ad6c Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Tue, 9 Sep 2025 00:55:12 -0500 Subject: [PATCH 183/367] Starting point for CRTVeto in caf --- sbncode/CAFMaker/CAFMakerParams.h | 6 ++++ sbncode/CAFMaker/CAFMaker_module.cc | 52 +++++++++++++++++++++++++++++ sbncode/CAFMaker/FillReco.cxx | 12 +++++++ sbncode/CAFMaker/FillReco.h | 5 +++ 4 files changed, 75 insertions(+) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 572bb5545..c419ce10a 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -338,6 +338,12 @@ namespace caf "crttracks" // sbnd }; + Atom SBNDCRTVetoLabel { + Name("SBNDCRTVetoLabel"), + Comment("Label of sbnd CRT Veto."), + "crtveto" // sbnd + }; + Atom CRTPMTLabel { Name("CRTPMTLabel"), Comment("Label for the CRTPMT Matched variables from the crtpmt data product"), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index f51183b46..9bd4f87e9 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1602,6 +1602,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector srcrttracks; std::vector srcrtspacepoints; std::vector srsbndcrttracks; + caf::SRSBNDCRTVeto srsbndcrtveto; if(fDet == kICARUS) { @@ -1650,6 +1651,44 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillSBNDCRTTrack(sbndcrttracks[i], srsbndcrttracks.back()); } } + // Fill CRT Veto + std::cout << std::endl; + std::cout << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << std::endl; + std::cout << std::endl; + art::Handle> sbndcrtveto_handle; + GetByLabelStrict(evt, fParams.SBNDCRTVetoLabel(), sbndcrtveto_handle); + // fill into event + if (sbndcrtveto_handle.isValid()) { + std::cout << "Found a valid CRT Veto Handle!!!" << std::endl; + const std::vector &sbndcrtvetos = *sbndcrtveto_handle; + //srsbndcrtveto.emplace_back(); + FillSBNDCRTVeto(sbndcrtvetos[0], srsbndcrtveto); + } + else { + std::cout << "Invalid CRT Veto Handle!" << std::endl; + return; + } + std::cout << std::endl; + std::cout << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; + std::cout << std::endl; + std::cout << std::endl; } // Get all of the CRTPMT Matches @@ -2349,6 +2388,12 @@ void CAFMaker::produce(art::Event& evt) noexcept { } // end loop over slices + std::cout << std::endl; + std::cout << std::endl; + std::cout << "// -------------- DEBUG FILL REC TREE --------------------- //" < const& hits, From 6cbfa8df1a0435d5c950de487608c02fef6453ee Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Tue, 9 Sep 2025 23:47:11 -0500 Subject: [PATCH 184/367] Added veto values in a different way for testing --- sbncode/CAFMaker/CAFMaker_module.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 9bd4f87e9..eeefc112d 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2420,6 +2420,12 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.crtpmt_matches = srcrtpmtmatches; rec.ncrtpmt_matches = srcrtpmtmatches.size(); + rec.sbnd_crtveto_v0 = srsbndcrtveto.V0; + rec.sbnd_crtveto_v1 = srsbndcrtveto.V1; + rec.sbnd_crtveto_v2 = srsbndcrtveto.V2; + rec.sbnd_crtveto_v3 = srsbndcrtveto.V3; + rec.sbnd_crtveto_v4 = srsbndcrtveto.V4; + std::cout << std::endl; std::cout << std::endl; std::cout << "// -------------- DEBUG After FILL REC TREE --------------------- //" < Date: Fri, 12 Sep 2025 15:26:19 -0500 Subject: [PATCH 185/367] adds new bundles --- .../ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc | 12 +++++++++++- .../job/icarusbnbspillinfo.fcl | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index 8802db658..66ce6964e 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -16,6 +16,8 @@ #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV3Fragment.hh" #include +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" +#include "sbncode/BeamSpillInfoRetriever/getFOM.h" namespace sbn { class ICARUSBNBRetriever; @@ -115,6 +117,8 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { // art::ServiceHandle ifbeam_handle; std::unique_ptr bfp; + std::unique_ptr offsets; + std::unique_ptr vp873; std::unique_ptr bfp_mwr; // @@ -213,6 +217,8 @@ sbn::ICARUSBNBRetriever::ICARUSBNBRetriever(Parameters const& params) raw_data_label(params().RawDataLabel()), fDeviceUsedForTiming(params().DeviceUsedForTiming()), bfp( ifbeam_handle->getBeamFolder(params().Bundle(), params().URL(), params().TimeWindow())), + vp873( ifbeam_handle->getBeamFolder(params().VP873Bundle(), params().URL(), params().TimeWindow())), + offsets( ifbeam_handle->getBeamFolder(params().OffsetBundle(), params().URL(), params().TimeWindow())), bfp_mwr( ifbeam_handle->getBeamFolder(params().MultiWireBundle(), params().URL(), params().MWR_TimeWindow())), fTriggerDatabaseFile(params().TriggerDatabaseFile()) { @@ -231,6 +237,8 @@ sbn::ICARUSBNBRetriever::ICARUSBNBRetriever(Parameters const& params) // bfp->set_epsilon(0.02); //20 ms, this was tuned by hand and compared to IFBeamDB times bfp_mwr->set_epsilon(0.5); + vp873->set_epsilon(0.02); + offsets->set_epsilon(600); //bfp_mwr->setValidWindow(86400); bfp_mwr->setValidWindow(3605); @@ -433,7 +441,9 @@ int sbn::ICARUSBNBRetriever::matchMultiWireData( }//end loop over MWR devices - sbn::BNBSpillInfo spillInfo = sbn::pot::makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp); + sbn::BNBSpillInfo spillInfo = sbn::pot::makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR, bfp, offsets, vp873); + double const spillFOM = sbn::getBNBqualityFOM(spillInfo); + spillInfo.FOM = spillFOM; beamInfos.push_back(std::move(spillInfo)); diff --git a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl index 16cd24c8b..03c63ab3e 100644 --- a/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/icarusbnbspillinfo.fcl @@ -9,6 +9,8 @@ icarusbnbspillinfo: { URL: "" #keep this blank and we're good Bundle: "BoosterNeutrinoBeam_read_expanded" MultiWireBundle: "BNBMultiWire" + VP873Bundle: "BNB_monitor" + OffsetBundle: "BNB_BPM_settings" TimeWindow: "700" #seconds MWR_TimeWindow: "3601" #seconds raw_data_label: "daq" From 0201e501a0cffc9c536c49d084585aa528ade80f Mon Sep 17 00:00:00 2001 From: Nathaniel Date: Fri, 12 Sep 2025 16:04:21 -0500 Subject: [PATCH 186/367] atom for new bundles --- .../ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index 66ce6964e..5c3e38b21 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -71,7 +71,16 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { Name{ "MultiWireBundle" }, Comment{ "name of collections of devices to grab from IFbeam for use as MWRdevices." } }; - + + fhicl::Atom VP873Bundle { + Name{ "VP873Bundle" }, + Comment{ "name of collections of devices to grab from IFbeam for use as VP873." } + }; + + fhicl::Atom OffsetBundle { + Name{ "OffsetBundle" }, + Comment{ "name of collections of devices to grab from IFbeam for use for offsets." } + }; fhicl::Atom MWR_TimeWindow { Name{ "MWR_TimeWindow" }, Comment{ "Window of time in seconds to use for mwr ifbeam queries." } From 34cc29f633588059c30367a45a981404296e19ba Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 12 Sep 2025 16:30:06 -0500 Subject: [PATCH 187/367] Fixes for compiler --- .../BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt | 1 + .../ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc | 2 +- sbncode/BeamSpillInfoRetriever/POTTools.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt index ffa6afb95..deeda3a5c 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt @@ -4,6 +4,7 @@ find_package(ifdh_art) cet_build_plugin(ICARUSBNBRetriever art::module LIBRARIES sbn_POTTools + sbn_getFOM SQLite::SQLite3 ) diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc index 5c3e38b21..077eb4c9e 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/ICARUSBNBRetriever_module.cc @@ -126,8 +126,8 @@ class sbn::ICARUSBNBRetriever : public art::EDProducer { // art::ServiceHandle ifbeam_handle; std::unique_ptr bfp; - std::unique_ptr offsets; std::unique_ptr vp873; + std::unique_ptr offsets; std::unique_ptr bfp_mwr; // diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index d9b4948ca..b13b987b6 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -74,7 +74,7 @@ namespace sbn::pot{ double LM875B = 0; // units R/s double LM875C = 0; // units R/s double HP873 = 0; // units mm - double VP873 = 0; // units mm + double VP873 = 0; // units mm; not in the first IFBeam query bunch double HP875 = 0; // units mm double VP875 = 0; // units mm double HPTG1 = 0; // units mm From 6c85c5288c6772f9598b1b3df5887d0d15e970b7 Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 12 Sep 2025 17:32:14 -0500 Subject: [PATCH 188/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c63696b8..ceb8f430f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.09.00 LANGUAGES CXX) +project(sbncode VERSION 10.10.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index c82e759aa..43011beaf 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -252,10 +252,10 @@ libdir fq_dir lib # #################################### product version qual flags -genie_xsec v3_06_00 - +genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_09_00 - -sbnalg v10_09_00 - +larsoft v10_10_02 - +sbnalg v10_10_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_07 - systematicstools v01_04_04 - From 65892227a1f988ca38156a756357a3d3e7f00cde Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Mon, 15 Sep 2025 16:48:34 -0500 Subject: [PATCH 189/367] New producer module to generate single (or a couple) MC muons for input to overlay wiremod samples. --- sbncode/EventGenerator/CMakeLists.txt | 1 + .../EventGenerator/WireModGen/CMakeLists.txt | 52 ++ .../WireModGen/CORSIKAGenSBN.cc | 603 ++++++++++++++++++ .../EventGenerator/WireModGen/CORSIKAGenSBN.h | 299 +++++++++ .../FilterPrimarySimChannel_module.cc | 84 +++ .../FilterPrimarySimEnergyDepo_module.cc | 120 ++++ .../WireModGen/WireModMuon_module.cc | 322 ++++++++++ .../WireModGen/filter_wiremod_sbn.fcl | 9 + .../WireModGen/wiremodmuon_sbn.fcl | 22 + 9 files changed, 1512 insertions(+) create mode 100644 sbncode/EventGenerator/WireModGen/CMakeLists.txt create mode 100644 sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.cc create mode 100644 sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.h create mode 100644 sbncode/EventGenerator/WireModGen/FilterPrimarySimChannel_module.cc create mode 100644 sbncode/EventGenerator/WireModGen/FilterPrimarySimEnergyDepo_module.cc create mode 100644 sbncode/EventGenerator/WireModGen/WireModMuon_module.cc create mode 100644 sbncode/EventGenerator/WireModGen/filter_wiremod_sbn.fcl create mode 100644 sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl diff --git a/sbncode/EventGenerator/CMakeLists.txt b/sbncode/EventGenerator/CMakeLists.txt index b5329a992..292682726 100644 --- a/sbncode/EventGenerator/CMakeLists.txt +++ b/sbncode/EventGenerator/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(MeVPrtl) add_subdirectory(MultiPart) +add_subdirectory(WireModGen) diff --git a/sbncode/EventGenerator/WireModGen/CMakeLists.txt b/sbncode/EventGenerator/WireModGen/CMakeLists.txt new file mode 100644 index 000000000..c119741b6 --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/CMakeLists.txt @@ -0,0 +1,52 @@ +cet_build_plugin(WireModMuon art::EDProducer + SOURCE CORSIKAGenSBN.cc WireModMuon_module.cc + LIBRARIES PRIVATE + larcore::Geometry_Geometry_service + larcorealg::Geometry + larcoreobj::SummaryData + nurandom::RandomUtils_NuRandomService_service + nusimdata::SimulationBase + art::Framework_Principal + art::Framework_Services_Registry + messagefacility::MF_MessageLogger + fhiclcpp::fhiclcpp + ifdh::ifdh + messagefacility::MF_MessageLogger + ROOT::Core + ROOT::EG + CLHEP::Random + SQLite::SQLite3 + lardata::DetectorInfoServices_DetectorPropertiesServiceStandard_service + lardata::DetectorInfoServices_DetectorClocksServiceStandard_service + lardata::DetectorClocksService +) + +cet_build_plugin(FilterPrimarySimChannel art::EDProducer + LIBRARIES PRIVATE + larsim::Simulation + art::Framework_Principal + art::Framework_Services_Registry + messagefacility::MF_MessageLogger + fhiclcpp::fhiclcpp + messagefacility::MF_MessageLogger +) + +cet_build_plugin(FilterPrimarySimEnergyDepo art::EDProducer + LIBRARIES PRIVATE + art::Framework_Services_Registry + larsim::Simulation + art::Framework_Principal + art::Framework_Services_Registry + messagefacility::MF_MessageLogger + fhiclcpp::fhiclcpp + messagefacility::MF_MessageLogger + larcore::Geometry_Geometry_service + larcorealg::Geometry + lardata::DetectorInfoServices_DetectorPropertiesServiceStandard_service + lardata::DetectorInfoServices_DetectorClocksServiceStandard_service + lardata::DetectorClocksService +) + +install_headers() +install_fhicl() +install_source() diff --git a/sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.cc b/sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.cc new file mode 100644 index 000000000..a9a4be372 --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.cc @@ -0,0 +1,603 @@ +//////////////////////////////////////////////////////////////////////// +/// \file CORSIKAGenSBN_module.cc +/// \brief Generator for cosmic-ray secondaries based on pre-generated CORSIKA shower databases. +/// Overrides the larsim CORSIKAGen module to allow to be inherited by a base class. +/// +/// \author gputnam@fnal.gov, taken from module by: Matthew.Bass@physics.ox.ac.uk +//////////////////////////////////////////////////////////////////////// + +#include "sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.h" + +namespace evgen { + + CORSIKAGenSBN::CORSIKAGenSBN(fhicl::ParameterSet const& p) + : EDProducer{p} + , fProjectToHeight(p.get("ProjectToHeight", 0.)) + , fShowerInputFiles(p.get>("ShowerInputFiles")) + , fShowerCopyType(p.get("ShowerCopyType", "IFDH")) + , fShowerFluxConstants(p.get>("ShowerFluxConstants")) + , fSampleTime(p.get("SampleTime", 0.)) + , fToffset(p.get("TimeOffset", 0.)) + , fBuffBox(p.get>("BufferBox", {0.0, 0.0, 0.0, 0.0, 0.0, 0.0})) + , fShowerAreaExtension(p.get("ShowerAreaExtension", 0.)) + , fRandomXZShift(p.get("RandomXZShift", 0.)) + , fGenEngine(art::ServiceHandle()->registerAndSeedEngine( + createEngine(0, "HepJamesRandom", "gen"), + "HepJamesRandom", + "gen", + p, + {"Seed", "SeedGenerator"})) + , fPoisEngine(art::ServiceHandle()->registerAndSeedEngine( + createEngine(0, "HepJamesRandom", "pois"), + "HepJamesRandom", + "pois", + p, + "SeedPoisson")) + { + if (fShowerInputFiles.size() != fShowerFluxConstants.size() || fShowerInputFiles.size() == 0 || + fShowerFluxConstants.size() == 0) + throw cet::exception("CORSIKAGenSBN") + << "ShowerInputFiles and ShowerFluxConstants have different or invalid sizes!" + << "\n"; + fShowerInputs = fShowerInputFiles.size(); + + if (fSampleTime == 0.) throw cet::exception("CORSIKAGenSBN") << "SampleTime not set!"; + + if (fProjectToHeight == 0.) mf::LogInfo("CORSIKAGenSBN") << "Using 0. for fProjectToHeight!"; + // create a default random engine; obtain the random seed from NuRandomService, + // unless overridden in configuration with key "Seed" + + this->openDBs(p.get("module_label")); + this->populateNShowers(); + this->populateTOffset(); + + produces>(); + produces(); + } + + CORSIKAGenSBN::~CORSIKAGenSBN() + { + for (int i = 0; i < fShowerInputs; i++) { + sqlite3_close(fdb[i]); + } + //cleanup temp files + fIFDH->cleanup(); + } + + void CORSIKAGenSBN::ProjectToBoxEdge(const double xyz[], + const double indxyz[], + const double xlo, + const double xhi, + const double ylo, + const double yhi, + const double zlo, + const double zhi, + double xyzout[]) + { + + //we want to project backwards, so take mirror of momentum + const double dxyz[3] = {-indxyz[0], -indxyz[1], -indxyz[2]}; + + // Compute the distances to the x/y/z walls + double dx = 99.E99; + double dy = 99.E99; + double dz = 99.E99; + if (dxyz[0] > 0.0) { dx = (xhi - xyz[0]) / dxyz[0]; } + else if (dxyz[0] < 0.0) { + dx = (xlo - xyz[0]) / dxyz[0]; + } + if (dxyz[1] > 0.0) { dy = (yhi - xyz[1]) / dxyz[1]; } + else if (dxyz[1] < 0.0) { + dy = (ylo - xyz[1]) / dxyz[1]; + } + if (dxyz[2] > 0.0) { dz = (zhi - xyz[2]) / dxyz[2]; } + else if (dxyz[2] < 0.0) { + dz = (zlo - xyz[2]) / dxyz[2]; + } + + // Choose the shortest distance + double d = 0.0; + if (dx < dy && dx < dz) + d = dx; + else if (dy < dz && dy < dx) + d = dy; + else if (dz < dx && dz < dy) + d = dz; + + // Make the step + for (int i = 0; i < 3; ++i) { + xyzout[i] = xyz[i] + dxyz[i] * d; + } + } + + void CORSIKAGenSBN::openDBs(std::string const& module_label) + { + //choose files based on fShowerInputFiles, copy them with ifdh, open them + // for c2: statement is unused + //sqlite3_stmt *statement; + CLHEP::RandFlat flat(fGenEngine); + + //setup ifdh object + if (!fIFDH) fIFDH = new ifdh_ns::ifdh; + const char* ifdh_debug_env = std::getenv("IFDH_DEBUG_LEVEL"); + if (ifdh_debug_env) { + mf::LogInfo("CORSIKAGenSBN") << "IFDH_DEBUG_LEVEL: " << ifdh_debug_env << "\n"; + fIFDH->set_debug(ifdh_debug_env); + } + + //get ifdh path for each file in fShowerInputFiles, put into selectedflist + //if 1 file returned, use that file + //if >1 file returned, randomly select one file + //if 0 returned, make exeption for missing files + std::vector> selectedflist; + for (int i = 0; i < fShowerInputs; i++) { + if (fShowerInputFiles[i].find("*") == std::string::npos) { + //if there are no wildcards, don't call findMatchingFiles + selectedflist.push_back(std::make_pair(fShowerInputFiles[i], 0)); + mf::LogInfo("CorsikaGen") << "Selected" << selectedflist.back().first << "\n"; + } + else { + //use findMatchingFiles + //default to IFDH approach when wildcards in path + std::vector> flist; + std::string path(gSystem->DirName(fShowerInputFiles[i].c_str())); + std::string pattern(gSystem->BaseName(fShowerInputFiles[i].c_str())); + flist = fIFDH->findMatchingFiles(path, pattern); + unsigned int selIndex = -1; + if (flist.size() == 1) { //0th element is the search path:pattern + selIndex = 0; + } + else if (flist.size() > 1) { + selIndex = (unsigned int)(flat() * (flist.size() - 1) + + 0.5); //rnd with rounding, dont allow picking the 0th element + } + else { + throw cet::exception("CORSIKAGenSBN") + << "No files returned for path:pattern: " << path << ":" << pattern << std::endl; + } + selectedflist.push_back(flist[selIndex]); + mf::LogInfo("CorsikaGen") << "For " << fShowerInputFiles[i] << ":" << pattern << "\nFound " + << flist.size() << " candidate files" + << "\nChoosing file number " << selIndex << "\n" + << "\nSelected " << selectedflist.back().first << "\n"; + } + } + + //do the fetching, store local filepaths in locallist + std::vector locallist; + for (unsigned int i = 0; i < selectedflist.size(); i++) { + mf::LogInfo("CorsikaGen") << "Fetching: " << selectedflist[i].first << " " + << selectedflist[i].second << "\n"; + if (fShowerCopyType == "IFDH") { + std::string fetchedfile(fIFDH->fetchInput(selectedflist[i].first)); + MF_LOG_DEBUG("CorsikaGen") << "Fetched; local path: " << fetchedfile << "; copy type: IFDH"; + locallist.push_back(fetchedfile); + } + else if (fShowerCopyType == "DIRECT") { + std::string fetchedfile(selectedflist[i].first); + MF_LOG_DEBUG("CorsikaGen") + << "Fetched; local path: " << fetchedfile << "; copy type: DIRECT"; + locallist.push_back(fetchedfile); + } + else + throw cet::exception("CORSIKAGenSBN") + << "Error copying shower db: ShowerCopyType must be \"IFDH\" or \"DIRECT\"\n"; + } + + //open the files in fShowerInputFilesLocalPaths with sqlite3 + for (unsigned int i = 0; i < locallist.size(); i++) { + //prepare and execute statement to attach db file + int res = sqlite3_open(locallist[i].c_str(), &fdb[i]); + if (res != SQLITE_OK) + throw cet::exception("CORSIKAGenSBN") + << "Error opening db: (" << locallist[i].c_str() << ") (" << res + << "): " << sqlite3_errmsg(fdb[i]) << "; memory used:<<" << sqlite3_memory_used() << "/" + << sqlite3_memory_highwater(0) << "\n"; + else + mf::LogInfo("CORSIKAGenSBN") << "Attached db " << locallist[i] << "\n"; + } + } + + double CORSIKAGenSBN::wrapvar(const double var, const double low, const double high) + { + //wrap variable so that it's always between low and high + return (var - (high - low) * floor(var / (high - low))) + low; + } + + double CORSIKAGenSBN::wrapvarBoxNo(const double var, const double low, const double high, int& boxno) + { + //wrap variable so that it's always between low and high + boxno = int(floor(var / (high - low))); + return (var - (high - low) * floor(var / (high - low))) + low; + } + + void CORSIKAGenSBN::populateTOffset() + { + //populate TOffset_corsika by finding minimum ParticleTime from db file + + sqlite3_stmt* statement; + const std::string kStatement("select min(t) from particles"); + double t = 0.; + + for (int i = 0; i < fShowerInputs; i++) { + //build and do query to get run min(t) from each db + if (sqlite3_prepare(fdb[i], kStatement.c_str(), -1, &statement, 0) == SQLITE_OK) { + int res = 0; + res = sqlite3_step(statement); + if (res == SQLITE_ROW) { + t = sqlite3_column_double(statement, 0); + mf::LogInfo("CORSIKAGenSBN") + << "For showers input " << i << " found particles.min(t)=" << t << "\n"; + if (i == 0 || t < fToffset_corsika) fToffset_corsika = t; + } + else { + throw cet::exception("CORSIKAGenSBN") + << "Unexpected sqlite3_step return value: (" << res << "); " + << "ERROR:" << sqlite3_errmsg(fdb[i]) << "\n"; + } + } + else { + throw cet::exception("CORSIKAGenSBN") << "Error preparing statement: (" << kStatement << "); " + << "ERROR:" << sqlite3_errmsg(fdb[i]) << "\n"; + } + } + + mf::LogInfo("CORSIKAGenSBN") << "Found corsika timeoffset [ns]: " << fToffset_corsika << "\n"; + } + + void CORSIKAGenSBN::populateNShowers() + { + //populate vector of the number of showers per event based on: + //AREA the showers are being distributed over + //TIME of the event (fSampleTime) + //flux constants that determine the overall normalizations (fShowerFluxConstants) + //Energy range over which the sample was generated (ERANGE_*) + //power spectrum over which the sample was generated (ESLOPE) + + //compute shower area based on the maximal x,z dimensions of cryostat boundaries + fShowerAreaExtension + art::ServiceHandle geom; + for (auto const& cryostat : geom->Iterate()) { + double bounds[6] = {0.}; + cryostat.Boundaries(bounds); + for (unsigned int bnd = 0; bnd < 6; bnd++) { + mf::LogVerbatim("CORSIKAGenSBN") << "Cryo Boundary: " << bnd << "=" << bounds[bnd] + << " ( + Buffer=" << fBuffBox[bnd] << ")\n"; + if (fabs(bounds[bnd]) > fabs(fShowerBounds[bnd])) { fShowerBounds[bnd] = bounds[bnd]; } + } + } + //add on fShowerAreaExtension without being clever + fShowerBounds[0] = fShowerBounds[0] - fShowerAreaExtension; + fShowerBounds[1] = fShowerBounds[1] + fShowerAreaExtension; + fShowerBounds[4] = fShowerBounds[4] - fShowerAreaExtension; + fShowerBounds[5] = fShowerBounds[5] + fShowerAreaExtension; + + double showersArea = (fShowerBounds[1] / 100 - fShowerBounds[0] / 100) * + (fShowerBounds[5] / 100 - fShowerBounds[4] / 100); + + mf::LogInfo("CORSIKAGenSBN") << "Area extended by : " << fShowerAreaExtension + << "\nShowers to be distributed betweeen: x=" << fShowerBounds[0] + << "," << fShowerBounds[1] << " & z=" << fShowerBounds[4] << "," + << fShowerBounds[5] + << "\nShowers to be distributed with random XZ shift: " + << fRandomXZShift << " cm" + << "\nShowers to be distributed over area: " << showersArea << " m^2" + << "\nShowers to be distributed over time: " << fSampleTime << " s" + << "\nShowers to be distributed with time offset: " << fToffset + << " s" + << "\nShowers to be distributed at y: " << fShowerBounds[3] << " cm"; + + //db variables + sqlite3_stmt* statement; + const std::string kStatement("select erange_high,erange_low,eslope,nshow from input"); + double upperLimitOfEnergyRange = 0., lowerLimitOfEnergyRange = 0., energySlope = 0., + oneMinusGamma = 0., EiToOneMinusGamma = 0., EfToOneMinusGamma = 0.; + + for (int i = 0; i < fShowerInputs; i++) { + //build and do query to get run info from databases + // double thisrnd=flat();//need a new random number for each query + if (sqlite3_prepare(fdb[i], kStatement.c_str(), -1, &statement, 0) == SQLITE_OK) { + int res = 0; + res = sqlite3_step(statement); + if (res == SQLITE_ROW) { + upperLimitOfEnergyRange = sqlite3_column_double(statement, 0); + lowerLimitOfEnergyRange = sqlite3_column_double(statement, 1); + energySlope = sqlite3_column_double(statement, 2); + fMaxShowers.push_back(sqlite3_column_int(statement, 3)); + oneMinusGamma = 1 + energySlope; + EiToOneMinusGamma = pow(lowerLimitOfEnergyRange, oneMinusGamma); + EfToOneMinusGamma = pow(upperLimitOfEnergyRange, oneMinusGamma); + mf::LogVerbatim("CORSIKAGenSBN") + << "For showers input " << i << " found e_hi=" << upperLimitOfEnergyRange + << ", e_lo=" << lowerLimitOfEnergyRange << ", slope=" << energySlope + << ", k=" << fShowerFluxConstants[i] << "\n"; + } + else { + throw cet::exception("CORSIKAGenSBN") + << "Unexpected sqlite3_step return value: (" << res << "); " + << "ERROR:" << sqlite3_errmsg(fdb[i]) << "\n"; + } + } + else { + throw cet::exception("CORSIKAGenSBN") << "Error preparing statement: (" << kStatement << "); " + << "ERROR:" << sqlite3_errmsg(fdb[i]) << "\n"; + } + + //this is computed, how? + double NShowers = (M_PI * showersArea * fShowerFluxConstants[i] * + (EfToOneMinusGamma - EiToOneMinusGamma) / oneMinusGamma) * + fSampleTime; + fNShowersPerEvent.push_back(NShowers); + mf::LogVerbatim("CORSIKAGenSBN") + << "For showers input " << i << " the number of showers per event is " << (int)NShowers + << "\n"; + } + } + + void CORSIKAGenSBN::GetSample(simb::MCTruth& mctruth) + { + //for each input, randomly pull fNShowersPerEvent[i] showers from the Particles table + //and randomly place them in time (between -fSampleTime/2 and fSampleTime/2) + //wrap their positions based on the size of the area under consideration + //based on http://nusoft.fnal.gov/larsoft/doxsvn/html/CRYHelper_8cxx_source.html (Sample) + + //query from sqlite db with select * from particles where shower in (select id from showers ORDER BY substr(id*0.51123124141,length(id)+2) limit 100000) ORDER BY substr(shower*0.51123124141,length(shower)+2); + //where 0.51123124141 is a random seed to allow randomly selecting rows and should be randomly generated for each query + //the inner order by is to select randomly from the possible shower id's + //the outer order by is to make sure the shower numbers are ordered randomly (without this, the showers always come out ordered by shower number + //and 100000 is the number of showers to be selected at random and needs to be less than the number of showers in the showers table + + //TDatabasePDG is for looking up particle masses + static TDatabasePDG* pdgt = TDatabasePDG::Instance(); + + //db variables + sqlite3_stmt* statement; + const TString kStatement( + "select shower,pdg,px,py,pz,x,z,t,e from particles where shower in (select id from showers " + "ORDER BY substr(id*%f,length(id)+2) limit %d) ORDER BY substr(shower*%f,length(shower)+2)"); + + CLHEP::RandFlat flat(fGenEngine); + CLHEP::RandPoissonQ randpois(fPoisEngine); + + // get geometry and figure where to project particles to, based on CRYHelper + art::ServiceHandle geom; + double x1, x2; + double y1, y2; + double z1, z2; + geom->WorldBox(&x1, &x2, &y1, &y2, &z1, &z2); + + // make the world box slightly smaller so that the projection to + // the edge avoids possible rounding errors later on with Geant4 + double fBoxDelta = 1.e-5; + x1 += fBoxDelta; + x2 -= fBoxDelta; + y1 += fBoxDelta; + y2 = fProjectToHeight; + z1 += fBoxDelta; + z2 -= fBoxDelta; + + //populate mctruth + int ntotalCtr = 0; //count number of particles added to mctruth + int lastShower = + 0; //keep track of last shower id so that t can be randomized on every new shower + int nShowerCntr = 0; //keep track of how many showers are left to be added to mctruth + int nShowerQry = 0; //number of showers to query from db + int shower, pdg; + double px, py, pz, x, z, tParticleTime, etot, + showerTime = 0., showerTimex = 0., showerTimez = 0., showerXOffset = 0., showerZOffset = 0., + t; + for (int i = 0; i < fShowerInputs; i++) { + nShowerCntr = randpois.fire(fNShowersPerEvent[i]); + mf::LogInfo("CORSIKAGEN") << " Shower input " << i << " with mean " << fNShowersPerEvent[i] + << " generating " << nShowerCntr; + + while (nShowerCntr > 0) { + //how many showers should we query? + if (nShowerCntr > fMaxShowers[i]) { + nShowerQry = fMaxShowers[i]; //take the group size + } + else { + nShowerQry = nShowerCntr; //take the rest that are needed + } + //build and do query to get nshowers + double thisrnd = flat(); //need a new random number for each query + TString kthisStatement = TString::Format(kStatement.Data(), thisrnd, nShowerQry, thisrnd); + MF_LOG_DEBUG("CORSIKAGenSBN") << "Executing: " << kthisStatement; + if (sqlite3_prepare(fdb[i], kthisStatement.Data(), -1, &statement, 0) == SQLITE_OK) { + int res = 0; + //loop over database rows, pushing particles into mctruth object + while (1) { + res = sqlite3_step(statement); + if (res == SQLITE_ROW) { + /* + * Memo columns: + * [0] shower + * [1] particle ID (PDG) + * [2] momentum: x component [GeV/c] + * [3] momentum: y component [GeV/c] + * [4] momentum: z component [GeV/c] + * [5] position: x component [cm] + * [6] position: z component [cm] + * [7] time [ns] + * [8] energy [GeV] + */ + shower = sqlite3_column_int(statement, 0); + if (shower != lastShower) { + //each new shower gets its own random time and position offsets + showerTime = 1e9 * (flat() * fSampleTime); //converting from s to ns + showerTimex = 1e9 * (flat() * fSampleTime); //converting from s to ns + showerTimez = 1e9 * (flat() * fSampleTime); //converting from s to ns + //and a random offset in both z and x controlled by the fRandomXZShift parameter + showerXOffset = flat() * fRandomXZShift - (fRandomXZShift / 2); + showerZOffset = flat() * fRandomXZShift - (fRandomXZShift / 2); + } + pdg = sqlite3_column_int(statement, 1); + //get mass for this particle + double m = 0.; // in GeV + TParticlePDG* pdgp = pdgt->GetParticle(pdg); + if (pdgp) m = pdgp->Mass(); + + //Note: position/momentum in db have north=-x and west=+z, rotate so that +z is north and +x is west + //get momentum components + px = sqlite3_column_double(statement, 4); //uboone x=Particlez + py = sqlite3_column_double(statement, 3); + pz = -sqlite3_column_double(statement, 2); //uboone z=-Particlex + etot = sqlite3_column_double(statement, 8); + + //get/calculate position components + int boxnoX = 0, boxnoZ = 0; + x = wrapvarBoxNo(sqlite3_column_double(statement, 6) + showerXOffset, + fShowerBounds[0], + fShowerBounds[1], + boxnoX); + z = wrapvarBoxNo(-sqlite3_column_double(statement, 5) + showerZOffset, + fShowerBounds[4], + fShowerBounds[5], + boxnoZ); + tParticleTime = sqlite3_column_double( + statement, 7); //time offset, includes propagation time from top of atmosphere + //actual particle time is particle surface arrival time + //+ shower start time + //+ global offset (fcl parameter, in s) + //- propagation time through atmosphere + //+ boxNo{X,Z} time offset to make grid boxes have different shower times + t = tParticleTime + showerTime + (1e9 * fToffset) - fToffset_corsika + + showerTimex * boxnoX + showerTimez * boxnoZ; + //wrap surface arrival so that it's in the desired time window + t = wrapvar(t, (1e9 * fToffset), 1e9 * (fToffset + fSampleTime)); + + simb::MCParticle p(ntotalCtr, pdg, "primary", -200, m, 1); + + //project back to wordvol/fProjectToHeight + /* + * This back propagation goes from a point on the upper surface of + * the cryostat back to the edge of the world, except that that + * world is cut short by `fProjectToHeight` (`y2`) ceiling. + * The projection will most often lie on that ceiling, but it may + * end up instead on one of the side edges of the world, or even + * outside it. + */ + double xyzo[3]; + double x0[3] = {x, fShowerBounds[3], z}; + double dx[3] = {px, py, pz}; + this->ProjectToBoxEdge(x0, dx, x1, x2, y1, y2, z1, z2, xyzo); + + TLorentzVector pos( + xyzo[0], xyzo[1], xyzo[2], t); // time needs to be in ns to match GENIE, etc + TLorentzVector mom(px, py, pz, etot); + p.AddTrajectoryPoint(pos, mom); + mctruth.Add(p); + ntotalCtr++; + lastShower = shower; + } + else if (res == SQLITE_DONE) { + break; + } + else { + throw cet::exception("CORSIKAGenSBN") + << "Unexpected sqlite3_step return value: (" << res << "); " + << "ERROR:" << sqlite3_errmsg(fdb[i]) << "\n"; + } + } + } + else { + throw cet::exception("CORSIKAGenSBN") + << "Error preparing statement: (" << kthisStatement << "); " + << "ERROR:" << sqlite3_errmsg(fdb[i]) << "\n"; + } + nShowerCntr = nShowerCntr - nShowerQry; + } + } + } + + void CORSIKAGenSBN::beginRun(art::Run& run) + { + art::ServiceHandle geo; + run.put(std::make_unique(geo->DetectorName()), art::fullRun()); + } + + void CORSIKAGenSBN::produce(art::Event& evt) + { + std::unique_ptr> truthcol(new std::vector); + + art::ServiceHandle geom; + + simb::MCTruth truth; + truth.SetOrigin(simb::kCosmicRay); + + simb::MCTruth pretruth; + GetSample(pretruth); + mf::LogInfo("CORSIKAGenSBN") << "GetSample number of particles returned: " << pretruth.NParticles() + << "\n"; + // loop over particles in the truth object + for (int i = 0; i < pretruth.NParticles(); ++i) { + simb::MCParticle particle = pretruth.GetParticle(i); + const TLorentzVector& v4 = particle.Position(); + const TLorentzVector& p4 = particle.Momentum(); + double x0[3] = {v4.X(), v4.Y(), v4.Z()}; + double dx[3] = {p4.Px(), p4.Py(), p4.Pz()}; + + // now check if the particle goes through any cryostat in the detector + // if so, add it to the truth object. + for (auto const& cryostat : geom->Iterate()) { + double bounds[6] = {0.}; + cryostat.Boundaries(bounds); + + //add a buffer box around the cryostat bounds to increase the acceptance and account for scattering + //By default, the buffer box has zero size + for (unsigned int cb = 0; cb < 6; cb++) + bounds[cb] = bounds[cb] + fBuffBox[cb]; + + //calculate the intersection point with each cryostat surface + bool intersects_cryo = false; + for (int bnd = 0; bnd != 6; ++bnd) { + if (bnd < 2) { + double p2[3] = {bounds[bnd], + x0[1] + (dx[1] / dx[0]) * (bounds[bnd] - x0[0]), + x0[2] + (dx[2] / dx[0]) * (bounds[bnd] - x0[0])}; + if (p2[1] >= bounds[2] && p2[1] <= bounds[3] && p2[2] >= bounds[4] && + p2[2] <= bounds[5]) { + intersects_cryo = true; + break; + } + } + else if (bnd >= 2 && bnd < 4) { + double p2[3] = {x0[0] + (dx[0] / dx[1]) * (bounds[bnd] - x0[1]), + bounds[bnd], + x0[2] + (dx[2] / dx[1]) * (bounds[bnd] - x0[1])}; + if (p2[0] >= bounds[0] && p2[0] <= bounds[1] && p2[2] >= bounds[4] && + p2[2] <= bounds[5]) { + intersects_cryo = true; + break; + } + } + else if (bnd >= 4) { + double p2[3] = {x0[0] + (dx[0] / dx[2]) * (bounds[bnd] - x0[2]), + x0[1] + (dx[1] / dx[2]) * (bounds[bnd] - x0[2]), + bounds[bnd]}; + if (p2[0] >= bounds[0] && p2[0] <= bounds[1] && p2[1] >= bounds[2] && + p2[1] <= bounds[3]) { + intersects_cryo = true; + break; + } + } + } + + if (intersects_cryo) { + truth.Add(particle); + break; //leave loop over cryostats to avoid adding particle multiple times + } // end if particle goes into a cryostat + } // end loop over cryostats in the detector + + } // loop on particles + + mf::LogInfo("CORSIKAGenSBN") + << "Number of particles from getsample crossing cryostat + bounding box: " + << truth.NParticles() << "\n"; + + truthcol->push_back(truth); + evt.put(std::move(truthcol)); + + return; + } // end produce + +} // end namespace diff --git a/sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.h b/sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.h new file mode 100644 index 000000000..e70d45c53 --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.h @@ -0,0 +1,299 @@ +//////////////////////////////////////////////////////////////////////// +/// \file CORSIKAGenSBN.h +/// \brief Class definition for cosmic-ray generator. +/// +/// \author gputnam@fnal.gov, taken from module by: Matthew.Bass@physics.ox.ac.uk +//////////////////////////////////////////////////////////////////////// +// +// ROOT includes +#include "TDatabasePDG.h" +#include "TString.h" +#include "TSystem.h" //need BaseName and DirName + +// Framework includes +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +// art extensions +#include "nurandom/RandomUtils/NuRandomService.h" + +// larsoft includes +#include "larcore/Geometry/Geometry.h" +#include "larcoreobj/SummaryData/RunData.h" +#include "nusimdata/SimulationBase/MCParticle.h" +#include "nusimdata/SimulationBase/MCTruth.h" + +#include "CLHEP/Random/RandFlat.h" +#include "CLHEP/Random/RandPoissonQ.h" +#include "ifdh.h" //to handle flux files +#include + +namespace evgen { + + /** + * @brief LArSoft interface to CORSIKA event generator. + * + * @note A presentation on this module by the original author is archived at: + * https://indico.fnal.gov/event/10893/contribution/3/material/slides + * + * In CORSIKA jargon, a "shower" is the cascade of particles resulting from + * a primary cosmic ray interaction. + * This module creates a single `simb::MCTruth` object (stored as data product + * into a `std::vector` with a single entry) containing all + * the particles from cosmic ray showers crossing a _surface_ above the + * detector. + * + * The generation procedure consists of selecting showers from a database of + * *pregenerated* events, and then to adapt them to the parameters requested + * in the module configuration. Pregenerated showers are "observed" at a + * altitude set in CORSIKA configuration. + * + * Databases need to be stored as files in SQLite3 format. Multiple file + * sources can be specified (`ShowerInputFiles` configuration parameter). + * From each source, one database file is selected and copied locally via + * IFDH. + * From each source, showers are extracted proportionally to the relative flux + * specified in the configuration (specified in `ShowerFluxConstants`, + * see @ref CORSIKAGenSBN_Normalization "normalization" below). + * The actual number of showers per event and per source is extracted + * according to a Poisson distribution around the predicted average number of + * primary cosmic rays for that source. + * + * + * Flux normalization + * ------------------- + * + * @anchor CORSIKAGenSBN_Normalization + * + * CORSIKA generates showers from each specific cosmic ray type @f$ A @f$ + * (e.g. iron, proton, etc.) according to a power law distribution + * @f$ \Phi_{A}(E) \propto E^{-\gamma_{A}} @f$ of the primary + * particle energy @f$ E @f$ [GeV]. When sampling pregenerated events, we + * bypass the normalization imposed by CORSIKA and gain complete + * control on it. + * + * Within CORSIKAGenSBN, for each source (usually each on a different primary + * cosmic ray type, e.g. iron, proton, etc.), the average number of generated + * showers is + * @f$ n_{A} = \pi S T k_{A} \int E^{-\gamma_{A}} dE @f$ with @f$ S @f$ the + * area of the surface the flux passes across, @f$ T @f$ the exposure time, + * the integral defined over the full energy range of the pregenerated showers + * in the source, and @f$ k_{A} @f$ a factor specified in the configuration + * (`ShowerFluxConstants` parameters). + * This is the flux of primary cosmic rays, not of the observed particles + * from their showers. Note that it depends on an area and a time interval, + * but it is uniform with respect to translations and constant in time. + * + * As explained @ref CORSIKAGenSBN_Coverage "below", we consider only the + * secondary particles that cross an "observation" surface. + * After cosmic ray primary particles cross the flux surface (@f$ S_{\Phi} @f$ + * above), they develop into showers of particles that spread across large + * areas. Limiting ourself to the observation of particles on a small surface + * @f$ S_{o} @f$ has two effects. We lose the part of the showers that misses + * that surface @f$ S_{o} @f$. Also, considering a span of time with + * multiple showers, we miss particles from other hypothetical showers + * whose primaries crossed outside the generation surface @f$ S_{\Phi} @f$ + * whose shower development would leak into @f$ S_{o} @f$: we did not simulate + * those showers at all! + * In terms of total flux of observed particles, under the assumption that the + * flux is uniform in space, choosing @f$ S_{\Phi} @f$ the same size as + * @f$ S_{o} @f$ makes the two effects get the same size: just as many + * particles from primaries from @f$ S_{\Phi} @f$ leak out of @f$ S_{o} @f$, + * as many particles from primaries from outside @f$ S_{\Phi} @f$ sneak in + * @f$ S_{o} @f$. + * In that case, counting _all_ the particles from the primaries crossing a + * surface @f$ S_{\Phi} @f$ of area _S_ regardless of where they land + * yields the right amount of cosmic ray secondary particles across an + * observation surface @f$ S_{o} @f$ also of area _S_. Practically, + * the particles landing outside @f$ S_{o} @f$ need to be recovered to + * preserve the correct normalization, which is described in the + * @ref CORSIKAGenSBN_Coverage "next section". + * + * + * Surface coverage, position and timing + * -------------------------------------- + * + * @anchor CORSIKAGenSBN_Coverage + * + * The surface we detect the particles through (let's call it @f$ S_{d} @f$) + * is defined by the smallest _rectangle_ including all cryostats in the + * detector, and located at the height of the ceiling of the tallest cryostat. + * This surface can be increased by specifying a positive value for + * `ShowerAreaExtension` configuration parameter, in which case each side of + * the rectangle will be extended by that amount. + * + * Showers are extracted one by one from the pregenerated samples and treated + * independently. + * Ideally, the detection surface @f$ S_{d} @f$ would be at the same exact + * altitude as the observation surface set in CORSIKA (called @f$ S_{o} @f$ + * above). In practice, we go the other way around, with the assumption that + * the shower observed at @f$ S_{d} @f$ would be very close to the one we + * actually generated at @f$ S_{o} @f$, and teleport the generated particles + * on @f$ S_{d} @f$. Since the cryostats may be just meters from the earth + * surface @f$ S_{o} @f$ lies on, this is an acceptable approximation. + * + * All the particles of one shower are compelled within surface @f$ S_{d} @f$ + * as a first step. As explained when describing the + * @anchor CORSIKAGenSBN_Normalization "normalization", we need to keep all the + * shower particles, one way or the other. + * So, particles of the shower that fell out of @f$ S_{d} @f$ are repackaged + * into other showers and translated back in. This is equivalent to assume the + * primary cosmic rays originating such shower would happen outside + * our generation volume (@f$ S_{\Phi} @f$), and their shower would then spill + * into @f$ S_{d} @f$. Since these repackaged showers are in principle + * independent and uncorrelated, they are assigned a random time different + * than the main shower, leveraging the assumption of constantness of the + * flux. + * + * As for the azimuth, this module uses an approximation by setting north + * direction to match the _z_ axis of LArSoft geometry (typically assumed + * to be the direction of the beam particle). + * + * The particles so manipulated are then back-propagated from the observation + * surface to an absolute height defined by `ProjectToHeight` (although for + * particular combination of position and direction, the particles might be + * propagated back to the edge of the world, or even outside it). + * + * As a final filter, only the particles whose straight projections cross any + * of the cryostats (with some buffer volume around, defined by `BufferBox`) + * are stored, while the other ones are discarded. Note that the actual + * interactions that particles from the generation surface undergo may deviate + * them enough to miss the cryostats anyway, and conversely particles that + * have been filtered out because shooting off the cryostats might have been + * subsequently deviated to actually cross them. This effect is not corrected + * for at this time. + * + * The time of the showers is uniformly distributed within the configured + * time interval, defined by `SampleTime` starting from `TimeOffset`. + * + * + * Configuration parameters + * ========================= + * + * * `ShowerInputFiles` (list of paths; mandatory): a list of file paths to + * pregenerated CORSIKA shower files. Each entry can be a single file or + * use wildcards (`*`) to specify a set of files to choose among. + * Paths and wildcards are processed by IFDH. + * * `ShowerFluxConstants` (list of real numbers; mandatory): for each entry + * @f$ A @f$ in `ShowerInputFiles`, specify the normalization factor + * @f$ K_{A} @f$ of their distribution [@f$ m^{-2}s^{-1} @f$] + * * `ProjectToHeight` (real, default: `0`): the generated particles will + * appear to come from this height [cm] + * * `TimeOffset` (real; default: `0`): start time of the exposure window [s], + * relative to the + * @ref DetectorClocksSimulationTime "simulation time start" + * * `SampleTime` (real; mandatory): duration of the simulated exposure to + * cosmic rays [s] + * * `ShowerAreaExtension` (real; default: `0`): + * extend the size of the observation surface of shower particles (_S_) + * by this much [cm]; e.g. 1000 will extend 10 m on each side + * * `RandomXZShift` (real; default: `0`): the original position of each + * shower is randomly shifted within a square with this length as side + * [cm] + * * `BufferBox` (list of six lengths, all `0` by default): + * extension to the volume of each cryostat for the purpose of filtering + * out the particles which do not cross the detector; each cryostat volume + * is independently extended by the same amount, specified here as + * *shifts* to lower _x_, higher _x_, lower _y_, higher _y_, lower _z_ + * and higher _z_, in that order [cm] (note that to extend e.g. the + * negative _x_ side by 5 meters the parameter value should be -500) + * * `SeedGenerator` (integer): force random number generator for event + * generation to the specified value + * * `SeedPoisson` (integer): force random number generator for number of + * showers to the specified value + * * `Seed`: alias for `SeedGenerator` + * + * + * Random engines + * --------------- + * + * Currently two random engines are used: + * * a generator engine (driven by `SeedGenerator`), of general use + * * a "Poisson" engine (driven by `SeedPoisson`), only used to determine the + * number of showers to be selected on each event + * + */ + class CORSIKAGenSBN : public art::EDProducer { + public: + explicit CORSIKAGenSBN(fhicl::ParameterSet const& pset); + virtual ~CORSIKAGenSBN(); + + void produce(art::Event& evt); + void beginRun(art::Run& run); + + protected: + void openDBs(std::string const& module_label); + void populateNShowers(); + void populateTOffset(); + void GetSample(simb::MCTruth&); + double wrapvar(const double var, const double low, const double high); + double wrapvarBoxNo(const double var, const double low, const double high, int& boxno); + /** + * @brief Propagates a point back to the surface of a box. + * @param xyz coordinates of the point to be propagated (`{ x, y, z }`) + * @param dxyz direction of the point (`{ dx, dy, dz }`) + * @param xlo lower _x_ coordinate of the target box + * @param xhi upper _x_ coordinate of the target box + * @param ylo lower _y_ coordinate of the target box + * @param yhi upper _y_ coordinate of the target box + * @param zlo lower _z_ coordinate of the target box + * @param zhi upper _z_ coordinate of the target box + * @param xyzout _(output, room for at least 3 numbers)_ propagated point + * + * The point `xyz`, assumed to be inside the box, is propagated at the level + * of _the closest among the sides of the box_. Note that this means the + * propagated point might still be not on the surface of the box, even if it + * would later reach it. + * It is anyway guaranteed that `xyzout` is not inside the target box, and + * that at least one of its three coordinates is on the box surface. + */ + void ProjectToBoxEdge(const double xyz[], + const double dxyz[], + const double xlo, + const double xhi, + const double ylo, + const double yhi, + const double zlo, + const double zhi, + double xyzout[]); + + int fShowerInputs = 0; ///< Number of shower inputs to process from + std::vector + fNShowersPerEvent; ///< Number of showers to put in each event of duration fSampleTime; one per showerinput + std::vector fMaxShowers; //< Max number of showers to query, one per showerinput + double fShowerBounds[6] = { + 0., + 0., + 0., + 0., + 0., + 0.}; ///< Boundaries of area over which showers are to be distributed (x(min), x(max), _unused_, y, z(min), z(max) ) + double fToffset_corsika = + 0.; ///< Timing offset to account for propagation time through atmosphere, populated from db + ifdh_ns::ifdh* fIFDH = 0; ///< (optional) flux file handling + + //fcl parameters + double fProjectToHeight = 0.; ///< Height to which particles will be projected [cm] + std::vector fShowerInputFiles; ///< Set of CORSIKA shower data files to use + std::string fShowerCopyType; // ifdh file selection and copying (default) or direct file path + std::vector + fShowerFluxConstants; ///< Set of flux constants to be associated with each shower data file + double fSampleTime = 0.; ///< Duration of sample [s] + double fToffset = 0.; ///< Time offset of sample, defaults to zero (no offset) [s] + std::vector + fBuffBox; ///< Buffer box extensions to cryostat in each direction (6 of them: x_lo,x_hi,y_lo,y_hi,z_lo,z_hi) [cm] + double fShowerAreaExtension = + 0.; ///< Extend distribution of corsika particles in x,z by this much (e.g. 1000 will extend 10 m in -x, +x, -z, and +z) [cm] + sqlite3* fdb[5]; ///< Pointers to sqlite3 database object, max of 5 + double fRandomXZShift = + 0.; ///< Each shower will be shifted by a random amount in xz so that showers won't repeatedly sample the same space [cm] + CLHEP::HepRandomEngine& fGenEngine; + CLHEP::HepRandomEngine& fPoisEngine; + }; +} + diff --git a/sbncode/EventGenerator/WireModGen/FilterPrimarySimChannel_module.cc b/sbncode/EventGenerator/WireModGen/FilterPrimarySimChannel_module.cc new file mode 100644 index 000000000..32c9fd3af --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/FilterPrimarySimChannel_module.cc @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////// +// Class: FilterPrimarySimChannel +// Plugin Type: filter (art v3_05_01) +// File: FilterPrimarySimChannel_module.cc +// +// Module for selecting events based on the presence of data products. +// +// Useful for processing data events, which sometimes have missing +// data products. +//////////////////////////////////////////////////////////////////////// + +#include "art/Framework/Core/EDFilter.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "lardataobj/Simulation/SimChannel.h" + +#include + +namespace sbn { + class FilterPrimarySimChannel; +} + +class sbn::FilterPrimarySimChannel : public art::EDFilter { +public: + explicit FilterPrimarySimChannel(fhicl::ParameterSet const& p); + // The compiler-generated destructor is fine for non-base + // classes without bare pointers or other resource use. + + // Plugins should not be copied or assigned. + FilterPrimarySimChannel(FilterPrimarySimChannel const&) = delete; + FilterPrimarySimChannel(FilterPrimarySimChannel&&) = delete; + FilterPrimarySimChannel& operator=(FilterPrimarySimChannel const&) = delete; + FilterPrimarySimChannel& operator=(FilterPrimarySimChannel&&) = delete; + + // Required functions. + bool filter(art::Event& e) override; + +private: + + // Declare member data here. + art::InputTag fSimChannelLabel; + std::vector fTrackIDs; + bool fVerbose; +}; + + +sbn::FilterPrimarySimChannel::FilterPrimarySimChannel(fhicl::ParameterSet const& p) + : EDFilter{p}, + fSimChannelLabel(p.get("SimChannelLabel")), + fTrackIDs(p.get>("TrackIDs", {1})), + fVerbose(p.get("Verbose", true)) +{} + +bool sbn::FilterPrimarySimChannel::filter(art::Event& e) { + art::ValidHandle> simchan = e.getValidHandle>(fSimChannelLabel); + + for (const sim::SimChannel &c: *simchan) { + const sim::SimChannel::TDCIDEs_t &tides = c.TDCIDEMap(); + + for (const sim::TDCIDE &tide: tides) { + for (const sim::IDE &ide: tide.second) { + if (fVerbose) std::cout << "ide at tdc: " << tide.first << " id: " << ide.trackID << " x: " << ide.x << " y: " << ide.y << " z: " << ide.z << " nelec: " << ide.numElectrons << std::endl; + for (int tid: fTrackIDs) { + if (ide.trackID == tid) { + if (fVerbose) std::cout << "Found matching sim channel for track ID: " << tid << std::endl; + return true; + } + } + } + } + } + + if (fVerbose) std::cout << "No matching sim channel." << std::endl; + + return false; +} + +DEFINE_ART_MODULE(sbn::FilterPrimarySimChannel) diff --git a/sbncode/EventGenerator/WireModGen/FilterPrimarySimEnergyDepo_module.cc b/sbncode/EventGenerator/WireModGen/FilterPrimarySimEnergyDepo_module.cc new file mode 100644 index 000000000..0ac810055 --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/FilterPrimarySimEnergyDepo_module.cc @@ -0,0 +1,120 @@ +//////////////////////////////////////////////////////////////////////// +// Class: FilterPrimarySimEnergyDepo +// Plugin Type: filter (art v3_05_01) +// File: FilterPrimarySimEnergyDepo_module.cc +// +// Module for selecting events based on the presence of data products. +// +// Useful for processing data events, which sometimes have missing +// data products. +//////////////////////////////////////////////////////////////////////// + +#include "art/Framework/Core/EDFilter.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Principal/Run.h" +#include "art/Framework/Principal/SubRun.h" +#include "canvas/Utilities/InputTag.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "lardataobj/Simulation/SimEnergyDeposit.h" +#include "larcorealg/Geometry/GeometryCore.h" +#include "larcore/Geometry/Geometry.h" +#include "larcore/CoreUtils/ServiceUtil.h" +#include "lardataalg/DetectorInfo/DetectorPropertiesStandard.h" +#include "lardata/DetectorInfoServices/DetectorPropertiesService.h" +#include "lardataalg/DetectorInfo/DetectorClocksStandard.h" +#include "lardata/DetectorInfoServices/DetectorClocksService.h" + +#include + +namespace sbn { + class FilterPrimarySimEnergyDepo; +} + +class sbn::FilterPrimarySimEnergyDepo : public art::EDFilter { +public: + explicit FilterPrimarySimEnergyDepo(fhicl::ParameterSet const& p); + // The compiler-generated destructor is fine for non-base + // classes without bare pointers or other resource use. + + // Plugins should not be copied or assigned. + FilterPrimarySimEnergyDepo(FilterPrimarySimEnergyDepo const&) = delete; + FilterPrimarySimEnergyDepo(FilterPrimarySimEnergyDepo&&) = delete; + FilterPrimarySimEnergyDepo& operator=(FilterPrimarySimEnergyDepo const&) = delete; + FilterPrimarySimEnergyDepo& operator=(FilterPrimarySimEnergyDepo&&) = delete; + + // Required functions. + bool filter(art::Event& e) override; + +private: + + // Declare member data here. + art::InputTag fSimEnergyDepoLabel; + std::vector fTrackIDs; + bool fVerbose; +}; + + +sbn::FilterPrimarySimEnergyDepo::FilterPrimarySimEnergyDepo(fhicl::ParameterSet const& p) + : EDFilter{p}, + fSimEnergyDepoLabel(p.get("SimEnergyDepoLabel")), + fTrackIDs(p.get>("TrackIDs", {1})), + fVerbose(p.get("Verbose", true)) +{} + +bool sbn::FilterPrimarySimEnergyDepo::filter(art::Event& e) { + art::ValidHandle> simdepo = e.getValidHandle>(fSimEnergyDepoLabel); + + const geo::GeometryCore *geometry = lar::providerFrom(); + auto const &clock_data = art::ServiceHandle()->DataFor(e); + auto const &dprop = + art::ServiceHandle()->DataFor(e, clock_data); + + for (const sim::SimEnergyDeposit &d: *simdepo) { + if (fVerbose) std::cout << "depo at time: " << d.T() << "x: " << d.X() << " y: " << d.Y() << " z: " << d.Z() << " nelec: " << d.NumElectrons() << " id: " << d.TrackID() << std::endl; + + // check if has correct ID, then check if fiducial and in-time + int match_index = -1; + for (unsigned i = 0; i < fTrackIDs.size(); i++) { + if (d.TrackID() == fTrackIDs[i]) { + match_index = (int)i; + } + } + if (match_index == -1) continue; + + for (auto const &cryo: geometry->Iterate()) { + for (auto const& TPC : geometry->Iterate(cryo.ID())) { + if (TPC.ContainsPosition(d.MidPoint())) { + // check drifted point in time + + geo::PlaneID plane(TPC.ID(), 0); // check against front plane + + // get the tick of the point. Subtract out the trigger time, which gets put into t_tick below + double tick = dprop.ConvertXToTicks(d.X(), plane); + + // convert the gen time to a TDC + double t_tdc = clock_data.TPCTick2TDC(clock_data.Time2Tick(d.T()/1e3)); + + // add in the offset from the drift + double x_tick = t_tdc + tick; + + if (fVerbose) std::cout << "Gen time: " << d.T() << " is at TPC tdc: " << t_tdc << ". After drift from X=" << d.X() << " arrival tick is: " << x_tick << ". TPC window is 0 to " << dprop.NumberTimeSamples() << std::endl; + + if ((x_tick > 0) && (x_tick < dprop.NumberTimeSamples())) { + if (fVerbose) std::cout << "Found matching deposit for track ID: " << fTrackIDs[match_index] << std::endl; + return true; + } + + } + } + } + } + + if (fVerbose) std::cout << "No matching deposit." << std::endl; + + return false; +} + +DEFINE_ART_MODULE(sbn::FilterPrimarySimEnergyDepo) diff --git a/sbncode/EventGenerator/WireModGen/WireModMuon_module.cc b/sbncode/EventGenerator/WireModGen/WireModMuon_module.cc new file mode 100644 index 000000000..ae326c1b4 --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/WireModMuon_module.cc @@ -0,0 +1,322 @@ +//////////////////////////////////////////////////////////////////////// +///// \file WireModMuon_module.cc +///// \brief Generates one muon hitting a bounding box, for use by WireMod +///// +///// \author gputnam@fnal.gov +////////////////////////////////////////////////////////////////////////// + +#include "sbncode/EventGenerator/WireModGen/CORSIKAGenSBN.h" + +#include "larcore/CoreUtils/ServiceUtil.h" +#include "larcoreobj/SimpleTypesAndConstants/geo_vectors.h" +#include "lardataalg/DetectorInfo/DetectorPropertiesStandard.h" +#include "lardata/DetectorInfoServices/DetectorPropertiesService.h" +#include "lardataalg/DetectorInfo/DetectorClocksStandard.h" +#include "lardata/DetectorInfoServices/DetectorClocksService.h" + +namespace sbn { + +class WireModMuon: public evgen::CORSIKAGenSBN { + public: + void produce(art::Event& evt) override; + void endRun(art::Run& run) override; + explicit WireModMuon(fhicl::ParameterSet const& pset); + + private: + bool GetMuon(const art::Event &e, const simb::MCTruth &intruth, simb::MCParticle &outparticle); + // Determine if particle ray should be selected + bool SelectRay(const art::Event &e, const TLorentzVector &pos, const TLorentzVector &mom); + // Whether a point is in the TPC readout time + bool PointInTime(const art::Event &e, const geo::TPCID &tpcid, const TVector3 &p, float t); + + struct Plane { + std::array pts; + + bool Intersects(const TVector3 &pos, const TVector3 &dir) const; + bool Intersects(const geo::Point_t &pos, const geo::Vector_t &dir) const; + }; + + // Digested geometry information + std::vector crt_planes; + std::vector tpc_bounds; + + // Enable for debugging output + bool fVerbose; + + // Selection configuration + bool fSelectCXR; + bool fSelectCRT; + unsigned fPrescaleCXR; + unsigned fPrescaleCRT; + unsigned fNMuonPerEvent; + + // Counters + unsigned fNCXR; + unsigned fNCRT; + + unsigned fNSelCXR; + unsigned fNSelCRT; + + unsigned fNCORSIKA; +}; + +} + +sbn::WireModMuon::WireModMuon(fhicl::ParameterSet const& pset): + CORSIKAGenSBN(pset) +{ + + // Load the CRT planes + std::vector crt_x0s = pset.get>("CRTX0", {}); + std::vector crt_x1s = pset.get>("CRTX1", {}); + std::vector crt_y0s = pset.get>("CRTY0", {}); + std::vector crt_y1s = pset.get>("CRTY1", {}); + std::vector crt_z0s = pset.get>("CRTZ0", {}); + std::vector crt_z1s = pset.get>("CRTZ1", {}); + + for (unsigned i_crt = 0; i_crt < crt_x0s.size(); i_crt++) { + std::array ps; + + if (crt_x0s[i_crt] == crt_x1s[i_crt] || crt_y0s[i_crt] == crt_y1s[i_crt]) { + geo::Point_t p1 {crt_x0s[i_crt], crt_y0s[i_crt], crt_z0s[i_crt]}; + geo::Point_t p2 {crt_x1s[i_crt], crt_y1s[i_crt], crt_z0s[i_crt]}; + geo::Point_t p3 {crt_x0s[i_crt], crt_y0s[i_crt], crt_z1s[i_crt]}; + geo::Point_t p4 {crt_x1s[i_crt], crt_y1s[i_crt], crt_z1s[i_crt]}; + ps = {p1, p2, p3, p4}; + } + else { + geo::Point_t p1 {crt_x0s[i_crt], crt_y0s[i_crt], crt_z0s[i_crt]}; + geo::Point_t p2 {crt_x0s[i_crt], crt_y1s[i_crt], crt_z0s[i_crt]}; + geo::Point_t p3 {crt_x1s[i_crt], crt_y0s[i_crt], crt_z1s[i_crt]}; + geo::Point_t p4 {crt_x1s[i_crt], crt_y1s[i_crt], crt_z1s[i_crt]}; + ps = {p1, p2, p3, p4}; + } + + sbn::WireModMuon::Plane crt_plane {ps}; + crt_planes.push_back(crt_plane); + } + + // Load selection config + fSelectCXR = pset.get("SelectCXR", true); + fSelectCRT = pset.get("SelectCRT", true); + + fPrescaleCXR = pset.get("PrescaleCXR", 1); + fPrescaleCRT = pset.get("PrescaleCRT", 1); + + fNMuonPerEvent = pset.get("NMuonPerEvent", 1); + + fNCXR = 0; + fNCRT = 0; + + fNSelCXR = 0; + fNSelCRT = 0; + + fNCORSIKA = 0; + + // debug output config + fVerbose = pset.get("Verbose", true); + +} + +void sbn::WireModMuon::endRun(art::Run& run) { + (void) run; + + mf::LogInfo("WireModMuon") << "Selected " << fNSelCXR << " of " << fNCXR << " cathode crossers and " << fNSelCRT << " of " << fNCRT << " CRT plane crossers. Called CORSIKA " << fNCORSIKA << " times.\n"; +} + +void sbn::WireModMuon::produce(art::Event& evt) { + // output + std::unique_ptr> truthcol(new std::vector); + + simb::MCTruth truth; + truth.SetOrigin(simb::kCosmicRay); + + for (unsigned i_muon = 0; i_muon < fNMuonPerEvent; i_muon++) { + // found a muon + bool foundmuon = false; + simb::MCParticle particle; + + while (!foundmuon) { + simb::MCTruth pretruth; + GetSample(pretruth); + fNCORSIKA ++; + + foundmuon = GetMuon(evt, pretruth, particle); + } + + mf::LogInfo("WireModMuon") << "Selected muon at pos(" << particle.Vx() << ", " << particle.Vy() << ", " << particle.Vz() << ") [cm], dir(" + << particle.Momentum().Vect().Unit().X() << ", " << particle.Momentum().Vect().Unit().Y() << ", " << particle.Momentum().Vect().Unit().Z() + << "), with momentum " << particle.Momentum().Vect().Mag() << " [GeV/c].\n"; + + truth.Add(particle); + } + + // save output + truthcol->push_back(truth); + evt.put(std::move(truthcol)); + + return; +} + +bool sbn::WireModMuon::PointInTime(const art::Event &e, const geo::TPCID &tpcid, const TVector3 &p, float t) { + auto const &clock_data = art::ServiceHandle()->DataFor(e); + auto const &dprop = + art::ServiceHandle()->DataFor(e, clock_data); + + if (fVerbose) std::cout << "Point: " << p.X() << " " << p.Y() << " " << p.Z() << " is in TPC: " << tpcid << std::endl; + + if (!tpcid) return false; + + geo::PlaneID plane(tpcid, 0); // check against front plane + + // get the tick of the point. Subtract out the trigger time, which gets put into t_tick below + double tick = dprop.ConvertXToTicks(p.X(), plane); + + // convert the gen time to a TDC + double t_tdc = clock_data.TPCTick2TDC(clock_data.Time2Tick(t/1e3)); + + // add in the offset from the drift + double x_tick = t_tdc + tick; + + if (fVerbose) std::cout << "Gen time: " << t << " is at TPC tdc: " << t_tdc << ". After drift from X=" << p.X() << " arrival tick is: " << x_tick << ". TPC window is 0 to " << dprop.NumberTimeSamples() << std::endl; + + // this needs to be inside the tpc window + return (x_tick > 0) && (x_tick < dprop.NumberTimeSamples()); +} + +bool sbn::WireModMuon::SelectRay(const art::Event &e, const TLorentzVector &pos, const TLorentzVector &mom) { + // load services + const geo::GeometryCore *geometry = lar::providerFrom(); + + bool CXR = false; + bool CRT = false; + + TVector3 dir = mom.Vect().Unit(); + TVector3 pos3 = pos.Vect(); + const double c_cm_per_ns = 29.9792; + double vel = mom.Beta()*c_cm_per_ns; + const double eps = 1e-1; // wiggle room to ensure inside volume + + for (auto const &cryo: geometry->Iterate()) { + for (auto const& TPC : geometry->Iterate(cryo.ID())) { + std::vector intersections = TPC.ActiveBoundingBox().GetIntersections(pos3, dir); + const double check_eps = 1e-1; + float cathode = (TPC.DriftDir().X() > 0) ? TPC.ActiveBoundingBox().MinX() : TPC.ActiveBoundingBox().MaxX(); + CXR = intersections.size() == 2 && ((abs(intersections[0].X() - cathode) < check_eps) || (abs(intersections[1].X() - cathode) < check_eps)); + + // check if cathode point is in-time + if (CXR) { + TVector3 cathode_point = (abs(intersections[0].X() - cathode) < abs(intersections[1].X() - cathode)) ? (intersections[0] + dir*eps) : (intersections[1] - dir*eps); + + if (fVerbose) std::cout << "Ray with initial time: " << pos.T() << " and arrival time: " << (pos.T() + cathode_point.Mag() / vel) << " with vel: " << vel << std::endl; + if (fVerbose) std::cout << "Checking if cathode intersection point: " << cathode_point.X() << " " << cathode_point.Y() << " " << cathode_point.Z() << " is in time." << std::endl; + CXR = PointInTime(e, TPC.ID(), cathode_point, pos.T() + (cathode_point - pos3).Mag() / vel); + } + if (CXR) break; + } + if (CXR) break; + } + if (fVerbose) std::cout << "CXR: " << CXR << std::endl; + + for (const sbn::WireModMuon::Plane &crt: crt_planes) { + CRT = crt.Intersects(pos3, dir); + if (CRT) { + // require intersect active volume + // + // and require either entrance or exit point to be in-time + for (auto const &cryo: geometry->Iterate()) { + for (auto const& TPC : geometry->Iterate(cryo.ID())) { + std::vector intersections = TPC.ActiveBoundingBox().GetIntersections(pos3, dir); + CRT = intersections.size() == 2; + if (CRT) { + if (fVerbose) std::cout << "Ray with initial time: " << pos.T() << " and arrival time: " << (pos.T() + (intersections[0] - pos3).Mag() / vel) << " with vel: " << vel << std::endl; + CRT = PointInTime(e, TPC.ID(), intersections[0] + dir*eps, pos.T() + (intersections[0] - pos3).Mag() / vel) || + PointInTime(e, TPC.ID(), intersections[1] - dir*eps, pos.T() + (intersections[1] - pos3).Mag() / vel); + } + if (CRT) break; + } + if (CRT) break; + } + } + if (CRT) break; + } + if (fVerbose) std::cout << "CRT: " << CRT << std::endl; + + if (CXR) fNCXR ++; + if (CRT) fNCRT ++; + + if (CXR && fSelectCXR && (fNCXR % fPrescaleCXR == 0)) { + fNSelCXR ++; + return true; + } + + if (CRT && fSelectCRT && (fNCRT % fPrescaleCRT == 0)) { + fNSelCRT ++; + return true; + } + + return false; + +} + +bool sbn::WireModMuon::GetMuon(const art::Event &e, const simb::MCTruth &intruth, simb::MCParticle &outparticle) { + for (int i = 0; i < intruth.NParticles(); ++i) { + const simb::MCParticle &particle = intruth.GetParticle(i); + if (abs(particle.PdgCode()) != 13) continue; // only muons + + if (fVerbose) std::cout << "Found muon at pos(" << particle.Vx() << ", " << particle.Vy() << ", " << particle.Vz() << ") [cm], dir(" + << particle.Momentum().Vect().Unit().X() << ", " << particle.Momentum().Vect().Unit().Y() << ", " << particle.Momentum().Vect().Unit().Z() + << "), with momentum " << particle.Momentum().Vect().Mag() << " [GeV/c].\n"; + + if (SelectRay(e, particle.Position(), particle.Momentum())) { + outparticle = particle; + return true; + } + } + + return false; +} + +bool sbn::WireModMuon::Plane::Intersects(const TVector3 &pos, const TVector3 &dir) const { + geo::Point_t pos_t(pos.X(), pos.Y(), pos.Z()); + geo::Vector_t dir_t(dir.X(), dir.Y(), dir.Z()); + return Intersects(pos_t, dir_t); +} + +bool sbn::WireModMuon::Plane::Intersects(const geo::Point_t &pos, const geo::Vector_t &dir) const { + // Get the u, v vectors + geo::Vector_t u = (geo::Vector_t(pts[1]) - geo::Vector_t(pts[0])).Unit(); + geo::Vector_t v = (geo::Vector_t(pts[2]) - geo::Vector_t(pts[0])).Unit(); + double ulen = (geo::Vector_t(pts[1]) - geo::Vector_t(pts[0])).Dot(u); + double vlen = (geo::Vector_t(pts[2]) - geo::Vector_t(pts[0])).Dot(v); + + // calculate the normal of the plane + geo::Vector_t normal = u.Cross(v); + + double denom = dir.Dot(normal); + + if (abs(denom) < 1e-5) { // parallel to plane + return false; + } + + // point along ray where it intersects plane + double t = (pts[3] - pos).Dot(normal) / denom; + + // intersection happens behind the ray + if (t < 0) { + return false; + } + + geo::Vector_t intersection = pos + dir*t - pts[0]; + + double int_u = intersection.Dot(u); + double int_v = intersection.Dot(v); + + // if (fVerbose) std::cout << "Plane check. ulen: " << ulen << " vlen: " << vlen << ". u: " << int_u << " v: " << int_v << " t: " << t << std::endl; + + return (int_u > 0) && (int_u < ulen) && (int_v > 0) && (int_v < vlen); +} + +namespace sbn { + DEFINE_ART_MODULE(WireModMuon) +} diff --git a/sbncode/EventGenerator/WireModGen/filter_wiremod_sbn.fcl b/sbncode/EventGenerator/WireModGen/filter_wiremod_sbn.fcl new file mode 100644 index 000000000..e04c0f49c --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/filter_wiremod_sbn.fcl @@ -0,0 +1,9 @@ +BEGIN_PROLOG + +filter_primary_simchan: { + module_type: FilterPrimarySimEnergyDepo + SimEnergyDepoLabel: ionization + TrackIDs: [1, 2, 3] +} + +END_PROLOG diff --git a/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl b/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl new file mode 100644 index 000000000..84ad9d0cd --- /dev/null +++ b/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl @@ -0,0 +1,22 @@ +BEGIN_PROLOG + +# needs the corsika config to be added to the table, inside the experimental codebase +wiremodmuon_icarus: { + module_type: WireModMuon + + # CRT bounds + CRTX0: [-550] + CRTX1: [550] + CRTY0: [618] + CRTY1: [618] + CRTZ0: [-1100] + CRTZ1: [1300] + + # selection config + SelectA2C: true + SelectCRT: true + PrescaleA2C: 1 + PrescaleCRT: 1 + NMuonPerEvent: 3 +} +END_PROLOG From 58a0b00887f3409d0dd7b74566230350dc5a718e Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Mon, 15 Sep 2025 17:14:45 -0500 Subject: [PATCH 190/367] Add in new TrackCaloSkimmer selection tool. --- sbncode/Calibration/CMakeLists.txt | 10 +++++++ ...ckCaloSkimmerSelectClearCosmicMuon_tool.cc | 30 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 sbncode/Calibration/TrackCaloSkimmerSelectClearCosmicMuon_tool.cc diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index 98059edc5..64439a086 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -70,6 +70,16 @@ cet_build_plugin(TrackCaloSkimmerSelectAllTrack art::tool ROOT::X3d ) +cet_build_plugin(TrackCaloSkimmerSelectClearCosmicMuon art::tool + LIBRARIES + sbnobj::Common_Calibration_dict + art::Persistency_Common + art::Utilities canvas::canvas + larcore::Geometry_Geometry_service + cetlib::cetlib cetlib_except::cetlib_except + ROOT::X3d +) + cet_build_plugin ( DataSelect art::module LIBRARIES ifdh_art::IFDH_service diff --git a/sbncode/Calibration/TrackCaloSkimmerSelectClearCosmicMuon_tool.cc b/sbncode/Calibration/TrackCaloSkimmerSelectClearCosmicMuon_tool.cc new file mode 100644 index 000000000..9346e953f --- /dev/null +++ b/sbncode/Calibration/TrackCaloSkimmerSelectClearCosmicMuon_tool.cc @@ -0,0 +1,30 @@ +// Framework Includes +#include "art/Utilities/ToolMacros.h" +#include "fhiclcpp/ParameterSet.h" + +#include "ITCSSelectionTool.h" + +namespace sbn { + +class TrackCaloSkimmerSelectClearCosmicMuon: public ITCSSelectionTool { +public: + + TrackCaloSkimmerSelectClearCosmicMuon(const fhicl::ParameterSet &p); + ~TrackCaloSkimmerSelectClearCosmicMuon() {} + + bool Select(const TrackInfo &t) override; + +private: +}; + +TrackCaloSkimmerSelectClearCosmicMuon::TrackCaloSkimmerSelectClearCosmicMuon(const fhicl::ParameterSet &p): + ITCSSelectionTool(p) +{} + +bool TrackCaloSkimmerSelectClearCosmicMuon::Select(const TrackInfo &t) { + return t.clear_cosmic_muon; +} + +DEFINE_ART_CLASS_TOOL(TrackCaloSkimmerSelectClearCosmicMuon) + +} // end namespace sbn From 56fd8be40cac144424b0d28e0333fa16020d0e32 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Tue, 16 Sep 2025 06:29:17 -0500 Subject: [PATCH 191/367] Make shower exclusion fcl-toggled but defaulted on --- sbncode/Calibration/TrackCaloSkimmer.h | 1 + sbncode/Calibration/TrackCaloSkimmer_module.cc | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer.h b/sbncode/Calibration/TrackCaloSkimmer.h index c69d8589d..497959518 100644 --- a/sbncode/Calibration/TrackCaloSkimmer.h +++ b/sbncode/Calibration/TrackCaloSkimmer.h @@ -223,6 +223,7 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { double fTopCRTDistanceCutPassing; double fSideCRTDistanceCutStopping; double fSideCRTDistanceCutPassing; + bool fAllowShowerLikePFPs; // tools std::vector> fSelectionTools; diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 6fe70bc1c..953e69ae9 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -92,7 +92,8 @@ sbn::TrackCaloSkimmer::TrackCaloSkimmer(fhicl::ParameterSet const& p) fTopCRTDistanceCutPassing = p.get("TopCRTDistanceCut_throughgoing", 100.); fSideCRTDistanceCutStopping = p.get("SideCRTDistanceCut_stopping", 100.); fSideCRTDistanceCutPassing = p.get("SideCRTDistanceCut_throughgoing", 100.); - + fAllowShowerLikePFPs = p.get("AllowShowerLikePFPs", false); + if (fTailFitResidualRange > 10.) { std::cout << "sbn::TrackCaloSkimmer: Bad tail fit residual range config :(" << fTailFitResidualRange << "). Fits will not be meaningful.\n"; } @@ -315,7 +316,7 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) for (art::Ptr p_pfp: PFParticleList) { const recob::PFParticle &pfp = *p_pfp; - if(p_pfp->PdgCode() == 11) + if(p_pfp->PdgCode() == 11 && !fAllowShowerLikePFPs) continue; const std::vector> thisTrack = fmTracks.at(p_pfp.key()); From 3a6116e4e4fb418014b8fb4445502c4ac2d6687e Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Wed, 17 Sep 2025 01:51:32 -0500 Subject: [PATCH 192/367] Added starting point for sp associations. Does not store info in recTree yet --- sbncode/CAFMaker/CAFMaker_module.cc | 67 +++++++++++++++++++++++++---- sbncode/CAFMaker/FillReco.cxx | 25 +++++++++-- sbncode/CAFMaker/FillReco.h | 5 ++- 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index eeefc112d..f7e77afac 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -118,6 +118,7 @@ #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" +#include "sbnobj/SBND/CRT/CRTVeto.hh" // GENIE #include "Framework/EventGen/EventRecord.h" @@ -1671,8 +1672,64 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (sbndcrtveto_handle.isValid()) { std::cout << "Found a valid CRT Veto Handle!!!" << std::endl; const std::vector &sbndcrtvetos = *sbndcrtveto_handle; - //srsbndcrtveto.emplace_back(); - FillSBNDCRTVeto(sbndcrtvetos[0], srsbndcrtveto); + + // And associated SpacePoint objects + // + //art::FindManyP fveto_sp = FindManyPStrict(sbndcrtvetos[0], evt, fParams.SBNDCRTVetoLabel()); + //art::FindManyP spAssoc(&sbndcrtvetos[0], evt, fParams.SBNDCRTVetoLabel()); + art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); + if (spAssoc.isValid()) { + std::cout << "Valid SpacePoint Association" << std::endl; + std::cout << "Association Size: " << spAssoc.size() << std::endl; + } + else { + std::cout << "Invalid Space Point Association" << std::endl; + } + + // Assume there is only one Veto per event + const std::vector> veto_sp_v(spAssoc.at(0)); + //for (auto const& sp: veto_sp_v) { + + //} + // + + // Fill the associated space points --> then add to the FillReco function + + std::vector vetoSpacePoints; + if (veto_sp_v.size() == 0) { + std::cout << " No Veto SpacePoints" << std::endl; + vetoSpacePoints.emplace_back(); // nullptr + } + else { + + for (auto const& sp: veto_sp_v) { + + vetoSpacePoints.push_back(*sp); + + } + } + + /* + if (fveto_sp.isValid()) { + std::cout << "Veto SP Association is valid! Size = " << fveto_sp.size() << std::endl; + //for (unsigned i = 0; i < fveto_sp.size(); i++) { + // Should have just one vector of possible space points + const std::vector> &theseSpacePoints = fveto_sp.at(0); + if (theseSpacePoints.size() == 0) { + std::cout << " No Veto SpacePoints" << std::endl; + vetoSpacePoints.emplace_back(); // nullptr + } + else if (theseSpacePoints.size() > 0) { + //vetoSpacePoints.push_back(*fveto_sp.at(i).at(0)); + for (auto const& sp: theseSpacePoints) { + vetoSpacePoints.push_back(*sp); + } + } + } + */ + //srsbndcrtveto.emplace_back(); + + FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); } else { std::cout << "Invalid CRT Veto Handle!" << std::endl; @@ -2420,12 +2477,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.crtpmt_matches = srcrtpmtmatches; rec.ncrtpmt_matches = srcrtpmtmatches.size(); - rec.sbnd_crtveto_v0 = srsbndcrtveto.V0; - rec.sbnd_crtveto_v1 = srsbndcrtveto.V1; - rec.sbnd_crtveto_v2 = srsbndcrtveto.V2; - rec.sbnd_crtveto_v3 = srsbndcrtveto.V3; - rec.sbnd_crtveto_v4 = srsbndcrtveto.V4; - std::cout << std::endl; std::cout << std::endl; std::cout << "// -------------- DEBUG After FILL REC TREE --------------------- //" < &points, + caf::SRSBNDCRTVeto &srsbndcrtveto, + bool allowEmpty) { - std::cout << "DEBUGGING!!!! veto.V0 " << veto.V0() << std::endl; srsbndcrtveto.V0 = veto.V0(); srsbndcrtveto.V1 = veto.V1(); srsbndcrtveto.V2 = veto.V2(); srsbndcrtveto.V3 = veto.V3(); srsbndcrtveto.V4 = veto.V4(); + + // add the CRTSpacePoint associations to the SR Veto + //std::vector srvetopoints; + // TODO --> Figure out if we want all SpacePoint Info or a subset + // Going with subset for now + + //for (long unsigned int i = 0; i < points.size(); ++i) { + //SRCRTSpacePoint this_srsp; + //FillCRTSpacePoint(points.at(i), this_srsp); + //srvetopoints.push_back(this_srsp) + int counter = 0; + for(auto const& sp : points) { + srsbndcrtveto.sp_position.emplace_back(sp.X(), sp.Y(), sp.Z()); + srsbndcrtveto.sp_time.emplace_back(sp.Ts0()); + srsbndcrtveto.sp_pe.emplace_back(sp.PE()); + std::cout << "Veto SP X " << srsbndcrtveto.sp_position[counter].x << std::endl; + counter += 1; + } + //srsbndcrtveto.crtveto_points = srvetopoints; } void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 44b881a96..3db13fb2c 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -256,8 +256,9 @@ namespace caf bool allowEmpty = false); void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, - caf::SRSBNDCRTVeto &srsbndcrtveto, - bool allowEmpty = false); + const std::vector &points, + caf::SRSBNDCRTVeto &srsbndcrtveto, + bool allowEmpty = false); void FillICARUSOpFlash(const recob::OpFlash &flash, std::vector const& hits, From 9ea0f594f8aec7d4f5ad28cb767e03e545f699c6 Mon Sep 17 00:00:00 2001 From: Linyan Wan Date: Wed, 17 Sep 2025 09:52:33 -0500 Subject: [PATCH 193/367] Fix initialization --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 29a35d0ee..03fd7abd4 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2476,7 +2476,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { // For more information, see: // https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 - if (isRealData && (fDet == kSBND)) + if (isRealData && (fDet == kSBND) && fSubRunPOT > 0) { // Fill trigger info FillTriggerSBND(srsbndtiminginfo, srtrigger); From 5e6c3dc6891ce3cb64dfd45bdc3f71ebdc50e5f6 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Wed, 17 Sep 2025 10:22:15 -0500 Subject: [PATCH 194/367] Use passed xshift --- .../Calibration/TrackCaloSkimmer_module.cc | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/sbncode/Calibration/TrackCaloSkimmer_module.cc b/sbncode/Calibration/TrackCaloSkimmer_module.cc index 953e69ae9..00a02b7fc 100644 --- a/sbncode/Calibration/TrackCaloSkimmer_module.cc +++ b/sbncode/Calibration/TrackCaloSkimmer_module.cc @@ -1458,29 +1458,6 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, } } - // If T0 provided CRT then we should appropriately shift the drift position (already done for pandora T0) - double recoX = std::numeric_limits::signaling_NaN(); - - if(!t0Info.hasT0Pandora && (t0Info.hasT0CRTTrack || t0Info.hasT0CRTHit || t0Info.hasT0CRTSpacePoint)) - { - int driftDir = geo->TPC(hit.WireID()).DriftDir().X(); - const double driftv(dprop.DriftVelocity(dprop.Efield(), dprop.Temperature())); - - double time = std::numeric_limits::signaling_NaN(); - - if(t0Info.hasT0CRTTrack) - time = t0Info.t0CRTTrack*1e-3; - else if(t0Info.hasT0CRTHit) - time = t0Info.t0CRTHit*1e-3; - else if(t0Info.hasT0CRTSpacePoint) - time = t0Info.t0CRTSpacePoint*1e-3; - - double anodeDistance = (hit.PeakTime()-dclock.Time2Tick(dclock.TriggerTime())-time/dclock.TPCClock().TickPeriod())*dclock.TPCClock().TickPeriod()*driftv; - double wirePlaneX = wireReadout->Plane(geo::PlaneID(hit.WireID().Cryostat, hit.WireID().TPC, hit.WireID().Plane)).GetCenter().X(); - - recoX = wirePlaneX - driftDir*anodeDistance; - } - // Information from the TrackHitMeta bool badhit = (thm.Index() == std::numeric_limits::max()) || (!trk.HasValidPoint(thm.Index())); @@ -1493,7 +1470,7 @@ sbn::TrackHitInfo sbn::TrackCaloSkimmer::MakeHit(const recob::Hit &hit, // The tp X coordinate is reconstructed only if it does not have a PandoraT0. hinfo.tp.x = loc.X(); - if((t0Info.hasT0CRTTrack || t0Info.hasT0CRTHit || t0Info.hasT0CRTSpacePoint) && !t0Info.hasT0Pandora && !isnan(hinfo.tp.x)) hinfo.tp.x = recoX; + if((t0Info.hasT0CRTTrack || t0Info.hasT0CRTHit || t0Info.hasT0CRTSpacePoint) && !t0Info.hasT0Pandora && !isnan(hinfo.tp.x)) hinfo.tp.x = loc.X() + xshift; hinfo.tp.y = loc.Y(); hinfo.tp.z = loc.Z(); From 807f1bd4d6e6388634995e5406ede41458b364eb Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:02:49 -0500 Subject: [PATCH 195/367] Update FillTrigger.cxx --- sbncode/CAFMaker/FillTrigger.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 8bf82c02c..c214f0a8d 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -40,7 +40,7 @@ namespace caf triggerInfo.global_trigger_time = timingInfo.hltEtrig; triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; - double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; + uint64_t diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; triggerInfo.trigger_within_gate = diff_ts; } From 9316f6f2662fdccfc2ac1d2b75cb86d5a2d6eb0b Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:21:46 -0500 Subject: [PATCH 196/367] Update FillTrigger.cxx --- sbncode/CAFMaker/FillTrigger.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index c214f0a8d..86f52626c 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -41,7 +41,7 @@ namespace caf triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; uint64_t diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; - triggerInfo.trigger_within_gate = diff_ts; + triggerInfo.trigger_within_gate = static_cast(diff_ts); } } From 4f20a897677f235d7c4a17f109aaa67c38354815 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:08:00 -0500 Subject: [PATCH 197/367] Update FillTrigger.cxx --- sbncode/CAFMaker/FillTrigger.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 86f52626c..369dbda05 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -39,9 +39,11 @@ namespace caf triggerInfo.global_trigger_time = timingInfo.hltEtrig; triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; - - uint64_t diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; - triggerInfo.trigger_within_gate = static_cast(diff_ts); + std::cout << "triggerInfo.global_trigger_det_time: " << triggerInfo.global_trigger_det_time << std::endl; + std::cout << "triggerInfo.beam_gate_det_time: " << triggerInfo.beam_gate_det_time << std::endl; + double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; + std::cout << "diff_ts: " << diff_ts << std::endl; + triggerInfo.trigger_within_gate = diff_ts; } } From 9eb83267a8f65d91ea80c4d04f0e80dee26c6c05 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:39:09 -0500 Subject: [PATCH 198/367] Update FillTrigger.cxx --- sbncode/CAFMaker/FillTrigger.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 369dbda05..9df7a190f 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -1,4 +1,4 @@ - +#include #include "sbncode/CAFMaker/FillTrigger.h" namespace caf From e599e803362663f89b19599d4e61bb116aaeed31 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:46:27 -0500 Subject: [PATCH 199/367] Update FillTrigger.cxx --- sbncode/CAFMaker/FillTrigger.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 9df7a190f..392d46566 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -12,7 +12,10 @@ namespace caf triggerInfo.beam_gate_time_abs = addltrig_info.beamGateTimestamp; triggerInfo.beam_gate_det_time = trig.BeamGateTime() + time_offset; triggerInfo.global_trigger_det_time = trig.TriggerTime() + time_offset; + std::cout << "Gen triggerInfo.global_trigger_det_time: " << triggerInfo.global_trigger_det_time << std::endl; + std::cout << "Gen triggerInfo.beam_gate_det_time: " << triggerInfo.beam_gate_det_time << std::endl; double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; + std::cout << "diff_ts: " << diff_ts << std::endl; triggerInfo.trigger_within_gate = diff_ts; triggerInfo.prev_global_trigger_time = addltrig_info.previousTriggerTimestamp; From 3b130923403fe481ab89b871e824b427901b740d Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:49:58 -0500 Subject: [PATCH 200/367] Update CAFMaker_module.cc --- sbncode/CAFMaker/CAFMaker_module.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 29a35d0ee..2d82e3ebf 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1628,6 +1628,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { // } // try to find the result of the Flash trigger if it was run + mf::LogInfo("CAFMaker") << " New Trigger Time = " << srtrigger.global_trigger_det_time << " us\n" + << " New Beam Gate Time = " << srtrigger.beam_gate_det_time << " us"; bool pass_flash_trig = false; art::Handle flashtrig_handle; GetByLabelStrict(evt, fParams.FlashTrigLabel(), flashtrig_handle); From 9254c246c4843c40518e452cfbd651e0f92c0ca1 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Wed, 17 Sep 2025 22:07:09 -0500 Subject: [PATCH 201/367] Cleaned up debug statements and code structure. Might need to adjust how empty associations are handled. --- sbncode/CAFMaker/CAFMaker_module.cc | 110 +++++----------------------- sbncode/CAFMaker/FillReco.cxx | 12 --- 2 files changed, 19 insertions(+), 103 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index f7e77afac..5597a0701 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1653,99 +1653,39 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } // Fill CRT Veto - std::cout << std::endl; - std::cout << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << std::endl; - std::cout << std::endl; art::Handle> sbndcrtveto_handle; GetByLabelStrict(evt, fParams.SBNDCRTVetoLabel(), sbndcrtveto_handle); // fill into event if (sbndcrtveto_handle.isValid()) { - std::cout << "Found a valid CRT Veto Handle!!!" << std::endl; const std::vector &sbndcrtvetos = *sbndcrtveto_handle; - // And associated SpacePoint objects - // - //art::FindManyP fveto_sp = FindManyPStrict(sbndcrtvetos[0], evt, fParams.SBNDCRTVetoLabel()); - //art::FindManyP spAssoc(&sbndcrtvetos[0], evt, fParams.SBNDCRTVetoLabel()); art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); + std::vector vetoSpacePoints; if (spAssoc.isValid()) { - std::cout << "Valid SpacePoint Association" << std::endl; - std::cout << "Association Size: " << spAssoc.size() << std::endl; - } - else { - std::cout << "Invalid Space Point Association" << std::endl; - } - // Assume there is only one Veto per event - const std::vector> veto_sp_v(spAssoc.at(0)); - //for (auto const& sp: veto_sp_v) { - - //} - // + // Assume there is only one Veto per event + const std::vector> veto_sp_v(spAssoc.at(0)); - // Fill the associated space points --> then add to the FillReco function + // Fill the associated space points --> then add to the FillReco function - std::vector vetoSpacePoints; - if (veto_sp_v.size() == 0) { - std::cout << " No Veto SpacePoints" << std::endl; - vetoSpacePoints.emplace_back(); // nullptr - } - else { + if (veto_sp_v.size() == 0) { + // TODO ? Need to decide how to handle this + // This version seems to work in skipping empty associations. It does break the rec.sbnd_crt_veto.sp_pe..length and + // rec.sbnd_crt_veto.sp_time..length branches? However, the rec.sbnd_crt_veto.sp_position..length still works and can be used? + std::cout << "No Veto Space Points" << std::endl; + //vetoSpacePoints.emplace_back(); // nullptr + } + else { - for (auto const& sp: veto_sp_v) { + for (auto const& sp: veto_sp_v) { - vetoSpacePoints.push_back(*sp); - - } - } - - /* - if (fveto_sp.isValid()) { - std::cout << "Veto SP Association is valid! Size = " << fveto_sp.size() << std::endl; - //for (unsigned i = 0; i < fveto_sp.size(); i++) { - // Should have just one vector of possible space points - const std::vector> &theseSpacePoints = fveto_sp.at(0); - if (theseSpacePoints.size() == 0) { - std::cout << " No Veto SpacePoints" << std::endl; - vetoSpacePoints.emplace_back(); // nullptr - } - else if (theseSpacePoints.size() > 0) { - //vetoSpacePoints.push_back(*fveto_sp.at(i).at(0)); - for (auto const& sp: theseSpacePoints) { - vetoSpacePoints.push_back(*sp); - } - } - } - */ - //srsbndcrtveto.emplace_back(); - - FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); - } - else { - std::cout << "Invalid CRT Veto Handle!" << std::endl; - return; + vetoSpacePoints.push_back(*sp); + + } + } + } + FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); } - std::cout << std::endl; - std::cout << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << "/------------- DEBUG DEBUG DEBUG DEBUG ------------------------ //" << std::endl; - std::cout << std::endl; - std::cout << std::endl; } // Get all of the CRTPMT Matches @@ -2445,12 +2385,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { } // end loop over slices - std::cout << std::endl; - std::cout << std::endl; - std::cout << "// -------------- DEBUG FILL REC TREE --------------------- //" < srvetopoints; - // TODO --> Figure out if we want all SpacePoint Info or a subset - // Going with subset for now - - //for (long unsigned int i = 0; i < points.size(); ++i) { - //SRCRTSpacePoint this_srsp; - //FillCRTSpacePoint(points.at(i), this_srsp); - //srvetopoints.push_back(this_srsp) - int counter = 0; for(auto const& sp : points) { srsbndcrtveto.sp_position.emplace_back(sp.X(), sp.Y(), sp.Z()); srsbndcrtveto.sp_time.emplace_back(sp.Ts0()); srsbndcrtveto.sp_pe.emplace_back(sp.PE()); - std::cout << "Veto SP X " << srsbndcrtveto.sp_position[counter].x << std::endl; - counter += 1; } - //srsbndcrtveto.crtveto_points = srvetopoints; } void FillCRTPMTMatch(const sbn::crt::CRTPMTMatching &match, From 2cf2d1fc0d762f4cefd01869d09d222f3183523c Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 18 Sep 2025 10:37:55 -0500 Subject: [PATCH 202/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ceb8f430f..c371e478d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.10.02 LANGUAGES CXX) +project(sbncode VERSION 10.10.03 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 43011beaf..2bb070be5 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,10 +254,10 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_10_02 - -sbnalg v10_10_02 - +larsoft v10_10_03 - +sbnalg v10_10_03 - sbndaq_artdaq_core v1_10_06 - -sbndata v01_07 - +sbndata v01_08 - systematicstools v01_04_04 - nusystematics v1_05_07 - geant4reweight v01_20_11 - From 45752cb3c215946795e698ab19ade4f76935d846 Mon Sep 17 00:00:00 2001 From: Nathaniel Date: Fri, 19 Sep 2025 11:40:17 -0500 Subject: [PATCH 203/367] bug fix --- sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl index 4f8505cb1..602bfe3f3 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbinfo_sbn.fcl @@ -34,7 +34,7 @@ physics: { stream1: [ out1 ] } -physics.producers.sbndbnbinfo.module_type: "SBNDBNBRetriever" +physics.producers.bnbinfo.module_type: "SBNDBNBRetriever" outputs: { out1: { @@ -45,4 +45,4 @@ outputs: { } } -physics.producers.sbndbnbinfo.fileNames: @local::outputs.out1.fileName +physics.producers.bnbinfo.fileNames: @local::outputs.out1.fileName From cb4d3048597c2b05a96a6a4c8f8962e37e513ce8 Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 19 Sep 2025 14:58:36 -0500 Subject: [PATCH 204/367] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c371e478d..c6a0b738d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.10.03 LANGUAGES CXX) +project(sbncode VERSION 10.10.03.01 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") From 200d488a9c6c19fcfaf58976285a685ccb986273 Mon Sep 17 00:00:00 2001 From: justinjmueller Date: Mon, 22 Sep 2025 14:15:07 -0500 Subject: [PATCH 205/367] Update Supera dependency of sbncode --- sbncode/Supera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Supera b/sbncode/Supera index d84d726d9..26e2abb92 160000 --- a/sbncode/Supera +++ b/sbncode/Supera @@ -1 +1 @@ -Subproject commit d84d726d95017f4b86a99537f6d86deeda3216c3 +Subproject commit 26e2abb92fe757510ca0a7e54444e8018aa721f7 From bf076297072b9212f082fe6d3707621ee2bce7b4 Mon Sep 17 00:00:00 2001 From: Nikki Pallat Date: Tue, 23 Sep 2025 12:47:56 -0500 Subject: [PATCH 206/367] Update CAFMaker to fill new trigger variables --- sbncode/CAFMaker/CAFMaker_module.cc | 1 + sbncode/CAFMaker/FillTrigger.cxx | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 6ede8b23b..c21420c69 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1606,6 +1606,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { GetByLabelStrict(evt, fParams.TriggerLabel().encode(), extratrig_handle); art::Handle> trig_handle; + std::cout<<"Trigger label: "<> unshifted_trig_handle; diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 8bf82c02c..6a13e420b 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -23,6 +23,12 @@ namespace caf triggerInfo.trigger_count = addltrig_info.triggerCount; triggerInfo.gate_count = addltrig_info.gateCount; triggerInfo.gate_delta = addltrig_info.gateCountFromPreviousTrigger; + + triggerInfo.passed_trigger = addltrig_info.triggerEmulation; + triggerInfo.num_pairs_over_threshold = addltrig_info.pairsOverThreshold; + triggerInfo.monpulses_flat = addltrig_info.MonPulses; + triggerInfo.monpulse_sizes = addltrig_info.MonPulseSizes; + } void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo) { @@ -32,7 +38,6 @@ namespace caf // Set this to 0 since the "MC" trigger is (for now) always at the spill time triggerInfo.trigger_within_gate = 0.; - // TODO: fill others? } void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo){ From 7e3023cfa79c766cdbec85a91116052d426605ee Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Wed, 24 Sep 2025 16:25:25 -0500 Subject: [PATCH 207/367] Fixed curly braces from last merge conflict --- sbncode/CAFMaker/CAFMakerParams.h | 1 + sbncode/CAFMaker/FillReco.cxx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index ddfbec72d..31fb2718c 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -343,6 +343,7 @@ namespace caf Name("SBNDCRTVetoLabel"), Comment("Label of sbnd CRT Veto."), "crtveto" // sbnd + }; Atom SBNDFrameShiftInfoLabel { Name("SBNDFrameShiftInfoLabel"), diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 0a4785825..4f5cbbc01 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -158,7 +158,7 @@ namespace caf srsbndcrtveto.sp_time.emplace_back(sp.Ts0()); srsbndcrtveto.sp_pe.emplace_back(sp.PE()); } - + }; void FillSBNDFrameShiftInfo(const sbnd::timing::FrameShiftInfo &frame, caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty) From d03d9f63dc0d98fae0d2ad4f6d4b03d9b307d6e0 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Wed, 24 Sep 2025 20:14:57 -0500 Subject: [PATCH 208/367] Removed unnecessary loop. passed veto key directly to association. Checked the veto size is exactly 1 before passing index 0 to other parts of the code --- sbncode/CAFMaker/CAFMaker_module.cc | 55 ++++++++++++++--------------- sbncode/CAFMaker/FillReco.cxx | 9 ++--- sbncode/CAFMaker/FillReco.h | 3 +- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 9d20da057..e99608cc1 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1698,41 +1698,38 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillSBNDCRTTrack(sbndcrttracks[i], srsbndcrttracks.back()); } } + + std::cout << std::endl; + std::cout << std::endl; + std::cout << "DEBUG --> Start CRT Veto Fill" <> sbndcrtveto_handle; GetByLabelStrict(evt, fParams.SBNDCRTVetoLabel(), sbndcrtveto_handle); + std::vector> vetoPtrs; // fill into event if (sbndcrtveto_handle.isValid()) { const std::vector &sbndcrtvetos = *sbndcrtveto_handle; - // And associated SpacePoint objects - art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); - std::vector vetoSpacePoints; - if (spAssoc.isValid()) { - - // Assume there is only one Veto per event - const std::vector> veto_sp_v(spAssoc.at(0)); - - // Fill the associated space points --> then add to the FillReco function - - if (veto_sp_v.size() == 0) { - // TODO ? Need to decide how to handle this - // This version seems to work in skipping empty associations. It does break the rec.sbnd_crt_veto.sp_pe..length and - // rec.sbnd_crt_veto.sp_time..length branches? However, the rec.sbnd_crt_veto.sp_position..length still works and can be used? - std::cout << "No Veto Space Points" << std::endl; - //vetoSpacePoints.emplace_back(); // nullptr - } - else { - - for (auto const& sp: veto_sp_v) { - - vetoSpacePoints.push_back(*sp); - - } - } - } - FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); + std::cout << "DEBUG: about to Fill veto ptrs" << std::endl; + art::fill_ptr_vector(vetoPtrs, sbndcrtveto_handle); + // Only one valid veto per event + if (sbndcrtvetos.size() == 1) { + std::cout << "DEBUG: veto size is 1" << std::endl; + // And associated SpacePoint objects + art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); + if (spAssoc.isValid()) { + std::cout << "DEBUG: Veto SP Ass is valid" << std::endl; + // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied + const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); + FillSBNDCRTVeto(sbndcrtvetos[0], veto_sp_v, srsbndcrtveto); + std::cout << "DEBUG: Filled the veto" << std::endl; + } + } + //FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); } - + std::cout << std::endl; + std::cout << std::endl; art::Handle sbndframeshiftinfo_handle; GetByLabelStrict(evt, fParams.SBNDFrameShiftInfoLabel(), sbndframeshiftinfo_handle); @@ -2491,7 +2488,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.ncrt_spacepoints = srcrtspacepoints.size(); rec.sbnd_crt_tracks = srsbndcrttracks; rec.nsbnd_crt_tracks = srsbndcrttracks.size(); - rec.sbnd_crt_veto = srsbndcrtveto; + rec.sbnd_crt_veto = srsbndcrtveto; rec.opflashes = srflashes; rec.nopflashes = srflashes.size(); rec.sbnd_frames = srsbndframeshiftinfo; diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 4f5cbbc01..eb00e4858 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -142,7 +142,8 @@ namespace caf } void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, - const std::vector &points, + //const std::vector &points, + const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty) { @@ -154,9 +155,9 @@ namespace caf // add the CRTSpacePoint associations to the SR Veto for(auto const& sp : points) { - srsbndcrtveto.sp_position.emplace_back(sp.X(), sp.Y(), sp.Z()); - srsbndcrtveto.sp_time.emplace_back(sp.Ts0()); - srsbndcrtveto.sp_pe.emplace_back(sp.PE()); + srsbndcrtveto.sp_position.emplace_back(sp->X(), sp->Y(), sp->Z()); + srsbndcrtveto.sp_time.emplace_back(sp->Ts0()/1000); /// convert to us + srsbndcrtveto.sp_pe.emplace_back(sp->PE()); } }; void FillSBNDFrameShiftInfo(const sbnd::timing::FrameShiftInfo &frame, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 263c1d1cd..430ca0cb1 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -277,7 +277,8 @@ namespace caf bool allowEmpty = false); void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, - const std::vector &points, + //const std::vector &points, + const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty = false); From 387d4ad7738c5479dcf317ed3acbf8bffea48921 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Wed, 24 Sep 2025 20:31:29 -0500 Subject: [PATCH 209/367] cleaned up print out statements --- sbncode/CAFMaker/CAFMaker_module.cc | 11 ----------- sbncode/CAFMaker/FillReco.cxx | 1 - sbncode/CAFMaker/FillReco.h | 1 - 3 files changed, 13 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index e99608cc1..e117ef330 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1699,11 +1699,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } - std::cout << std::endl; - std::cout << std::endl; - std::cout << "DEBUG --> Start CRT Veto Fill" <> sbndcrtveto_handle; GetByLabelStrict(evt, fParams.SBNDCRTVetoLabel(), sbndcrtveto_handle); @@ -1711,25 +1706,19 @@ void CAFMaker::produce(art::Event& evt) noexcept { // fill into event if (sbndcrtveto_handle.isValid()) { const std::vector &sbndcrtvetos = *sbndcrtveto_handle; - std::cout << "DEBUG: about to Fill veto ptrs" << std::endl; art::fill_ptr_vector(vetoPtrs, sbndcrtveto_handle); // Only one valid veto per event if (sbndcrtvetos.size() == 1) { - std::cout << "DEBUG: veto size is 1" << std::endl; // And associated SpacePoint objects art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); if (spAssoc.isValid()) { - std::cout << "DEBUG: Veto SP Ass is valid" << std::endl; // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); FillSBNDCRTVeto(sbndcrtvetos[0], veto_sp_v, srsbndcrtveto); - std::cout << "DEBUG: Filled the veto" << std::endl; } } //FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); } - std::cout << std::endl; - std::cout << std::endl; art::Handle sbndframeshiftinfo_handle; GetByLabelStrict(evt, fParams.SBNDFrameShiftInfoLabel(), sbndframeshiftinfo_handle); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index eb00e4858..45e811596 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -142,7 +142,6 @@ namespace caf } void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, - //const std::vector &points, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty) diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 430ca0cb1..661a76deb 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -277,7 +277,6 @@ namespace caf bool allowEmpty = false); void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, - //const std::vector &points, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty = false); From 5ccd5e7172b05c1485efc8039531ed0e537108d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Castillo?= Date: Fri, 26 Sep 2025 09:41:35 -0500 Subject: [PATCH 210/367] Change CorrectedOpFlash attributed --- sbncode/CAFMaker/FillReco.cxx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 7f77c067a..5b40125fd 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -302,13 +302,10 @@ namespace caf slice.correctedOpFlash.setDefault(); if ( slcCorrectedOpFlash.empty()==false ) { const sbn::CorrectedOpFlashTiming &_correctedOpFlash = *slcCorrectedOpFlash[0]; - //TODO: use the score of the match to fill the information accordingly slice.correctedOpFlash.OpFlashT0 = _correctedOpFlash.OpFlashT0; - slice.correctedOpFlash.UpstreamTime_lightonly = _correctedOpFlash.UpstreamTime_lightonly; - slice.correctedOpFlash.UpstreamTime_tpczcorr = _correctedOpFlash.UpstreamTime_tpczcorr; - slice.correctedOpFlash.UpstreamTime_propcorr_tpczcorr = _correctedOpFlash.UpstreamTime_propcorr_tpczcorr; - slice.correctedOpFlash.FMScore = _correctedOpFlash.FMScore; - slice.correctedOpFlash.SliceNuScore = _correctedOpFlash.SliceNuScore; + slice.correctedOpFlash.NuToFLight = _correctedOpFlash.NuToFLight; + slice.correctedOpFlash.NuToFCharge = _correctedOpFlash.NuToFCharge; + slice.correctedOpFlash.OpFlashT0Corrected = _correctedOpFlash.OpFlashT0Corrected; } } From 51bf49fee530565ef0665278e214f33701519a94 Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Mon, 29 Sep 2025 17:08:41 -0500 Subject: [PATCH 211/367] Add in planes for each component of the top CRT. --- .../WireModGen/wiremodmuon_sbn.fcl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl b/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl index 84ad9d0cd..9ab3ebf5d 100644 --- a/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl +++ b/sbncode/EventGenerator/WireModGen/wiremodmuon_sbn.fcl @@ -5,12 +5,16 @@ wiremodmuon_icarus: { module_type: WireModMuon # CRT bounds - CRTX0: [-550] - CRTX1: [550] - CRTY0: [618] - CRTY1: [618] - CRTZ0: [-1100] - CRTZ1: [1300] + # + # Each entry (in X0, X1, Y0, Y1, Z0, Z1) is one plane that will be included in the intersection check + # + # listed as: Top horizontal, Top Rim West, Top Rim East, Top Rim South + CRTX0: [-580, 555, -555, -560, -560] + CRTX1: [580, 555, -555, 380, 560] + CRTY0: [617.4, 400, 400, 400, 420] + CRTY1: [617.4, 600, 600, 600, 620] + CRTZ0: [-1180, -1180, -1180, -1143, 1533] + CRTZ1: [1460, 1460, 1460, -1143, 1533] # selection config SelectA2C: true From a56595db268c954f02c9be07f4b4f491a8cb95a0 Mon Sep 17 00:00:00 2001 From: kjplows Date: Tue, 30 Sep 2025 10:31:53 -0500 Subject: [PATCH 212/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6a0b738d..1e8541f53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.10.03.01 LANGUAGES CXX) +project(sbncode VERSION 10.10.03.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 2bb070be5..fcf0513e5 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v10_10_03 - -sbnalg v10_10_03 - +sbnalg v10_10_03_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From 33f34553003226b5f729a3418ad4398b107587fb Mon Sep 17 00:00:00 2001 From: Gray Putnam Date: Tue, 30 Sep 2025 13:41:20 -0500 Subject: [PATCH 213/367] Add truth matching info to CRT hits. --- sbncode/CAFMaker/CAFMakerParams.h | 6 +++ sbncode/CAFMaker/CAFMaker_module.cc | 64 ++++++++++++++++++++++++++++- sbncode/CAFMaker/FillReco.cxx | 50 +++++++++++++++++++++- sbncode/CAFMaker/FillReco.h | 3 ++ 4 files changed, 120 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index e2c2efbe8..61d634d99 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -320,6 +320,12 @@ namespace caf "crthit" // icarus }; + Atom CRTSimChanLabel { + Name("CRTSimChanLabel"), + Comment("Label of AuxDetSimChannels."), + "genericcrt" // icarus + }; + Atom CRTTrackLabel { Name("CRTTrackLabel"), Comment("Label of sbn CRT tracks."), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 29a35d0ee..5e4e415ca 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -139,6 +139,7 @@ #include "sbnanaobj/StandardRecord/Flat/FlatRecord.h" #include "lardataobj/RawData/ExternalTrigger.h" #include "lardataobj/RawData/TriggerData.h" +#include "lardataobj/Simulation/AuxDetSimChannel.h" // // CAFMaker #include "sbncode/CAFMaker/AssociationUtil.h" @@ -286,6 +287,11 @@ class CAFMaker : public art::EDProducer { std::vector> fTPCVolumes; std::vector fActiveVolumes; + // CRT geometry info + // + // ICARUS + std::map, int> fFEBChannel2AuxDetID; + // random number generator for fake reco CLHEP::HepRandomEngine& fFakeRecoRandomEngine; @@ -314,6 +320,7 @@ class CAFMaker : public art::EDProducer { double GetBlindPOTScale() const; void InitVolumes(); ///< Initialize volumes from Gemotry service + void InitCRTMapping(); ///< Initialize CRT mapping void FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time); void FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_time, double CRTT1_reference_time); @@ -422,6 +429,9 @@ class CAFMaker : public art::EDProducer { // setup volume definitions InitVolumes(); + // setup CRT mapping + InitCRTMapping(); + fSaveGENIEEventRecord = fParams.SaveGENIEEventRecord(); } @@ -595,6 +605,36 @@ void CAFMaker::FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_ } +void CAFMaker::InitCRTMapping() { + + // ICARUS + cet::search_path searchPath("FW_SEARCH_PATH"); + std::string fullFileName; + searchPath.find_file("feb_map.txt",fullFileName); + std::ifstream fin; + fin.open(fullFileName, std::ios::in); + + if (fin.good()) { + std::string line; + + while(std::getline(fin,line)) { + std::vector row; + std::string word; + + std::stringstream s(line); + while (std::getline(s, word, ',')) { + row.push_back(word); + } + int auxDetID = std::stoi(row[0]); // auxDetID + int mac5 = std::stoi(row[1]); // FEB ID + int chan = std::stoi(row[2]); // FEB channel + fFEBChannel2AuxDetID[std::make_pair(mac5, chan)] = auxDetID; + } + + fin.close(); + } +} + void CAFMaker::InitVolumes() { const geo::GeometryCore *geometry = lar::providerFrom(); @@ -1648,16 +1688,36 @@ void CAFMaker::produce(art::Event& evt) noexcept { caf::SRSBNDFrameShiftInfo srsbndframeshiftinfo; caf::SRSBNDTimingInfo srsbndtiminginfo; + // Mapping of (feb, channel) to truth information (AuxDetSimChannel) -- filled for ICARUS + std::map, sim::AuxDetSimChannel> crtsimchanmap; + if(fDet == kICARUS) { art::Handle> crthits_handle; GetByLabelStrict(evt, fParams.CRTHitLabel(), crthits_handle); + + art::Handle> auxdetsimchan_handle; + GetByLabelStrict(evt, fParams.CRTSimChanLabel(), auxdetsimchan_handle); + // fill into event if (crthits_handle.isValid()) { const std::vector &crthits = *crthits_handle; + + std::vector empty; + const std::vector &crtsimchanvec = (auxdetsimchan_handle.isValid()) ? *auxdetsimchan_handle : empty; + // Turn the AuxDetSimChannel's into a map that can be looked up from a CRT Hit + for (const sim::AuxDetSimChannel &crtsimchan: crtsimchanvec) { + for (auto const &map_pair: fFEBChannel2AuxDetID) { + if (map_pair.second == (int)crtsimchan.AuxDetID()) { + crtsimchanmap[map_pair.first] = crtsimchan; + break; + } + } + } + for (unsigned i = 0; i < crthits.size(); i++) { srcrthits.emplace_back(); - FillCRTHit(crthits[i], fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, srcrthits.back()); + FillCRTHit(crthits[i], fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, crtsimchanmap, srcrthits.back()); } } @@ -2328,7 +2388,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { crthittagginginfo = fmCRTHitMatchInfo.at(iPart); } - FillTrackCRTHit(fmCRTHitMatch.at(iPart), crthitmatch, crthittagginginfo, fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, trk); + FillTrackCRTHit(fmCRTHitMatch.at(iPart), crthitmatch, crthittagginginfo, fParams.CRTUseTS0(), CRT_T0_reference_time, CRT_T1_reference_time, crtsimchanmap, trk); } // NOTE: SEE TODO AT fmCRTTrackMatch if (fmCRTTrackMatch.isValid() && fDet == kICARUS) { diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 95e76532b..0939e41b6 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -68,6 +68,7 @@ namespace caf bool use_ts0, int64_t CRT_T0_reference_time, // ns, signed double CRT_T1_reference_time, // us + const std::map, sim::AuxDetSimChannel> &crtsimchanmap, caf::SRCRTHit &srhit, bool allowEmpty) { @@ -86,6 +87,52 @@ namespace caf srhit.pe = hit.peshit; srhit.plane = hit.plane; + // lookup truth matching information + std::map true_energy; + std::set> checked; // keep track of what AuxDetSimChannels we have looked at + for (auto const &mac_to_pes: hit.pesmap) { + int mac = (int)mac_to_pes.first; + for (const std::pair &chan_pe: mac_to_pes.second) { + int chan = chan_pe.first; + + // check for the 3-pos Minos ("m") modules, or the 1-pos other modules + bool is_minos_module = mac < 94; + int pos = is_minos_module ? (chan/10 + 1) : 1; + + std::pair key {mac, pos}; + if (checked.count(key)) continue; // already looked here + + checked.insert(key); + + if (crtsimchanmap.count(key)) { + const sim::AuxDetSimChannel &crtsimchan = crtsimchanmap.at(key); + for (const sim::AuxDetIDE &ide: crtsimchan.AuxDetIDEs()) { + double hit_time_us = srhit.time; + double tru_time_us = ide.entryT/1e3; // ns -> us + + // 1us cut on truth matching + if (abs(hit_time_us - tru_time_us) < 1) { + // std::cout << "Hit at time: " << (srhit.time/1e3) << " " << (srhit.t0/1e3) << " " << (srhit.t1/1e3) << " pes: " << chan_pe.second << " of " << srhit.pe << " on FEB: " << mac << " channel: " << chan << " matched to AuxDetID: " << crtsimchan.AuxDetID() << " G4ID: " << ide.trackID << " E: " << ide.energyDeposited << " T: " << (ide.entryT/1e6) << std::endl; + true_energy[ide.trackID] += ide.energyDeposited; + } + + } + } + } + } + + // sort results by energy + std::vector> true_energy_list; + for (auto const &pair: true_energy) true_energy_list.push_back(std::make_pair(pair.second, pair.first)); + std::sort(true_energy_list.begin(), true_energy_list.end(), std::greater<>()); + + // Save to the SRCRTHit truth + for (auto const &pair: true_energy_list) { + srhit.truth.match_e.push_back(pair.first); + srhit.truth.match_id.push_back(pair.second); + } + if (true_energy_list.size() > 0) srhit.truth.bestmatch_id = true_energy_list[0].second; + } void FillCRTTrack(const sbn::crt::CRTTrack &track, @@ -640,6 +687,7 @@ namespace caf bool use_ts0, int64_t CRT_T0_reference_time, // ns, signed double CRT_T1_reference_time, // us + const std::map, sim::AuxDetSimChannel> &crtsimchanmap, caf::SRTrack &srtrack, bool allowEmpty) { @@ -666,7 +714,7 @@ namespace caf srtrack.crthit.hit.plane = t0match[0]->fID; } if (hitmatch.size()) { - FillCRTHit(*hitmatch[0], use_ts0, CRT_T0_reference_time, CRT_T1_reference_time, srtrack.crthit.hit, allowEmpty); + FillCRTHit(*hitmatch[0], use_ts0, CRT_T0_reference_time, CRT_T1_reference_time, crtsimchanmap, srtrack.crthit.hit, allowEmpty); } } diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index eb4a034df..cde13dbae 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -25,6 +25,7 @@ #include "lardataobj/AnalysisBase/T0.h" #include "lardataobj/RecoBase/PFParticleMetadata.h" #include "lardataobj/RecoBase/MCSFitResult.h" +#include "lardataobj/Simulation/AuxDetSimChannel.h" #include "larrecodnn/CVN/func/Result.h" #include "sbnobj/Common/Reco/Stub.h" #include "sbnobj/Common/Reco/RangeP.h" @@ -175,6 +176,7 @@ namespace caf bool use_ts0, int64_t CRT_T0_reference_time, // ns, signed double CRT_T1_reference_time, // us + const std::map, sim::AuxDetSimChannel> &crtsimchanmap, caf::SRTrack &srtrack, bool allowEmpty = false); @@ -242,6 +244,7 @@ namespace caf bool use_ts0, int64_t CRT_T0_reference_time, // ns, signed double CRT_T1_reference_time, // us + const std::map, sim::AuxDetSimChannel> &crtsimchanmap, caf::SRCRTHit &srhit, bool allowEmpty = false); void FillCRTTrack(const sbn::crt::CRTTrack &track, From 4f27e3380b2bcba06e914eb9aed27155e1cbec04 Mon Sep 17 00:00:00 2001 From: Nikki Pallat Date: Tue, 30 Sep 2025 17:59:38 -0500 Subject: [PATCH 214/367] Updated to work with and fill trigger emulation variables --- sbncode/CAFMaker/CAFMakerParams.h | 24 ++++++++++++++++++++++++ sbncode/CAFMaker/CAFMaker_module.cc | 27 +++++++++++++++++++++++++-- sbncode/CAFMaker/CMakeLists.txt | 1 + sbncode/CAFMaker/FillTrigger.cxx | 18 +++++++++++++----- sbncode/CAFMaker/FillTrigger.h | 7 +++++++ 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 2ecf63f04..06fb87ad6 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -417,6 +417,30 @@ namespace caf "emuTriggerUnshifted" }; + Atom MonPulsesTriggerLabel { + Name("MonPulsesTriggerLabel"), + Comment("Label of trigger emulation product MonPulses (number of PMT pairs above threshold for all channels) for all flashes."), + art::InputTag("opdaq", "MonPulses", "DetSim") + }; + + Atom MonPulseSizesTriggerLabel { + Name("MonPulseSizesTriggerLabel"), + Comment("Label of trigger emulation product MonPulses Sizes, which gives the length of each trigger response in MonPulses."), + art::InputTag("opdaq", "MonPulseSizes", "DetSim") + }; + + Atom PairsTriggerLabel { + Name("PairsTriggerLabel"), + Comment("Label of number of PMT pairs over threshold."), + art::InputTag("opdaq", "pairsOverThreshold", "DetSim") + }; + + Atom EmulatedTriggerLabel { + Name("EmulatedTriggerLabel"), + Comment("Label of bool of passing the trigger."), + art::InputTag("opdaq", "triggerEmulation", "DetSim") + }; + Atom FlashTrigLabel { Name("FlashTrigLabel"), Comment("Label of bool of passing flash trigger."), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index c21420c69..80dff4d1f 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1600,29 +1600,52 @@ void CAFMaker::produce(art::Event& evt) noexcept { //####################################################### // Fill detector & reco //####################################################### - + //Beam gate and Trigger info art::Handle extratrig_handle; GetByLabelStrict(evt, fParams.TriggerLabel().encode(), extratrig_handle); art::Handle> trig_handle; - std::cout<<"Trigger label: "<> unshifted_trig_handle; if (!isRealData) GetByLabelStrict(evt, fParams.UnshiftedTriggerLabel().encode(), unshifted_trig_handle); + //Trigger emulation handles + art::Handle> monpulses_handle; + GetByLabelStrict(evt, fParams.MonPulsesTriggerLabel().encode(), monpulses_handle); + + art::Handle> monpulse_sizes_handle; + GetByLabelStrict(evt, fParams.MonPulseSizesTriggerLabel().encode(), monpulse_sizes_handle); + + art::Handle pairs_handle; + GetByLabelStrict(evt, fParams.PairsTriggerLabel().encode(), pairs_handle); + + art::Handle trigemu_handle; + GetByLabelStrict(evt, fParams.EmulatedTriggerLabel().encode(), trigemu_handle); + + // Check trigger handles const bool isValidTrigger = extratrig_handle.isValid() && trig_handle.isValid() && trig_handle->size() == 1; const bool isValidUnshiftedTrigger = unshifted_trig_handle.isValid() && unshifted_trig_handle->size() == 1; + const bool isValidEmulationTrigger = monpulses_handle.isValid() && monpulse_sizes_handle.isValid() && pairs_handle.isValid() && trigemu_handle.isValid(); const double triggerShift = (isValidUnshiftedTrigger && isValidTrigger)? unshifted_trig_handle->at(0).TriggerTime() - trig_handle->at(0).TriggerTime() : 0.; + // Fill local ExtraTriggerInfo struct + sbn::ExtraTriggerInfo extratrig; + if (extratrig_handle.isValid()) extratrig = *extratrig_handle; + caf::SRTrigger srtrigger; if (isValidTrigger) { FillTrigger(*extratrig_handle, trig_handle->at(0), srtrigger, triggerShift); } + // Fill trigger emulation information + if (isValidEmulationTrigger) { + FillTriggerEmulation(monpulses_handle, monpulse_sizes_handle, pairs_handle, trigemu_handle, srtrigger); + } + // If not real data, fill in enough of the SRTrigger to make (e.g.) the CRT // time referencing work. TODO: add more stuff to a "MC"-Trigger? // No longer needed with incorporation of trigger emulation in the MC. diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index df8b01a54..aa42cba8a 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -36,6 +36,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_Reco sbnobj::Common_Analysis sbnobj::Common_PMT_Data + sbnobj::Common_Trigger sbnobj::SBND_CRT sbnobj::SBND_Timing lardataalg::DetectorInfo diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 6a13e420b..03f142dce 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -24,11 +24,6 @@ namespace caf triggerInfo.gate_count = addltrig_info.gateCount; triggerInfo.gate_delta = addltrig_info.gateCountFromPreviousTrigger; - triggerInfo.passed_trigger = addltrig_info.triggerEmulation; - triggerInfo.num_pairs_over_threshold = addltrig_info.pairsOverThreshold; - triggerInfo.monpulses_flat = addltrig_info.MonPulses; - triggerInfo.monpulse_sizes = addltrig_info.MonPulseSizes; - } void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo) { @@ -49,4 +44,17 @@ namespace caf triggerInfo.trigger_within_gate = diff_ts; } + void FillTriggerEmulation(art::Handle> const& monpulsesFlat, + art::Handle> const& monpulseSizes, + art::Handle const& numPairs, + art::Handle const& passedTrig, + caf::SRTrigger& triggerInfo) { + + triggerInfo.monpulses_flat = *monpulsesFlat; + triggerInfo.monpulse_sizes = *monpulseSizes; + triggerInfo.num_pairs_over_threshold = *numPairs; + triggerInfo.passed_trigger = *passedTrig; + + } + } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index ea1aab7eb..1988b6876 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -6,6 +6,7 @@ #include "sbnanaobj/StandardRecord/SRTrigger.h" #include "sbnanaobj/StandardRecord/SRSBNDTimingInfo.h" #include "lardataobj/RawData/TriggerData.h" +#include "art/Framework/Principal/Handle.h" #include @@ -20,6 +21,12 @@ namespace caf void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo); void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo); + + void FillTriggerEmulation(art::Handle> const& monpulsesFlat, + art::Handle> const& monpulseSizes, + art::Handle const& numPairs, + art::Handle const& passedTrig, + caf::SRTrigger& triggerInfo); } #endif From 188b9c42013d01149b7d79acf3425bf432a20909 Mon Sep 17 00:00:00 2001 From: kjplows Date: Thu, 2 Oct 2025 15:16:31 -0500 Subject: [PATCH 215/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e8541f53..e45655eed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.10.03.02 LANGUAGES CXX) +project(sbncode VERSION 10.10.05 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index fcf0513e5..8ec4e5537 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_10_03 - -sbnalg v10_10_03_01 - +larsoft v10_10_05 - +sbnalg v10_10_05 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From 25ef6cc465ad9f96dcfaf213528808795b854d99 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Mon, 6 Oct 2025 13:11:51 -0500 Subject: [PATCH 216/367] Changed the FillReco function to have just the veto ptrs. Needs testing still --- sbncode/CAFMaker/CAFMaker_module.cc | 8 +++++--- sbncode/CAFMaker/FillReco.cxx | 13 +++++++------ sbncode/CAFMaker/FillReco.h | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index e117ef330..fa25ad13a 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1705,16 +1705,18 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector> vetoPtrs; // fill into event if (sbndcrtveto_handle.isValid()) { - const std::vector &sbndcrtvetos = *sbndcrtveto_handle; + //const std::vector &sbndcrtvetos = *sbndcrtveto_handle; art::fill_ptr_vector(vetoPtrs, sbndcrtveto_handle); // Only one valid veto per event - if (sbndcrtvetos.size() == 1) { + //if (sbndcrtvetos.size() == 1) { + if (vetoPtrs.size() == 1) { // And associated SpacePoint objects art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); if (spAssoc.isValid()) { // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); - FillSBNDCRTVeto(sbndcrtvetos[0], veto_sp_v, srsbndcrtveto); + //FillSBNDCRTVeto(sbndcrtvetos[0], veto_sp_v, srsbndcrtveto); + FillSBNDCRTVeto(vetoPtrs[0], veto_sp_v, srsbndcrtveto); } } //FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 45e811596..c2563fdc3 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -141,16 +141,17 @@ namespace caf srsbndcrttrack.tof = track.ToF(); } - void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, + //void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, + void FillSBNDCRTVeto(const art::Ptr &veto, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty) { - srsbndcrtveto.V0 = veto.V0(); - srsbndcrtveto.V1 = veto.V1(); - srsbndcrtveto.V2 = veto.V2(); - srsbndcrtveto.V3 = veto.V3(); - srsbndcrtveto.V4 = veto.V4(); + srsbndcrtveto.V0 = veto->V0(); + srsbndcrtveto.V1 = veto->V1(); + srsbndcrtveto.V2 = veto->V2(); + srsbndcrtveto.V3 = veto->V3(); + srsbndcrtveto.V4 = veto->V4(); // add the CRTSpacePoint associations to the SR Veto for(auto const& sp : points) { diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 661a76deb..d3f9927a6 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -276,7 +276,8 @@ namespace caf caf::SRSBNDCRTTrack &srsbndcrttrack, bool allowEmpty = false); - void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, + //void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, + void FillSBNDCRTVeto(const art::Ptr &veto, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty = false); From c0119548ad52c3657bae0ef8eb395953df606efa Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Tue, 7 Oct 2025 22:43:22 -0500 Subject: [PATCH 217/367] Cleaned up comments. Only a vector of veto ptrs is used now. Still needs to be tested with sbndcode. --- sbncode/CAFMaker/CAFMaker_module.cc | 4 ---- sbncode/CAFMaker/FillReco.cxx | 4 ++-- sbncode/CAFMaker/FillReco.h | 1 - 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 8a9b8d229..195cef19a 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1791,21 +1791,17 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector> vetoPtrs; // fill into event if (sbndcrtveto_handle.isValid()) { - //const std::vector &sbndcrtvetos = *sbndcrtveto_handle; art::fill_ptr_vector(vetoPtrs, sbndcrtveto_handle); // Only one valid veto per event - //if (sbndcrtvetos.size() == 1) { if (vetoPtrs.size() == 1) { // And associated SpacePoint objects art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); if (spAssoc.isValid()) { // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); - //FillSBNDCRTVeto(sbndcrtvetos[0], veto_sp_v, srsbndcrtveto); FillSBNDCRTVeto(vetoPtrs[0], veto_sp_v, srsbndcrtveto); } } - //FillSBNDCRTVeto(sbndcrtvetos[0], vetoSpacePoints, srsbndcrtveto); } art::Handle sbndframeshiftinfo_handle; diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 25896e843..084e2fba8 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -188,7 +188,6 @@ namespace caf srsbndcrttrack.tof = track.ToF(); } - //void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, void FillSBNDCRTVeto(const art::Ptr &veto, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, @@ -206,7 +205,8 @@ namespace caf srsbndcrtveto.sp_time.emplace_back(sp->Ts0()/1000); /// convert to us srsbndcrtveto.sp_pe.emplace_back(sp->PE()); } - }; + } + void FillSBNDFrameShiftInfo(const sbnd::timing::FrameShiftInfo &frame, caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty) diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 26d5a2fdc..f4ad71446 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -279,7 +279,6 @@ namespace caf caf::SRSBNDCRTTrack &srsbndcrttrack, bool allowEmpty = false); - //void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, void FillSBNDCRTVeto(const art::Ptr &veto, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, From 534f1ca5c1fd0c62e2bb3b2e65f4fcbda24e7ed0 Mon Sep 17 00:00:00 2001 From: Linyan Wan Date: Wed, 8 Oct 2025 13:23:44 -0500 Subject: [PATCH 218/367] Add IsCC to flat GENIE tree --- sbncode/CAFMaker/CAFMaker_module.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 6ede8b23b..b0324e947 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -263,6 +263,7 @@ class CAFMaker : public art::EDProducer { double fGenieEvtRec_brEvtXSec = 0.0; ////< Cross section for selected event (1e-38 cm2) double fGenieEvtRec_brEvtDXSec = 0.0; ////< Cross section for selected event kinematics (1e-38 cm2 / {K^n}) unsigned int fGenieEvtRec_brEvtKPS = 0; ////< Kinematic phase space variables. See $GENIE/src/Framework/Conventions/KinePhaseSpace.h -> KinePhaseSpace_t + bool fGenieEvtRec_brIsCC = 0; ////< Is weakCC double fGenieEvtRec_brEvtWght = 0.0; ////< Weight for that event double fGenieEvtRec_brEvtProb = 0.0; ////< Probability for that event (given cross section, path lengths, etc) double fGenieEvtRec_brEvtVtx[4] = {0.0}; ////< Event vertex position in detector coord syst (SI) @@ -1142,6 +1143,7 @@ void CAFMaker::InitializeOutfiles() fFlatGenieTree->Branch("GenieEvtRec.EvtXSec", &fGenieEvtRec_brEvtXSec, "GenieEvtRec.EvtXSec/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtDXSec", &fGenieEvtRec_brEvtDXSec, "GenieEvtRec.EvtDXSec/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtKPS", &fGenieEvtRec_brEvtKPS, "GenieEvtRec.EvtKPS/i" ); + fFlatGenieTree->Branch("GenieEvtRec.IsCC", &fGenieEvtRec_brIsCC, "GenieEvtRec.IsCC/O" ); fFlatGenieTree->Branch("GenieEvtRec.EvtWght", &fGenieEvtRec_brEvtWght, "GenieEvtRec.EvtWght/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtProb", &fGenieEvtRec_brEvtProb, "GenieEvtRec.EvtProb/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtVtx", fGenieEvtRec_brEvtVtx, "GenieEvtRec.EvtVtx[4]/D" ); @@ -1507,6 +1509,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { fGenieEvtRec_brEvtXSec = genie_rec->XSec() * (1e+38/genie::units::cm2); fGenieEvtRec_brEvtDXSec = genie_rec->DiffXSec() * (1e+38/genie::units::cm2); fGenieEvtRec_brEvtKPS = genie_rec->DiffXSecVars(); + fGenieEvtRec_brIsCC = genie_rec->Summary()->ProcInfo().IsWeakCC(); fGenieEvtRec_brEvtWght = genie_rec->Weight(); fGenieEvtRec_brEvtProb = genie_rec->Probability(); fGenieEvtRec_brEvtVtx[0] = genie_rec->Vertex()->X(); @@ -1630,6 +1633,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { // } // try to find the result of the Flash trigger if it was run + mf::LogInfo("CAFMaker") << " New Trigger Time = " << srtrigger.global_trigger_det_time << " us\n" + << " New Beam Gate Time = " << srtrigger.beam_gate_det_time << " us"; bool pass_flash_trig = false; art::Handle flashtrig_handle; GetByLabelStrict(evt, fParams.FlashTrigLabel(), flashtrig_handle); From f98a84b5c07fadec957850a88152819d3d8b070d Mon Sep 17 00:00:00 2001 From: Linyan Wan Date: Wed, 8 Oct 2025 16:40:13 -0500 Subject: [PATCH 219/367] Adding interaction type and scattering type --- sbncode/CAFMaker/CAFMaker_module.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index fc4d39a51..6904ad260 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -264,7 +264,8 @@ class CAFMaker : public art::EDProducer { double fGenieEvtRec_brEvtXSec = 0.0; ////< Cross section for selected event (1e-38 cm2) double fGenieEvtRec_brEvtDXSec = 0.0; ////< Cross section for selected event kinematics (1e-38 cm2 / {K^n}) unsigned int fGenieEvtRec_brEvtKPS = 0; ////< Kinematic phase space variables. See $GENIE/src/Framework/Conventions/KinePhaseSpace.h -> KinePhaseSpace_t - bool fGenieEvtRec_brIsCC = 0; ////< Is weakCC + int fGenieEvtRec_brSctType = 0; ////< See ScatteringType.h + int fGenieEvtRec_brIntType = 0; ////< See InteractionType.h double fGenieEvtRec_brEvtWght = 0.0; ////< Weight for that event double fGenieEvtRec_brEvtProb = 0.0; ////< Probability for that event (given cross section, path lengths, etc) double fGenieEvtRec_brEvtVtx[4] = {0.0}; ////< Event vertex position in detector coord syst (SI) @@ -1183,7 +1184,8 @@ void CAFMaker::InitializeOutfiles() fFlatGenieTree->Branch("GenieEvtRec.EvtXSec", &fGenieEvtRec_brEvtXSec, "GenieEvtRec.EvtXSec/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtDXSec", &fGenieEvtRec_brEvtDXSec, "GenieEvtRec.EvtDXSec/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtKPS", &fGenieEvtRec_brEvtKPS, "GenieEvtRec.EvtKPS/i" ); - fFlatGenieTree->Branch("GenieEvtRec.IsCC", &fGenieEvtRec_brIsCC, "GenieEvtRec.IsCC/O" ); + fFlatGenieTree->Branch("GenieEvtRec.SctType", &fGenieEvtRec_brSctType, "GenieEvtRec.SctType/I" ); + fFlatGenieTree->Branch("GenieEvtRec.IntType", &fGenieEvtRec_brIntType, "GenieEvtRec.IntType/I" ); fFlatGenieTree->Branch("GenieEvtRec.EvtWght", &fGenieEvtRec_brEvtWght, "GenieEvtRec.EvtWght/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtProb", &fGenieEvtRec_brEvtProb, "GenieEvtRec.EvtProb/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtVtx", fGenieEvtRec_brEvtVtx, "GenieEvtRec.EvtVtx[4]/D" ); @@ -1549,7 +1551,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { fGenieEvtRec_brEvtXSec = genie_rec->XSec() * (1e+38/genie::units::cm2); fGenieEvtRec_brEvtDXSec = genie_rec->DiffXSec() * (1e+38/genie::units::cm2); fGenieEvtRec_brEvtKPS = genie_rec->DiffXSecVars(); - fGenieEvtRec_brIsCC = genie_rec->Summary()->ProcInfo().IsWeakCC(); + fGenieEvtRec_brSctType = genie_rec->Summary()->ProcInfo().ScatteringTypeId(); + fGenieEvtRec_brIntType = genie_rec->Summary()->ProcInfo().InteractionTypeId(); fGenieEvtRec_brEvtWght = genie_rec->Weight(); fGenieEvtRec_brEvtProb = genie_rec->Probability(); fGenieEvtRec_brEvtVtx[0] = genie_rec->Vertex()->X(); From 536905ba10646764670283e56b8333905f9954f8 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Tue, 14 Oct 2025 19:38:36 -0500 Subject: [PATCH 220/367] added new ICARUS HW trigger info --- sbncode/CAFMaker/FillTrigger.cxx | 53 +++++++++++++++++++++++++++----- sbncode/CAFMaker/FillTrigger.h | 1 - 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 009deccef..75b385f77 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -4,9 +4,9 @@ namespace caf { void FillTrigger(const sbn::ExtraTriggerInfo& addltrig_info, - const raw::Trigger& trig, - caf::SRTrigger& triggerInfo, - const double time_offset = 0.0) + const raw::Trigger& trig, + caf::SRTrigger& triggerInfo, + const double time_offset = 0.0) { triggerInfo.global_trigger_time = addltrig_info.triggerTimestamp; triggerInfo.beam_gate_time_abs = addltrig_info.beamGateTimestamp; @@ -14,7 +14,6 @@ namespace caf triggerInfo.global_trigger_det_time = trig.TriggerTime() + time_offset; double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; triggerInfo.trigger_within_gate = diff_ts; - triggerInfo.prev_global_trigger_time = addltrig_info.previousTriggerTimestamp; triggerInfo.source_type = sbn::bits::value(addltrig_info.sourceType); triggerInfo.trigger_type = sbn::bits::value(addltrig_info.triggerType); @@ -25,14 +24,52 @@ namespace caf triggerInfo.gate_delta = addltrig_info.gateCountFromPreviousTrigger; } - void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo) { + void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo) + { triggerInfo.global_trigger_time = absolute_time; triggerInfo.beam_gate_time_abs = absolute_time; + triggerInfo.trigger_within_gate = 0.; // Set this to 0 since the "MC" trigger is (for now) always at the spill time + } + + void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, + caf::SRTrigger& triggerInfo) + { + triggerInfo.global_trigger_time = timingInfo.hltEtrig; + triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; + double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; + triggerInfo.trigger_within_gate = diff_ts; + } + + void FillTriggerICARUS(const sbn::ExtraTriggerInfo& addltrig_info, + caf::SRTrigger& triggerInfo) + { + // Per-cryostat additional trigger information, straight from the trigger hardware + const auto& addltrig_info_cryoE = addltrig_info.cryostats[sbn::ExtraTriggerInfo::EastCryostat]; + const auto& addltrig_info_cryoW = addltrig_info.cryostats[sbn::ExtraTriggerInfo::WestCryostat]; - // Set this to 0 since the "MC" trigger is (for now) always at the spill time - triggerInfo.trigger_within_gate = 0.; + // Choose the cryostat that triggered first (if both are available) + if (addltrig_info_cryoE.hasTrigger() && (!addltrig_info_cryoW.hasTrigger() || addltrig_info_cryoE.beamToTrigger <= addltrig_info_cryoW.beamToTrigger)) { + triggerInfo.trigger_cryo_source = 0; ///< East + triggerInfo.trigger_logic_bits = addltrig_info_cryoE.triggerLogicBits; + triggerInfo.beam_to_trigger_time = addltrig_info_cryoE.beamToTrigger; + } + else if (addltrig_info_cryoW.hasTrigger()) { + triggerInfo.trigger_cryo_source = 1; ///< West + triggerInfo.trigger_logic_bits = addltrig_info_cryoW.triggerLogicBits; + triggerInfo.beam_to_trigger_time = addltrig_info_cryoW.beamToTrigger; + } + } - // TODO: fill others? + void FillTriggerEmulation(art::Handle> const& monpulsesFlat, + art::Handle> const& monpulseSizes, + art::Handle const& numPairs, + art::Handle const& passedTrig, + caf::SRTrigger& triggerInfo) + { + triggerInfo.monpulses_flat = *monpulsesFlat; + triggerInfo.monpulse_sizes = *monpulseSizes; + triggerInfo.num_pairs_over_threshold = *numPairs; + triggerInfo.passed_trigger = *passedTrig; } } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index b83c2e9f0..f3e510867 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -10,7 +10,6 @@ namespace caf { - void FillTrigger(const sbn::ExtraTriggerInfo& addltrig_info, const raw::Trigger& trig_info, caf::SRTrigger& triggerInfo, From a132aa787ba007f3b3fc8827ea8afc6ca7b88fa8 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Wed, 15 Oct 2025 12:12:28 -0500 Subject: [PATCH 221/367] fixed typo --- sbncode/CAFMaker/FillTrigger.cxx | 2 +- sbncode/CAFMaker/FillTrigger.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 75b385f77..380aae542 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -48,7 +48,7 @@ namespace caf const auto& addltrig_info_cryoW = addltrig_info.cryostats[sbn::ExtraTriggerInfo::WestCryostat]; // Choose the cryostat that triggered first (if both are available) - if (addltrig_info_cryoE.hasTrigger() && (!addltrig_info_cryoW.hasTrigger() || addltrig_info_cryoE.beamToTrigger <= addltrig_info_cryoW.beamToTrigger)) { + if (addltrig_info_cryoE.hasTrigger() && (!addltrig_info_cryoW.hasTrigger() || (addltrig_info_cryoE.beamToTrigger <= addltrig_info_cryoW.beamToTrigger))) { triggerInfo.trigger_cryo_source = 0; ///< East triggerInfo.trigger_logic_bits = addltrig_info_cryoE.triggerLogicBits; triggerInfo.beam_to_trigger_time = addltrig_info_cryoE.beamToTrigger; diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index f3e510867..9dd0e020a 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -17,6 +17,16 @@ namespace caf void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo); + void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo); + + void FillTriggerICARUS(const sbn::ExtraTriggerInfo& addltrig_info, + caf::SRTrigger& triggerInfo); + + void FillTriggerEmulation(art::Handle> const& monpulsesFlat, + art::Handle> const& monpulseSizes, + art::Handle const& numPairs, + art::Handle const& passedTrig, + caf::SRTrigger& triggerInfo); } #endif From ffaad0875114e839b6b9a0af991d72d669f3c299 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Wed, 15 Oct 2025 17:46:35 -0500 Subject: [PATCH 222/367] cleaned up commit from the cherry-pick --- sbncode/CAFMaker/CAFMaker_module.cc | 1 + sbncode/CAFMaker/FillTrigger.cxx | 21 --------------------- sbncode/CAFMaker/FillTrigger.h | 12 +----------- 3 files changed, 2 insertions(+), 32 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 48da84e8f..e2e910454 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1577,6 +1577,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { caf::SRTrigger srtrigger; if (isValidTrigger) { FillTrigger(*extratrig_handle, trig_handle->at(0), srtrigger, triggerShift); + FillTriggerICARUS(*extratrig_handle, srtrigger); } // If not real data, fill in enough of the SRTrigger to make (e.g.) the CRT // time referencing work. TODO: add more stuff to a "MC"-Trigger? diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 380aae542..2e8d014ea 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -31,15 +31,6 @@ namespace caf triggerInfo.trigger_within_gate = 0.; // Set this to 0 since the "MC" trigger is (for now) always at the spill time } - void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, - caf::SRTrigger& triggerInfo) - { - triggerInfo.global_trigger_time = timingInfo.hltEtrig; - triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; - double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; - triggerInfo.trigger_within_gate = diff_ts; - } - void FillTriggerICARUS(const sbn::ExtraTriggerInfo& addltrig_info, caf::SRTrigger& triggerInfo) { @@ -60,16 +51,4 @@ namespace caf } } - void FillTriggerEmulation(art::Handle> const& monpulsesFlat, - art::Handle> const& monpulseSizes, - art::Handle const& numPairs, - art::Handle const& passedTrig, - caf::SRTrigger& triggerInfo) - { - triggerInfo.monpulses_flat = *monpulsesFlat; - triggerInfo.monpulse_sizes = *monpulseSizes; - triggerInfo.num_pairs_over_threshold = *numPairs; - triggerInfo.passed_trigger = *passedTrig; - } - } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index 9dd0e020a..0dd78d998 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -6,8 +6,6 @@ #include "sbnanaobj/StandardRecord/SRTrigger.h" #include "lardataobj/RawData/TriggerData.h" -#include - namespace caf { void FillTrigger(const sbn::ExtraTriggerInfo& addltrig_info, @@ -17,16 +15,8 @@ namespace caf void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo); - void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo); - void FillTriggerICARUS(const sbn::ExtraTriggerInfo& addltrig_info, - caf::SRTrigger& triggerInfo); - - void FillTriggerEmulation(art::Handle> const& monpulsesFlat, - art::Handle> const& monpulseSizes, - art::Handle const& numPairs, - art::Handle const& passedTrig, - caf::SRTrigger& triggerInfo); + caf::SRTrigger& triggerInfo); } #endif From 3984fc098a4c440424e95303643f93c417a4816f Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Fri, 17 Oct 2025 12:24:13 -0500 Subject: [PATCH 223/367] adding an if condition for fixing exactly same start and end positions of true particles from nu-int --- sbncode/CAFMaker/FillTrue.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index 491c813c0..bbc936e88 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -777,6 +777,9 @@ namespace caf { if (exit_point < 0 && entry_point >= 0) { exit_point = particle.NumberTrajectoryPoints() - 1; } + if(exit_point >= 0 && entry_point >=0 && exit_point == entry_point && exit_point < static_cast(particle.NumberTrajectoryPoints()) - 1){ + exit_point++; // to avoid exactly the same start and end positions when single index is inside the active volumne + } if (exit_point >= 0 && ((unsigned)exit_point) < particle.NumberTrajectoryPoints() - 1) { srparticle.wallout = GetWallCross(active_volumes.at(cryostat_index), particle.Position(exit_point).Vect(), particle.Position(exit_point+1).Vect()); } From a10224977bdd980375df3156ac8ee5591427eca5 Mon Sep 17 00:00:00 2001 From: kjplows Date: Mon, 20 Oct 2025 06:44:04 -0500 Subject: [PATCH 224/367] Updated dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e45655eed..ec6466da4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.10.05 LANGUAGES CXX) +project(sbncode VERSION 10.11.01 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 8ec4e5537..4d4d45499 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - -larsoft v10_10_05 - -sbnalg v10_10_05 - +larsoft v10_11_01 - +sbnalg v10_11_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From 9bea391de146e8bf44032e7fc903754177067c9e Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Mon, 20 Oct 2025 09:54:23 -0500 Subject: [PATCH 225/367] adding TrackLikePidLabel in CAFMakerParams.h --- sbncode/CAFMaker/CAFMakerParams.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index a7740263e..322d9fd27 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -255,6 +255,12 @@ namespace caf "pandoraPid" }; + Atom TrackLikePidLabel { + Name("TrackLikePidLabel"), + Comment("Base label of track likelihood particle-id producer."), + "pandoraLikePid" + }; + Atom TrackScatterClosestApproachLabel { Name("TrackScatterClosestApproachLabel"), Comment("Base label of track track scatter closestapproach producer."), From 2af2c087a8e0f1b33596f0ef9d18130b954a025a Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Mon, 20 Oct 2025 10:55:45 -0500 Subject: [PATCH 226/367] updating FillReco for likelihood pid --- sbncode/CAFMaker/FillReco.cxx | 47 +++++++++++++++++++++++++++++++++++ sbncode/CAFMaker/FillReco.h | 4 +++ 2 files changed, 51 insertions(+) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 76c9a50b7..c53ef9296 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -892,6 +892,53 @@ namespace caf } } + void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikePID &srlikepid) { + + // Assign dummy values. + + srlikepid.lambda_muon = 0.; + srlikepid.lambda_pion = 0.; + srlikepid.lambda_proton = 0.; + srlikepid.pid_ndof = 0; + + // Loop over algorithm scores and extract the ones we want. + // Get the ndof from any likelihood pid algorithm + + std::vector AlgScoresVec = particle_id.ParticleIDAlgScores(); + for (size_t i_algscore=0; i_algscore> particleIDs, + caf::SRTrack& srtrack, + bool allowEmpty) + { + // get the particle ID's + for (unsigned i = 0; i < particleIDs.size(); i++) { + const anab::ParticleID &particle_id = *particleIDs[i]; + if (particle_id.PlaneID()) { + unsigned plane_id = particle_id.PlaneID().Plane; + assert(plane_id < 3); + FillPlaneLikePID(particle_id, srtrack.likepid[plane_id]); + } + } + } + void FillTrackPlaneCalo(const anab::Calorimetry &calo, const std::vector> &hits, bool fill_calo_points, float fillhit_rrstart, float fillhit_rrend, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 85d0a3e67..6a1e19bdc 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -226,6 +226,10 @@ namespace caf void FillTrackChi2PID(const std::vector> particleIDs, caf::SRTrack& srtrack, bool allowEmpty = false); + void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikePID &srlikepid); + void FillTrackLikePID(const std::vector> particleIDs, + caf::SRTrack& srtrack, + bool allowEmptySRTrkLikePID); void FillTrackPlaneCalo(const anab::Calorimetry &calo, const std::vector> &hits, From 3eeef15ed262020e5b29c3ad10634d4002dfe2f7 Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Mon, 20 Oct 2025 11:47:50 -0500 Subject: [PATCH 227/367] update CAFMaker_module.cc for likelihood pid --- sbncode/CAFMaker/CAFMaker_module.cc | 7 +++++++ sbncode/CAFMaker/FillReco.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..060bd5b6d 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2125,6 +2125,10 @@ void CAFMaker::produce(art::Event& evt) noexcept { FindManyPStrict(slcTracks, evt, fParams.TrackChi2PidLabel() + slice_tag_suff); + art::FindManyP fmLikePID = + FindManyPStrict(slcTracks, evt, + fParams.TrackLikePidLabel() + slice_tag_suff); + art::FindManyP fmScatterClosestApproach = FindManyPStrict(slcTracks, evt, fParams.TrackScatterClosestApproachLabel() + slice_tag_suff); @@ -2416,6 +2420,9 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (fmChi2PID.isValid()) { FillTrackChi2PID(fmChi2PID.at(iPart), trk); } + if (fmLikePID.isValid()) { + FillTrackLikePID(fmLikePID.at(iPart), trk); + } if (fmScatterClosestApproach.isValid() && fmScatterClosestApproach.at(iPart).size()==1) { FillTrackScatterClosestApproach(fmScatterClosestApproach.at(iPart).front(), trk); } diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 6a1e19bdc..57ea88d37 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -229,7 +229,7 @@ namespace caf void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikePID &srlikepid); void FillTrackLikePID(const std::vector> particleIDs, caf::SRTrack& srtrack, - bool allowEmptySRTrkLikePID); + bool allowEmpty = false); void FillTrackPlaneCalo(const anab::Calorimetry &calo, const std::vector> &hits, From 2af891e210e6cdc3633d2d1085c7db6d0e12eff9 Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Tue, 21 Oct 2025 09:50:04 -0500 Subject: [PATCH 228/367] likepid default values to -5. --- sbncode/CAFMaker/FillReco.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index c53ef9296..d5680696f 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -896,10 +896,10 @@ namespace caf // Assign dummy values. - srlikepid.lambda_muon = 0.; - srlikepid.lambda_pion = 0.; - srlikepid.lambda_proton = 0.; - srlikepid.pid_ndof = 0; + srlikepid.lambda_muon = -5.; + srlikepid.lambda_pion = -5.; + srlikepid.lambda_proton = -5.; + srlikepid.pid_ndof = -5; // Loop over algorithm scores and extract the ones we want. // Get the ndof from any likelihood pid algorithm From 2651da1f53e759296af6e3a457f28fd6483c3e94 Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Tue, 21 Oct 2025 09:52:24 -0500 Subject: [PATCH 229/367] like pid lambda default value to -99999. --- sbncode/CAFMaker/FillReco.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d5680696f..123ea3d84 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -896,9 +896,9 @@ namespace caf // Assign dummy values. - srlikepid.lambda_muon = -5.; - srlikepid.lambda_pion = -5.; - srlikepid.lambda_proton = -5.; + srlikepid.lambda_muon = -9999.; + srlikepid.lambda_pion = -9999.; + srlikepid.lambda_proton = -9999.; srlikepid.pid_ndof = -5; // Loop over algorithm scores and extract the ones we want. From ff96233dab3f548e4d56cb5e31ab848cf4072eb4 Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Tue, 21 Oct 2025 10:04:18 -0500 Subject: [PATCH 230/367] updating SRTrkLikePID to SRTrkLikelihoodPID --- sbncode/CAFMaker/FillReco.cxx | 2 +- sbncode/CAFMaker/FillReco.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 123ea3d84..6b35c66fc 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -892,7 +892,7 @@ namespace caf } } - void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikePID &srlikepid) { + void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikelihoodPID &srlikepid) { // Assign dummy values. diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 57ea88d37..039f09c8a 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -226,7 +226,7 @@ namespace caf void FillTrackChi2PID(const std::vector> particleIDs, caf::SRTrack& srtrack, bool allowEmpty = false); - void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikePID &srlikepid); + void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikelihoodPID &srlikepid); void FillTrackLikePID(const std::vector> particleIDs, caf::SRTrack& srtrack, bool allowEmpty = false); From 539709f16ca76066e86f65a7f7087a9f1eb98d51 Mon Sep 17 00:00:00 2001 From: linyan-w <53352772+linyan-w@users.noreply.github.com> Date: Wed, 22 Oct 2025 17:12:06 -0500 Subject: [PATCH 231/367] Update sbncode/CAFMaker/CAFMaker_module.cc Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMaker_module.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 6904ad260..b1cde10b8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -264,8 +264,8 @@ class CAFMaker : public art::EDProducer { double fGenieEvtRec_brEvtXSec = 0.0; ////< Cross section for selected event (1e-38 cm2) double fGenieEvtRec_brEvtDXSec = 0.0; ////< Cross section for selected event kinematics (1e-38 cm2 / {K^n}) unsigned int fGenieEvtRec_brEvtKPS = 0; ////< Kinematic phase space variables. See $GENIE/src/Framework/Conventions/KinePhaseSpace.h -> KinePhaseSpace_t - int fGenieEvtRec_brSctType = 0; ////< See ScatteringType.h - int fGenieEvtRec_brIntType = 0; ////< See InteractionType.h + int fGenieEvtRec_brSctType = 0; ///< See [`genie::EScatteringType`](https://hep.ph.liv.ac.uk/~costasa/genie_doxygen/master/html/namespacegenie.html#ab97d2b4d1f37af8d967dadd15be88d0b) + int fGenieEvtRec_brIntType = 0; ///< See [`genie::EInteractionType`](https://hep.ph.liv.ac.uk/~costasa/genie_doxygen/master/html/namespacegenie.html#a554f81bb9954c9e46bbabadfcd403111) double fGenieEvtRec_brEvtWght = 0.0; ////< Weight for that event double fGenieEvtRec_brEvtProb = 0.0; ////< Probability for that event (given cross section, path lengths, etc) double fGenieEvtRec_brEvtVtx[4] = {0.0}; ////< Event vertex position in detector coord syst (SI) From 298a8b0d7a3d1080b7bdd2394b4da87b06fc8a60 Mon Sep 17 00:00:00 2001 From: linyan-w <53352772+linyan-w@users.noreply.github.com> Date: Wed, 22 Oct 2025 17:12:15 -0500 Subject: [PATCH 232/367] Update sbncode/CAFMaker/CAFMaker_module.cc Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMaker_module.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index b1cde10b8..afb47992c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1184,8 +1184,8 @@ void CAFMaker::InitializeOutfiles() fFlatGenieTree->Branch("GenieEvtRec.EvtXSec", &fGenieEvtRec_brEvtXSec, "GenieEvtRec.EvtXSec/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtDXSec", &fGenieEvtRec_brEvtDXSec, "GenieEvtRec.EvtDXSec/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtKPS", &fGenieEvtRec_brEvtKPS, "GenieEvtRec.EvtKPS/i" ); - fFlatGenieTree->Branch("GenieEvtRec.SctType", &fGenieEvtRec_brSctType, "GenieEvtRec.SctType/I" ); - fFlatGenieTree->Branch("GenieEvtRec.IntType", &fGenieEvtRec_brIntType, "GenieEvtRec.IntType/I" ); + fFlatGenieTree->Branch("GenieEvtRec.SctType", &fGenieEvtRec_brSctType, "GenieEvtRec.SctType/I" ); + fFlatGenieTree->Branch("GenieEvtRec.IntType", &fGenieEvtRec_brIntType, "GenieEvtRec.IntType/I" ); fFlatGenieTree->Branch("GenieEvtRec.EvtWght", &fGenieEvtRec_brEvtWght, "GenieEvtRec.EvtWght/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtProb", &fGenieEvtRec_brEvtProb, "GenieEvtRec.EvtProb/D" ); fFlatGenieTree->Branch("GenieEvtRec.EvtVtx", fGenieEvtRec_brEvtVtx, "GenieEvtRec.EvtVtx[4]/D" ); From 264bd4f2a3b09a23c4735680ac627a75bd62a9a0 Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Thu, 23 Oct 2025 09:11:44 -0500 Subject: [PATCH 233/367] removing defaulting part for likelihood pid --- sbncode/CAFMaker/FillReco.cxx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 6b35c66fc..b861bf0b1 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -894,13 +894,6 @@ namespace caf void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikelihoodPID &srlikepid) { - // Assign dummy values. - - srlikepid.lambda_muon = -9999.; - srlikepid.lambda_pion = -9999.; - srlikepid.lambda_proton = -9999.; - srlikepid.pid_ndof = -5; - // Loop over algorithm scores and extract the ones we want. // Get the ndof from any likelihood pid algorithm From 0d3daf8c0484a40bfd963cd724c2c55670b915b0 Mon Sep 17 00:00:00 2001 From: Brinden Carlson Date: Thu, 23 Oct 2025 12:02:54 -0500 Subject: [PATCH 234/367] Update multipart generator to have engines run without segmentation faults --- .../EventGenerator/MultiPart/CMakeLists.txt | 66 -- .../MultiPart/MultiPartRain_module.cc | 521 ------------- .../MultiPart/MultiPartVertex_module.cc | 709 ------------------ .../EventGenerator/MultiPart/gen_mpvmpr.fcl | 4 +- 4 files changed, 2 insertions(+), 1298 deletions(-) delete mode 100644 sbncode/EventGenerator/MultiPart/MultiPartRain_module.cc delete mode 100644 sbncode/EventGenerator/MultiPart/MultiPartVertex_module.cc diff --git a/sbncode/EventGenerator/MultiPart/CMakeLists.txt b/sbncode/EventGenerator/MultiPart/CMakeLists.txt index 752ac5ed7..47833dbee 100644 --- a/sbncode/EventGenerator/MultiPart/CMakeLists.txt +++ b/sbncode/EventGenerator/MultiPart/CMakeLists.txt @@ -1,69 +1,3 @@ -cet_build_plugin( MultiPartRain art::module - LIBRARIES - larcorealg::Geometry - larcore::Geometry_Geometry_service - lardata::Utilities - larevt::Filters - lardataobj::RawData - larevt::CalibrationDBI_IOVData - larevt::CalibrationDBI_Providers - lardataobj::RecoBase - lardata::ArtDataHelper - larsim::Simulation nug4::ParticleNavigation - lardataobj::Simulation - nusimdata::SimulationBase - lardata::Utilities - lardataobj::MCBase - larcoreobj::SummaryData - nusimdata::SimulationBase - nurandom::RandomUtils_NuRandomService_service - lardataobj::MCBase - CLHEP::CLHEP - art::Framework_Core - art::Framework_Principal - art::Framework_Services_Registry - art_root_io::tfile_support ROOT::Core - art_root_io::TFileService_service - art::Persistency_Common - art::Persistency_Provenance - art::Utilities - canvas::canvas - ROOT::EG - ) - -cet_build_plugin( MultiPartVertex art::module - LIBRARIES - larcorealg::Geometry - larcore::Geometry_Geometry_service - lardata::Utilities - larevt::Filters - lardataobj::RawData - larevt::CalibrationDBI_IOVData - larevt::CalibrationDBI_Providers - lardataobj::RecoBase - lardata::ArtDataHelper - larsim::Simulation nug4::ParticleNavigation - lardataobj::Simulation - nusimdata::SimulationBase - lardata::Utilities - lardataobj::MCBase - larcoreobj::SummaryData - nusimdata::SimulationBase - nurandom::RandomUtils_NuRandomService_service - lardataobj::MCBase - CLHEP::CLHEP - art::Framework_Core - art::Framework_Principal - art::Framework_Services_Registry - art_root_io::tfile_support ROOT::Core - art_root_io::TFileService_service - art::Persistency_Common - art::Persistency_Provenance - art::Utilities - canvas::canvas - ROOT::EG - ) - install_headers() install_fhicl() install_source() diff --git a/sbncode/EventGenerator/MultiPart/MultiPartRain_module.cc b/sbncode/EventGenerator/MultiPart/MultiPartRain_module.cc deleted file mode 100644 index 303746118..000000000 --- a/sbncode/EventGenerator/MultiPart/MultiPartRain_module.cc +++ /dev/null @@ -1,521 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Class: MultiPartRain -// Module Type: producer -// File: MultiPartRain_module.cc -// -// Generated at Tue Dec 13 15:48:59 2016 by Kazuhiro Terao using artmod -// from cetpkgsupport v1_11_00. -//////////////////////////////////////////////////////////////////////// - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -//#include "art/Utilities/InputTag.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include -#include -#include -#include "cetlib/pow.h" - -#include "CLHEP/Random/RandFlat.h" -#include "CLHEP/Random/RandGauss.h" -#include "CLHEP/Random/RandGeneral.h" - -#include "TRandom.h" -#include "nurandom/RandomUtils/NuRandomService.h" -#include "larcore/Geometry/Geometry.h" -#include "larcore/CoreUtils/ServiceUtil.h" -#include "larcoreobj/SummaryData/RunData.h" -#include "larcoreobj/SimpleTypesAndConstants/PhysicalConstants.h" - -#include "nusimdata/SimulationBase/MCTruth.h" -#include "nusimdata/SimulationBase/MCParticle.h" - -#include "TLorentzVector.h" -#include "TDatabasePDG.h" - -struct PartGenParam { - std::vector pdg; - std::vector mass; - std::array multi; - std::array kerange; - bool use_mom; - bool direct_inward; - double weight; -}; - -class MultiPartRain; - -class MultiPartRain : public art::EDProducer { -public: - explicit MultiPartRain(fhicl::ParameterSet const & p); - // The destructor generated by the compiler is fine for classes - // without bare pointers or other resource use. - ~MultiPartRain(); - - // Plugins should not be copied or assigned. - MultiPartRain(MultiPartRain const &) = delete; - MultiPartRain(MultiPartRain &&) = delete; - MultiPartRain & operator = (MultiPartRain const &) = delete; - MultiPartRain & operator = (MultiPartRain &&) = delete; - - // Required functions. - void produce(art::Event & e) override; - - void beginRun(art::Run& run) override; - - void GenPosition(double& x, double& y, double& z); - - std::array extractDirection() const; - void GenMomentum(const PartGenParam& param, const double& mass, double& px, double& py, double& pz, - const double x, const double y, const double z); - - std::vector GenParticles() const; - -private: - - CLHEP::HepRandomEngine& fFlatEngine; - std::unique_ptr fFlatRandom; - std::unique_ptr fNormalRandom; - std::unique_ptr fCosmicAngleRandom; - - // exception thrower - void abort(const std::string msg) const; - - // array of particle info for generation - std::vector _param_v; - - // g4 time of generation - double _t0; - double _t0_sigma; - - // g4 position - std::array _xrange; - std::array _yrange; - std::array _zrange; - - // Whether to use uniform or cosmic-like angle distribution - bool _cosmic_distribution; - - // TPC array - std::vector > _tpc_v; - - // multiplicity constraint - size_t _multi_min; - size_t _multi_max; - - // verbosity flag - unsigned short _debug; -}; - -void MultiPartRain::abort(const std::string msg) const -{ - std::cerr << "\033[93m" << msg.c_str() << "\033[00m" << std::endl; - throw std::exception(); -} - -MultiPartRain::~MultiPartRain() -{ } - -MultiPartRain::MultiPartRain(fhicl::ParameterSet const & p) -: EDProducer(p) -, fFlatEngine(art::ServiceHandle()->registerAndSeedEngine( - createEngine(0, "HepJamesRandom", "GenRain"), "HepJamesRandom", "GenRain")) - //, fFlatEngine(art::ServiceHandle()->createEngine(*this, "HepJamesRandom", "Gen", p, "Seed")) -// : -// Initialize member data here. -{ - - // - // Random engine initialization - // - fFlatRandom = std::make_unique(fFlatEngine,0,1); - fNormalRandom = std::make_unique(fFlatEngine); - - // x^2 distribution for fCosmicAngleRandom - // will be used to draw cos(theta) - const int nbins(100); - double parent[nbins]; - for (size_t idx = 0; idx < nbins; ++idx) { - //parent[idx] = cet::square(cos(((float) idx)/nbins * util::pi())); - parent[idx] = cet::square(((float) idx)/nbins); - } - fCosmicAngleRandom = std::make_unique(fFlatEngine, parent, nbins); - - produces< std::vector >(); - produces< sumdata::RunData, art::InRun >(); - - _debug = p.get("DebugMode",0); - - _t0 = p.get("G4Time"); - _t0_sigma = p.get("G4TimeJitter"); - if(_t0_sigma < 0) this->abort("Cannot have a negative value for G4 time jitter"); - - _multi_min = p.get("MultiMin"); - _multi_max = p.get("MultiMax"); - _cosmic_distribution = p.get("CosmicDistribution", false); - - _tpc_v = p.get > >("TPCRange"); - auto const xrange = p.get > ("XRange"); - auto const yrange = p.get > ("YRange"); - auto const zrange = p.get > ("ZRange"); - auto const part_cfg = p.get("ParticleParameter"); - - _param_v.clear(); - auto const pdg_v = part_cfg.get > > ("PDGCode"); - auto const minmult_v = part_cfg.get > ("MinMulti"); - auto const maxmult_v = part_cfg.get > ("MaxMulti"); - auto const weight_v = part_cfg.get > ("ProbWeight"); - - auto kerange_v = part_cfg.get > > ("KERange"); - auto momrange_v = part_cfg.get > > ("MomRange"); - - if( (kerange_v.empty() && momrange_v.empty()) || - (!kerange_v.empty() && !momrange_v.empty()) ) { - this->abort("Only one of KERange or MomRange must be empty!"); - } - - bool use_mom = false; - if(kerange_v.empty()){ - kerange_v = momrange_v; - use_mom = true; - } - // sanity check - if( pdg_v.size() != kerange_v.size() || - pdg_v.size() != minmult_v.size() || - pdg_v.size() != maxmult_v.size() || - pdg_v.size() != weight_v.size() ) - this->abort("configuration parameters have incompatible lengths!"); - - // further sanity check (1 more depth for some double-array) - for(auto const& r : pdg_v ) { if( r.empty() ) this->abort("PDG code not given!"); } - for(auto const& r : kerange_v) { if( r.size()!=2) this->abort("Incompatible legnth @ KE vector!"); } - - for(size_t idx=0; idx maxmult_v[idx]) this->abort("Particle MinMulti > Particle MaxMulti!"); - if(minmult_v[idx] > _multi_max) this->abort("Particle MinMulti > overall MultiMax!"); - if(minmult_v[idx] > _multi_min) - _multi_min = minmult_v[idx]; - } - if(_multi_max < _multi_min) this->abort("Overall MultiMax <= overall MultiMin!"); - - if(!xrange.empty() && xrange.size() >2) this->abort("Incompatible legnth @ X vector!" ); - if(!yrange.empty() && yrange.size() >2) this->abort("Incompatible legnth @ Y vector!" ); - if(!zrange.empty() && zrange.size() >2) this->abort("Incompatible legnth @ Z vector!" ); - - // slight modification from mpv: define the overall volume across specified TPC IDs + range options - double xmin,xmax,ymin,ymax,zmin,zmax; - xmin = ymin = zmin = 1.e20; - xmax = ymax = zmax = -1.e20; - // Implementation of required member function here. - auto geop = lar::providerFrom(); - for(auto const& tpc_id : _tpc_v) { - assert(tpc_id.size() == 2); - size_t cid = tpc_id[0]; - size_t tid = tpc_id[1]; - auto const& cryostat = geop->Cryostat(geo::CryostatID(cid)); - assert(cryostat.HasTPC(tid)); - - auto const& tpc = cryostat.TPC(tid); - auto const& tpcabox = tpc.ActiveBoundingBox(); - xmin = std::min(tpcabox.MinX(), xmin); - ymin = std::min(tpcabox.MinY(), ymin); - zmin = std::min(tpcabox.MinZ(), zmin); - xmax = std::max(tpcabox.MaxX(), xmax); - ymax = std::max(tpcabox.MaxY(), ymax); - zmax = std::max(tpcabox.MaxZ(), zmax); - - if(_debug) { - std::cout << "Using Cryostat " << tpc_id[0] << " TPC " << tpc_id[1] - << " ... X " << xmin << " => " << xmax - << " ... Y " << ymin << " => " << ymax - << " ... Z " << zmin << " => " << zmax - << std::endl; - } - } - - // range register - if(xrange.size()==1) { _xrange[0] = _xrange[1] = xrange[0]; } - if(yrange.size()==1) { _yrange[0] = _yrange[1] = yrange[0]; } - if(zrange.size()==1) { _zrange[0] = _zrange[1] = zrange[0]; } - if(xrange.size()==2) { _xrange[0] = xrange[0]; _xrange[1] = xrange[1]; } - if(yrange.size()==2) { _yrange[0] = yrange[0]; _yrange[1] = yrange[1]; } - if(zrange.size()==2) { _zrange[0] = zrange[0]; _zrange[1] = zrange[1]; } - - _xrange[0] = xmin + _xrange[0]; - _xrange[1] = xmax - _xrange[1]; - _yrange[0] = ymin + _yrange[0]; - _yrange[1] = ymax - _yrange[1]; - _zrange[0] = zmin + _zrange[0]; - _zrange[1] = zmax - _zrange[1]; - - // check - assert(_xrange[0] <= _xrange[1]); - assert(_yrange[0] <= _yrange[1]); - assert(_zrange[0] <= _zrange[1]); - - if(_debug>0) { - std::cout<<"Particle generation world boundaries..."< " << _xrange[1] << std::endl - <<"Y " << _yrange[0] << " => " << _yrange[1] << std::endl - <<"Z " << _zrange[0] << " => " << _zrange[1] << std::endl; - } - - - // register - //auto db = new TDatabasePDG; - auto db = TDatabasePDG::Instance(); - bool direct_inward = p.get("DirectInward", true); - if (_cosmic_distribution && direct_inward) { - std::cout << "Cannot satisfy both CosmicDistribution and Inward Directioning at the same time" << std::endl; - throw std::exception(); - } - for(size_t idx=0; idxGetParticle(param.pdg[i])->Mass(); - - // sanity check - if(kerange[0]<0 || kerange[1]<0) - this->abort("You provided negative energy? Fuck off Mr. Trump."); - - // overall range check - if(param.kerange[0] > param.kerange[1]) this->abort("KE range has no phase space..."); - - if(_debug>0) { - std::cout << "Generating particle (PDG"; - for(auto const& pdg : param.pdg) std::cout << " " << pdg; - std::cout << ")" << std::endl - << (param.use_mom ? " KE range ....... " : " Mom range ....... ") - << param.kerange[0] << " => " << param.kerange[1] << " MeV" << std::endl - << std::endl; - } - - _param_v.push_back(param); - } -} - -void MultiPartRain::beginRun(art::Run& run) -{ - // grab the geometry object to see what geometry we are using - art::ServiceHandle geo; - - std::unique_ptr runData(new sumdata::RunData(geo->DetectorName())); - - run.put(std::move(runData), art::fullRun()); - - return; -} - -std::vector MultiPartRain::GenParticles() const { - - std::vector result; - std::vector gen_count_v(_param_v.size(),0); - std::vector weight_v(_param_v.size(),0); - for(size_t idx=0; idx<_param_v.size(); ++idx) - weight_v[idx] = _param_v[idx].weight; - - int num_part = (int)(fFlatRandom->fire(_multi_min,_multi_max+1-1.e-10)); - - while(num_part) { - - double total_weight = 0; - for(auto const& v : weight_v) total_weight += v; - - double rval = 0; - rval = fFlatRandom->fire(0,total_weight); - - size_t idx = 0; - for(idx = 0; idx < weight_v.size(); ++idx) { - rval -= weight_v[idx]; - if(rval <=0.) break; - } - - // register to the output - result.push_back(idx); - - // if generation count exceeds max, set probability weight to be 0 - gen_count_v[idx] += 1; - if(gen_count_v[idx] >= _param_v[idx].multi[1]) - weight_v[idx] = 0.; - - --num_part; - } - return result; -} - -void MultiPartRain::GenPosition(double& x, double& y, double& z) { - - x = fFlatRandom->fire(_xrange[0],_xrange[1]); - y = fFlatRandom->fire(_yrange[0],_yrange[1]); - z = fFlatRandom->fire(_zrange[0],_zrange[1]); - - if(_debug>0) { - std::cout << "Generating a rain particle at (" - << x << "," << y << "," << z << ")" << std::endl; - } -} - -std::array MultiPartRain::extractDirection() const { - double px, py, pz; - if (_cosmic_distribution) { - double phi = fFlatRandom->fire(0, 2 * util::pi()); - // Zenith Angle Theta is in [pi/2, pi] - double costheta = - 1. * fCosmicAngleRandom->fire(); - double sintheta = sqrt(1 - costheta * costheta); - pz = cos(phi) * sintheta; - px = sin(phi) * sintheta; - py = costheta; - } else { - px = fNormalRandom->fire(0, 1); - py = fNormalRandom->fire(0, 1); - pz = fNormalRandom->fire(0, 1); - double p = std::hypot(px, py, pz); - px = px / p; - py = py / p; - pz = pz / p; - } - - std::array result = {px, py, pz}; - return result; -} - -void MultiPartRain::GenMomentum(const PartGenParam& param, const double& mass, double& px, double& py, double& pz, - const double x, const double y, const double z) { - - double tot_energy = 0; - if(param.use_mom) - tot_energy = sqrt(cet::square(fFlatRandom->fire(param.kerange[0],param.kerange[1])) + cet::square(mass)); - else - tot_energy = fFlatRandom->fire(param.kerange[0],param.kerange[1]) + mass; - - double mom_mag = sqrt(cet::square(tot_energy) - cet::square(mass)); - - /* Generating unit vector with uniform distribution - * in direction = over the sphere. - * - * It is sufficient to draw a normal variable in - * each direction and normalize. - * - * https://mathworld.wolfram.com/SpherePointPicking.html - */ - - if(!param.direct_inward) { - std::cout<<"No inward directioning..."< p = extractDirection(); - px = p[0]; py = p[1]; pz = p[2]; - }else{ - double sign_x = ( (x - _xrange[0]) < (_xrange[1] - x) ? 1.0 : -1.0 ); - double sign_y = ( (y - _yrange[0]) < (_yrange[1] - y) ? 1.0 : -1.0 ); - double sign_z = ( (z - _zrange[0]) < (_zrange[1] - z) ? 1.0 : -1.0 ); - - if(_debug) { - std::cout<<"Generating XYZ direction sign for a particle at (" << x << "," << y << "," << z << ")" << std::endl - <<"X: " << _xrange[0] << " => " << _xrange[1] << " ... " << sign_x << std::endl - <<"Y: " << _yrange[0] << " => " << _yrange[1] << " ... " << sign_y << std::endl - <<"Z: " << _zrange[0] << " => " << _zrange[1] << " ... " << sign_z << std::endl - << std::endl; - } - - while(1) { - std::array p = extractDirection(); - px = p[0]; py = p[1]; pz = p[2]; - if( (px * sign_x) >= 0. && - (py * sign_y) >= 0. && - (pz * sign_z) >= 0. ) - break; - } - - } - //std::cout<<"LOGME,"<1) - std::cout << " Direction : (" << px << "," << py << "," << pz << ")" << std::endl - << " Momentum : " << mom_mag << " [MeV/c]" << std::endl - << " Energy : " << tot_energy << " [MeV/c^2]" << std::endl; - px *= mom_mag; - py *= mom_mag; - pz *= mom_mag; - -} - -void MultiPartRain::produce(art::Event & e) -{ - if(_debug>0) std::cout << "Processing a new event..." << std::endl; - - std::unique_ptr< std::vector > mctArray(new std::vector); - - simb::MCTruth mct; - - mct.SetOrigin(simb::kCosmicRay); - - std::vector part_v; - - auto const param_idx_v = GenParticles(); - if(_debug) - std::cout << "Generating" << param_idx_v.size() << " particles..." << std::endl; - - for(size_t idx=0; idxfire(0,param.pdg.size()-1.e-10)); - auto const& pdg = param.pdg[pdg_index]; - auto const& mass = param.mass[pdg_index]; - if(_debug) std::cout << " " << idx << "th instance PDG " << pdg << std::endl; - double x, y, z; - GenPosition(x,y,z); - double g4_time = fFlatRandom->fire(_t0 - _t0_sigma/2., _t0 + _t0_sigma/2.); - TLorentzVector pos(x,y,z,g4_time); - std::cout<<"Generating momentum..."<push_back(mct); - - e.put(std::move(mctArray)); -} - -DEFINE_ART_MODULE(MultiPartRain) diff --git a/sbncode/EventGenerator/MultiPart/MultiPartVertex_module.cc b/sbncode/EventGenerator/MultiPart/MultiPartVertex_module.cc deleted file mode 100644 index 5a4e3cf08..000000000 --- a/sbncode/EventGenerator/MultiPart/MultiPartVertex_module.cc +++ /dev/null @@ -1,709 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// Class: MultiPartVertex -// Module Type: producer -// File: MultiPartVertex_module.cc -// -// Generated at Tue Dec 13 15:48:59 2016 by Kazuhiro Terao using artmod -// from cetpkgsupport v1_11_00. -//////////////////////////////////////////////////////////////////////// - -#include "art/Framework/Core/EDProducer.h" -#include "art/Framework/Core/ModuleMacros.h" -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/Handle.h" -#include "art/Framework/Principal/Run.h" -#include "art/Framework/Principal/SubRun.h" -//#include "art/Utilities/InputTag.h" -#include "fhiclcpp/ParameterSet.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include -#include -#include "cetlib/pow.h" - -#include "CLHEP/Random/RandFlat.h" -#include "CLHEP/Random/RandGauss.h" -#include "TRandom.h" -#include "nurandom/RandomUtils/NuRandomService.h" -#include "larcore/Geometry/Geometry.h" -#include "larcore/CoreUtils/ServiceUtil.h" -#include "larcoreobj/SummaryData/RunData.h" -#include "larcoreobj/SimpleTypesAndConstants/PhysicalConstants.h" - -#include "nusimdata/SimulationBase/MCTruth.h" -#include "nusimdata/SimulationBase/MCParticle.h" - -#include "TLorentzVector.h" -#include "TDatabasePDG.h" - -struct PartGenParam { - std::vector pdg; - std::vector mass; - std::array multi; - std::array kerange; - bool use_mom; - double weight; -}; - -class MultiPartVertex; - -class MultiPartVertex : public art::EDProducer { -public: - explicit MultiPartVertex(fhicl::ParameterSet const & p); - // The destructor generated by the compiler is fine for classes - // without bare pointers or other resource use. - ~MultiPartVertex(); - - // Plugins should not be copied or assigned. - MultiPartVertex(MultiPartVertex const &) = delete; - MultiPartVertex(MultiPartVertex &&) = delete; - MultiPartVertex & operator = (MultiPartVertex const &) = delete; - MultiPartVertex & operator = (MultiPartVertex &&) = delete; - - // Required functions. - void produce(art::Event & e) override; - - void beginRun(art::Run& run) override; - - void GenPosition(double& x, double& y, double& z); - void GenBoost(double& bx, double& by, double& bz); - - std::array extractDirection() const; - void GenMomentum(const PartGenParam& param, const double& mass, double& px, double& py, double& pz); - void GenMomentum(const PartGenParam& param, const double& mass, double& px, double& py, double& pz, bool& same_range); - - void GenMomentumSF(const double& sf, const double& mass, const double& p, double &p_sf); - std::vector GenParticles() const; - -private: - - CLHEP::HepRandomEngine& fFlatEngine; - std::unique_ptr fFlatRandom; - std::unique_ptr fNormalRandom; - - // exception thrower - void abort(const std::string msg) const; - - // array of particle info for generation - std::vector _param_v; - - // g4 time of generation - double _t0; - double _t0_sigma; - - // g4 position - std::array _xrange; - std::array _yrange; - std::array _zrange; - - // TPC range - std::vector > _tpc_v; - - // multiplicity constraint - size_t _multi_min; - size_t _multi_max; - - // Range of boosts - std::array _gamma_beta_range; - - // verbosity flag - unsigned short _debug; - - unsigned short _use_boost; - - unsigned short _revert; -}; - -void MultiPartVertex::abort(const std::string msg) const -{ - std::cerr << "\033[93m" << msg.c_str() << "\033[00m" << std::endl; - throw std::exception(); -} - -MultiPartVertex::~MultiPartVertex() -{ } - -MultiPartVertex::MultiPartVertex(fhicl::ParameterSet const & p) - : EDProducer(p) - , fFlatEngine(art::ServiceHandle()->registerAndSeedEngine( - createEngine(0, "HepJamesRandom", "GenVertex"), "HepJamesRandom", "GenVertex")) - //, fFlatEngine(art::ServiceHandle()->createEngine(*this, "HepJamesRandom", "Gen", p, "Seed")) - // Initialize member data here. -{ - - // - // Random engine initialization - // - fFlatRandom = std::make_unique(fFlatEngine,0,1); - fNormalRandom = std::make_unique(fFlatEngine); - - produces< std::vector >(); - produces< sumdata::RunData, art::InRun >(); - - _debug = p.get("DebugMode",0); - _revert = p.get("Revert",0); - _use_boost = p.get("UseBoost",0); - _t0 = p.get("G4Time"); - _t0_sigma = p.get("G4TimeJitter"); - if(_t0_sigma < 0) this->abort("Cannot have a negative value for G4 time jitter"); - - _multi_min = p.get("MultiMin"); - _multi_max = p.get("MultiMax"); - - _tpc_v = p.get > >("TPCRange"); - auto const xrange = p.get > ("XRange"); - auto const yrange = p.get > ("YRange"); - auto const zrange = p.get > ("ZRange"); - - auto const part_cfg = p.get("ParticleParameter"); - _gamma_beta_range = p.get >("GammaBetaRange", {0.0,0.0}); // _gamma_beta denotes gamma * beta - - _param_v.clear(); - auto const pdg_v = part_cfg.get > > ("PDGCode"); - auto const minmult_v = part_cfg.get > ("MinMulti"); - auto const maxmult_v = part_cfg.get > ("MaxMulti"); - auto const weight_v = part_cfg.get > ("ProbWeight"); - - auto kerange_v = part_cfg.get > > ("KERange"); - auto momrange_v = part_cfg.get > > ("MomRange"); - - if( (kerange_v.empty() && momrange_v.empty()) || - (!kerange_v.empty() && !momrange_v.empty()) ) { - this->abort("Only one of KERange or MomRange must be empty!"); - } - - bool use_mom = false; - if(kerange_v.empty()){ - kerange_v = momrange_v; - use_mom = true; - } - // sanity check - if( pdg_v.size() != kerange_v.size() || - pdg_v.size() != minmult_v.size() || - pdg_v.size() != maxmult_v.size() || - pdg_v.size() != weight_v.size() ) - this->abort("configuration parameters have incompatible lengths!"); - - // further sanity check (1 more depth for some double-array) - for(auto const& r : pdg_v ) { if( r.empty() ) this->abort("PDG code not given!"); } - for(auto const& r : kerange_v) { if( r.size()!=2) this->abort("Incompatible legnth @ KE vector!"); } - if(_gamma_beta_range[0] > _gamma_beta_range[1]) this->abort("Incompatible boost range!"); - - size_t multi_min = 0; - for(size_t idx=0; idx maxmult_v[idx]) this->abort("Particle MinMulti > Particle MaxMulti!"); - if(minmult_v[idx] > _multi_max) this->abort("Particle MinMulti > overall MultiMax!"); - multi_min += minmult_v[idx]; - } - _multi_min = std::max(_multi_min, multi_min); - if(_multi_max < _multi_min) this->abort("Overall MultiMax <= overall MultiMin!"); - - /* - if(!xrange.empty() && xrange.size() >2) this->abort("Incompatible legnth @ X vector!" ); - if(!yrange.empty() && yrange.size() >2) this->abort("Incompatible legnth @ Y vector!" ); - if(!zrange.empty() && zrange.size() >2) this->abort("Incompatible legnth @ Z vector!" ); - - // range register - if(xrange.size()==1) { _xrange[0] = _xrange[1] = xrange[0]; } - if(xrange.size()==2) { _xrange[0] = xrange[0]; _xrange[1] = xrange[1]; } - if(yrange.size()==1) { _yrange[0] = _yrange[1] = yrange[0]; } - if(yrange.size()==2) { _yrange[0] = yrange[0]; _yrange[1] = yrange[1]; } - if(zrange.size()==1) { _zrange[0] = _zrange[1] = zrange[0]; } - if(zrange.size()==2) { _zrange[0] = zrange[0]; _zrange[1] = zrange[1]; } - */ - - if(!xrange.empty() && xrange.size() >2) this->abort("Incompatible legnth @ X vector!" ); - if(!yrange.empty() && yrange.size() >2) this->abort("Incompatible legnth @ Y vector!" ); - if(!zrange.empty() && zrange.size() >2) this->abort("Incompatible legnth @ Z vector!" ); - - // slight modification from mpv: define the overall volume across specified TPC IDs + range options - double xmin,xmax,ymin,ymax,zmin,zmax; - xmin = ymin = zmin = 1.e20; - xmax = ymax = zmax = -1.e20; - // Implementation of required member function here. - auto geop = lar::providerFrom(); - for(auto const& tpc_id : _tpc_v) { - assert(tpc_id.size() == 2); - size_t cid = tpc_id[0]; - size_t tid = tpc_id[1]; - auto const& cryostat = geop->Cryostat(geo::CryostatID(cid)); - assert(cryostat.HasTPC(tid)); - - auto const& tpc = cryostat.TPC(tid); - auto const& tpcabox = tpc.ActiveBoundingBox(); - xmin = std::min(tpcabox.MinX(), xmin); - ymin = std::min(tpcabox.MinY(), ymin); - zmin = std::min(tpcabox.MinZ(), zmin); - xmax = std::max(tpcabox.MaxX(), xmax); - ymax = std::max(tpcabox.MaxY(), ymax); - zmax = std::max(tpcabox.MaxZ(), zmax); - - if(_debug) { - std::cout << "Using Cryostat " << tpc_id[0] << " TPC " << tpc_id[1] - << " ... X " << xmin << " => " << xmax - << " ... Y " << ymin << " => " << ymax - << " ... Z " << zmin << " => " << zmax - << std::endl; - } - } - - // range register - if(xrange.size()==1) { _xrange[0] = _xrange[1] = xrange[0]; } - if(yrange.size()==1) { _yrange[0] = _yrange[1] = yrange[0]; } - if(zrange.size()==1) { _zrange[0] = _zrange[1] = zrange[0]; } - if(xrange.size()==2) { _xrange[0] = xrange[0]; _xrange[1] = xrange[1]; } - if(yrange.size()==2) { _yrange[0] = yrange[0]; _yrange[1] = yrange[1]; } - if(zrange.size()==2) { _zrange[0] = zrange[0]; _zrange[1] = zrange[1]; } - - _xrange[0] = xmin + _xrange[0]; - _xrange[1] = xmax - _xrange[1]; - _yrange[0] = ymin + _yrange[0]; - _yrange[1] = ymax - _yrange[1]; - _zrange[0] = zmin + _zrange[0]; - _zrange[1] = zmax - _zrange[1]; - - // check - assert(_xrange[0] <= _xrange[1]); - assert(_yrange[0] <= _yrange[1]); - assert(_zrange[0] <= _zrange[1]); - - if(_debug>0) { - std::cout<<"Particle generation world boundaries..."< " << _xrange[1] << std::endl - <<"Y " << _yrange[0] << " => " << _yrange[1] << std::endl - <<"Z " << _zrange[0] << " => " << _zrange[1] << std::endl; - } - - - // register - //auto db = new TDatabasePDG; - auto db = TDatabasePDG::Instance(); - for(size_t idx=0; idxGetParticle(param.pdg[i])->Mass(); - - // sanity check - if(kerange[0]<0 || kerange[1]<0) - this->abort("You provided negative energy? Fuck off Mr. Trump."); - - // overall range check - if(param.kerange[0] > param.kerange[1]) this->abort("KE range has no phase space..."); - - if(_debug>0) { - std::cout << "Generating particle (PDG"; - for(auto const& pdg : param.pdg) std::cout << " " << pdg; - std::cout << ")" << std::endl - << (param.use_mom ? " KE range ....... " : " Mom range ....... ") - << param.kerange[0] << " => " << param.kerange[1] << " MeV" << std::endl - << std::endl; - } - - _param_v.push_back(param); - } -} - -void MultiPartVertex::beginRun(art::Run& run) -{ - // grab the geometry object to see what geometry we are using - art::ServiceHandle geo; - - std::unique_ptr runData(new sumdata::RunData(geo->DetectorName())); - - run.put(std::move(runData), art::fullRun()); - - return; -} - -std::vector MultiPartVertex::GenParticles() const { - - std::vector result; - std::vector gen_count_v(_param_v.size(),0); - - int num_part = (int)(fFlatRandom->fire(_multi_min,_multi_max+1-1.e-10)); - - // generate min multiplicity first - std::vector weight_v(_param_v.size(),0); - for(size_t idx=0; idx<_param_v.size(); ++idx) { - weight_v[idx] = _param_v[idx].weight; - for(size_t ctr=0; ctr<_param_v[idx].multi[0]; ++ctr) { - result.push_back(idx); - gen_count_v[idx] += 1; - num_part -= 1; - } - if(gen_count_v[idx] >= _param_v[idx].multi[1]) - weight_v[idx] = 0.; - } - - assert(num_part >= 0); - - while(num_part) { - - double total_weight = 0; - for(auto const& v : weight_v) total_weight += v; - - double rval = 0; - rval = fFlatRandom->fire(0,total_weight); - - size_t idx = 0; - for(idx = 0; idx < weight_v.size(); ++idx) { - rval -= weight_v[idx]; - if(rval <=0.) break; - } - - // register to the output - result.push_back(idx); - - // if generation count exceeds max, set probability weight to be 0 - gen_count_v[idx] += 1; - if(gen_count_v[idx] >= _param_v[idx].multi[1]) - weight_v[idx] = 0.; - - --num_part; - } - return result; -} - - -void MultiPartVertex::GenPosition(double& x, double& y, double& z) { - - x = fFlatRandom->fire(_xrange[0],_xrange[1]); - y = fFlatRandom->fire(_yrange[0],_yrange[1]); - z = fFlatRandom->fire(_zrange[0],_zrange[1]); - - if(_debug>0) { - std::cout << "Generating a rain particle at (" - << x << "," << y << "," << z << ")" << std::endl; - } -} - -void MultiPartVertex::GenBoost(double& bx, double& by, double& bz) { - - double gbmag = 0.; // saves gamma * beta - if ( _gamma_beta_range[1] > _gamma_beta_range[0]) { - gbmag = fFlatRandom->fire(_gamma_beta_range[0],_gamma_beta_range[1]); - } - else { - gbmag = _gamma_beta_range[0]; - } - double ct = fFlatRandom->fire(-1.0,1.0); - double st = TMath::Sqrt(1.0 - ct*ct); - double phi = fFlatRandom->fire(0.0,2.0 * M_PI); - double bmag = gbmag / TMath::Sqrt(1.0 + gbmag*gbmag); - - bx = bmag * st * TMath::Cos(phi); - by = bmag * st * TMath::Sin(phi); - bz = bmag * ct; - - if(_debug>0) { - std::cout << "Generated boost parameter gamma beta = " << gbmag << ", cos(theta) = " << ct - << ", phi = " << phi << std::endl; - std::cout << "Generating a boost (" - << bx << "," << by << "," << bz << ")" << std::endl; - } -} - -/* -void MultiPartVertex::GenPosition(double& x, double& y, double& z) { - - auto const& tpc_id = _tpc_v.at((size_t)(fFlatRandom->fire(0,_tpc_v.size()))); - // Implementation of required member function here. - auto geop = lar::providerFrom(); - size_t cid = tpc_id[0]; - size_t tid = tpc_id[1]; - auto const& cryostat = geop->Cryostat(cid); - if(!cryostat.HasTPC(tid)) { - std::cerr<< "\033[93mTPC " << tid << " not found... in cryostat " << cid << "\033[00m" << std::endl; - throw std::exception(); - } - - auto const& tpc = cryostat.TPC(tid); - auto const& tpcabox = tpc.ActiveBoundingBox(); - double xmin = tpcabox.MinX() + _xrange[0]; - double xmax = tpcabox.MaxX() - _xrange[1]; - double ymin = tpcabox.MinY() + _yrange[0]; - double ymax = tpcabox.MaxY() - _yrange[1]; - double zmin = tpcabox.MinZ() + _zrange[0]; -double zmax = tpcabox.MaxZ() - _zrange[1]; -x = fFlatRandom->fire(xmin,xmax); -y = fFlatRandom->fire(ymin,ymax); -z = fFlatRandom->fire(zmin,zmax); - -} -*/ - -std::array MultiPartVertex::extractDirection() const { - double ct = fFlatRandom->fire(-1.0,1.0); - double st = TMath::Sqrt(1.0 - ct*ct); - double phi = fFlatRandom->fire(0.0,2.0*M_PI); - double px = st * TMath::Cos(phi); - double py = st * TMath::Sin(phi); - double pz = ct; - std::array result = { px, py, pz }; - return result; -} -/* -std::array MultiPartVertex::extractDirection() const { - double px, py, pz; - px = fNormalRandom->fire(0, 1); - py = fNormalRandom->fire(0, 1); - pz = fNormalRandom->fire(0, 1); - double p = std::hypot(px, py, pz); - px = px / p; - py = py / p; - pz = pz / p; - std::array result = { px, py, pz }; - return result; -} -*/ - -void MultiPartVertex::GenMomentum(const PartGenParam& param, const double& mass, double& px, double& py, double& pz) { - - double tot_energy = 0; - if(param.use_mom) - tot_energy = sqrt(cet::square(fFlatRandom->fire(param.kerange[0],param.kerange[1])) + cet::square(mass)); - else - tot_energy = fFlatRandom->fire(param.kerange[0],param.kerange[1]) + mass; - - double mom_mag = sqrt(cet::square(tot_energy) - cet::square(mass)); - - std::array p = extractDirection(); - px = p[0]; py = p[1]; pz = p[2]; - - if(_debug>1) - std::cout << " Direction : (" << px << "," << py << "," << pz << ")" << std::endl - << " Momentum : " << mom_mag << " [MeV/c]" << std::endl - << " Energy : " << tot_energy << " [MeV/c^2]" << std::endl; - px *= mom_mag; - py *= mom_mag; - pz *= mom_mag; - -} - -void MultiPartVertex::GenMomentum(const PartGenParam& param, const double& mass, double& px, double& py, double& pz, bool& same_range) { - - if (!same_range){ - GenMomentum(param, mass, px, py, pz); - } - else{ - double tot_energy = 0; - if(param.use_mom) - tot_energy = sqrt(cet::square(fFlatRandom->fire(param.kerange[0],param.kerange[1])) + cet::square(mass)); - else - tot_energy = fFlatRandom->fire(param.kerange[0],1) + mass; - - double mom_mag = sqrt(cet::square(tot_energy) - cet::square(mass)); - - std::array p = extractDirection(); - px = p[0]; py = p[1]; pz = p[2]; - - if(_debug>1) - std::cout << " Direction : (" << px << "," << py << "," << pz << ")" << std::endl - << " Momentum : " << mom_mag << " [MeV/c]" << std::endl - << " Energy : " << tot_energy << " [MeV/c^2]" << std::endl; - px *= mom_mag; - py *= mom_mag; - pz *= mom_mag; - } -} - - -void MultiPartVertex::GenMomentumSF(const double& sf, const double& m, const double& p, double& p_sf) -{ - p_sf = sqrt( sf*( 2*(sf-1)*cet::square(m)-2*(sf-1)*m*sqrt(cet::square(m)+cet::square(p))+sf*cet::square(p) ) )/p; -} - -void MultiPartVertex::produce(art::Event & e) -{ - if(_debug>0) std::cout << "Processing a new event..." << std::endl; - - std::unique_ptr< std::vector > mctArray(new std::vector); - - double g4_time = fFlatRandom->fire(_t0 - _t0_sigma/2., _t0 + _t0_sigma/2.); - - double x, y, z; - GenPosition(x,y,z); - TLorentzVector pos(x,y,z,g4_time); - - double bx,by,bz; - GenBoost(bx,by,bz); - - simb::MCTruth mct; - - mct.SetOrigin(simb::kBeamNeutrino); - - std::vector part_v; - - std::vector E_vec; - std::vector mass_vec; - std::vector pdg_vec; - std::vector px_vec; - std::vector py_vec; - std::vector pz_vec; - - auto const param_idx_v = GenParticles(); - if(_debug) - std::cout << "Event Vertex @ (" << x << "," << y << "," << z << ") ... " << param_idx_v.size() << " particles..." << std::endl; - - for(size_t idx=0; idxfire(0,param.pdg.size()-1.e-10)); - auto const& pdg = param.pdg[pdg_index]; - auto const& mass = param.mass[pdg_index]; - if(_debug) std::cout << " " << idx << "th instance PDG " << pdg << std::endl; - - if (_revert) { - GenMomentum(param,mass,px,py,pz); - } - else { - GenMomentum(param,mass,px,py,pz,same_range); - } - // moving boost - // - //TLorentzVector mom(px,py,pz,sqrt(cet::square(px)+cet::square(py)+cet::square(pz)+cet::square(mass))); - // - /* - if(_use_boost){ - mom.Boost(bx,by,bz); - px=mom.X(); - py=mom.Y(); - pz=mom.Z(); - }*/ - - E_vec.push_back(sqrt(cet::square(px)+cet::square(py)+cet::square(pz)+cet::square(mass))); - mass_vec.push_back(mass); - pdg_vec.push_back(pdg); - px_vec.push_back(px); - py_vec.push_back(py); - pz_vec.push_back(pz); - - } - - if(_revert){ - for(size_t idx=0; idx1.){ - - for(size_t idx=0; idxfire(0,1); - double total_KE_sf = gen_total_KE/total_KE; - if(_debug) std::cout << "gen_total_KE: "<< gen_total_KE << " , KE scale factor : " << total_KE_sf << std::endl; - - for(size_t idx=0; idxpush_back(mct); - - e.put(std::move(mctArray)); -} - -DEFINE_ART_MODULE(MultiPartVertex) diff --git a/sbncode/EventGenerator/MultiPart/gen_mpvmpr.fcl b/sbncode/EventGenerator/MultiPart/gen_mpvmpr.fcl index 2b046e5e0..6193d8937 100644 --- a/sbncode/EventGenerator/MultiPart/gen_mpvmpr.fcl +++ b/sbncode/EventGenerator/MultiPart/gen_mpvmpr.fcl @@ -63,8 +63,8 @@ physics.producers.generator.ZRange : [30,30] physics.producers.generator.TPCRange : [[0,0],[0,1],[0,2],[0,3]] #[1,0],[1,1],[1,2],[1,3]] physics.producers.generator.MultiMax : 7 #6 physics.producers.generator.GammaBetaRange : [0.0, 3.0] # [0.0,20.0] # Boost, GammaBeta = Gamma * Beta -physics.producers.generator.Revert: 0 #1 -physics.producers.generator.UseBoost : 0# 1 +physics.producers.generator.Revert: false #1 +physics.producers.generator.UseBoost : false# 1 physics.producers.generator.MultiMin : 2 physics.producers.generator.ParticleParameter.PDGCode : [[-11,11,-13,13], [111], [211,-211], [2212], [22]] physics.producers.generator.ParticleParameter.MinMulti : [ 0, 0, 0, 0, 0] From 3f2b0e3e940d3ffc558842ce7ff5803edd91b7b7 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Thu, 23 Oct 2025 12:12:05 -0500 Subject: [PATCH 235/367] implemented GP's comment --- sbncode/CAFMaker/FillTrigger.cxx | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 2e8d014ea..868be100f 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -34,21 +34,17 @@ namespace caf void FillTriggerICARUS(const sbn::ExtraTriggerInfo& addltrig_info, caf::SRTrigger& triggerInfo) { - // Per-cryostat additional trigger information, straight from the trigger hardware - const auto& addltrig_info_cryoE = addltrig_info.cryostats[sbn::ExtraTriggerInfo::EastCryostat]; - const auto& addltrig_info_cryoW = addltrig_info.cryostats[sbn::ExtraTriggerInfo::WestCryostat]; - // Choose the cryostat that triggered first (if both are available) - if (addltrig_info_cryoE.hasTrigger() && (!addltrig_info_cryoW.hasTrigger() || (addltrig_info_cryoE.beamToTrigger <= addltrig_info_cryoW.beamToTrigger))) { - triggerInfo.trigger_cryo_source = 0; ///< East - triggerInfo.trigger_logic_bits = addltrig_info_cryoE.triggerLogicBits; - triggerInfo.beam_to_trigger_time = addltrig_info_cryoE.beamToTrigger; - } - else if (addltrig_info_cryoW.hasTrigger()) { - triggerInfo.trigger_cryo_source = 1; ///< West - triggerInfo.trigger_logic_bits = addltrig_info_cryoW.triggerLogicBits; - triggerInfo.beam_to_trigger_time = addltrig_info_cryoW.beamToTrigger; - } + int const cryo = addltrig_info.cryostats[sbn::ExtraTriggerInfo::EastCryostat].beamToTrigger < addltrig_info.cryostats[sbn::ExtraTriggerInfo::WestCryostat].beamToTrigger + ? sbn::ExtraTriggerInfo::EastCryostat + : sbn::ExtraTriggerInfo::WestCryostat; + + sbn::ExtraTriggerInfo::CryostatInfo const& cryoInfo = addltrig_info.cryostats[cryo]; + if (cryoInfo.hasTrigger()) { + triggerInfo.trigger_cryo_source = cryo; + triggerInfo.trigger_logic_bits = cryoInfo.triggerLogicBits; + triggerInfo.gate_to_trigger_time = static_cast(cryoInfo.beamToTrigger) / 1000.0f; // [us] + } } } From 89516ab43edbd9b970fb55ef58ed97079cd0dd59 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Thu, 23 Oct 2025 13:54:39 -0500 Subject: [PATCH 236/367] Changed SpacePoint times back to ns --- sbncode/CAFMaker/FillReco.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 084e2fba8..f320cde39 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -202,7 +202,7 @@ namespace caf // add the CRTSpacePoint associations to the SR Veto for(auto const& sp : points) { srsbndcrtveto.sp_position.emplace_back(sp->X(), sp->Y(), sp->Z()); - srsbndcrtveto.sp_time.emplace_back(sp->Ts0()/1000); /// convert to us + srsbndcrtveto.sp_time.emplace_back(sp->Ts0()); /// ns for SBND CRT SpacePoints srsbndcrtveto.sp_pe.emplace_back(sp->PE()); } } From 7cdb76eb4cbde33e4f244f116db0bc23f5536656 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Thu, 23 Oct 2025 16:14:23 -0500 Subject: [PATCH 237/367] Fixed white space for FillReco? --- sbncode/CAFMaker/FillReco.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index f4ad71446..db212fdfc 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -280,7 +280,7 @@ namespace caf bool allowEmpty = false); void FillSBNDCRTVeto(const art::Ptr &veto, - const std::vector> &points, + const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty = false); From 1b4390bbec31d99ca2f3edcb99d9aca8b5a1bea9 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Thu, 23 Oct 2025 16:42:11 -0500 Subject: [PATCH 238/367] Fixed white space for CAFMaker module --- sbncode/CAFMaker/CAFMaker_module.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index c730c9c2f..bfb02ed43 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1792,16 +1792,16 @@ void CAFMaker::produce(art::Event& evt) noexcept { // fill into event if (sbndcrtveto_handle.isValid()) { art::fill_ptr_vector(vetoPtrs, sbndcrtveto_handle); - // Only one valid veto per event + // Only one valid veto per event if (vetoPtrs.size() == 1) { - // And associated SpacePoint objects - art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); + // And associated SpacePoint objects + art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); if (spAssoc.isValid()) { - // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied - const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); + // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied + const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); FillSBNDCRTVeto(vetoPtrs[0], veto_sp_v, srsbndcrtveto); - } - } + } + } } art::Handle sbndframeshiftinfo_handle; From e8cffd30475df460308993a3bce33984fef770f8 Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 24 Oct 2025 07:45:01 -0500 Subject: [PATCH 239/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec6466da4..2c3ffab03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.11.01 LANGUAGES CXX) +project(sbncode VERSION 10.11.01.01 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 4d4d45499..f7720ec60 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_04_00 - larcv2 v2_2_6 - larsoft v10_11_01 - -sbnalg v10_11_01 - +sbnalg v10_11_01_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From c0b9c7dc93563cac282114b1422355baeb1ab420 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Fri, 24 Oct 2025 10:35:40 -0500 Subject: [PATCH 240/367] add histograms to file even when total events are 0 for POT accounting --- sbncode/CAFMaker/CAFMaker_module.cc | 52 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..bd8026ca0 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2802,29 +2802,26 @@ void CAFMaker::endSubRun(art::SubRun& sr) { //...................................................................... void CAFMaker::endJob() { - if (fTotalEvents == 0) { - std::cerr << "No events processed in this file. Aborting rather than " - "produce an empty CAF." + // Only produce empty recTree/GenieTree since it relies on non-zero art events. + // Still want to keep POT histograms. + if (fTotalEvents == 0) { + std::cerr << "No events processed in this file. Producing empty recTree/GenieTree." << std::endl; - // n.b. changed abort() to return so that eny exceptions thrown during startup - // still get printed to the user by art - return; } - - if(fFile){ - AddHistogramsToFile(fFile); - fRecTree->SetDirectory(fFile); - if(fGenieTree){ - fGenieTree->BuildIndex("SourceFileHash", "GENIEEntry"); - fGenieTree->SetDirectory(fFile); - } - if (fParams.CreateBlindedCAF()) { - fRecTreeb->SetDirectory(fFileb); - fRecTreep->SetDirectory(fFilep); + if (fTotalEvents > 0) { + if(fGenieTree){ + fGenieTree->BuildIndex("SourceFileHash", "GENIEEntry"); + fGenieTree->SetDirectory(fFile); + } + fRecTree->SetDirectory(fFile); + if (fParams.CreateBlindedCAF()) { + fRecTreeb->SetDirectory(fFileb); + fRecTreep->SetDirectory(fFilep); + } } fFile->cd(); fFile->Write(); @@ -2840,17 +2837,20 @@ void CAFMaker::endJob() { } if(fFlatFile){ - AddHistogramsToFile(fFlatFile); - fFlatTree->SetDirectory(fFlatFile); - if(fFlatGenieTree){ - fFlatGenieTree->BuildIndex("SourceFileHash", "GENIEEntry"); - fFlatGenieTree->SetDirectory(fFlatFile); - } - if (fParams.CreateBlindedCAF() && fFlatFileb) { - fFlatTreeb->SetDirectory(fFlatFileb); - fFlatTreep->SetDirectory(fFlatFilep); + if (fTotalEvents > 0) { + if(fFlatGenieTree){ + fFlatGenieTree->BuildIndex("SourceFileHash", "GENIEEntry"); + fFlatGenieTree->SetDirectory(fFlatFile); + } + fFlatTree->SetDirectory(fFlatFile); + if (fParams.CreateBlindedCAF() && fFlatFileb) { + fFlatTreeb->SetDirectory(fFlatFileb); + fFlatTreep->SetDirectory(fFlatFilep); + } } + std::cout << "here4" << std::endl; + fFlatFile->cd(); fFlatFile->Write(); if (fParams.CreateBlindedCAF()) { From 78a102fce196b683de7a3629c361b2e2bbd9cd1a Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Mon, 27 Oct 2025 10:26:56 -0500 Subject: [PATCH 241/367] remove debug cout --- sbncode/CAFMaker/CAFMaker_module.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index bd8026ca0..691087a0e 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2849,7 +2849,6 @@ void CAFMaker::endJob() { fFlatTreep->SetDirectory(fFlatFilep); } } - std::cout << "here4" << std::endl; fFlatFile->cd(); fFlatFile->Write(); From 04a5a6c36ee8d4d0d3fb26fa252bd397b61fee55 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Tue, 28 Oct 2025 01:37:35 -0500 Subject: [PATCH 242/367] Removed pointers --- sbncode/CAFMaker/CAFMaker_module.cc | 9 ++++----- sbncode/CAFMaker/FillReco.cxx | 12 ++++++------ sbncode/CAFMaker/FillReco.h | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index bfb02ed43..fa0524a7e 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1788,18 +1788,17 @@ void CAFMaker::produce(art::Event& evt) noexcept { // Fill CRT Veto art::Handle> sbndcrtveto_handle; GetByLabelStrict(evt, fParams.SBNDCRTVetoLabel(), sbndcrtveto_handle); - std::vector> vetoPtrs; // fill into event if (sbndcrtveto_handle.isValid()) { - art::fill_ptr_vector(vetoPtrs, sbndcrtveto_handle); + const std::vector &sbndcrtveto_vec = *sbndcrtveto_handle; // Only one valid veto per event - if (vetoPtrs.size() == 1) { + if (sbndcrtveto_vec.size() == 1) { // And associated SpacePoint objects art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); if (spAssoc.isValid()) { // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied - const std::vector> veto_sp_v(spAssoc.at(vetoPtrs[0].key())); - FillSBNDCRTVeto(vetoPtrs[0], veto_sp_v, srsbndcrtveto); + const std::vector> veto_sp_v(spAssoc.at(0)); + FillSBNDCRTVeto(sbndcrtveto_vec[0], veto_sp_v, srsbndcrtveto); } } } diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index f320cde39..d6ce9d6da 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -188,16 +188,16 @@ namespace caf srsbndcrttrack.tof = track.ToF(); } - void FillSBNDCRTVeto(const art::Ptr &veto, + void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty) { - srsbndcrtveto.V0 = veto->V0(); - srsbndcrtveto.V1 = veto->V1(); - srsbndcrtveto.V2 = veto->V2(); - srsbndcrtveto.V3 = veto->V3(); - srsbndcrtveto.V4 = veto->V4(); + srsbndcrtveto.V0 = veto.V0(); + srsbndcrtveto.V1 = veto.V1(); + srsbndcrtveto.V2 = veto.V2(); + srsbndcrtveto.V3 = veto.V3(); + srsbndcrtveto.V4 = veto.V4(); // add the CRTSpacePoint associations to the SR Veto for(auto const& sp : points) { diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index db212fdfc..25b2bb867 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -279,7 +279,7 @@ namespace caf caf::SRSBNDCRTTrack &srsbndcrttrack, bool allowEmpty = false); - void FillSBNDCRTVeto(const art::Ptr &veto, + void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, const std::vector> &points, caf::SRSBNDCRTVeto &srsbndcrtveto, bool allowEmpty = false); From 4c47688c87f99ad37761ffda84918b1f1f40bcde Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Tue, 28 Oct 2025 10:24:30 -0500 Subject: [PATCH 243/367] Following Gianluca's comments --- sbncode/CAFMaker/FillReco.cxx | 35 ++++++++++++++++++----------------- sbncode/CAFMaker/FillReco.h | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index b861bf0b1..afeeaefb8 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -897,33 +897,34 @@ namespace caf // Loop over algorithm scores and extract the ones we want. // Get the ndof from any likelihood pid algorithm - std::vector AlgScoresVec = particle_id.ParticleIDAlgScores(); - for (size_t i_algscore=0; i_algscore const& AlgScoresVec = particle_id.ParticleIDAlgScores(); + for (anab::sParticleIDAlgScores const& AlgScore: AlgScoresVec){ if (AlgScore.fAlgName == "Likelihood"){ - if (TMath::Abs(AlgScore.fAssumedPdg) == 13) { // lambda_mu - srlikepid.lambda_muon = AlgScore.fValue; - srlikepid.pid_ndof = AlgScore.fNdf; - } - else if (TMath::Abs(AlgScore.fAssumedPdg) == 211) { // lambda_pi - srlikepid.lambda_pion = AlgScore.fValue; - srlikepid.pid_ndof = AlgScore.fNdf; - } - else if (TMath::Abs(AlgScore.fAssumedPdg) == 2212) { // lambda_pr - srlikepid.lambda_proton = AlgScore.fValue; - srlikepid.pid_ndof = AlgScore.fNdf; + switch (std::abs(AlgScore.fAssumedPdg)) { + case 13: // lambda_mu + srlikepid.lambda_muon = AlgScore.fValue; + srlikepid.pid_ndof = AlgScore.fNdf; + break; + case 211: // lambda_pi + srlikepid.lambda_pion = AlgScore.fValue; + srlikepid.pid_ndof = AlgScore.fNdf; + break; + case 2212: // lambda_pr + srlikepid.lambda_proton = AlgScore.fValue; + srlikepid.pid_ndof = AlgScore.fNdf; + break; } } } } - void FillTrackLikePID(const std::vector> particleIDs, + void FillTrackLikePID(const std::vector>& particleIDs, caf::SRTrack& srtrack, bool allowEmpty) { // get the particle ID's - for (unsigned i = 0; i < particleIDs.size(); i++) { - const anab::ParticleID &particle_id = *particleIDs[i]; + for (art::Ptr const& pidPtr: particleIDs) { + const anab::ParticleID &particle_id = *pidPtr; if (particle_id.PlaneID()) { unsigned plane_id = particle_id.PlaneID().Plane; assert(plane_id < 3); diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 039f09c8a..77c807b22 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -227,7 +227,7 @@ namespace caf caf::SRTrack& srtrack, bool allowEmpty = false); void FillPlaneLikePID(const anab::ParticleID &particle_id, caf::SRTrkLikelihoodPID &srlikepid); - void FillTrackLikePID(const std::vector> particleIDs, + void FillTrackLikePID(const std::vector>& particleIDs, caf::SRTrack& srtrack, bool allowEmpty = false); From ad25a042fa3f21db9cde399f30c27332924d1586 Mon Sep 17 00:00:00 2001 From: sungbinoh Date: Tue, 28 Oct 2025 11:06:42 -0500 Subject: [PATCH 244/367] adding setDefault for likelihood pid --- sbncode/CAFMaker/FillReco.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index afeeaefb8..f8baad172 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -896,6 +896,7 @@ namespace caf // Loop over algorithm scores and extract the ones we want. // Get the ndof from any likelihood pid algorithm + srlikepid.setDefault(); std::vector const& AlgScoresVec = particle_id.ParticleIDAlgScores(); for (anab::sParticleIDAlgScores const& AlgScore: AlgScoresVec){ From 18b28ecdab983edfa6fb62fbfcddd74105bfaf63 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Wed, 29 Oct 2025 09:07:49 -0500 Subject: [PATCH 245/367] first draft of adding blips --- sbncode/CAFMaker/FillBlip.cxx | 54 +++++++++++++++++++++++++++++++++++ sbncode/CAFMaker/FillBlip.h | 17 +++++++++++ 2 files changed, 71 insertions(+) create mode 100644 sbncode/CAFMaker/FillBlip.cxx create mode 100644 sbncode/CAFMaker/FillBlip.h diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx new file mode 100644 index 000000000..66be0188f --- /dev/null +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -0,0 +1,54 @@ +#include "sbncode/CAFMaker/FillBlip.h" + +namespace caf +{ + void FillBlip( const std::vector& LarBlips, std::vector& CAF_Blips) + { + int NBlips = LarBlips->size(); + for(int iBlip=0; iBlip= 0 ) //MC Blip + { + FillMCTruthBlip( &CurrentBlip, &NewBlip ); + } + FillBlipRealtedHitCluster( &CurrentBlip, &NewBlip ); + } + + } + + void FillMCTruthBlip( blip::Blip& LarBlip, caf::SRBlip &CAF_Blip ) + { + CAF_Blip->truthBlip = LarBlip->truthBlip; + CAF_Blip->truthBlip.Energy = CAF_Blip->truthBlip.Energy/1000.; //convert to GeV + } + + void FillBlipRealtedHitCluster(blip::Blip& LarBlip, caf::SRBlip &CAF_Blip) + { + int NumPlanes = sizeof(LarBlip->clusters)/sizeof(LarBlip->clusters[0]); + for(int iPlane=0; iPlaneclusters[iPlane] = LarBlip->clusters[iPlane] + } + } +} \ No newline at end of file diff --git a/sbncode/CAFMaker/FillBlip.h b/sbncode/CAFMaker/FillBlip.h new file mode 100644 index 000000000..501556c15 --- /dev/null +++ b/sbncode/CAFMaker/FillBlip.h @@ -0,0 +1,17 @@ +#ifndef CAF_FILLBLIP_H +#define CAF_FILLBLIP_H +#include +#include "sbnanaobj/StandardRecord/SRBlip.h" +#include "sbndcode/BlipRecoSBND/Utils/BlipUtils.h" + +#include + +namespace caf +{ + + void FillBlip( const std::vector& LarBlips, std::vector& CAF_Blips); + void FillMCTruthBlip(blip::Blip& LarBlip, caf::SRBlip& CAF_Blip ); + void FillBlipRealtedHitCluster(blip::Blip& LarBlip, caf::SRBlip& CAF_Blip); +} + +#endif From daa5c8e79ae31a364cbd216ea5a08e2a75bba917 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Wed, 29 Oct 2025 10:35:51 -0500 Subject: [PATCH 246/367] Added blip library --- sbncode/CAFMaker/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index aa42cba8a..fd3eeee8b 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -42,6 +42,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service + sbndcode_BlipUtils larsim::Utils larevt::SpaceCharge systematicstools::interface From 8dfaab07c8935a07a392697bde67004dd159cd93 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Wed, 29 Oct 2025 10:50:27 -0500 Subject: [PATCH 247/367] forgot to add my blip to the vector --- sbncode/CAFMaker/FillBlip.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 66be0188f..2ae303b5a 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -33,6 +33,7 @@ namespace caf FillMCTruthBlip( &CurrentBlip, &NewBlip ); } FillBlipRealtedHitCluster( &CurrentBlip, &NewBlip ); + CAF_Blips->push_back(NewBlip); } } From 23c5909dee7ec0a6306f96b70e9db5e19a700d02 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Thu, 30 Oct 2025 08:53:12 -0500 Subject: [PATCH 248/367] Adding blips to cafmaker --- sbncode/CAFMaker/CAFMaker_module.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..ae0b9ca8c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -20,6 +20,7 @@ #include "sbncode/CAFMaker/FillExposure.h" #include "sbncode/CAFMaker/FillTrigger.h" #include "sbncode/CAFMaker/Utils.h" +#include "sbncode/CAFMaker/FillBlip.h" // C/C++ includes #include @@ -1874,6 +1875,13 @@ void CAFMaker::produce(art::Event& evt) noexcept { } } + //Fill blips. art::handle for blips and then call fill blips for each one. Make a vector to hold all of them. I handle for loop in Fill blip + art::Handle> blipHandle; + std::vector> srblips; + if(evt.GetByLabel( fBlipTag, blipHandle)) //fill SR blips + { + FillBlip( (*LarBlips) , srblips); + } // collect the TPC slices std::vector> slices; std::vector slice_tag_suffixes; @@ -2543,6 +2551,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.nsbnd_crt_tracks = srsbndcrttracks.size(); rec.opflashes = srflashes; rec.nopflashes = srflashes.size(); + rec.blips = srblips; rec.sbnd_frames = srsbndframeshiftinfo; rec.sbnd_timings = srsbndtiminginfo; From c29001e192c3d9d3515e0d32f3bcb7484723c39d Mon Sep 17 00:00:00 2001 From: aantonakis <137554725+aantonakis@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:00:37 -0700 Subject: [PATCH 249/367] Update sbncode/CAFMaker/CAFMaker_module.cc Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index fa0524a7e..ad8ff63d6 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1797,7 +1797,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::FindManyP spAssoc(sbndcrtveto_handle, evt, fParams.SBNDCRTVetoLabel()); if (spAssoc.isValid()) { // There is one vector of SpacePoints per Veto --> can be empty if no veto condition was satisfied - const std::vector> veto_sp_v(spAssoc.at(0)); + const std::vector>& veto_sp_v(spAssoc.at(0)); FillSBNDCRTVeto(sbndcrtveto_vec[0], veto_sp_v, srsbndcrtveto); } } From 1ee32b76ec480c2b1cdfa267a6b11eb8117b7d4c Mon Sep 17 00:00:00 2001 From: aantonakis <137554725+aantonakis@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:01:04 -0700 Subject: [PATCH 250/367] Update sbncode/CAFMaker/FillReco.cxx Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/FillReco.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index d6ce9d6da..86688d4d1 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -202,7 +202,7 @@ namespace caf // add the CRTSpacePoint associations to the SR Veto for(auto const& sp : points) { srsbndcrtveto.sp_position.emplace_back(sp->X(), sp->Y(), sp->Z()); - srsbndcrtveto.sp_time.emplace_back(sp->Ts0()); /// ns for SBND CRT SpacePoints + srsbndcrtveto.sp_time.emplace_back(sp->Ts0()); // ns for SBND CRT SpacePoints srsbndcrtveto.sp_pe.emplace_back(sp->PE()); } } From d2f5729a81d8ae022bb1f91f064d7e6763a35d06 Mon Sep 17 00:00:00 2001 From: Alexander Antonakis Date: Thu, 30 Oct 2025 18:09:29 -0500 Subject: [PATCH 251/367] Changed emplace_back to push_back --- sbncode/CAFMaker/FillReco.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 86688d4d1..ecb84472b 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -202,8 +202,8 @@ namespace caf // add the CRTSpacePoint associations to the SR Veto for(auto const& sp : points) { srsbndcrtveto.sp_position.emplace_back(sp->X(), sp->Y(), sp->Z()); - srsbndcrtveto.sp_time.emplace_back(sp->Ts0()); // ns for SBND CRT SpacePoints - srsbndcrtveto.sp_pe.emplace_back(sp->PE()); + srsbndcrtveto.sp_time.push_back(sp->Ts0()); // ns for SBND CRT SpacePoints + srsbndcrtveto.sp_pe.push_back(sp->PE()); } } From c7dde1e4099b61fe3d12ccfb3332f6be3a2d01df Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Mon, 3 Nov 2025 11:03:35 -0600 Subject: [PATCH 252/367] add functionality to save ngenevt on a run-level in new histogram - add check for opening a new file - access the run process history to get the number of generated events - add new histogram to save ngenevt, paralleling fTotalPOT --- sbncode/CAFMaker/CAFMaker_module.cc | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 691087a0e..80f909ab8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -207,6 +207,8 @@ class CAFMaker : public art::EDProducer { std::string fSourceFile; std::uint32_t fSourceFileHash; + + bool fNewInputFile; bool fOverrideRealData; bool fFirstInSubRun; @@ -224,6 +226,7 @@ class CAFMaker : public art::EDProducer { double fTotalEvents; double fBlindEvents; double fPrescaleEvents; + double fNGenEvents; std::vector fBNBInfo; ///< Store detailed BNB info to save into the first StandardRecord of the output file std::vector fNuMIInfo; ///< Store detailed NuMI info to save into the first StandardRecord of the output file std::map fBNBInfoEventMap; ///< Store detailed BNB info to save for the particular spills of events @@ -783,6 +786,7 @@ void CAFMaker::respondToOpenInputFile(const art::FileBlock& fb) { // so should be less than or equal to 32-bit fSourceFileHash = static_cast(fSourceFileHashFull); + fNewInputFile = true; } //...................................................................... @@ -858,6 +862,18 @@ void CAFMaker::beginRun(art::Run& run) { fDet = override; } + if (std::exchange(fNewInputFile, false)){ + for (const art::ProcessConfiguration &process: run.processHistory()) { + std::optional gen_config = run.getProcessParameterSet(process.processName()); + if (gen_config && gen_config->has_key("source") && gen_config->has_key("source.maxEvents") && gen_config->has_key("source.module_type") ) { + int max_events = gen_config->get("source.maxEvents"); + std::string module_type = gen_config->get("source.module_type"); + if (module_type == "EmptyEvent") { + fNGenEvents += max_events; + } + } + } + } if(fParams.SystWeightLabels().empty()) return; // no need for globalTree @@ -1212,6 +1228,7 @@ void CAFMaker::InitializeOutfiles() fTotalEvents = 0; fBlindEvents = 0; fPrescaleEvents = 0; + fNGenEvents = 0; fIndexInFile = SRHeader::NoSourceIndex; fFirstInSubRun = false; fFirstBlindInSubRun = false; @@ -2770,11 +2787,11 @@ void CAFMaker::endSubRun(art::SubRun& sr) { //...................................................................... void CAFMaker::AddHistogramsToFile(TFile* outfile,bool isBlindPOT = false, bool isPrescalePOT = false) const { - outfile->cd(); TH1* hPOT = new TH1D("TotalPOT", "TotalPOT;; POT", 1, 0, 1); TH1* hEvents = new TH1D("TotalEvents", "TotalEvents;; Events", 1, 0, 1); + TH1* hGen = new TH1D("NGenEvents", "NGenEvents;; Events", 1, 0, 1); if (isBlindPOT) { hPOT->Fill(0.5,fTotalPOT*(1-(1/fParams.PrescaleFactor()))*GetBlindPOTScale()); @@ -2786,13 +2803,15 @@ void CAFMaker::endSubRun(art::SubRun& sr) { hPOT->Fill(0.5,fTotalPOT); } hEvents->Fill(0.5,fTotalEvents); + hGen->Fill(0.5,fNGenEvents); hPOT->Write(); hEvents->Write(); + hGen->Write(); if (fParams.CreateBlindedCAF()) { TH1*hBlindEvents = new TH1D("BlindEvents", "BlindEvents;; Events", 1, 0, 1); - TH1* hPrescaleEvents = new TH1D("PrescaleEvents", "PrescaleEvents;; Events", 1, 0, 1); + TH1*hPrescaleEvents = new TH1D("PrescaleEvents", "PrescaleEvents;; Events", 1, 0, 1); hBlindEvents->Fill(0.5, fBlindEvents); hPrescaleEvents->Fill(0.5, fPrescaleEvents); hBlindEvents->Write(); From 5ee3fb2bfe1795a4d8173e2a1f14ba932ac9ee28 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Mon, 3 Nov 2025 11:41:57 -0600 Subject: [PATCH 253/367] rename NGenEvents to TotalGenEvents to share similar syntax with POT and Events variables --- sbncode/CAFMaker/CAFMaker_module.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 80f909ab8..74f53df06 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -226,7 +226,7 @@ class CAFMaker : public art::EDProducer { double fTotalEvents; double fBlindEvents; double fPrescaleEvents; - double fNGenEvents; + double fTotalGenEvents; std::vector fBNBInfo; ///< Store detailed BNB info to save into the first StandardRecord of the output file std::vector fNuMIInfo; ///< Store detailed NuMI info to save into the first StandardRecord of the output file std::map fBNBInfoEventMap; ///< Store detailed BNB info to save for the particular spills of events @@ -869,7 +869,7 @@ void CAFMaker::beginRun(art::Run& run) { int max_events = gen_config->get("source.maxEvents"); std::string module_type = gen_config->get("source.module_type"); if (module_type == "EmptyEvent") { - fNGenEvents += max_events; + fTotalGenEvents += max_events; } } } @@ -1228,7 +1228,7 @@ void CAFMaker::InitializeOutfiles() fTotalEvents = 0; fBlindEvents = 0; fPrescaleEvents = 0; - fNGenEvents = 0; + fTotalGenEvents = 0; fIndexInFile = SRHeader::NoSourceIndex; fFirstInSubRun = false; fFirstBlindInSubRun = false; @@ -2791,7 +2791,7 @@ void CAFMaker::endSubRun(art::SubRun& sr) { TH1* hPOT = new TH1D("TotalPOT", "TotalPOT;; POT", 1, 0, 1); TH1* hEvents = new TH1D("TotalEvents", "TotalEvents;; Events", 1, 0, 1); - TH1* hGen = new TH1D("NGenEvents", "NGenEvents;; Events", 1, 0, 1); + TH1* hGen = new TH1D("TotalGenEvents", "TotalGenEvents;; Events", 1, 0, 1); if (isBlindPOT) { hPOT->Fill(0.5,fTotalPOT*(1-(1/fParams.PrescaleFactor()))*GetBlindPOTScale()); @@ -2803,7 +2803,7 @@ void CAFMaker::endSubRun(art::SubRun& sr) { hPOT->Fill(0.5,fTotalPOT); } hEvents->Fill(0.5,fTotalEvents); - hGen->Fill(0.5,fNGenEvents); + hGen->Fill(0.5,fTotalGenEvents); hPOT->Write(); hEvents->Write(); From bee607625e9ad11b724c0d65a990f0c58ffa1645 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 5 Nov 2025 08:59:08 -0600 Subject: [PATCH 254/367] eps increase, window shrink, def vals --- sbncode/BeamSpillInfoRetriever/POTTools.cpp | 94 +++++++++---------- .../SBNDBNBRetriever_module.cc | 2 +- .../job/sbndbnbdefaults.fcl | 2 +- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index 48f6984df..585fdba5b 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -68,42 +68,42 @@ namespace sbn::pot{ // initializing all of our device carriers // device definitions can be found in BNBSpillInfo.h - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP873 = 0; // units mm - double VP873 = 0; // units mm; not in the first IFBeam query bunch - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps - double M875HS = 0; // units mm - double M875VS = 0; // units mm - double M875HM = 0; // units mm - double M875VM = 0; // units mm - double M876HS = 0; // units mm - double M876VS = 0; // units mm - double M876HM = 0; // units mm - double M876VM = 0; // units mm + double TOR860 = -999; // units e12 protons + double TOR875 = -999; // units e12 protons + double LM875A = -999; // units R/s + double LM875B = -999; // units R/s + double LM875C = -999; // units R/s + double HP873 = -999; // units mm + double VP873 = -999; // units mm; not in the first IFBeam query bunch + double HP875 = -999; // units mm + double VP875 = -999; // units mm + double HPTG1 = -999; // units mm + double VPTG1 = -999; // units mm + double HPTG2 = -999; // units mm + double VPTG2 = -999; // units mm + double BTJT2 = -999; // units Deg C + double THCURR = -999; // units kiloAmps + double M875HS = -999; // units mm + double M875VS = -999; // units mm + double M875HM = -999; // units mm + double M875VM = -999; // units mm + double M876HS = -999; // units mm + double M876VS = -999; // units mm + double M876HM = -999; // units mm + double M876VM = -999; // units mm - double HP875Offset =0;//units mm; make a another separate IFBeam query bunch for offsets - double VP875Offset =0;//units mm - double VP873Offset =0;//units mm - double HPTG1Offset =0;//units mm - double HPTG2Offset =0;//units mm - double VPTG1Offset =0;//units mm - double VPTG2Offset =0;//units mm + double HP875Offset =-999;//units mm; make a another separate IFBeam query bunch for offsets + double VP875Offset =-999;//units mm + double VP873Offset =-999;//units mm + double HPTG1Offset =-999;//units mm + double HPTG2Offset =-999;//units mm + double VPTG1Offset =-999;//units mm + double VPTG2Offset =-999;//units mm - double TOR860_time = 0; // units s + double TOR860_time = -999; // units s - double FOM =0; + double FOM =-999; // Here we request all the devices // since sometimes devices fail to report we'll @@ -116,7 +116,7 @@ namespace sbn::pot{ try{bfp->GetNamedData(time, "E:LM875B",&LM875B);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:LM875C",&LM875C);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:HP873",&HP873);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} - try{bfp->GetNamedData(time, "E:VP873",&VP873);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} + try{vp873->GetNamedData(time, "E:VP873",&VP873);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:HP875",&HP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:VP875",&VP875);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} try{bfp->GetNamedData(time, "E:HPTG1",&HPTG1);}catch (WebAPIException &we) {mf::LogDebug("BNBRetriever")<< "At time : " << time << " " << "got exception: " << we.what() << "\n";} @@ -231,21 +231,21 @@ namespace sbn::pot{ bool BrokenClock(double time, std::unique_ptr const& bfp) { - double TOR860 = 0; // units e12 protons - double TOR875 = 0; // units e12 protons - double LM875A = 0; // units R/s - double LM875B = 0; // units R/s - double LM875C = 0; // units R/s - double HP875 = 0; // units mm - double VP875 = 0; // units mm - double HPTG1 = 0; // units mm - double VPTG1 = 0; // units mm - double HPTG2 = 0; // units mm - double VPTG2 = 0; // units mm - double BTJT2 = 0; // units Deg C - double THCURR = 0; // units kiloAmps + double TOR860 = -999; // units e12 protons + double TOR875 = -999; // units e12 protons + double LM875A = -999; // units R/s + double LM875B = -999; // units R/s + double LM875C = -999; // units R/s + double HP875 = -999; // units mm + double VP875 = -999; // units mm + double HPTG1 = -999; // units mm + double VPTG1 = -999; // units mm + double HPTG2 = -999; // units mm + double VPTG2 = -999; // units mm + double BTJT2 = -999; // units Deg C + double THCURR = -999; // units kiloAmps - double TOR860_time = 0; // units s + double TOR860_time = -999; // units s // Here we request all the devices // since sometimes devices fail to report we'll diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 97ca57d6d..779be4053 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -71,7 +71,7 @@ sbn::SBNDBNBRetriever::SBNDBNBRetriever(fhicl::ParameterSet const & params) vp873->set_epsilon(0.02); offsets = ifbeam_handle->getBeamFolder(params.get("OffsetBundle"), params.get("URL"), timeWindow); - offsets->set_epsilon(600); + offsets->set_epsilon(1000); } diff --git a/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl b/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl index 2ef9a7491..47f37d9ba 100644 --- a/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/sbndbnbdefaults.fcl @@ -12,7 +12,7 @@ sbndbnbspillinfo: { OffsetBundle: "BNB_BPM_settings" TimeWindow: "700" #seconds - MWR_TimeWindow: "3601" #seconds + MWR_TimeWindow: "700" #seconds DeviceUsedForTiming: "E:TOR860" } From 1bec764b822eb781f3c6f5c4c67f4df38b22c25e Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 5 Nov 2025 17:31:44 -0600 Subject: [PATCH 255/367] Updated dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c3ffab03..ce67d433c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.11.01.01 LANGUAGES CXX) +project(sbncode VERSION 10.12.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index f7720ec60..e3a7fc034 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -252,15 +252,15 @@ libdir fq_dir lib # #################################### product version qual flags -genie_xsec v3_04_00 - +genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_11_01 - -sbnalg v10_11_01_01 - +larsoft v10_12_02 - +sbnalg v10_12_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_07 - -geant4reweight v01_20_11 - +nusystematics v1_05_09 - +geant4reweight v01_20_13 - cetmodules v3_24_01 - only_for_build end_product_list #################################### From 8ad1d07634c8721a0b2a99dba751609b3fb2ca44 Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Mon, 10 Nov 2025 11:02:57 -0600 Subject: [PATCH 256/367] added ICARUS guard --- sbncode/CAFMaker/CAFMaker_module.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index e2e910454..1a5c3df9d 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1577,7 +1577,8 @@ void CAFMaker::produce(art::Event& evt) noexcept { caf::SRTrigger srtrigger; if (isValidTrigger) { FillTrigger(*extratrig_handle, trig_handle->at(0), srtrigger, triggerShift); - FillTriggerICARUS(*extratrig_handle, srtrigger); + if (fDet == kICARUS) + FillTriggerICARUS(*extratrig_handle, srtrigger); } // If not real data, fill in enough of the SRTrigger to make (e.g.) the CRT // time referencing work. TODO: add more stuff to a "MC"-Trigger? From 116ae1fa68443854ee21f0c9b52df3ee93de18ea Mon Sep 17 00:00:00 2001 From: Riccardo Triozzi Date: Mon, 10 Nov 2025 11:10:54 -0600 Subject: [PATCH 257/367] removed SBND couts --- sbncode/CAFMaker/FillTrigger.cxx | 6 ------ sbncode/CAFMaker/FillTrigger.h | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 774268efd..4a34f5045 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -12,10 +12,7 @@ namespace caf triggerInfo.beam_gate_time_abs = addltrig_info.beamGateTimestamp; triggerInfo.beam_gate_det_time = trig.BeamGateTime() + time_offset; triggerInfo.global_trigger_det_time = trig.TriggerTime() + time_offset; - std::cout << "Gen triggerInfo.global_trigger_det_time: " << triggerInfo.global_trigger_det_time << std::endl; - std::cout << "Gen triggerInfo.beam_gate_det_time: " << triggerInfo.beam_gate_det_time << std::endl; double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; - std::cout << "diff_ts: " << diff_ts << std::endl; triggerInfo.trigger_within_gate = diff_ts; triggerInfo.prev_global_trigger_time = addltrig_info.previousTriggerTimestamp; triggerInfo.source_type = sbn::bits::value(addltrig_info.sourceType); @@ -55,10 +52,7 @@ namespace caf triggerInfo.global_trigger_time = timingInfo.hltEtrig; triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; - std::cout << "triggerInfo.global_trigger_det_time: " << triggerInfo.global_trigger_det_time << std::endl; - std::cout << "triggerInfo.beam_gate_det_time: " << triggerInfo.beam_gate_det_time << std::endl; double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; - std::cout << "diff_ts: " << diff_ts << std::endl; triggerInfo.trigger_within_gate = diff_ts; } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index b47a9ae66..51e8a8bf6 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -18,7 +18,8 @@ namespace caf void FillTriggerMC(double absolute_time, caf::SRTrigger& triggerInfo); void FillTriggerICARUS(const sbn::ExtraTriggerInfo& addltrig_info, - caf::SRTrigger& triggerInfo); + caf::SRTrigger& triggerInfo); + void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo); void FillTriggerEmulation(art::Handle> const& monpulsesFlat, From 3812b043518cbcc168ee229e671bd0fa85672d55 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 10 Nov 2025 15:26:58 -0600 Subject: [PATCH 258/367] added blips to cafmaker --- sbncode/CAFMaker/CAFMakerParams.h | 4 ++ sbncode/CAFMaker/CAFMaker_module.cc | 12 +++-- sbncode/CAFMaker/CMakeLists.txt | 1 + sbncode/CAFMaker/FillBlip.cxx | 69 ++++++++++++++++++++++++----- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 4fc80a207..ce9bfd20f 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -622,6 +622,10 @@ namespace caf Comment("Label of CVN scores."), "cvn" }; + Atom fBlipTag { Name("BlipTag"), + Comment("Provide a string to label the blip input"), "reco2:Blip:BlipReco" + }; + }; } diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 2cf0b9084..b822e7910 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -284,6 +284,7 @@ class CAFMaker : public art::EDProducer { int fGenieEvtRec_brStdHepLd [250] = {0}; ////< Last daughter int fGenieEvtRec_brStdHepFm [250] = {0}; ////< First mother int fGenieEvtRec_brStdHepLm [250] = {0}; ////< Last mother + //std::string fBlipTag; flat::Flat* fFlatRecord = 0; flat::Flat* fFlatRecordb = 0; @@ -1919,10 +1920,15 @@ void CAFMaker::produce(art::Event& evt) noexcept { //Fill blips. art::handle for blips and then call fill blips for each one. Make a vector to hold all of them. I handle for loop in Fill blip art::Handle> blipHandle; - std::vector> srblips; - if(evt.GetByLabel( fBlipTag, blipHandle)) //fill SR blips + std::vector srblips; + if(evt.getByLabel( fParams.fBlipTag(), blipHandle)) //fill SR blips { - FillBlip( (*LarBlips) , srblips); + FillBlip( (*blipHandle), srblips); + //for(int i=0; isize()); i++) + // { + // auto LarBlips = (*(blipHandle))[i]; + // FillBlip( (LarBlips) , srblips); + // } } // collect the TPC slices std::vector> slices; diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index fd3eeee8b..ff0411e46 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -39,6 +39,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_Trigger sbnobj::SBND_CRT sbnobj::SBND_Timing + sbndobj_BlipDataTypes lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 2ae303b5a..fa300f743 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -4,7 +4,7 @@ namespace caf { void FillBlip( const std::vector& LarBlips, std::vector& CAF_Blips) { - int NBlips = LarBlips->size(); + int NBlips = LarBlips.size(); for(int iBlip=0; iBlip= 0 ) //MC Blip + if(CurrentBlip.truth.ID >= 0 ) //MC Blip { - FillMCTruthBlip( &CurrentBlip, &NewBlip ); + FillMCTruthBlip( CurrentBlip, NewBlip ); } - FillBlipRealtedHitCluster( &CurrentBlip, &NewBlip ); - CAF_Blips->push_back(NewBlip); + FillBlipRealtedHitCluster( CurrentBlip, NewBlip ); + CAF_Blips.push_back(NewBlip); } } void FillMCTruthBlip( blip::Blip& LarBlip, caf::SRBlip &CAF_Blip ) { - CAF_Blip->truthBlip = LarBlip->truthBlip; - CAF_Blip->truthBlip.Energy = CAF_Blip->truthBlip.Energy/1000.; //convert to GeV + //CAF_Blip.truthBlip = LarBlip.truth; + CAF_Blip.truthBlip.ID = LarBlip.truth.ID; + CAF_Blip.truthBlip.Cryostat =LarBlip.truth.Cryostat; + CAF_Blip.truthBlip.TPC =LarBlip.truth.TPC; + CAF_Blip.truthBlip.Time =LarBlip.truth.Time; + CAF_Blip.truthBlip.TimeTick =LarBlip.truth.TimeTick; + CAF_Blip.truthBlip.DriftTime =LarBlip.truth.DriftTime; + CAF_Blip.truthBlip.Energy =LarBlip.truth.Energy; + CAF_Blip.truthBlip.DepElectrons =LarBlip.truth.DepElectrons; + CAF_Blip.truthBlip.NumElectrons =LarBlip.truth.NumElectrons; + CAF_Blip.truthBlip.LeadG4ID =LarBlip.truth.LeadG4ID; + CAF_Blip.truthBlip.LeadG4Index =LarBlip.truth.LeadG4Index; + CAF_Blip.truthBlip.LeadG4PDG =LarBlip.truth.LeadG4PDG; + CAF_Blip.truthBlip.LeadCharge =LarBlip.truth.LeadCharge; + CAF_Blip.truthBlip.Position =LarBlip.truth.Position; + CAF_Blip.truthBlip.Energy = CAF_Blip.truthBlip.Energy/1000.; //convert to GeV } void FillBlipRealtedHitCluster(blip::Blip& LarBlip, caf::SRBlip &CAF_Blip) { - int NumPlanes = sizeof(LarBlip->clusters)/sizeof(LarBlip->clusters[0]); + int NumPlanes = sizeof(LarBlip.clusters)/sizeof(LarBlip.clusters[0]); for(int iPlane=0; iPlaneclusters[iPlane] = LarBlip->clusters[iPlane] + CAF_Blip.clusters[iPlane].ID = LarBlip.clusters[iPlane].ID; + CAF_Blip.clusters[iPlane].isValid = LarBlip.clusters[iPlane].isValid; + CAF_Blip.clusters[iPlane].CenterChan = LarBlip.clusters[iPlane].CenterChan; + CAF_Blip.clusters[iPlane].CenterWire = LarBlip.clusters[iPlane].CenterWire; + CAF_Blip.clusters[iPlane].isTruthMatched = LarBlip.clusters[iPlane].isTruthMatched; + CAF_Blip.clusters[iPlane].isMerged = LarBlip.clusters[iPlane].isMerged; + CAF_Blip.clusters[iPlane].isMatched = LarBlip.clusters[iPlane].isMatched; + CAF_Blip.clusters[iPlane].DeadWireSep = LarBlip.clusters[iPlane].DeadWireSep; + CAF_Blip.clusters[iPlane].Cryostat = LarBlip.clusters[iPlane].Cryostat; + CAF_Blip.clusters[iPlane].TPC = LarBlip.clusters[iPlane].TPC; + CAF_Blip.clusters[iPlane].Plane = LarBlip.clusters[iPlane].Plane; + CAF_Blip.clusters[iPlane].NHits = LarBlip.clusters[iPlane].NHits; + CAF_Blip.clusters[iPlane].NWires = LarBlip.clusters[iPlane].NWires; + CAF_Blip.clusters[iPlane].ADCs = LarBlip.clusters[iPlane].ADCs; + CAF_Blip.clusters[iPlane].Amplitude = LarBlip.clusters[iPlane].Amplitude; + CAF_Blip.clusters[iPlane].Charge = LarBlip.clusters[iPlane].Charge; + CAF_Blip.clusters[iPlane].SigmaCharge = LarBlip.clusters[iPlane].SigmaCharge; + CAF_Blip.clusters[iPlane].TimeTick = LarBlip.clusters[iPlane].TimeTick; + CAF_Blip.clusters[iPlane].Time = LarBlip.clusters[iPlane].Time; + CAF_Blip.clusters[iPlane].StartHitTime = LarBlip.clusters[iPlane].StartHitTime; + CAF_Blip.clusters[iPlane].EndHitTime = LarBlip.clusters[iPlane].EndHitTime; + CAF_Blip.clusters[iPlane].StartTime = LarBlip.clusters[iPlane].StartTime; + CAF_Blip.clusters[iPlane].EndTime = LarBlip.clusters[iPlane].EndTime; + CAF_Blip.clusters[iPlane].Timespan = LarBlip.clusters[iPlane].Timespan; + CAF_Blip.clusters[iPlane].RMS = LarBlip.clusters[iPlane].RMS; + CAF_Blip.clusters[iPlane].StartWire = LarBlip.clusters[iPlane].StartWire; + CAF_Blip.clusters[iPlane].EndWire = LarBlip.clusters[iPlane].EndWire; + CAF_Blip.clusters[iPlane].NPulseTrainHits = LarBlip.clusters[iPlane].NPulseTrainHits; + CAF_Blip.clusters[iPlane].GoodnessOfFit = LarBlip.clusters[iPlane].GoodnessOfFit; + CAF_Blip.clusters[iPlane].BlipID = LarBlip.clusters[iPlane].BlipID; + CAF_Blip.clusters[iPlane].EdepID = LarBlip.clusters[iPlane].EdepID; + //These are sets that need to become vectors so we need to do some loops + for(auto HitID : LarBlip.clusters[iPlane].HitIDs) CAF_Blip.clusters[iPlane].HitIDs.push_back(HitID); + for(auto Wire : LarBlip.clusters[iPlane].Wires) CAF_Blip.clusters[iPlane].Wires.push_back(Wire); + for(auto Chan : LarBlip.clusters[iPlane].Chans) CAF_Blip.clusters[iPlane].Chans.push_back(Chan); + for(auto G4ID : LarBlip.clusters[iPlane].G4IDs) CAF_Blip.clusters[iPlane].G4IDs.push_back(G4ID); } } -} \ No newline at end of file +} From 2daacc437905614f3c54bab4fba463771a2a473f Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 11 Nov 2025 16:25:42 -0600 Subject: [PATCH 259/367] temporary comment timing-related in caf --- sbncode/CAFMaker/CAFMaker_module.cc | 120 ++++++++++++++-------------- sbncode/CAFMaker/FillReco.cxx | 15 ++-- 2 files changed, 68 insertions(+), 67 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..5e0217b88 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -327,8 +327,8 @@ class CAFMaker : public art::EDProducer { void FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time); void FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_time, double CRTT1_reference_time); - void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const; - void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const; + //void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const; + //void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const; /// Equivalent of FindManyP except a return that is !isValid() prints a /// messsage and aborts if StrictMode is true. @@ -516,43 +516,43 @@ void CAFMaker::BlindEnergyParameters(StandardRecord* brec) { } } -void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { - - //CRT Space Point - for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ - sp.time += SBNDFrame; //ns - } - - //CRT Track - for (SRSBNDCRTTrack &trk: rec.sbnd_crt_tracks){ - trk.time += SBNDFrame; //ns - } - - //TODO: CRT Space Point and Track Match - for (SRSlice &slc: rec.slc){ - for (SRPFP &pfp: slc.reco.pfp){ - if(!std::isnan(pfp.trk.crtspacepoint.score)) pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; - - if(!std::isnan(pfp.trk.crtsbndtrack.score)) pfp.trk.crtsbndtrack.track.time += SBNDFrame; - } - } -} - -void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { - - double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us - - //Op Flash - for (SROpFlash &opf: rec.opflashes) { - opf.time += SBNDFrame_us; - opf.firsttime += SBNDFrame_us; - } - - //OpT0 match to slice - for (SRSlice &s: rec.slc) { - s.opt0.time += SBNDFrame_us; - } -} +//void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { +// +// //CRT Space Point +// for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ +// sp.time += SBNDFrame; //ns +// } +// +// //CRT Track +// for (SRSBNDCRTTrack &trk: rec.sbnd_crt_tracks){ +// trk.time += SBNDFrame; //ns +// } +// +// //TODO: CRT Space Point and Track Match +// for (SRSlice &slc: rec.slc){ +// for (SRPFP &pfp: slc.reco.pfp){ +// if(!std::isnan(pfp.trk.crtspacepoint.score)) pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; +// +// if(!std::isnan(pfp.trk.crtsbndtrack.score)) pfp.trk.crtsbndtrack.track.time += SBNDFrame; +// } +// } +//} +// +//void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { +// +// double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us +// +// //Op Flash +// for (SROpFlash &opf: rec.opflashes) { +// opf.time += SBNDFrame_us; +// opf.firsttime += SBNDFrame_us; +// } +// +// //OpT0 match to slice +// for (SRSlice &s: rec.slc) { +// s.opt0.time += SBNDFrame_us; +// } +//} void CAFMaker::FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time) { // Fix the flashes @@ -2587,27 +2587,27 @@ void CAFMaker::produce(art::Event& evt) noexcept { // TODO: TPC? - // SBND: Fix the Reference time in data depending on the stream - // For more information, see: - // https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 - - if (isRealData && (fDet == kSBND) && fSubRunPOT > 0) - { - // Fill trigger info - FillTriggerSBND(srsbndtiminginfo, srtrigger); - - // Shift timing reference frame - if (!std::isnan(rec.sbnd_frames.frameApplyAtCaf) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ - mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" - << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; - - //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match - SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - - //shift reference frame for PMT objects: opflash, opt0 - SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - } - } + //// SBND: Fix the Reference time in data depending on the stream + //// For more information, see: + //// https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 + + //if (isRealData && (fDet == kSBND) && fSubRunPOT > 0) + //{ + // // Fill trigger info + // FillTriggerSBND(srsbndtiminginfo, srtrigger); + + // // Shift timing reference frame + // if (!std::isnan(rec.sbnd_frames.frameApplyAtCaf) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ + // mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" + // << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; + // + // //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match + // SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + + // //shift reference frame for PMT objects: opflash, opt0 + // SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + // } + //} // Get metadata information for header unsigned int run = evt.run(); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 76c9a50b7..075044be5 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -192,13 +192,14 @@ namespace caf caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty) { - srsbndframe.timingType = frame.TimingType(); - srsbndframe.frameTdcCrtt1 = frame.FrameTdcCrtt1(); - srsbndframe.frameTdcBes = frame.FrameTdcBes(); - srsbndframe.frameTdcRwm = frame.FrameTdcRwm(); - srsbndframe.frameHltCrtt1 = frame.FrameHltCrtt1(); - srsbndframe.frameHltBeamGate = frame.FrameHltBeamGate(); - srsbndframe.frameApplyAtCaf = frame.FrameApplyAtCaf(); + std::cout << "FIX ME: FillSBNDFrameShiftInfo" << std::endl; + //srsbndframe.timingType = frame.TimingType(); + //srsbndframe.frameTdcCrtt1 = frame.FrameTdcCrtt1(); + //srsbndframe.frameTdcBes = frame.FrameTdcBes(); + //srsbndframe.frameTdcRwm = frame.FrameTdcRwm(); + //srsbndframe.frameHltCrtt1 = frame.FrameHltCrtt1(); + //srsbndframe.frameHltBeamGate = frame.FrameHltBeamGate(); + //srsbndframe.frameApplyAtCaf = frame.FrameApplyAtCaf(); } void FillSBNDTimingInfo(const sbnd::timing::TimingInfo &timing, From 47c8b21195768752976b13ec48013f14a7d2d0fd Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Wed, 12 Nov 2025 16:31:56 -0600 Subject: [PATCH 260/367] first commit of software trigger additions --- sbncode/CAFMaker/CAFMakerParams.h | 6 ++++++ sbncode/CAFMaker/CAFMaker_module.cc | 11 +++++++++++ sbncode/CAFMaker/CMakeLists.txt | 3 ++- sbncode/CAFMaker/FillTrigger.cxx | 6 +++++- sbncode/CAFMaker/FillTrigger.h | 3 +++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index a7740263e..bb089b0e4 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -357,6 +357,12 @@ namespace caf "" // sbnd }; + Atom SBNDSoftwareTriggerLabel{ + Name("SBNDSoftwareTriggerLabel"), + Comment("Label for software trigger producer"), + "" // sbnd + }; + Atom CRTPMTLabel { Name("CRTPMTLabel"), Comment("Label for the CRTPMT Matched variables from the crtpmt data product"), diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..b9410b4f8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1715,6 +1715,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector srsbndcrttracks; caf::SRSBNDFrameShiftInfo srsbndframeshiftinfo; caf::SRSBNDTimingInfo srsbndtiminginfo; + caf::SRSoftwareTrigger srsbndsofttrig; // Mapping of (feb, channel) to truth information (AuxDetSimChannel) -- filled for ICARUS std::map, sim::AuxDetSimChannel> crtsimchanmap; @@ -1799,6 +1800,15 @@ void CAFMaker::produce(art::Event& evt) noexcept { sbnd::timing::TimingInfo const& sbndtiminginfo(*sbndtiminginfo_handle); FillSBNDTimingInfo(sbndtiminginfo, srsbndtiminginfo); } + + art::Handle> sbndsofttrig_handle; + GetByLabelStrict(evt, fParams.SBNDSoftwareTriggerLabel(), sbndsofttrig_handle); + if (sbndsofttrig_handle.isValid()){ + const std::vector &sbndsofttrig = *sbndsofttrig_handle; + if (sbndsofttrig.size()==1){ + FillSoftwareTrigger(sbndsofttrig.at(0), srsbndsofttrig); + } + } } // Get all of the CRTPMT Matches @@ -2545,6 +2555,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { rec.nopflashes = srflashes.size(); rec.sbnd_frames = srsbndframeshiftinfo; rec.sbnd_timings = srsbndtiminginfo; + rec.soft_trig = srsbndsofttrig; if (fParams.FillTrueParticles()) { rec.true_particles = true_particles; diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index aa42cba8a..5dd4f2a8f 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -43,12 +43,13 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service larsim::Utils - larevt::SpaceCharge + larevt::SpaceCharge systematicstools::interface systematicstools::interpreters systematicstools::utility ${GENIE_LIB_LIST} nugen::EventGeneratorBase_GENIE + sbndaq_artdaq_core::sbndaq-artdaq-core_Obj_SBND ) cet_build_plugin ( CAFMaker art::module diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 908bf6559..17f1dbe8d 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -59,7 +59,11 @@ namespace caf triggerInfo.monpulse_sizes = *monpulseSizes; triggerInfo.num_pairs_over_threshold = *numPairs; triggerInfo.passed_trigger = *passedTrig; - } + void FillSoftwareTrigger(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo){ + caf_softInfo.npmts = softInfo.nAboveThreshold; + caf_softInfo.flash_peakpe = softInfo.peakPE; + caf_softInfo.flash_peaktime = softInfo.peaktime + softInfo.trig_ts*1e-3; + } } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index 1988b6876..848b9dac2 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -4,9 +4,11 @@ #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Trigger/BeamBits.h" #include "sbnanaobj/StandardRecord/SRTrigger.h" +#include "sbnanaobj/StandardRecord/SRSoftwareTrigger.h" #include "sbnanaobj/StandardRecord/SRSBNDTimingInfo.h" #include "lardataobj/RawData/TriggerData.h" #include "art/Framework/Principal/Handle.h" +#include "sbndaq-artdaq-core/Obj/SBND/pmtSoftwareTrigger.hh" #include @@ -27,6 +29,7 @@ namespace caf art::Handle const& numPairs, art::Handle const& passedTrig, caf::SRTrigger& triggerInfo); + void FillSoftwareTrigger(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo); } #endif From 1ef7e9c9ab12a585a88f94fd17a31425e62643c9 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Thu, 13 Nov 2025 09:52:44 -0600 Subject: [PATCH 261/367] add SBND to fill function name --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillTrigger.cxx | 2 +- sbncode/CAFMaker/FillTrigger.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index b9410b4f8..64393320c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1806,7 +1806,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (sbndsofttrig_handle.isValid()){ const std::vector &sbndsofttrig = *sbndsofttrig_handle; if (sbndsofttrig.size()==1){ - FillSoftwareTrigger(sbndsofttrig.at(0), srsbndsofttrig); + FillSoftwareTriggerSBND(sbndsofttrig.at(0), srsbndsofttrig); } } } diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 17f1dbe8d..093f78ebe 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -61,7 +61,7 @@ namespace caf triggerInfo.passed_trigger = *passedTrig; } - void FillSoftwareTrigger(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo){ + void FillSoftwareTriggerSBND(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo){ caf_softInfo.npmts = softInfo.nAboveThreshold; caf_softInfo.flash_peakpe = softInfo.peakPE; caf_softInfo.flash_peaktime = softInfo.peaktime + softInfo.trig_ts*1e-3; diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index 848b9dac2..bacdd8cd6 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -29,7 +29,7 @@ namespace caf art::Handle const& numPairs, art::Handle const& passedTrig, caf::SRTrigger& triggerInfo); - void FillSoftwareTrigger(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo); + void FillSoftwareTriggerSBND(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo); } #endif From e4cc10e116b0e28a3ff969bbc11486d41a2ff61a Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Thu, 13 Nov 2025 16:47:45 -0600 Subject: [PATCH 262/367] mistake in the cmakelist --- sbncode/CAFMaker/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index ff0411e46..b9ddd40f9 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -43,7 +43,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service - sbndcode_BlipUtils + #sbndcode_BlipUtils larsim::Utils larevt::SpaceCharge systematicstools::interface From 74f680a74058fc08304881055a19f3ab8ed21cbc Mon Sep 17 00:00:00 2001 From: Jamie Dyer Date: Thu, 13 Nov 2025 17:08:01 -0600 Subject: [PATCH 263/367] add factor of 2 to StoPipPip decay in HiggsMakeDecay_tool.cc. Needed bc the charged pions comprise two components of the pions' isospin triplet. --- .../EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc index 8de728c27..24f2fabe7 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc @@ -140,7 +140,7 @@ double PionPartialWidth(double pion_mass, double higs_mass, double mixing) { } double PiPlusPartialWidth(double higs_mass, double mixing) { - return PionPartialWidth(Constants::Instance().piplus_mass, higs_mass, mixing); + return 2*PionPartialWidth(Constants::Instance().piplus_mass, higs_mass, mixing); } double PiZeroPartialWidth(double higs_mass, double mixing) { From 0c6241963733b6cbe6000270f60a0181f4881111 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Thu, 13 Nov 2025 17:13:41 -0600 Subject: [PATCH 264/367] Updating include --- sbncode/CAFMaker/FillBlip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillBlip.h b/sbncode/CAFMaker/FillBlip.h index 501556c15..d08e0d5e7 100644 --- a/sbncode/CAFMaker/FillBlip.h +++ b/sbncode/CAFMaker/FillBlip.h @@ -2,7 +2,7 @@ #define CAF_FILLBLIP_H #include #include "sbnanaobj/StandardRecord/SRBlip.h" -#include "sbndcode/BlipRecoSBND/Utils/BlipUtils.h" +#include "sbnobj/SBND/Blip/BlipDataTypes.h" #include From 6853934b756b03ef489c325361d72adb9a8b1c02 Mon Sep 17 00:00:00 2001 From: Max Dubnowski <90648380+maxdubnowski@users.noreply.github.com> Date: Fri, 14 Nov 2025 12:45:33 -0500 Subject: [PATCH 265/367] Add VP873Offset to CAFMaker --- sbncode/CAFMaker/FillExposure.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/CAFMaker/FillExposure.cxx b/sbncode/CAFMaker/FillExposure.cxx index 195884698..b6bd758a9 100644 --- a/sbncode/CAFMaker/FillExposure.cxx +++ b/sbncode/CAFMaker/FillExposure.cxx @@ -26,6 +26,7 @@ namespace caf single_store.FOM = info.FOM; single_store.VP873 = info.VP873; single_store.VP875Offset = info.VP875Offset; + single_store.VP873Offset = info.VP873Offset; single_store.HP875Offset = info.HP875Offset; single_store.VPTG1Offset = info.VPTG1Offset; single_store.HPTG1Offset = info.HPTG1Offset; From 3c70d8e4500bddee226ffcb530403208768463a1 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Fri, 14 Nov 2025 12:01:35 -0600 Subject: [PATCH 266/367] Hot fix to how we fill the best plane variables for showers --- sbncode/CAFMaker/FillReco.cxx | 45 ++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 76c9a50b7..8d65925d3 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -395,11 +395,43 @@ namespace caf // It's sth like this but not quite. And will need to pass a simb::MCtruth object vtx position anyway. // srshower.conversion_gap = (shower.ShowerStart() - vertex.Position()).Mag(); - if(shower.best_plane() != -999){ - srshower.bestplane = shower.best_plane(); - srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; - srshower.bestplane_energy = srshower.plane[shower.best_plane()].energy; - } + for(int p = 0; p < 3; ++p) srshower.plane[p].nHits = 0; + for (auto const& hit:hits) ++srshower.plane[hit->WireID().Plane].nHits; + + int bestplane_for_energy = -999; + int mosthits = -1; + for(int p = 0; p < 3; ++p) + { + if((int)srshower.plane[p].nHits > mosthits) + { + mosthits = srshower.plane[p].nHits; + bestplane_for_energy = p; + } + } + + if(bestplane_for_energy != -999) + { + srshower.bestplane_for_energy = bestplane_for_energy; + srshower.bestplane_energy = srshower.plane[bestplane_for_energy].energy; + } + + if(shower.best_plane() != -999 && srshower.plane[shower.best_plane()].dEdx != -999) + { + srshower.bestplane_for_dedx = shower.best_plane(); + srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; + } + else + { + for(int p = 2; p >= 0; --p) + { + if(srshower.plane[p].dEdx != -999) + { + srshower.bestplane_for_dedx = p; + srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; + break; + } + } + } if(shower.has_open_angle()) srshower.open_angle = shower.OpenAngle(); @@ -422,9 +454,6 @@ namespace caf srshower.end = shower.ShowerStart()+ (shower.Length() * shower.Direction()); } - for(int p = 0; p < 3; ++p) srshower.plane[p].nHits = 0; - for (auto const& hit:hits) ++srshower.plane[hit->WireID().Plane].nHits; - for (geo::PlaneGeo const& plane: wireReadout.Iterate()) { const double angleToVert(wireReadout.WireAngleToVertical(plane.View(), plane.ID()) - 0.5*M_PI); From 8a0969654487383bcf607721a9b1211409f37713 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Mon, 17 Nov 2025 03:46:02 -0600 Subject: [PATCH 267/367] Make changes ICARUS friendly --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillReco.cxx | 60 ++++++++++++++++++----------- sbncode/CAFMaker/FillReco.h | 1 + 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..c4aef400c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2481,7 +2481,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { assert(thisShower.size() == 1); SRShower& shw = pfp.shw; - FillShowerVars(*thisShower[0], vertex, fmShowerHit.at(iPart), wireReadout, producer, shw); + FillShowerVars(*thisShower[0], vertex, fmShowerHit.at(iPart), wireReadout, producer, shw, fDet); // We may have many residuals per shower depending on how many showers ar in the slice if (fmShowerRazzle.isValid() && fmShowerRazzle.at(iPart).size()==1) { diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 8d65925d3..e7ee532b1 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -375,6 +375,7 @@ namespace caf const geo::WireReadoutGeom& wireReadout, unsigned producer, caf::SRShower &srshower, + Det_t det, bool allowEmpty) { @@ -398,38 +399,51 @@ namespace caf for(int p = 0; p < 3; ++p) srshower.plane[p].nHits = 0; for (auto const& hit:hits) ++srshower.plane[hit->WireID().Plane].nHits; - int bestplane_for_energy = -999; - int mosthits = -1; - for(int p = 0; p < 3; ++p) + if(det == kSBND) { - if((int)srshower.plane[p].nHits > mosthits) + int bestplane_for_energy = -999; + int mosthits = -1; + for(int p = 0; p < 3; ++p) { - mosthits = srshower.plane[p].nHits; - bestplane_for_energy = p; + if((int)srshower.plane[p].nHits > mosthits) + { + mosthits = srshower.plane[p].nHits; + bestplane_for_energy = p; + } } - } - if(bestplane_for_energy != -999) - { - srshower.bestplane_for_energy = bestplane_for_energy; - srshower.bestplane_energy = srshower.plane[bestplane_for_energy].energy; - } + if(bestplane_for_energy != -999) + { + srshower.bestplane_for_energy = bestplane_for_energy; + srshower.bestplane_energy = srshower.plane[bestplane_for_energy].energy; + } - if(shower.best_plane() != -999 && srshower.plane[shower.best_plane()].dEdx != -999) - { - srshower.bestplane_for_dedx = shower.best_plane(); - srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; + if(shower.best_plane() != -999 && srshower.plane[shower.best_plane()].dEdx != -999) + { + srshower.bestplane_for_dedx = shower.best_plane(); + srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; + } + else + { + for(int p = 2; p >= 0; --p) + { + if(srshower.plane[p].dEdx != -999) + { + srshower.bestplane_for_dedx = p; + srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; + break; + } + } + } } else { - for(int p = 2; p >= 0; --p) + if(shower.best_plane() != -999) { - if(srshower.plane[p].dEdx != -999) - { - srshower.bestplane_for_dedx = p; - srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; - break; - } + srshower.bestplane_for_energy = shower.best_plane(); + srshower.bestplane_for_dedx = shower.best_plane(); + srshower.bestplane_dEdx = srshower.plane[shower.best_plane()].dEdx; + srshower.bestplane_energy = srshower.plane[shower.best_plane()].energy; } } diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 85d0a3e67..e6199d690 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -69,6 +69,7 @@ namespace caf const geo::WireReadoutGeom& wireReadout, unsigned producer, caf::SRShower& srshower, + Det_t det, bool allowEmpty = false); void FillShowerRazzle(const art::Ptr razzle, From e7c41a837d0b8af1c4f3597ae2884620174fe296 Mon Sep 17 00:00:00 2001 From: justinjmueller Date: Wed, 19 Nov 2025 10:03:27 -0600 Subject: [PATCH 268/367] Update Supera submodule to point at updates to hyper-parameters for SBND Fall Production --- sbncode/Supera | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Supera b/sbncode/Supera index 26e2abb92..9e7b533d4 160000 --- a/sbncode/Supera +++ b/sbncode/Supera @@ -1 +1 @@ -Subproject commit 26e2abb92fe757510ca0a7e54444e8018aa721f7 +Subproject commit 9e7b533d44236c64ddc17748e92dbd9d2fbe0fae From ee878b1c039807c1a420aac3d9f9bbe7110d5bd1 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Wed, 19 Nov 2025 13:17:48 -0600 Subject: [PATCH 269/367] add sim energy deposit info and light calo info --- sbncode/CAFMaker/CAFMakerParams.h | 12 ++++++++ sbncode/CAFMaker/CAFMaker_module.cc | 47 +++++++++++++++++++++++++++++ sbncode/CAFMaker/CMakeLists.txt | 1 + sbncode/CAFMaker/FillReco.cxx | 11 +++++++ sbncode/CAFMaker/FillReco.h | 5 ++- 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index a7740263e..b6413459d 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -465,6 +465,12 @@ namespace caf "simdrift" }; + Atom SimEnergyDepositLabel { + Name("SimEnergyDepositLabel"), + Comment("Label of input sim::SimEnergyDeposit objects."), + art::InputTag("ionandscint", "priorSCE","G4") + }; + Atom FillTrueParticles { Name("FillTrueParticles"), Comment("Whether to fill the rec.true_particles branch. The information on true particles" @@ -616,6 +622,12 @@ namespace caf Comment("Label of CVN scores."), "cvn" }; + + Atom LightCaloLabel { + Name("LightCaloLabel"), + Comment("Label of light calorimetry producer"), + "lightcalo" + }; }; } diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 7baf6ef0c..dd2bed86e 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -97,6 +97,7 @@ #include "lardataobj/RecoBase/MCSFitResult.h" #include "lardataobj/RecoBase/Cluster.h" #include "lardataobj/AnalysisBase/MVAOutput.h" +#include "lardataobj/Simulation/SimEnergyDeposit.h" #include "nusimdata/SimulationBase/MCFlux.h" #include "nusimdata/SimulationBase/MCTruth.h" @@ -119,6 +120,7 @@ #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" #include "sbnobj/Common/Reco/CorrectedOpFlashTiming.h" +#include "sbnobj/Common/Reco/LightCalo.h" #include "sbnobj/SBND/Timing/TimingInfo.hh" #include "sbnobj/SBND/Timing/FrameShiftInfo.hh" @@ -1422,6 +1424,15 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::fill_ptr_vector(simchannels, simchannel_handle); } + // get sim energy deposits if they're there + ::art::Handle> sed_handle; + GetByLabelStrict(evt, fParams.SimEnergyDepositLabel().encode(), sed_handle); + + std::vector> seds; + if (sed_handle.isValid()){ + art::fill_ptr_vector(seds, sed_handle); + } + art::Handle> mcflux_handle; GetByLabelStrict(evt, std::string("generator"), mcflux_handle); @@ -1614,6 +1625,34 @@ void CAFMaker::produce(art::Event& evt) noexcept { } // end for fm } // end for i (mctruths) + + if (!isRealData && sed_handle.isValid()){ + art::ServiceHandle pi_serv; + + srtruthbranch.dep.reserve(mctruths.size()); + for (size_t n=0; nTrackID(); + + art::Ptr mctruth = pi_serv->TrackIdToMCTruth_P(trackID); + auto it = std::find(mctruths.begin(), mctruths.end(), mctruth); + if (it == mctruths.end()) continue; + + auto idx = std::distance(mctruths.begin(), it); + srtruthbranch.dep.at(idx).energy += sed->Energy()*1e-3; // GeV + srtruthbranch.dep.at(idx).photons += sed->NumPhotons(); + srtruthbranch.dep.at(idx).electrons += sed->NumElectrons(); + } + } + // get the number of events generated in the gen stage unsigned n_gen_evt = 0; for (const art::ProcessConfiguration &process: evt.processHistory()) { @@ -1995,6 +2034,13 @@ void CAFMaker::produce(art::Event& evt) noexcept { if (fmCorrectedOpFlash.isValid()) slcCorrectedOpFlash = fmCorrectedOpFlash.at(0); + art::FindOneP foLightCalo = + FindOnePStrict(sliceList,evt, + fParams.LightCaloLabel() + slice_tag_suff); + const sbn::LightCalo *slcLightCalo = nullptr; + if (foLightCalo.isValid()) { + slcLightCalo = foLightCalo.at(0).get(); + } art::FindOneP foCVNResult = FindOnePStrict(sliceList, evt, @@ -2250,6 +2296,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillSliceCRUMBS(slcCRUMBS, recslc); FillSliceOpT0Finder(slcOpT0, recslc); FillSliceBarycenter(slcHits, slcSpacePoints, recslc); + FillSliceLightCalo(slcLightCalo, recslc); FillTPCPMTBarycenterMatch(barycenterMatch, recslc); FillCorrectedOpFlashTiming(slcCorrectedOpFlash, recslc); FillCVNScores(cvnResult, recslc); diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index aa42cba8a..e98e5672c 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -25,6 +25,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker caf_RecoUtils lardataobj::AnalysisBase lardataobj::RecoBase + lardataobj::Simulation larrecodnn::CVN_func larcorealg::Geometry larcore::Geometry_Geometry_service diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 76c9a50b7..81f3f3429 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -634,6 +634,17 @@ namespace caf } } + void FillSliceLightCalo(const sbn::LightCalo *lightcalo, + caf::SRSlice &slice) + { + if (lightcalo != nullptr) { + slice.lightcalo.charge = lightcalo->charge; + slice.lightcalo.light = lightcalo->light; + slice.lightcalo.energy = lightcalo->energy; + slice.lightcalo.bestplane = lightcalo->bestplane; + } + } + void FillSliceBarycenter(const std::vector> &inputHits, const std::vector> &inputPoints, caf::SRSlice &slice) diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 85d0a3e67..8df3d2e75 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -47,7 +47,7 @@ #include "sbnobj/Common/PMT/Data/PMTBeamSignal.hh" #include "sbnobj/SBND/Timing/TimingInfo.hh" #include "sbnobj/SBND/Timing/FrameShiftInfo.hh" - +#include "sbnobj/Common/Reco/LightCalo.h" #include "nusimdata/SimulationBase/MCParticle.h" #include "nusimdata/SimulationBase/MCTruth.h" @@ -108,6 +108,9 @@ namespace caf void FillSliceOpT0Finder(const std::vector> &opt0_v, caf::SRSlice &slice); + void FillSliceLightCalo(const sbn::LightCalo *lightcalo, + caf::SRSlice& slice); + void FillSliceBarycenter(const std::vector> &inputHits, const std::vector> &inputPoints, caf::SRSlice &slice); From 97b9db8c5bb10304ca4646126eb77ddf50b8af29 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Thu, 20 Nov 2025 08:57:36 -0600 Subject: [PATCH 270/367] Fixing comments that aren't tabs --- sbncode/CAFMaker/CAFMakerParams.h | 2 +- sbncode/CAFMaker/CAFMaker_module.cc | 1 - sbncode/CAFMaker/FillBlip.cxx | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index ce9bfd20f..e69e50208 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -623,7 +623,7 @@ namespace caf "cvn" }; Atom fBlipTag { Name("BlipTag"), - Comment("Provide a string to label the blip input"), "reco2:Blip:BlipReco" + Comment("Provide a string to label the blip input"), "blipreco" }; diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index b822e7910..09cb0e205 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -284,7 +284,6 @@ class CAFMaker : public art::EDProducer { int fGenieEvtRec_brStdHepLd [250] = {0}; ////< Last daughter int fGenieEvtRec_brStdHepFm [250] = {0}; ////< First mother int fGenieEvtRec_brStdHepLm [250] = {0}; ////< Last mother - //std::string fBlipTag; flat::Flat* fFlatRecord = 0; flat::Flat* fFlatRecordb = 0; diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index fa300f743..8857a060d 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -55,7 +55,7 @@ namespace caf CAF_Blip.truthBlip.LeadG4PDG =LarBlip.truth.LeadG4PDG; CAF_Blip.truthBlip.LeadCharge =LarBlip.truth.LeadCharge; CAF_Blip.truthBlip.Position =LarBlip.truth.Position; - CAF_Blip.truthBlip.Energy = CAF_Blip.truthBlip.Energy/1000.; //convert to GeV + CAF_Blip.truthBlip.Energy = CAF_Blip.truthBlip.Energy/1000.; //convert to GeV } void FillBlipRealtedHitCluster(blip::Blip& LarBlip, caf::SRBlip &CAF_Blip) @@ -69,7 +69,7 @@ namespace caf CAF_Blip.clusters[iPlane].CenterWire = LarBlip.clusters[iPlane].CenterWire; CAF_Blip.clusters[iPlane].isTruthMatched = LarBlip.clusters[iPlane].isTruthMatched; CAF_Blip.clusters[iPlane].isMerged = LarBlip.clusters[iPlane].isMerged; - CAF_Blip.clusters[iPlane].isMatched = LarBlip.clusters[iPlane].isMatched; + CAF_Blip.clusters[iPlane].isMatched = LarBlip.clusters[iPlane].isMatched; CAF_Blip.clusters[iPlane].DeadWireSep = LarBlip.clusters[iPlane].DeadWireSep; CAF_Blip.clusters[iPlane].Cryostat = LarBlip.clusters[iPlane].Cryostat; CAF_Blip.clusters[iPlane].TPC = LarBlip.clusters[iPlane].TPC; From 44e03a47610b9f31c2eeff75094e2d3bad7cb140 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Thu, 20 Nov 2025 09:55:23 -0600 Subject: [PATCH 271/367] Fixing indentation --- sbncode/CAFMaker/FillBlip.cxx | 72 +++++++++++++++++------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 8857a060d..44b734b9e 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -63,42 +63,42 @@ namespace caf int NumPlanes = sizeof(LarBlip.clusters)/sizeof(LarBlip.clusters[0]); for(int iPlane=0; iPlane Date: Fri, 21 Nov 2025 09:06:14 -0600 Subject: [PATCH 272/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce67d433c..0720a9ddb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.12.02 LANGUAGES CXX) +project(sbncode VERSION 10.14.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index e3a7fc034..755bb2211 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,13 +254,13 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_12_02 - -sbnalg v10_12_02 - +larsoft v10_14_00 - +sbnalg v10_14_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_09 - -geant4reweight v01_20_13 - +nusystematics v1_05_10 - +geant4reweight v01_20_14 - cetmodules v3_24_01 - only_for_build end_product_list #################################### From 340f04319eecff328fb911c8668f6a420427f549 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Wed, 26 Nov 2025 13:14:10 -0600 Subject: [PATCH 273/367] Update CafMaker for refactoring frameshift module --- sbncode/CAFMaker/CAFMaker_module.cc | 115 +++++++++++++--------------- sbncode/CAFMaker/FillReco.cxx | 24 ++++-- sbncode/CAFMaker/FillTrigger.cxx | 22 ++++-- 3 files changed, 85 insertions(+), 76 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 5e0217b88..8b1f8d949 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -327,8 +327,8 @@ class CAFMaker : public art::EDProducer { void FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time); void FixCRTReferenceTimes(StandardRecord &rec, double CRTT0_reference_time, double CRTT1_reference_time); - //void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const; - //void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const; + void SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const; + void SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const; /// Equivalent of FindManyP except a return that is !isValid() prints a /// messsage and aborts if StrictMode is true. @@ -516,43 +516,43 @@ void CAFMaker::BlindEnergyParameters(StandardRecord* brec) { } } -//void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { -// -// //CRT Space Point -// for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ -// sp.time += SBNDFrame; //ns -// } -// -// //CRT Track -// for (SRSBNDCRTTrack &trk: rec.sbnd_crt_tracks){ -// trk.time += SBNDFrame; //ns -// } -// -// //TODO: CRT Space Point and Track Match -// for (SRSlice &slc: rec.slc){ -// for (SRPFP &pfp: slc.reco.pfp){ -// if(!std::isnan(pfp.trk.crtspacepoint.score)) pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; -// -// if(!std::isnan(pfp.trk.crtsbndtrack.score)) pfp.trk.crtsbndtrack.track.time += SBNDFrame; -// } -// } -//} -// -//void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { -// -// double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us -// -// //Op Flash -// for (SROpFlash &opf: rec.opflashes) { -// opf.time += SBNDFrame_us; -// opf.firsttime += SBNDFrame_us; -// } -// -// //OpT0 match to slice -// for (SRSlice &s: rec.slc) { -// s.opt0.time += SBNDFrame_us; -// } -//} +void CAFMaker::SBNDShiftCRTReference(StandardRecord &rec, double SBNDFrame) const { + + //CRT Space Point + for (SRCRTSpacePoint &sp: rec.crt_spacepoints){ + sp.time += SBNDFrame; //ns + } + + //CRT Track + for (SRSBNDCRTTrack &trk: rec.sbnd_crt_tracks){ + trk.time += SBNDFrame; //ns + } + + //TODO: CRT Space Point and Track Match + for (SRSlice &slc: rec.slc){ + for (SRPFP &pfp: slc.reco.pfp){ + if(!std::isnan(pfp.trk.crtspacepoint.score)) pfp.trk.crtspacepoint.spacepoint.time += SBNDFrame; + + if(!std::isnan(pfp.trk.crtsbndtrack.score)) pfp.trk.crtsbndtrack.track.time += SBNDFrame; + } + } +} + +void CAFMaker::SBNDShiftPMTReference(StandardRecord &rec, double SBNDFrame) const { + + double SBNDFrame_us = SBNDFrame / 1000.0; //convert ns to us + + //Op Flash + for (SROpFlash &opf: rec.opflashes) { + opf.time += SBNDFrame_us; + opf.firsttime += SBNDFrame_us; + } + + //OpT0 match to slice + for (SRSlice &s: rec.slc) { + s.opt0.time += SBNDFrame_us; + } +} void CAFMaker::FixPMTReferenceTimes(StandardRecord &rec, double PMT_reference_time) { // Fix the flashes @@ -2586,28 +2586,21 @@ void CAFMaker::produce(art::Event& evt) noexcept { FixPMTReferenceTimes(rec, PMT_reference_time); // TODO: TPC? - - //// SBND: Fix the Reference time in data depending on the stream - //// For more information, see: - //// https://sbn-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=43090 - - //if (isRealData && (fDet == kSBND) && fSubRunPOT > 0) - //{ - // // Fill trigger info - // FillTriggerSBND(srsbndtiminginfo, srtrigger); - - // // Shift timing reference frame - // if (!std::isnan(rec.sbnd_frames.frameApplyAtCaf) && (rec.sbnd_frames.frameApplyAtCaf != 0.0)){ - // mf::LogInfo("CAFMaker") << "Setting Reference Timing for timing object in SBND \n" - // << " Shift Apply At Caf Level = " << rec.sbnd_frames.frameApplyAtCaf << " ns\n"; - // - // //shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match - // SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - - // //shift reference frame for PMT objects: opflash, opt0 - // SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - // } - //} + + + if (isRealData && (fDet == kSBND)) + { + // Fill trigger info + FillTriggerSBND(srsbndtiminginfo, srtrigger); + + //// Legacy: Timing correction is being done at decoding/reconstruction level + //// SBND: Fix the Reference time in data depending on the stream + ////shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match + //SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + + ////shift reference frame for PMT objects: opflash, opt0 + //SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); + } // Get metadata information for header unsigned int run = evt.run(); diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 075044be5..6203f2675 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -192,14 +192,22 @@ namespace caf caf::SRSBNDFrameShiftInfo &srsbndframe, bool allowEmpty) { - std::cout << "FIX ME: FillSBNDFrameShiftInfo" << std::endl; - //srsbndframe.timingType = frame.TimingType(); - //srsbndframe.frameTdcCrtt1 = frame.FrameTdcCrtt1(); - //srsbndframe.frameTdcBes = frame.FrameTdcBes(); - //srsbndframe.frameTdcRwm = frame.FrameTdcRwm(); - //srsbndframe.frameHltCrtt1 = frame.FrameHltCrtt1(); - //srsbndframe.frameHltBeamGate = frame.FrameHltBeamGate(); - //srsbndframe.frameApplyAtCaf = frame.FrameApplyAtCaf(); + srsbndframe.frameCrtt1 = frame.FrameCrtt1(); + srsbndframe.timingTypeCrtt1 = frame.TimingTypeCrtt1(); + srsbndframe.timingChannelCrtt1 = frame.TimingChannelCrtt1(); + + srsbndframe.frameBeamGate = frame.FrameBeamGate(); + srsbndframe.timingTypeBeamGate = frame.TimingTypeBeamGate(); + srsbndframe.timingChannelBeamGate = frame.TimingChannelBeamGate(); + + srsbndframe.frameEtrig = frame.FrameEtrig(); + srsbndframe.timingTypeEtrig = frame.TimingTypeEtrig(); + srsbndframe.timingChannelEtrig = frame.TimingChannelEtrig(); + + srsbndframe.frameDefault = frame.FrameDefault(); + srsbndframe.timingTypeDefault = frame.TimingTypeDefault(); + srsbndframe.timingChannelDefault = frame.TimingChannelDefault(); + } void FillSBNDTimingInfo(const sbnd::timing::TimingInfo &timing, diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 908bf6559..d7753fce7 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -39,13 +39,21 @@ namespace caf } void FillTriggerSBND(caf::SRSBNDTimingInfo& timingInfo, caf::SRTrigger& triggerInfo){ - - triggerInfo.global_trigger_time = timingInfo.hltEtrig; - triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; - std::cout << "triggerInfo.global_trigger_det_time: " << triggerInfo.global_trigger_det_time << std::endl; - std::cout << "triggerInfo.beam_gate_det_time: " << triggerInfo.beam_gate_det_time << std::endl; - double diff_ts = triggerInfo.global_trigger_det_time - triggerInfo.beam_gate_det_time; - std::cout << "diff_ts: " << diff_ts << std::endl; + + if (timingInfo.hltEtrig != std::numeric_limits::max()) triggerInfo.global_trigger_time = timingInfo.hltEtrig; + if (timingInfo.hltBeamGate != std::numeric_limits::max()) triggerInfo.beam_gate_time_abs = timingInfo.hltBeamGate; + + double diff_ts = std::numeric_limits::max(); + + if ((triggerInfo.global_trigger_time != std::numeric_limits::max()) & (triggerInfo.beam_gate_time_abs != std::numeric_limits::max())){ + + if (triggerInfo.global_trigger_time > triggerInfo.beam_gate_time_abs){ + diff_ts = triggerInfo.global_trigger_time - triggerInfo.beam_gate_time_abs; + } + else{ + diff_ts = (triggerInfo.beam_gate_time_abs - triggerInfo.global_trigger_time)*(double)-1; + } + } triggerInfo.trigger_within_gate = diff_ts; } From e5bf1347f84b648519088f3bf45c168d8faf20bd Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 28 Nov 2025 05:53:18 -0600 Subject: [PATCH 274/367] Adds guards to Geant4WeightCalc::GetWeight and sbn::GetWallCross Geant4WeightCalc::GetWeight gets a guard against trajectory points outside the world volume sbn::GetWallCross gets a guard against lines that don't intersect the detector --- sbncode/CAFMaker/FillTrue.cxx | 22 ++++++++++++++++++- .../Calculators/Geant4/Geant4WeightCalc.cxx | 3 +++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index bbc936e88..419ad7540 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -1260,7 +1260,27 @@ caf::Wall_t caf::GetWallCross(const geo::BoxBoundedGeo &volume, const TVector3 p TVector3 direction = (p1 - p0) * ( 1. / (p1 - p0).Mag()); std::vector intersections = volume.GetIntersections(p0, direction); - assert(intersections.size() == 2); + //assert(intersections.size() == 2); + /* + * There are either infinity, two, or one, or zero intersection points. + * As per larcorealg/Geometry/BoxBoundedGeo.h documentation: + * If the return std::vector is empty the trajectory does not intersect with the box. + * Normally the return value should have one (if the trajectory originates in the box) or two (else) entries. + * If the return value has two entries the first represents the entry point and the second the exit point + */ + switch( intersections.size() ) { + case 0: // Set kWallNone and return + return caf::kWallNone; + break; + case 1: // Set the second intersection to be the same as the first, and fall through + intersections.emplace_back(intersections.front()); + [[fallthrough]]; + case 2: + break; + default: // There are infinity points to consider. Just use the first two. + intersections.resize(2); + break; + } // get the intersection point closer to p0 int intersection_i = ((intersections[0] - p0).Mag() < (intersections[1] - p0).Mag()) ? 0 : 1; diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index ec9d8cc6e..15dbbbb4b 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -297,6 +297,9 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { double Z = p.Position(i).Z(); geo::Point_t testpoint1 { X, Y, Z }; const TGeoMaterial* testmaterial1 = fGeometryService->Material( testpoint1 ); + if( ! testmaterial1 || testmaterial1 == nullptr ) { + break; // The trajectory point is outside the world, or the geometry service is unable to handle the point + } //For now, just going to reweight the points within the LAr of the TPC // TODO check if this is right if ( !strcmp( testmaterial1->GetName(), "LAr" ) ){ From a44f4c69bc98bb076533e3425a39f4abae2c2d60 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Sat, 29 Nov 2025 12:54:57 -0600 Subject: [PATCH 275/367] part of general tvector3 replacement --- sbncode/CAFMaker/FillBlip.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 44b734b9e..636264312 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -24,7 +24,7 @@ namespace caf NewBlip.ProxTrkDist = CurrentBlip.ProxTrkDist; NewBlip.ProxTrkID = CurrentBlip.ProxTrkID; NewBlip.inCylinder = CurrentBlip.inCylinder; - NewBlip.Position = CurrentBlip.Position; + NewBlip.Position.SetXYZ(CurrentBlip.Position.X(), CurrentBlip.Position.Y(), CurrentBlip.Position.Z()); NewBlip.SigmaYZ = CurrentBlip.SigmaYZ; NewBlip.dX = CurrentBlip.dX; NewBlip.dYZ = CurrentBlip.dYZ; @@ -54,7 +54,7 @@ namespace caf CAF_Blip.truthBlip.LeadG4Index =LarBlip.truth.LeadG4Index; CAF_Blip.truthBlip.LeadG4PDG =LarBlip.truth.LeadG4PDG; CAF_Blip.truthBlip.LeadCharge =LarBlip.truth.LeadCharge; - CAF_Blip.truthBlip.Position =LarBlip.truth.Position; + CAF_Blip.truthBlip.Position.SetXYZ(LarBlip.truth.Position.X(), LarBlip.truth.Position.Y(), LarBlip.truth.Position.Z()); CAF_Blip.truthBlip.Energy = CAF_Blip.truthBlip.Energy/1000.; //convert to GeV } From b6b0f4fef9bed535581361842d7f18e95e11e73e Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Sat, 29 Nov 2025 13:07:41 -0600 Subject: [PATCH 276/367] Missed one cmake list update --- sbncode/CAFMaker/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index b9ddd40f9..820e43fbc 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -39,11 +39,10 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker sbnobj::Common_Trigger sbnobj::SBND_CRT sbnobj::SBND_Timing - sbndobj_BlipDataTypes + sbnobj::SBND_Blip lardataalg::DetectorInfo art::Framework_Services_System_TriggerNamesService_service sbncode_Metadata_MetadataSBN_service - #sbndcode_BlipUtils larsim::Utils larevt::SpaceCharge systematicstools::interface From ddda71aeea6af98e115a53878f1acde75a7f9e3b Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Sun, 30 Nov 2025 16:32:01 -0600 Subject: [PATCH 277/367] Adjusting fillBlip to account for removed variables --- sbncode/CAFMaker/FillBlip.cxx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 636264312..4f56c945a 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -40,12 +40,10 @@ namespace caf void FillMCTruthBlip( blip::Blip& LarBlip, caf::SRBlip &CAF_Blip ) { - //CAF_Blip.truthBlip = LarBlip.truth; CAF_Blip.truthBlip.ID = LarBlip.truth.ID; CAF_Blip.truthBlip.Cryostat =LarBlip.truth.Cryostat; CAF_Blip.truthBlip.TPC =LarBlip.truth.TPC; CAF_Blip.truthBlip.Time =LarBlip.truth.Time; - CAF_Blip.truthBlip.TimeTick =LarBlip.truth.TimeTick; CAF_Blip.truthBlip.DriftTime =LarBlip.truth.DriftTime; CAF_Blip.truthBlip.Energy =LarBlip.truth.Energy; CAF_Blip.truthBlip.DepElectrons =LarBlip.truth.DepElectrons; @@ -68,7 +66,6 @@ namespace caf CAF_Blip.clusters[iPlane].CenterChan = LarBlip.clusters[iPlane].CenterChan; CAF_Blip.clusters[iPlane].CenterWire = LarBlip.clusters[iPlane].CenterWire; CAF_Blip.clusters[iPlane].isTruthMatched = LarBlip.clusters[iPlane].isTruthMatched; - CAF_Blip.clusters[iPlane].isMerged = LarBlip.clusters[iPlane].isMerged; CAF_Blip.clusters[iPlane].isMatched = LarBlip.clusters[iPlane].isMatched; CAF_Blip.clusters[iPlane].DeadWireSep = LarBlip.clusters[iPlane].DeadWireSep; CAF_Blip.clusters[iPlane].Cryostat = LarBlip.clusters[iPlane].Cryostat; @@ -82,8 +79,6 @@ namespace caf CAF_Blip.clusters[iPlane].SigmaCharge = LarBlip.clusters[iPlane].SigmaCharge; CAF_Blip.clusters[iPlane].TimeTick = LarBlip.clusters[iPlane].TimeTick; CAF_Blip.clusters[iPlane].Time = LarBlip.clusters[iPlane].Time; - CAF_Blip.clusters[iPlane].StartHitTime = LarBlip.clusters[iPlane].StartHitTime; - CAF_Blip.clusters[iPlane].EndHitTime = LarBlip.clusters[iPlane].EndHitTime; CAF_Blip.clusters[iPlane].StartTime = LarBlip.clusters[iPlane].StartTime; CAF_Blip.clusters[iPlane].EndTime = LarBlip.clusters[iPlane].EndTime; CAF_Blip.clusters[iPlane].Timespan = LarBlip.clusters[iPlane].Timespan; From 05878a398c6e87d3422d8b0fba702f64eaf1025c Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Sun, 30 Nov 2025 17:20:37 -0600 Subject: [PATCH 278/367] change to camelcase --- sbncode/CAFMaker/FillBlip.cxx | 98 +++++++++++++++++------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 4f56c945a..30194b19b 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -11,21 +11,21 @@ namespace caf caf::SRBlip NewBlip; NewBlip.ID = CurrentBlip.ID; NewBlip.isValid = CurrentBlip.isValid; - NewBlip.Cryostat = CurrentBlip.Cryostat; + NewBlip.cryostat = CurrentBlip.Cryostat; NewBlip.TPC = CurrentBlip.TPC; - NewBlip.NPlanes = CurrentBlip.NPlanes; - NewBlip.MaxWireSpan = CurrentBlip.MaxWireSpan; - NewBlip.TimeTick = CurrentBlip.TimeTick; - NewBlip.Time = CurrentBlip.Time; - NewBlip.Charge = CurrentBlip.Charge; - NewBlip.Energy = CurrentBlip.Energy/1000.; //convert to GeV - NewBlip.EnergyESTAR = CurrentBlip.EnergyESTAR/1000.; //convert to GeV - NewBlip.EnergyPSTAR = CurrentBlip.EnergyPSTAR/1000.; //convert to GeV - NewBlip.ProxTrkDist = CurrentBlip.ProxTrkDist; - NewBlip.ProxTrkID = CurrentBlip.ProxTrkID; + NewBlip.nPlanes = CurrentBlip.NPlanes; + NewBlip.maxWireSpan = CurrentBlip.MaxWireSpan; + NewBlip.timeTick = CurrentBlip.TimeTick; + NewBlip.time = CurrentBlip.Time; + NewBlip.charge = CurrentBlip.Charge; + NewBlip.energy = CurrentBlip.Energy/1000.; //convert to GeV + NewBlip.energyESTAR = CurrentBlip.EnergyESTAR/1000.; //convert to GeV + NewBlip.energyPSTAR = CurrentBlip.EnergyPSTAR/1000.; //convert to GeV + NewBlip.proxTrkDist = CurrentBlip.ProxTrkDist; + NewBlip.proxTrkID = CurrentBlip.ProxTrkID; NewBlip.inCylinder = CurrentBlip.inCylinder; - NewBlip.Position.SetXYZ(CurrentBlip.Position.X(), CurrentBlip.Position.Y(), CurrentBlip.Position.Z()); - NewBlip.SigmaYZ = CurrentBlip.SigmaYZ; + NewBlip.position.SetXYZ(CurrentBlip.Position.X(), CurrentBlip.Position.Y(), CurrentBlip.Position.Z()); + NewBlip.sigmaYZ = CurrentBlip.SigmaYZ; NewBlip.dX = CurrentBlip.dX; NewBlip.dYZ = CurrentBlip.dYZ; if(CurrentBlip.truth.ID >= 0 ) //MC Blip @@ -41,19 +41,19 @@ namespace caf void FillMCTruthBlip( blip::Blip& LarBlip, caf::SRBlip &CAF_Blip ) { CAF_Blip.truthBlip.ID = LarBlip.truth.ID; - CAF_Blip.truthBlip.Cryostat =LarBlip.truth.Cryostat; + CAF_Blip.truthBlip.cryostat =LarBlip.truth.Cryostat; CAF_Blip.truthBlip.TPC =LarBlip.truth.TPC; - CAF_Blip.truthBlip.Time =LarBlip.truth.Time; - CAF_Blip.truthBlip.DriftTime =LarBlip.truth.DriftTime; - CAF_Blip.truthBlip.Energy =LarBlip.truth.Energy; - CAF_Blip.truthBlip.DepElectrons =LarBlip.truth.DepElectrons; - CAF_Blip.truthBlip.NumElectrons =LarBlip.truth.NumElectrons; - CAF_Blip.truthBlip.LeadG4ID =LarBlip.truth.LeadG4ID; - CAF_Blip.truthBlip.LeadG4Index =LarBlip.truth.LeadG4Index; - CAF_Blip.truthBlip.LeadG4PDG =LarBlip.truth.LeadG4PDG; - CAF_Blip.truthBlip.LeadCharge =LarBlip.truth.LeadCharge; - CAF_Blip.truthBlip.Position.SetXYZ(LarBlip.truth.Position.X(), LarBlip.truth.Position.Y(), LarBlip.truth.Position.Z()); - CAF_Blip.truthBlip.Energy = CAF_Blip.truthBlip.Energy/1000.; //convert to GeV + CAF_Blip.truthBlip.time =LarBlip.truth.Time; + CAF_Blip.truthBlip.driftTime =LarBlip.truth.DriftTime; + CAF_Blip.truthBlip.energy =LarBlip.truth.Energy; + CAF_Blip.truthBlip.depElectrons =LarBlip.truth.DepElectrons; + CAF_Blip.truthBlip.numElectrons =LarBlip.truth.NumElectrons; + CAF_Blip.truthBlip.leadG4ID =LarBlip.truth.LeadG4ID; + CAF_Blip.truthBlip.leadG4Index =LarBlip.truth.LeadG4Index; + CAF_Blip.truthBlip.leadG4PDG =LarBlip.truth.LeadG4PDG; + CAF_Blip.truthBlip.leadCharge =LarBlip.truth.LeadCharge; + CAF_Blip.truthBlip.position.SetXYZ(LarBlip.truth.Position.X(), LarBlip.truth.Position.Y(), LarBlip.truth.Position.Z()); + CAF_Blip.truthBlip.energy = CAF_Blip.truthBlip.energy/1000.; //convert to GeV } void FillBlipRealtedHitCluster(blip::Blip& LarBlip, caf::SRBlip &CAF_Blip) @@ -63,36 +63,36 @@ namespace caf { CAF_Blip.clusters[iPlane].ID = LarBlip.clusters[iPlane].ID; CAF_Blip.clusters[iPlane].isValid = LarBlip.clusters[iPlane].isValid; - CAF_Blip.clusters[iPlane].CenterChan = LarBlip.clusters[iPlane].CenterChan; - CAF_Blip.clusters[iPlane].CenterWire = LarBlip.clusters[iPlane].CenterWire; + CAF_Blip.clusters[iPlane].centerChan = LarBlip.clusters[iPlane].CenterChan; + CAF_Blip.clusters[iPlane].centerWire = LarBlip.clusters[iPlane].CenterWire; CAF_Blip.clusters[iPlane].isTruthMatched = LarBlip.clusters[iPlane].isTruthMatched; CAF_Blip.clusters[iPlane].isMatched = LarBlip.clusters[iPlane].isMatched; - CAF_Blip.clusters[iPlane].DeadWireSep = LarBlip.clusters[iPlane].DeadWireSep; - CAF_Blip.clusters[iPlane].Cryostat = LarBlip.clusters[iPlane].Cryostat; + CAF_Blip.clusters[iPlane].deadWireSep = LarBlip.clusters[iPlane].DeadWireSep; + CAF_Blip.clusters[iPlane].cryostat = LarBlip.clusters[iPlane].Cryostat; CAF_Blip.clusters[iPlane].TPC = LarBlip.clusters[iPlane].TPC; - CAF_Blip.clusters[iPlane].Plane = LarBlip.clusters[iPlane].Plane; - CAF_Blip.clusters[iPlane].NHits = LarBlip.clusters[iPlane].NHits; - CAF_Blip.clusters[iPlane].NWires = LarBlip.clusters[iPlane].NWires; + CAF_Blip.clusters[iPlane].plane = LarBlip.clusters[iPlane].Plane; + CAF_Blip.clusters[iPlane].nHits = LarBlip.clusters[iPlane].NHits; + CAF_Blip.clusters[iPlane].nWires = LarBlip.clusters[iPlane].NWires; CAF_Blip.clusters[iPlane].ADCs = LarBlip.clusters[iPlane].ADCs; - CAF_Blip.clusters[iPlane].Amplitude = LarBlip.clusters[iPlane].Amplitude; - CAF_Blip.clusters[iPlane].Charge = LarBlip.clusters[iPlane].Charge; - CAF_Blip.clusters[iPlane].SigmaCharge = LarBlip.clusters[iPlane].SigmaCharge; - CAF_Blip.clusters[iPlane].TimeTick = LarBlip.clusters[iPlane].TimeTick; - CAF_Blip.clusters[iPlane].Time = LarBlip.clusters[iPlane].Time; - CAF_Blip.clusters[iPlane].StartTime = LarBlip.clusters[iPlane].StartTime; - CAF_Blip.clusters[iPlane].EndTime = LarBlip.clusters[iPlane].EndTime; - CAF_Blip.clusters[iPlane].Timespan = LarBlip.clusters[iPlane].Timespan; + CAF_Blip.clusters[iPlane].amplitude = LarBlip.clusters[iPlane].Amplitude; + CAF_Blip.clusters[iPlane].charge = LarBlip.clusters[iPlane].Charge; + CAF_Blip.clusters[iPlane].sigmaCharge = LarBlip.clusters[iPlane].SigmaCharge; + CAF_Blip.clusters[iPlane].timeTick = LarBlip.clusters[iPlane].TimeTick; + CAF_Blip.clusters[iPlane].time = LarBlip.clusters[iPlane].Time; + CAF_Blip.clusters[iPlane].startTime = LarBlip.clusters[iPlane].StartTime; + CAF_Blip.clusters[iPlane].endTime = LarBlip.clusters[iPlane].EndTime; + CAF_Blip.clusters[iPlane].timespan = LarBlip.clusters[iPlane].Timespan; CAF_Blip.clusters[iPlane].RMS = LarBlip.clusters[iPlane].RMS; - CAF_Blip.clusters[iPlane].StartWire = LarBlip.clusters[iPlane].StartWire; - CAF_Blip.clusters[iPlane].EndWire = LarBlip.clusters[iPlane].EndWire; - CAF_Blip.clusters[iPlane].NPulseTrainHits = LarBlip.clusters[iPlane].NPulseTrainHits; - CAF_Blip.clusters[iPlane].GoodnessOfFit = LarBlip.clusters[iPlane].GoodnessOfFit; - CAF_Blip.clusters[iPlane].BlipID = LarBlip.clusters[iPlane].BlipID; - CAF_Blip.clusters[iPlane].EdepID = LarBlip.clusters[iPlane].EdepID; + CAF_Blip.clusters[iPlane].startWire = LarBlip.clusters[iPlane].StartWire; + CAF_Blip.clusters[iPlane].endWire = LarBlip.clusters[iPlane].EndWire; + CAF_Blip.clusters[iPlane].nPulseTrainHits = LarBlip.clusters[iPlane].NPulseTrainHits; + CAF_Blip.clusters[iPlane].goodnessOfFit = LarBlip.clusters[iPlane].GoodnessOfFit; + CAF_Blip.clusters[iPlane].blipID = LarBlip.clusters[iPlane].BlipID; + CAF_Blip.clusters[iPlane].edepID = LarBlip.clusters[iPlane].EdepID; //These are sets that need to become vectors so we need to do some loops - for(auto HitID : LarBlip.clusters[iPlane].HitIDs) CAF_Blip.clusters[iPlane].HitIDs.push_back(HitID); - for(auto Wire : LarBlip.clusters[iPlane].Wires) CAF_Blip.clusters[iPlane].Wires.push_back(Wire); - for(auto Chan : LarBlip.clusters[iPlane].Chans) CAF_Blip.clusters[iPlane].Chans.push_back(Chan); + for(auto HitID : LarBlip.clusters[iPlane].HitIDs) CAF_Blip.clusters[iPlane].hitIDs.push_back(HitID); + for(auto Wire : LarBlip.clusters[iPlane].Wires) CAF_Blip.clusters[iPlane].wires.push_back(Wire); + for(auto Chan : LarBlip.clusters[iPlane].Chans) CAF_Blip.clusters[iPlane].chans.push_back(Chan); for(auto G4ID : LarBlip.clusters[iPlane].G4IDs) CAF_Blip.clusters[iPlane].G4IDs.push_back(G4ID); } } From c660c6419041eac37668b7974a3e97b5ffbc35b4 Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 3 Dec 2025 07:27:29 -0600 Subject: [PATCH 279/367] Compute closest intersection in a loop --- sbncode/CAFMaker/FillTrue.cxx | 49 ++++++++++++++--------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index 419ad7540..b746a5b5e 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -1260,58 +1260,49 @@ caf::Wall_t caf::GetWallCross(const geo::BoxBoundedGeo &volume, const TVector3 p TVector3 direction = (p1 - p0) * ( 1. / (p1 - p0).Mag()); std::vector intersections = volume.GetIntersections(p0, direction); - //assert(intersections.size() == 2); /* - * There are either infinity, two, or one, or zero intersection points. + * There are either two, or one, or zero intersection points. * As per larcorealg/Geometry/BoxBoundedGeo.h documentation: * If the return std::vector is empty the trajectory does not intersect with the box. * Normally the return value should have one (if the trajectory originates in the box) or two (else) entries. * If the return value has two entries the first represents the entry point and the second the exit point */ - switch( intersections.size() ) { - case 0: // Set kWallNone and return - return caf::kWallNone; - break; - case 1: // Set the second intersection to be the same as the first, and fall through - intersections.emplace_back(intersections.front()); - [[fallthrough]]; - case 2: - break; - default: // There are infinity points to consider. Just use the first two. - intersections.resize(2); - break; - } + + if( intersections.empty() ) return caf::kWallNone; + // ensure intersections has two points. No op if already 2 + intersections.resize( 2, intersections.front() ); // get the intersection point closer to p0 - int intersection_i = ((intersections[0] - p0).Mag() < (intersections[1] - p0).Mag()) ? 0 : 1; + TVector3 closestIntersection; + double minDistance2 = std::numeric_limits::max(); + + for( TVector3 const & point : intersections ) { + const double d2 = (point - p0).Mag2(); + if( d2 > minDistance2 ) continue; + minDistance2 = d2; + closestIntersection = point; + } double eps = 1e-3; - if (abs(intersections[intersection_i].X() - volume.MinX()) < eps) { - //std::cout << "Left\n"; + if (abs(closestIntersection.X() - volume.MinX()) < eps) { return caf::kWallLeft; } - else if (abs(intersections[intersection_i].X() - volume.MaxX()) < eps) { - //std::cout << "Right\n"; + else if (abs(closestIntersection.X() - volume.MaxX()) < eps) { return caf::kWallRight; } - else if (abs(intersections[intersection_i].Y() - volume.MinY()) < eps) { - //std::cout << "Bottom\n"; + else if (abs(closestIntersection.Y() - volume.MinY()) < eps) { return caf::kWallBottom; } - else if (abs(intersections[intersection_i].Y() - volume.MaxY()) < eps) { - //std::cout << "Top\n"; + else if (abs(closestIntersection.Y() - volume.MaxY()) < eps) { return caf::kWallTop; } - else if (abs(intersections[intersection_i].Z() - volume.MinZ()) < eps) { - //std::cout << "Front\n"; + else if (abs(closestIntersection.Z() - volume.MinZ()) < eps) { return caf::kWallFront; } - else if (abs(intersections[intersection_i].Z() - volume.MaxZ()) < eps) { - //std::cout << "Back\n"; + else if (abs(closestIntersection.Z() - volume.MaxZ()) < eps) { return caf::kWallBack; } else assert(false); - //std::cout << "None\n"; return caf::kWallNone; }//GetWallCross From 6cdd11d96901d594f07bfbdcc3a796a97c431f4e Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 3 Dec 2025 07:27:37 -0600 Subject: [PATCH 280/367] Remove duplicate check on testmaterial1 --- sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index 15dbbbb4b..896eaa2ef 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -297,7 +297,7 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { double Z = p.Position(i).Z(); geo::Point_t testpoint1 { X, Y, Z }; const TGeoMaterial* testmaterial1 = fGeometryService->Material( testpoint1 ); - if( ! testmaterial1 || testmaterial1 == nullptr ) { + if( ! testmaterial1 ) { break; // The trajectory point is outside the world, or the geometry service is unable to handle the point } //For now, just going to reweight the points within the LAr of the TPC From 240b73c82670b0e41f458424fc1ccfcd9085606d Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 3 Dec 2025 09:31:33 -0600 Subject: [PATCH 281/367] fix module fcl issue --- sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl index 88201c999..af2f8d1ac 100644 --- a/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl +++ b/sbncode/BeamSpillInfoRetriever/job/run_sbndbnbextinfo_sbn.fcl @@ -34,7 +34,7 @@ physics: { stream1: [ out1 ] } -physics.producers.sbndbnbextinfo.module_type: "SBNDBNBEXTRetriever" +physics.producers.bnbextinfo.module_type: "SBNDBNBEXTRetriever" outputs: { out1: { @@ -44,4 +44,4 @@ outputs: { compressionLevel: 1 } } -physics.producers.sbndbnbextinfo.fileNames: @local::outputs.out1.fileName +physics.producers.bnbextinfo.fileNames: @local::outputs.out1.fileName From e8fa24b7c66253892f4c6efb4230fbd587e13c6e Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 3 Dec 2025 10:34:21 -0600 Subject: [PATCH 282/367] no resizing needed --- sbncode/CAFMaker/FillTrue.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index b746a5b5e..ef1b4cc0c 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -1269,8 +1269,6 @@ caf::Wall_t caf::GetWallCross(const geo::BoxBoundedGeo &volume, const TVector3 p */ if( intersections.empty() ) return caf::kWallNone; - // ensure intersections has two points. No op if already 2 - intersections.resize( 2, intersections.front() ); // get the intersection point closer to p0 TVector3 closestIntersection; From 0efe3ed161cc3b8f4583163c0ff8791ac6f5ac7d Mon Sep 17 00:00:00 2001 From: Lynn Garren Date: Wed, 3 Dec 2025 22:50:02 -0600 Subject: [PATCH 283/367] G4InfoReducer and SimpleMerge are part of larg4 --- sbncode/LArG4/CMakeLists.txt | 19 ------------------- sbncode/LArG4/g4inforeducer.fcl | 12 ------------ sbncode/LArG4/simplemerge.fcl | 9 --------- 3 files changed, 40 deletions(-) delete mode 100644 sbncode/LArG4/g4inforeducer.fcl delete mode 100644 sbncode/LArG4/simplemerge.fcl diff --git a/sbncode/LArG4/CMakeLists.txt b/sbncode/LArG4/CMakeLists.txt index dd353af96..f377b254d 100644 --- a/sbncode/LArG4/CMakeLists.txt +++ b/sbncode/LArG4/CMakeLists.txt @@ -1,15 +1,5 @@ add_subdirectory(PhysicsLists) -cet_build_plugin(G4InfoReducer art::module - LIBRARIES - larsim::Simulation - larcore::Geometry_Geometry_service - lardata::DetectorInfoServices_DetectorClocksServiceStandard_service - art::Persistency_Common - art::Persistency_Provenance - art::Utilities canvas::canvas - BASENAME_ONLY) - set( MODULE_LIBRARIES art::Utilities @@ -61,14 +51,5 @@ cet_build_plugin(MergeSimSourcesSBN art::EDProducer BASENAME_ONLY ) -cet_build_plugin(SimpleMerge art::EDProducer - LIBRARIES - lardataobj::MCBase - larcorealg::headers - larcorealg::CoreUtils - messagefacility::MF_MessageLogger -) - install_headers() -install_fhicl() install_source() diff --git a/sbncode/LArG4/g4inforeducer.fcl b/sbncode/LArG4/g4inforeducer.fcl deleted file mode 100644 index ced065f67..000000000 --- a/sbncode/LArG4/g4inforeducer.fcl +++ /dev/null @@ -1,12 +0,0 @@ -BEGIN_PROLOG - -sbn_largeant_info_reducer: { - module_type: "G4InfoReducer" - SimEnergyDepositLabel: "largeant:TPCActive" - VoxelSizeX: 0.3 - VoxelSizeY: 0.3 - VoxelSizeZ: 0.3 - useOrigTrackID: true -} - -END_PROLOG diff --git a/sbncode/LArG4/simplemerge.fcl b/sbncode/LArG4/simplemerge.fcl deleted file mode 100644 index 01ad905be..000000000 --- a/sbncode/LArG4/simplemerge.fcl +++ /dev/null @@ -1,9 +0,0 @@ -BEGIN_PROLOG - -simplemerge : { - module_type: "SimpleMerge" - InputSourcesLabels: ["largeant", "largeantdropped"] - ResetMotherIDs: [ 10000000, 20000000 ] -} - -END_PROLOG \ No newline at end of file From 8b5120e22be68ea6353f66d28b5dd8a788f71e05 Mon Sep 17 00:00:00 2001 From: Benjamin Harris Date: Thu, 4 Dec 2025 12:02:41 -0600 Subject: [PATCH 284/367] Add PTB HLT and LLT information to CAF files for real SBND data --- sbncode/BeamSpillInfoRetriever/POTTools.cpp | 30 +++++++++++++++++++++ sbncode/BeamSpillInfoRetriever/POTTools.h | 13 ++++++++- sbncode/CAFMaker/CAFMaker_module.cc | 19 +++++++++++++ sbncode/CAFMaker/CMakeLists.txt | 1 + sbncode/CAFMaker/FillTrigger.cxx | 24 +++++++++++++++++ sbncode/CAFMaker/FillTrigger.h | 3 +++ 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index 585fdba5b..d2b85dc0c 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -43,6 +43,36 @@ namespace sbn::pot{ } } + std::vector extractAllPTBInfo(art::Handle > cont_frags) { + std::vector PTBInfoVec; + for (auto const& cont : *cont_frags) + { + artdaq::ContainerFragment cont_frag(cont); + for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) + { + artdaq::Fragment frag = *cont_frag[fragi]; + sbndaq::CTBFragment ctb_frag(frag); + for(size_t word_i = 0; word_i < ctb_frag.NWords(); ++word_i) + { + if(ctb_frag.Trigger(word_i)){ + PTBInfo_t PTBInfo; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS; + uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp; + double currTS_candidate = std::bitset<64>(RawcurrPTBTimeStamp).to_ullong()/50e6; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp).to_ullong()/50e6; + PTBInfo.currPTBTimeStamp = currTS_candidate; + PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; + PTBInfo.isHLT = ctb_frag.Trigger(word_i)->IsHLT(); + PTBInfo.triggerWord = ctb_frag.Trigger(word_i)->trigger_word; + PTBInfoVec.push_back(PTBInfo); + } + } + } + } + + return PTBInfoVec; + } + double extractTDCTimeStamp(art::Handle > cont_frags) { double TDCTimeStamp = 0; diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.h b/sbncode/BeamSpillInfoRetriever/POTTools.h index cb78fe686..3518f8d3a 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.h +++ b/sbncode/BeamSpillInfoRetriever/POTTools.h @@ -13,6 +13,7 @@ #include "sbncode/BeamSpillInfoRetriever/MWRData.h" #include "larcorealg/CoreUtils/counter.h" +#include namespace sbn::pot{ @@ -20,6 +21,8 @@ namespace sbn::pot{ double currPTBTimeStamp = 1e20; double prevPTBTimeStamp = 0; unsigned int GateCounter = 0; + bool isHLT = false; + uint64_t triggerWord = 0; } PTBInfo_t; typedef struct TriggerInfo_t { @@ -36,13 +39,21 @@ namespace sbn::pot{ } MWRdata_t; /** - * @brief Extracts information from PTB for use in SBND POT accounting. + * @brief Extracts information from PTB for a single HLT for use in SBND POT accounting. * * @param cont_frags The PTB fragments to examine. * @param HLT The high level trigger we are searching for. */ PTBInfo_t extractPTBInfo(art::Handle > cont_frags, int HLT); + /** + * @brief Extracts ALL PTB information for using in SBND CAF files. + * + * @param cont_frags The PTB fragments to examine. + * @return Vector of PTBInfo_t containing all triggers found. + */ + std::vector extractAllPTBInfo(art::Handle > cont_frags); + /** * @brief Extracts information from TDC for use in SBND POT accounting. * diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 9f2c01590..04550ffaf 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -115,6 +115,8 @@ #include "sbnobj/Common/POTAccounting/BNBSpillInfo.h" #include "sbnobj/Common/POTAccounting/EXTCountInfo.h" #include "sbnobj/Common/POTAccounting/NuMISpillInfo.h" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" +#include "artdaq-core/Data/ContainerFragment.hh" #include "sbnobj/Common/Trigger/ExtraTriggerInfo.h" #include "sbnobj/Common/Reco/CRUMBSResult.h" #include "sbnobj/Common/Reco/OpT0FinderResult.h" @@ -1711,6 +1713,23 @@ void CAFMaker::produce(art::Event& evt) noexcept { FillTriggerEmulation(monpulses_handle, monpulse_sizes_handle, pairs_handle, trigemu_handle, srtrigger); } + + // Fill PTB (Penn Trigger Board) information for SBND real data + if (isRealData && fDet == kSBND) { + art::InputTag PTB_itag("daq", "ContainerPTB"); + art::Handle ptb_frags_handle; + evt.getByLabel(PTB_itag, ptb_frags_handle); + if (ptb_frags_handle.isValid()) { + try { + std::vector ptb_triggers = sbn::pot::extractAllPTBInfo(ptb_frags_handle); + FillPTBTriggersSBND(ptb_triggers, srtrigger); + } + catch (...) { + std::cout << "CAFMaker: Failed to extract PTB triggers" << std::endl; + } + } + } + // If not real data, fill in enough of the SRTrigger to make (e.g.) the CRT // time referencing work. TODO: add more stuff to a "MC"-Trigger? // No longer needed with incorporation of trigger emulation in the MC. diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 5dd4f2a8f..24228ba3f 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -50,6 +50,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker ${GENIE_LIB_LIST} nugen::EventGeneratorBase_GENIE sbndaq_artdaq_core::sbndaq-artdaq-core_Obj_SBND + sbn_POTTools ) cet_build_plugin ( CAFMaker art::module diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index fab6ae074..2fcf30914 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -73,4 +73,28 @@ namespace caf caf_softInfo.flash_peakpe = softInfo.peakPE; caf_softInfo.flash_peaktime = softInfo.peaktime + softInfo.trig_ts*1e-3; } + + void FillPTBTriggersSBND(const std::vector& ptb_triggers, caf::SRTrigger& triggerInfo) { + triggerInfo.ptb_hlt_timestamp.clear(); + triggerInfo.ptb_hlt_bit.clear(); + triggerInfo.ptb_llt_timestamp.clear(); + triggerInfo.ptb_llt_bit.clear(); + + // Decode trigger words: each set bit becomes a separate entry with the same timestamp + for(const auto& trig : ptb_triggers) { + std::uint64_t triggerWord = trig.triggerWord; + for(int bit = 0; bit < 64; ++bit) { + std::uint64_t bitMask = 1ULL << bit; + if(triggerWord & bitMask) { + if(trig.isHLT) { + triggerInfo.ptb_hlt_timestamp.push_back(trig.currPTBTimeStamp); + triggerInfo.ptb_hlt_bit.push_back(bit); + } else { + triggerInfo.ptb_llt_timestamp.push_back(trig.currPTBTimeStamp); + triggerInfo.ptb_llt_bit.push_back(bit); + } + } + } + } + } } diff --git a/sbncode/CAFMaker/FillTrigger.h b/sbncode/CAFMaker/FillTrigger.h index 2c2ada243..203fbe57c 100644 --- a/sbncode/CAFMaker/FillTrigger.h +++ b/sbncode/CAFMaker/FillTrigger.h @@ -9,6 +9,7 @@ #include "lardataobj/RawData/TriggerData.h" #include "art/Framework/Principal/Handle.h" #include "sbndaq-artdaq-core/Obj/SBND/pmtSoftwareTrigger.hh" +#include "sbncode/BeamSpillInfoRetriever/POTTools.h" namespace caf { @@ -30,6 +31,8 @@ namespace caf art::Handle const& passedTrig, caf::SRTrigger& triggerInfo); void FillSoftwareTriggerSBND(const sbnd::trigger::pmtSoftwareTrigger& softInfo, caf::SRSoftwareTrigger& caf_softInfo); + + void FillPTBTriggersSBND(const std::vector& ptb_triggers, caf::SRTrigger& triggerInfo); } #endif From 4ba47c2d9c94db812089ac1ae7df1c828831747c Mon Sep 17 00:00:00 2001 From: Patrick Green Date: Thu, 4 Dec 2025 19:31:51 -0600 Subject: [PATCH 285/367] fix g4rw daughters --- .../Calculators/Geant4/Geant4WeightCalc.cxx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx index ec9d8cc6e..8677f7c55 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx +++ b/sbncode/SBNEventWeight/Calculators/Geant4/Geant4WeightCalc.cxx @@ -389,10 +389,13 @@ std::vector Geant4WeightCalc::GetWeight(art::Event& e, size_t itruth ) { theTraj.AddStep( theStep ); - for( size_t k = 0; k < daughter_PDGs.size(); ++k ){ - theTraj.AddChild( new G4ReweightTraj(daughter_IDs[k], daughter_PDGs[k], mcpID, event_num, std::make_pair(0,0) ) ); - } } // end loop over nSteps (istep) + + // add daughters + for( size_t k = 0; k < daughter_PDGs.size(); ++k ){ + theTraj.AddChild( new G4ReweightTraj(daughter_IDs[k], daughter_PDGs[k], mcpID, event_num, std::make_pair(0,0) ) ); + } + p_track_length = theTraj.GetTotalLength(); p_init_momentum = sqrt( theTraj.GetEnergy()*theTraj.GetEnergy() - mass*mass ); From a8d06c2b96cb1d0503b0615f37fdf4e2dd7d8e15 Mon Sep 17 00:00:00 2001 From: Marco Del Tutto Date: Tue, 9 Dec 2025 14:10:45 -0600 Subject: [PATCH 286/367] Make flux calculator compatible with g4bnb flux --- .../Calculators/BNBFlux/FluxCalcPrep.cxx | 47 ++++++++++++++++--- .../Calculators/BNBFlux/FluxCalcPrep.h | 4 ++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx index 640a84769..b1677ce35 100644 --- a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx +++ b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx @@ -213,8 +213,16 @@ namespace sbn { // std::cout<<"SBNEventWeight : getweight for the "< > mcFluxHandle; - e.getByLabel(fGeneratorModuleLabel,mcFluxHandle); + e.getByLabel(fGeneratorModuleLabel, mcFluxHandle); std::vector const& fluxlist = *mcFluxHandle; + + art::Handle< std::vector > dk2nuHandle; + std::vector const* dk2nu_v = nullptr; + e.getByLabel(fGeneratorModuleLabel, dk2nuHandle); + if (dk2nuHandle.isValid()) { + dk2nu_v = dk2nuHandle.product(); + } + //or do the above 3 lines in one line // auto const& mclist = *e.getValidHandle>(fGeneratorModuleLabel); @@ -287,9 +295,35 @@ namespace sbn { // First let's check that the parent of the neutrino we are looking for is // the particle we intended it to be, if not set all weights to 1 - if (std::find(fprimaryHad.begin(), fprimaryHad.end(),(fluxlist[inu].ftptype)) == fprimaryHad.end() ){//if it does not contain any particles we need get 1 + + simb::MCFlux flux; + flux.ftptype = fluxlist[inu].ftptype; + flux.ftpx = fluxlist[inu].ftpx; + flux.ftpy = fluxlist[inu].ftpy; + flux.ftpz = fluxlist[inu].ftpz; + + // int tptype = fluxlist[inu].ftptype; + + // If Dk2Nu flux, use ancestors to evaluate tptype + if (fluxlist[inu].fFluxType == simb::kDk2Nu) { + + // Find the first inelastic interaction + int firstInelastic = 0; + while (dk2nu_v->at(inu).ancestor[firstInelastic].proc.find("HadronInelastic")==std::string::npos||dk2nu_v->at(inu).ancestor[firstInelastic].proc.find("QEBooNE")!=std::string::npos) firstInelastic++; + + // Get the parent/ancestor (this should be the secondary in the p+Be interaction) + flux.ftptype = dk2nu_v->at(inu).ancestor[firstInelastic].pdg; + flux.ftpx = dk2nu_v->at(inu).ancestor[firstInelastic].startpx; + flux.ftpy = dk2nu_v->at(inu).ancestor[firstInelastic].startpy; + flux.ftpz = dk2nu_v->at(inu).ancestor[firstInelastic].startpz; + + } + + + if (std::find(fprimaryHad.begin(), fprimaryHad.end(),(flux.ftptype)) == fprimaryHad.end() ){//if it does not contain any particles we need get 1 weights.resize( NUni); std::fill(weights.begin(), weights.end(), 1); + std::cout << "We don't need this parent, returning." << std::endl; return weights;//done, all 1 }// Hadronic parent check @@ -301,19 +335,18 @@ namespace sbn { std::vector< float > Vrandom = (fParameterSet.fParameterMap.begin())->second;//vector of random # std::vector< float > subVrandom;//sub-vector of random numbers; if( CalcType == "PrimaryHadronNormalization"){//Normalization - test_weight = PHNWeightCalc(fluxlist[inu], Vrandom[i]); + test_weight = PHNWeightCalc(flux, Vrandom[i]); } else { subVrandom = {Vrandom.begin()+i*FitCov->GetNcols(), Vrandom.begin()+(i+1)*FitCov->GetNcols()}; if( CalcType == "PrimaryHadronFeynmanScaling"){//FeynmanScaling - test_weight = PHFSWeightCalc(fluxlist[inu], subVrandom); + test_weight = PHFSWeightCalc(flux, subVrandom); } else if( CalcType == "PrimaryHadronSanfordWang"){//SanfordWang - test_weight = PHSWWeightCalc(fluxlist[inu], subVrandom); + test_weight = PHSWWeightCalc(flux, subVrandom); } else if( CalcType == "PrimaryHadronSWCentralSplineVariation"){//SWCentaralSplineVariation - test_weight = PHSWCSVWeightCalc(fluxlist[inu], subVrandom); - + test_weight = PHSWCSVWeightCalc(flux, subVrandom); } else throw cet::exception(__PRETTY_FUNCTION__) << GetName() << ": this shouldnt happen.."< Date: Tue, 9 Dec 2025 14:28:33 -0600 Subject: [PATCH 287/367] Remove spurious cout --- sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx index b1677ce35..7e0e9265e 100644 --- a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx +++ b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx @@ -323,7 +323,6 @@ namespace sbn { if (std::find(fprimaryHad.begin(), fprimaryHad.end(),(flux.ftptype)) == fprimaryHad.end() ){//if it does not contain any particles we need get 1 weights.resize( NUni); std::fill(weights.begin(), weights.end(), 1); - std::cout << "We don't need this parent, returning." << std::endl; return weights;//done, all 1 }// Hadronic parent check From fe6e4101b3db960d6d268ee418403ea9e4a5a0d8 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 15 Dec 2025 16:10:52 -0600 Subject: [PATCH 288/367] Removed old code --- sbncode/CAFMaker/CAFMaker_module.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 8e9fced83..86efb71b8 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1935,11 +1935,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { if(evt.getByLabel( fParams.fBlipTag(), blipHandle)) //fill SR blips { FillBlip( (*blipHandle), srblips); - //for(int i=0; isize()); i++) - // { - // auto LarBlips = (*(blipHandle))[i]; - // FillBlip( (LarBlips) , srblips); - // } } // collect the TPC slices std::vector> slices; From 19f6c9222a0b6ad13f95a59a4076b6cd49bc5ea9 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 15 Dec 2025 16:13:39 -0600 Subject: [PATCH 289/367] Aligning fcl param code indentation --- sbncode/CAFMaker/CAFMakerParams.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 5ff287d91..6843b4ad9 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -634,11 +634,12 @@ namespace caf Comment("Label of CVN scores."), "cvn" }; - Atom fBlipTag { Name("BlipTag"), - Comment("Provide a string to label the blip input"), "blipreco" - }; - + Atom fBlipTag { + Name("BlipTag"), + Comment("Provide a string to label the blip input"), + "blipreco" + }; }; } From bd6ecab80cc2333db63f3a137cc857c22760f177 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 15 Dec 2025 16:16:14 -0600 Subject: [PATCH 290/367] Changed for loop per suggestion --- sbncode/CAFMaker/FillBlip.cxx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 30194b19b..e8ea0e064 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -4,10 +4,8 @@ namespace caf { void FillBlip( const std::vector& LarBlips, std::vector& CAF_Blips) { - int NBlips = LarBlips.size(); - for(int iBlip=0; iBlip Date: Mon, 15 Dec 2025 16:53:35 -0600 Subject: [PATCH 291/367] Assorted updated per PR comments --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillBlip.cxx | 111 ++++++++++++++-------------- sbncode/CAFMaker/FillBlip.h | 13 +++- 3 files changed, 65 insertions(+), 61 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 86efb71b8..46c1d475c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1934,7 +1934,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { std::vector srblips; if(evt.getByLabel( fParams.fBlipTag(), blipHandle)) //fill SR blips { - FillBlip( (*blipHandle), srblips); + FillBlip( *blipHandle, srblips); } // collect the TPC slices std::vector> slices; diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index e8ea0e064..f91d07a2b 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -2,9 +2,9 @@ namespace caf { - void FillBlip( const std::vector& LarBlips, std::vector& CAF_Blips) + void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips) { - for(blip::Blip const& CurrentBlip: LarBlips) + for(blip::Blip const& CurrentBlip: LAr_Blips) { caf::SRBlip NewBlip; NewBlip.ID = CurrentBlip.ID; @@ -28,70 +28,69 @@ namespace caf NewBlip.dYZ = CurrentBlip.dYZ; if(CurrentBlip.truth.ID >= 0 ) //MC Blip { - FillMCTruthBlip( CurrentBlip, NewBlip ); + FillMCTruthBlip( CurrentBlip.truth, NewBlip.truthBlip ); + } + for(int iPlane=0; iPlane #include "sbnanaobj/StandardRecord/SRBlip.h" #include "sbnobj/SBND/Blip/BlipDataTypes.h" @@ -9,9 +14,9 @@ namespace caf { - void FillBlip( const std::vector& LarBlips, std::vector& CAF_Blips); - void FillMCTruthBlip(blip::Blip& LarBlip, caf::SRBlip& CAF_Blip ); - void FillBlipRealtedHitCluster(blip::Blip& LarBlip, caf::SRBlip& CAF_Blip); + void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips); + void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRBlipTrueBlip &TrueCAF_Blip ); + void FillBlipRealtedHitCluster(blip::HitClust const & LAr_HitClust, caf::SRBlipHitClust &CAF_HitClust); } #endif From 5062c12e164335c35f50ce82d46e804ff1be9308 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 15 Dec 2025 17:03:10 -0600 Subject: [PATCH 292/367] Compiler issue --- sbncode/CAFMaker/FillBlip.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index f91d07a2b..dce5d7cae 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -30,7 +30,7 @@ namespace caf { FillMCTruthBlip( CurrentBlip.truth, NewBlip.truthBlip ); } - for(int iPlane=0; iPlane Date: Mon, 15 Dec 2025 17:07:46 -0600 Subject: [PATCH 293/367] Compiler issue --- sbncode/CAFMaker/FillBlip.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index dce5d7cae..b6c86422b 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -30,7 +30,7 @@ namespace caf { FillMCTruthBlip( CurrentBlip.truth, NewBlip.truthBlip ); } - for(int iPlane=0; iPlane Date: Tue, 16 Dec 2025 09:48:13 -0600 Subject: [PATCH 294/367] Use BooNEpBeInteraction to identify pBe interaction, also better loop Co-authored-by: John Plows kom.plows@gmail.com --- .../Calculators/BNBFlux/FluxCalcPrep.cxx | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx index 7e0e9265e..ff461c562 100644 --- a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx +++ b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx @@ -302,24 +302,20 @@ namespace sbn { flux.ftpy = fluxlist[inu].ftpy; flux.ftpz = fluxlist[inu].ftpz; - // int tptype = fluxlist[inu].ftptype; - // If Dk2Nu flux, use ancestors to evaluate tptype if (fluxlist[inu].fFluxType == simb::kDk2Nu) { - // Find the first inelastic interaction - int firstInelastic = 0; - while (dk2nu_v->at(inu).ancestor[firstInelastic].proc.find("HadronInelastic")==std::string::npos||dk2nu_v->at(inu).ancestor[firstInelastic].proc.find("QEBooNE")!=std::string::npos) firstInelastic++; - - // Get the parent/ancestor (this should be the secondary in the p+Be interaction) - flux.ftptype = dk2nu_v->at(inu).ancestor[firstInelastic].pdg; - flux.ftpx = dk2nu_v->at(inu).ancestor[firstInelastic].startpx; - flux.ftpy = dk2nu_v->at(inu).ancestor[firstInelastic].startpy; - flux.ftpz = dk2nu_v->at(inu).ancestor[firstInelastic].startpz; - + for( const bsim::Ancestor & ancestor : dk2nu_v->at(inu).ancestor ) { + std::string aproc = ancestor.proc; + if( (aproc.find("BooNEHadronInelastic:BooNEpBeInteraction") != std::string::npos) && (aproc.find("QEBooNE") == std::string::npos) ) { + flux.ftptype = ancestor.pdg; + flux.ftpx = ancestor.startpx; + flux.ftpy = ancestor.startpy; + flux.ftpz = ancestor.startpz; + } // found it + } // find first inelastic } - if (std::find(fprimaryHad.begin(), fprimaryHad.end(),(flux.ftptype)) == fprimaryHad.end() ){//if it does not contain any particles we need get 1 weights.resize( NUni); std::fill(weights.begin(), weights.end(), 1); From ef71ae71577d239d72ac24c9c2e795e226556615 Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 17 Dec 2025 02:21:37 -0600 Subject: [PATCH 295/367] Updated dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0720a9ddb..d6932da42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.14.00 LANGUAGES CXX) +project(sbncode VERSION 10.14.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 755bb2211..2ff8b27d9 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_14_00 - -sbnalg v10_14_00 - +larsoft v10_14_02 - +sbnalg v10_14_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From 0ff66f926b936b396f8550a13c03f157154573d7 Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:21:13 -0500 Subject: [PATCH 296/367] Update dissonant_higgs.fcl Add a parameter to determine whether new form factor is used --- sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl b/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl index eb91ecdd0..0aa2b8d21 100644 --- a/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl +++ b/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl @@ -8,6 +8,7 @@ kaon2higgs: { tool_type: Kaon2HiggsFlux M: @local::higgsM MixingAngle: 1e-5 + NewFormFactorModel: True KDAROnly: false #as written this only includes KDAR from absorber (not all KDAR) KDIFOnly: false #includes KDIF (from absorber or beamline) KDIFandBeamline: false #inlcudes KDIF from beamline, KDIF from absorber, and KDAR from beamline (this option orthogonal to "KDAROnly") From 8bb0792f07cbd5d9e0343a99e96f63b2de5b4137 Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:33:05 -0500 Subject: [PATCH 297/367] Update HiggsMakeDecay_tool.cc Added an optional new form factor to use for determining decays of Higgs portal scalar to pions --- .../MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc index 24f2fabe7..f43c54ee0 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc @@ -73,6 +73,7 @@ class HiggsMakeDecay : public IMeVPrtlDecay { double fReferenceRayDistance; double fReferenceHiggsMass; double fReferenceHiggsMixing; + bool fNewFormFactor; double fReferenceHiggsEnergy; double fReferenceHiggsKaonEnergy; @@ -132,7 +133,17 @@ double PionPartialWidth(double pion_mass, double higs_mass, double mixing) { double higgs_vev = Constants::Instance().higgs_vev; - double form_factor = (2. / 9.) * higs_mass * higs_mass + (11. / 9.) * pion_mass * pion_mass; + double form_factor = 0.; + if (fNewFormFactor) { + // New, improved form factor based on the plot in arXiv:1909.11670v4 + // This form factor is significnatly different than in older versions + // The expression is a fit to the Fig. 1 left panel in arXiv:1909.11670v4 + form_factor = 0.289 * pow(higs_mass - 2 * Constants::Instance().pizero_mass,1.5); + } + else { + // Old form factor + (2. / 9.) * higs_mass * higs_mass + (11. / 9.) * pion_mass * pion_mass; + } double width = (mixing * mixing * 3 * form_factor * form_factor / (32 * M_PI * higgs_vev * higgs_vev * higs_mass)) * pow(1- 4. * pion_mass * pion_mass / (higs_mass * higs_mass), 1. / 2.); @@ -166,6 +177,7 @@ void HiggsMakeDecay::configure(fhicl::ParameterSet const &pset) fReferenceRayDistance = pset.get("ReferenceRayDistance", 0.); fReferenceHiggsMass = pset.get("ReferenceHiggsMass", -1); fReferenceHiggsMixing = pset.get("ReferenceHiggsMixing", -1); + fReferenceHiggsMass = pset.get("NewFormFactor", -1); fReferenceHiggsEnergy = pset.get("ReferenceHiggsEnergy", -1); fReferenceHiggsKaonEnergy = pset.get("ReferenceHiggsEnergyFromKaonEnergy", -1.); From 6b09cf50aaf0c5ef533451757994455b3cf2d0db Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:35:49 -0500 Subject: [PATCH 298/367] Update HiggsMakeDecay_tool.cc Fixed an error with the new form factor implementation --- .../EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc index f43c54ee0..12f85fb65 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc @@ -138,7 +138,7 @@ double PionPartialWidth(double pion_mass, double higs_mass, double mixing) { // New, improved form factor based on the plot in arXiv:1909.11670v4 // This form factor is significnatly different than in older versions // The expression is a fit to the Fig. 1 left panel in arXiv:1909.11670v4 - form_factor = 0.289 * pow(higs_mass - 2 * Constants::Instance().pizero_mass,1.5); + form_factor = pow(0.289 * pow(higs_mass - 2 * Constants::Instance().pizero_mass,1.5),0.5); } else { // Old form factor From 4f161a8f513d5ac022425c671ce6e838d698951a Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:54:33 -0500 Subject: [PATCH 299/367] Update HiggsMakeDecay_tool.cc Corrected a typo in setting the Boolean for the new form factor. --- .../EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc index 12f85fb65..c48ef57b7 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc @@ -177,7 +177,7 @@ void HiggsMakeDecay::configure(fhicl::ParameterSet const &pset) fReferenceRayDistance = pset.get("ReferenceRayDistance", 0.); fReferenceHiggsMass = pset.get("ReferenceHiggsMass", -1); fReferenceHiggsMixing = pset.get("ReferenceHiggsMixing", -1); - fReferenceHiggsMass = pset.get("NewFormFactor", -1); + fNewFormFactor = pset.get("NewFormFactor", -1); fReferenceHiggsEnergy = pset.get("ReferenceHiggsEnergy", -1); fReferenceHiggsKaonEnergy = pset.get("ReferenceHiggsEnergyFromKaonEnergy", -1.); From 95f6a37a4cb890e110215f4e7dc17f5143764fbe Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Tue, 6 Jan 2026 20:24:33 -0500 Subject: [PATCH 300/367] Update dissonant_higgs.fcl Corrected a typo in the new parameter name for the form factor selection --- sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl b/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl index 0aa2b8d21..bfb5bb05b 100644 --- a/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl +++ b/sbncode/EventGenerator/MeVPrtl/config/Higgs/dissonant_higgs.fcl @@ -8,7 +8,6 @@ kaon2higgs: { tool_type: Kaon2HiggsFlux M: @local::higgsM MixingAngle: 1e-5 - NewFormFactorModel: True KDAROnly: false #as written this only includes KDAR from absorber (not all KDAR) KDIFOnly: false #includes KDIF (from absorber or beamline) KDIFandBeamline: false #inlcudes KDIF from beamline, KDIF from absorber, and KDAR from beamline (this option orthogonal to "KDAROnly") @@ -42,6 +41,7 @@ decay_higgs: { ReferenceRayLength: 2100 # 21m ReferenceHiggsMass: @local::higgsM ReferenceHiggsMixing: 1e-5 + NewFormFactor: true ReferenceRayDistance: 80000 # 800m ReferenceHiggsEnergyFromKaonEnergy: 15. # GeV AddTimeOfFlight: true From 442253e1a8b0a9ca69d784493b568cace3bdb3bd Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:17:41 -0500 Subject: [PATCH 301/367] Update HiggsMakeDecay_tool.cc Fixed a bug with setting the boolean for the new form factor --- .../Tools/Higgs/HiggsMakeDecay_tool.cc | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc index c48ef57b7..f0551f1cc 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc @@ -73,7 +73,6 @@ class HiggsMakeDecay : public IMeVPrtlDecay { double fReferenceRayDistance; double fReferenceHiggsMass; double fReferenceHiggsMixing; - bool fNewFormFactor; double fReferenceHiggsEnergy; double fReferenceHiggsKaonEnergy; @@ -83,6 +82,7 @@ class HiggsMakeDecay : public IMeVPrtlDecay { bool fAllowMuonDecay; bool fAllowPionDecay; bool fAllowPi0Decay; + bool fNewFormFactor; bool fAddTimeOfFlight; }; @@ -128,13 +128,13 @@ double MuonPartialWidth(double higs_mass, double mixing) { return LeptonPartialWidth(Constants::Instance().muon_mass, higs_mass, mixing); } -double PionPartialWidth(double pion_mass, double higs_mass, double mixing) { +double PionPartialWidth(double pion_mass, double higs_mass, double mixing, bool use_new_ff) { if (pion_mass * 2 >= higs_mass) return 0.; double higgs_vev = Constants::Instance().higgs_vev; double form_factor = 0.; - if (fNewFormFactor) { + if (use_new_ff) { // New, improved form factor based on the plot in arXiv:1909.11670v4 // This form factor is significnatly different than in older versions // The expression is a fit to the Fig. 1 left panel in arXiv:1909.11670v4 @@ -142,7 +142,7 @@ double PionPartialWidth(double pion_mass, double higs_mass, double mixing) { } else { // Old form factor - (2. / 9.) * higs_mass * higs_mass + (11. / 9.) * pion_mass * pion_mass; + form_factor = (2. / 9.) * higs_mass * higs_mass + (11. / 9.) * pion_mass * pion_mass; } double width = (mixing * mixing * 3 * form_factor * form_factor / (32 * M_PI * higgs_vev * higgs_vev * higs_mass)) * pow(1- 4. * pion_mass * pion_mass / (higs_mass * higs_mass), 1. / 2.); @@ -150,12 +150,12 @@ double PionPartialWidth(double pion_mass, double higs_mass, double mixing) { return width; } -double PiPlusPartialWidth(double higs_mass, double mixing) { - return 2*PionPartialWidth(Constants::Instance().piplus_mass, higs_mass, mixing); +double PiPlusPartialWidth(double higs_mass, double mixing, bool use_new_ff) { + return 2*PionPartialWidth(Constants::Instance().piplus_mass, higs_mass, mixing, use_new_ff); } -double PiZeroPartialWidth(double higs_mass, double mixing) { - return PionPartialWidth(Constants::Instance().pizero_mass, higs_mass, mixing); +double PiZeroPartialWidth(double higs_mass, double mixing, bool use_new_ff) { + return PionPartialWidth(Constants::Instance().pizero_mass, higs_mass, mixing, use_new_ff); } HiggsMakeDecay::HiggsMakeDecay(fhicl::ParameterSet const &pset): @@ -177,7 +177,6 @@ void HiggsMakeDecay::configure(fhicl::ParameterSet const &pset) fReferenceRayDistance = pset.get("ReferenceRayDistance", 0.); fReferenceHiggsMass = pset.get("ReferenceHiggsMass", -1); fReferenceHiggsMixing = pset.get("ReferenceHiggsMixing", -1); - fNewFormFactor = pset.get("NewFormFactor", -1); fReferenceHiggsEnergy = pset.get("ReferenceHiggsEnergy", -1); fReferenceHiggsKaonEnergy = pset.get("ReferenceHiggsEnergyFromKaonEnergy", -1.); @@ -185,6 +184,7 @@ void HiggsMakeDecay::configure(fhicl::ParameterSet const &pset) fAllowMuonDecay = pset.get("AllowMuonDecay", true); fAllowPionDecay = pset.get("AllowPionDecay", true); fAllowPi0Decay = pset.get("AllowPi0Decay", true); + fNewFormFactor = pset.get("NewFormFactor", true); fAddTimeOfFlight = pset.get("AddTimeOfFlight", true); if (fReferenceHiggsEnergy < 0. && fReferenceHiggsKaonEnergy > 0.) { @@ -197,8 +197,8 @@ void HiggsMakeDecay::configure(fhicl::ParameterSet const &pset) // Get each partial width double width_elec = ElectronPartialWidth(fReferenceHiggsMass, fReferenceHiggsMixing); double width_muon = MuonPartialWidth(fReferenceHiggsMass, fReferenceHiggsMixing); - double width_piplus = PiPlusPartialWidth(fReferenceHiggsMass, fReferenceHiggsMixing); - double width_pizero = PiZeroPartialWidth(fReferenceHiggsMass, fReferenceHiggsMixing); + double width_piplus = PiPlusPartialWidth(fReferenceHiggsMass, fReferenceHiggsMixing, fNewFormFactor); + double width_pizero = PiZeroPartialWidth(fReferenceHiggsMass, fReferenceHiggsMixing, fNewFormFactor); // total lifetime double lifetime_ns = Constants::Instance().hbar / (width_elec + width_muon + width_piplus + width_pizero); @@ -253,8 +253,8 @@ bool HiggsMakeDecay::Decay(const MeVPrtlFlux &flux, const TVector3 &in, const TV // Get each partial width double width_elec = ElectronPartialWidth(flux.mass, mixing); double width_muon = MuonPartialWidth(flux.mass, mixing); - double width_piplus = PiPlusPartialWidth(flux.mass, mixing); - double width_pizero = PiZeroPartialWidth(flux.mass, mixing); + double width_piplus = PiPlusPartialWidth(flux.mass, mixing, fNewFormFactor); + double width_pizero = PiZeroPartialWidth(flux.mass, mixing, fNewFormFactor); // total lifetime double lifetime_ns = Constants::Instance().hbar / (width_elec + width_muon + width_piplus + width_pizero); From 2ff1bf60f144cb13bd7417f3a746955184bd42f7 Mon Sep 17 00:00:00 2001 From: jberger7 <31707684+jberger7@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:45:23 -0500 Subject: [PATCH 302/367] Update HiggsMakeDecay_tool.cc Simplified the form factor calculation (with some speed improvement) --- .../EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc index f0551f1cc..172e42cf2 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/HiggsMakeDecay_tool.cc @@ -138,7 +138,7 @@ double PionPartialWidth(double pion_mass, double higs_mass, double mixing, bool // New, improved form factor based on the plot in arXiv:1909.11670v4 // This form factor is significnatly different than in older versions // The expression is a fit to the Fig. 1 left panel in arXiv:1909.11670v4 - form_factor = pow(0.289 * pow(higs_mass - 2 * Constants::Instance().pizero_mass,1.5),0.5); + form_factor = 0.537569 * pow(higs_mass - 2 * Constants::Instance().pizero_mass,0.75); } else { // Old form factor From 652109317c6a9ae7477540e86ca4eba947f85117 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Fri, 9 Jan 2026 13:44:59 -0600 Subject: [PATCH 303/367] Adjusting labels for sbnanaobj updates --- sbncode/CAFMaker/FillBlip.cxx | 2 +- sbncode/CAFMaker/FillBlip.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index b6c86422b..fb89174d1 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -39,7 +39,7 @@ namespace caf } - void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRBlipTrueBlip &TrueCAF_Blip ) + void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRTrueBlip &TrueCAF_Blip ) { TrueCAF_Blip.ID = TrueLAr_Blip.ID; TrueCAF_Blip.cryostat = TrueLAr_Blip.Cryostat; diff --git a/sbncode/CAFMaker/FillBlip.h b/sbncode/CAFMaker/FillBlip.h index 4c894ab3d..6e5b77f71 100644 --- a/sbncode/CAFMaker/FillBlip.h +++ b/sbncode/CAFMaker/FillBlip.h @@ -15,7 +15,7 @@ namespace caf { void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips); - void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRBlipTrueBlip &TrueCAF_Blip ); + void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRTrueBlip &TrueCAF_Blip ); void FillBlipRealtedHitCluster(blip::HitClust const & LAr_HitClust, caf::SRBlipHitClust &CAF_HitClust); } From 9442f944fe3a1526225202d942f8b320cf3ca77b Mon Sep 17 00:00:00 2001 From: hbjamin Date: Fri, 9 Jan 2026 15:55:27 -0600 Subject: [PATCH 304/367] code cleanup from requested changes --- sbncode/BeamSpillInfoRetriever/POTTools.cpp | 17 +++++++------ sbncode/BeamSpillInfoRetriever/POTTools.h | 10 ++++---- .../SBNDBNBRetriever_module.cc | 6 ++--- .../SBNDBNBZEROBIASRetriever_module.cc | 6 ++--- sbncode/CAFMaker/CAFMaker_module.cc | 16 +++++++------ sbncode/CAFMaker/FillTrigger.cxx | 24 +++++++++---------- 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.cpp b/sbncode/BeamSpillInfoRetriever/POTTools.cpp index d2b85dc0c..e43dce397 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.cpp +++ b/sbncode/BeamSpillInfoRetriever/POTTools.cpp @@ -20,11 +20,11 @@ namespace sbn::pot{ if (ctb_frag.Trigger(word_i)->IsHLT() && ctb_frag.Trigger(word_i)->IsTrigger(HLT)) { foundHLT = true; - uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS * 20; - uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp * 20; - double currTS_candidate = std::bitset<64>(RawcurrPTBTimeStamp/20).to_ullong()/50e6; + uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS; + uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp; + std::uint64_t currTS_candidate = std::bitset<64>(RawcurrPTBTimeStamp).to_ullong() * 20; if(currTS_candidate < PTBInfo.currPTBTimeStamp){ - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp / 20).to_ullong()/50e6; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp).to_ullong() * 20; PTBInfo.currPTBTimeStamp = currTS_candidate; PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; } @@ -43,9 +43,9 @@ namespace sbn::pot{ } } - std::vector extractAllPTBInfo(art::Handle > cont_frags) { + std::vector extractAllPTBInfo(std::vector const& cont_frags) { std::vector PTBInfoVec; - for (auto const& cont : *cont_frags) + for (auto const& cont : cont_frags) { artdaq::ContainerFragment cont_frag(cont); for (size_t fragi = 0; fragi < cont_frag.block_count(); ++fragi) @@ -58,9 +58,8 @@ namespace sbn::pot{ PTBInfo_t PTBInfo; uint64_t RawprevPTBTimeStamp = ctb_frag.PTBWord(word_i)->prevTS; uint64_t RawcurrPTBTimeStamp = ctb_frag.Trigger(word_i)->timestamp; - double currTS_candidate = std::bitset<64>(RawcurrPTBTimeStamp).to_ullong()/50e6; - PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp).to_ullong()/50e6; - PTBInfo.currPTBTimeStamp = currTS_candidate; + PTBInfo.prevPTBTimeStamp = std::bitset<64>(RawprevPTBTimeStamp).to_ullong() * 20; + PTBInfo.currPTBTimeStamp = std::bitset<64>(RawcurrPTBTimeStamp).to_ullong() * 20; PTBInfo.GateCounter = ctb_frag.Trigger(word_i)->gate_counter; PTBInfo.isHLT = ctb_frag.Trigger(word_i)->IsHLT(); PTBInfo.triggerWord = ctb_frag.Trigger(word_i)->trigger_word; diff --git a/sbncode/BeamSpillInfoRetriever/POTTools.h b/sbncode/BeamSpillInfoRetriever/POTTools.h index 3518f8d3a..1e54647a8 100644 --- a/sbncode/BeamSpillInfoRetriever/POTTools.h +++ b/sbncode/BeamSpillInfoRetriever/POTTools.h @@ -18,16 +18,16 @@ namespace sbn::pot{ typedef struct PTBInfo_t { - double currPTBTimeStamp = 1e20; - double prevPTBTimeStamp = 0; + std::uint64_t currPTBTimeStamp = UINT64_MAX; ///< Timestamp in UTC nanoseconds since Unix epoch (converted from 20ns clock ticks) + std::uint64_t prevPTBTimeStamp = 0; unsigned int GateCounter = 0; bool isHLT = false; - uint64_t triggerWord = 0; + uint64_t triggerWord = 0; ///< Timestamp in s since beam extraction signal } PTBInfo_t; typedef struct TriggerInfo_t { int gate_type = 0; ///< Source of the spill: `1`: BNB, `2`: NuMI - double t_current_event = 0; + double t_current_event = 0; ///< Timestamp in UTC seconds since Unix epoch (converted from 20ns clock ticks) double t_previous_event = 0; unsigned int number_of_gates_since_previous_event = 0; std::int64_t WR_to_Spill_conversion = 0; @@ -52,7 +52,7 @@ namespace sbn::pot{ * @param cont_frags The PTB fragments to examine. * @return Vector of PTBInfo_t containing all triggers found. */ - std::vector extractAllPTBInfo(art::Handle > cont_frags); + std::vector extractAllPTBInfo(std::vector const& cont_frags); /** * @brief Extracts information from TDC for use in SBND POT accounting. diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc index 779be4053..e6465d45b 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/SBNDBNBRetriever_module.cc @@ -123,13 +123,13 @@ sbn::pot::TriggerInfo_t sbn::SBNDBNBRetriever::extractTriggerInfo(art::Event con else{ // If missing TDC, use PTB instead mf::LogDebug("SBNDBNBRetriever") << " Missing TDC Container Fragments!!! " << std::endl; - triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp - fBESOffset; + triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp / 1e9 - fBESOffset; } - triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp - fBESOffset; + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp / 1e9 - fBESOffset; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - double PTBandCurrOffset = PTBInfo.currPTBTimeStamp - triggerInfo.t_current_event - fBESOffset; + double PTBandCurrOffset = PTBInfo.currPTBTimeStamp / 1e9 - triggerInfo.t_current_event - fBESOffset; // Catch for an issue seen a few times where PTB off by a second. // Only need to correct prevTS because either currTS is from TDC diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc index c22c70411..298e0df91 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/SBNDBNBZEROBIASRetriever_module.cc @@ -126,13 +126,13 @@ sbn::pot::TriggerInfo_t sbn::SBNDBNBZEROBIASRetriever::extractTriggerInfo(art::E else{ // If missing TDC, use PTB instead mf::LogDebug("SBNDBNBZEROBIASRetriever") << " Missing TDC Container Fragments!!!" << std::endl; - triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp - fBESOffset; + triggerInfo.t_current_event = PTBInfo.currPTBTimeStamp / 1e9 - fBESOffset; } - triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp - fBESOffset; + triggerInfo.t_previous_event = PTBInfo.prevPTBTimeStamp / 1e9 - fBESOffset; triggerInfo.number_of_gates_since_previous_event = PTBInfo.GateCounter; - double PTBandCurrOffset = PTBInfo.currPTBTimeStamp - triggerInfo.t_current_event - fBESOffset; + double PTBandCurrOffset = PTBInfo.currPTBTimeStamp / 1e9 - triggerInfo.t_current_event - fBESOffset; // Catch for an issue seen a few times where PTB off by a second. // Only need to correct prevTS because either currTS is from TDC diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 04550ffaf..29ead35da 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1380,6 +1380,7 @@ bool CAFMaker::GetPsetParameter(const fhicl::ParameterSet& pset, //...................................................................... void CAFMaker::produce(art::Event& evt) noexcept { + mf::LogInfo("CAFMaker") << "CAFMaker::produce called for event: " << evt.id(); bool const firstInFile = (fIndexInFile++ == 0); @@ -1720,13 +1721,14 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::Handle ptb_frags_handle; evt.getByLabel(PTB_itag, ptb_frags_handle); if (ptb_frags_handle.isValid()) { - try { - std::vector ptb_triggers = sbn::pot::extractAllPTBInfo(ptb_frags_handle); - FillPTBTriggersSBND(ptb_triggers, srtrigger); - } - catch (...) { - std::cout << "CAFMaker: Failed to extract PTB triggers" << std::endl; - } + mf::LogDebug("CAFMaker") << "Found ContainerPTB, extracting PTB triggers..."; + std::vector ptb_triggers = sbn::pot::extractAllPTBInfo(*ptb_frags_handle); + mf::LogDebug("CAFMaker") << "Extracted " << ptb_triggers.size() << " PTB triggers"; + FillPTBTriggersSBND(ptb_triggers, srtrigger); + mf::LogDebug("CAFMaker") << "PTB HLT triggers: " << srtrigger.ptb_hlt_timestamp.size() + << ", LLT triggers: " << srtrigger.ptb_llt_timestamp.size(); + } else { + mf::LogDebug("CAFMaker") << "ContainerPTB not found for event " << evt.id(); } } diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 2fcf30914..10805371e 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -1,4 +1,5 @@ #include +#include #include "sbncode/CAFMaker/FillTrigger.h" namespace caf @@ -82,18 +83,17 @@ namespace caf // Decode trigger words: each set bit becomes a separate entry with the same timestamp for(const auto& trig : ptb_triggers) { - std::uint64_t triggerWord = trig.triggerWord; - for(int bit = 0; bit < 64; ++bit) { - std::uint64_t bitMask = 1ULL << bit; - if(triggerWord & bitMask) { - if(trig.isHLT) { - triggerInfo.ptb_hlt_timestamp.push_back(trig.currPTBTimeStamp); - triggerInfo.ptb_hlt_bit.push_back(bit); - } else { - triggerInfo.ptb_llt_timestamp.push_back(trig.currPTBTimeStamp); - triggerInfo.ptb_llt_bit.push_back(bit); - } - } + // Choose destination vectors based on trigger type + auto& ptb_timestamp = trig.isHLT ? triggerInfo.ptb_hlt_timestamp : triggerInfo.ptb_llt_timestamp; + auto& ptb_bit = trig.isHLT ? triggerInfo.ptb_hlt_bit : triggerInfo.ptb_llt_bit; + + std::bitset<64> const triggerWord { trig.triggerWord }; + // currPTBTimeStamp is already in nanoseconds (uint64_t), use directly + // Loop variable is uint8_t since we know bit values are 0-63 (fits in uint8_t) + for(std::uint8_t bit = 0; bit < triggerWord.size(); ++bit) { + if(!triggerWord[bit]) continue; + ptb_timestamp.push_back(trig.currPTBTimeStamp); + ptb_bit.push_back(bit); } } } From 0f08627b2ecaabfc77c3d61e6cba80b84a94f291 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Fri, 9 Jan 2026 16:17:18 -0600 Subject: [PATCH 305/367] bugfix MeVPrtl to classify boone ntuple flux type as simple flux, and fix flux weight calculator to pick neutrino energy from MCTruth if MCFlux energy is -1 --- sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc | 2 +- sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc index 6d4ed4711..7d74a9942 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc @@ -311,7 +311,7 @@ simb::MCFlux BNBKaonGen::MakeMCFlux(const bsim::BooNe &boone) { << std::endl; } - flux.fFluxType = simb::kDk2Nu; + flux.fFluxType = simb::kSimple_Flux; flux.fnimpwt = fBooneNtp.beamwgt; flux.fvx = fBooneNtp.ini_pos[0][0]; //0 flux.fvy = fBooneNtp.ini_pos[0][1]; //0 diff --git a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx index d832e8638..ff2b10b99 100644 --- a/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx +++ b/sbncode/SBNEventWeight/Calculators/BNBFlux/FluxCalcPrep.cxx @@ -224,7 +224,7 @@ namespace sbn { } //or do the above 3 lines in one line -// auto const& mclist = *e.getValidHandle>(fGeneratorModuleLabel); + auto const& mclist = *e.getValidHandle>(fGeneratorModuleLabel); // If no neutrinos in this event, gives 0 weight; int NUni = fParameterSet.fNuniverses; @@ -264,8 +264,8 @@ namespace sbn { } // Collect neutrino energy; mclist is replaced with fluxlist. -// double enu= mclist[inu].GetNeutrino().Nu().E(); double enu= fluxlist[inu].fnenergyn; + if ( enu == -1 ) enu= mclist[inu].GetNeutrino().Nu().E(); //For MeVPrtl generator, not all MCFlux result in a neutrino, so equivalent neutrino energy is computed and saved as MCTruth //Let's make a weights based on the calculator you have requested From 9ed57fe48baf71091e107a6bc33446bc44f1d20c Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:04:46 -0600 Subject: [PATCH 306/367] Fix some loop bonuds --- sbncode/CAFMaker/FillTrue.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index ef1b4cc0c..41fff543e 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -465,7 +465,7 @@ namespace caf { srneutrino.index = i; - for (int c = 0; c < 2; c++) { + for (int c = 0; c < (int)active_volumes.size(); c++) { SRTrueInteractionPlaneInfo init; init.visE = 0.; init.nhit = 0; @@ -483,7 +483,7 @@ namespace caf { // total up the deposited energy for(int p = 0; p < 3; ++p) { - for (int i_cryo = 0; i_cryo < 2; i_cryo++) { + for (int i_cryo = 0; i_cryo < (int)active_volumes.size(); i_cryo++) { srneutrino.plane[i_cryo][p].visE += part.plane[i_cryo][p].visE; } } @@ -493,7 +493,7 @@ namespace caf { // Set of hits per-plane: primary particles { - std::vector, 3>> planehitIDs(2); + std::vector, 3>> planehitIDs(active_volumes.size()); for (unsigned i_part = 0; i_part < srparticles.size(); i_part++) { if (srparticles[i_part].start_process == caf::kG4primary && srparticles[i_part].interaction_id == (int)i) { int track_id = srparticles[i_part].G4ID; @@ -507,7 +507,7 @@ namespace caf { } for(int p = 0; p < 3; ++p) { - for (int i_cryo = 0; i_cryo < 2; i_cryo++) { + for (int i_cryo = 0; i_cryo < (int)active_volumes.size(); i_cryo++) { srneutrino.plane[i_cryo][p].nhitprim = planehitIDs[i_cryo][p].size(); } } @@ -515,7 +515,7 @@ namespace caf { // Set of hits per-plane: all particles { - std::vector, 3>> planehitIDs(2); + std::vector, 3>> planehitIDs(active_volumes.size()); for (unsigned i_part = 0; i_part < srparticles.size(); i_part++) { if (srparticles[i_part].interaction_id == (int)i) { int track_id = srparticles[i_part].G4ID; @@ -529,7 +529,7 @@ namespace caf { } for(int p = 0; p < 3; ++p) { - for (int i_cryo = 0; i_cryo < 2; i_cryo++) { + for (int i_cryo = 0; i_cryo < (int)active_volumes.size(); i_cryo++) { srneutrino.plane[i_cryo][p].nhit = planehitIDs[i_cryo][p].size(); } } @@ -599,7 +599,7 @@ namespace caf { } // Set the cryostat of the position - for (int icryo = 0; icryo < 2; icryo++) { + for (int icryo = 0; icryo < (int)active_volumes.size(); icryo++) { if (active_volumes[icryo].ContainsPosition(nu.Nu().Position().Vect())) { srneutrino.cryostat = icryo; break; From a21662e49bbb4588a2f832341422c7176b690d41 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 14 Jan 2026 12:45:21 -0600 Subject: [PATCH 307/367] revert change to 2x3 arrays --- sbncode/CAFMaker/FillTrue.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index 41fff543e..8b433628b 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -493,7 +493,7 @@ namespace caf { // Set of hits per-plane: primary particles { - std::vector, 3>> planehitIDs(active_volumes.size()); + std::vector, 3>> planehitIDs(2); for (unsigned i_part = 0; i_part < srparticles.size(); i_part++) { if (srparticles[i_part].start_process == caf::kG4primary && srparticles[i_part].interaction_id == (int)i) { int track_id = srparticles[i_part].G4ID; @@ -515,7 +515,7 @@ namespace caf { // Set of hits per-plane: all particles { - std::vector, 3>> planehitIDs(active_volumes.size()); + std::vector, 3>> planehitIDs(2); for (unsigned i_part = 0; i_part < srparticles.size(); i_part++) { if (srparticles[i_part].interaction_id == (int)i) { int track_id = srparticles[i_part].G4ID; From df2423866e4618fe3394149012bde1bad420f396 Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Wed, 14 Jan 2026 13:58:32 -0600 Subject: [PATCH 308/367] make sure all planes filled --- sbncode/CAFMaker/FillTrue.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/FillTrue.cxx b/sbncode/CAFMaker/FillTrue.cxx index 8b433628b..4d1d794d0 100644 --- a/sbncode/CAFMaker/FillTrue.cxx +++ b/sbncode/CAFMaker/FillTrue.cxx @@ -465,7 +465,7 @@ namespace caf { srneutrino.index = i; - for (int c = 0; c < (int)active_volumes.size(); c++) { + for (int c = 0; c < 2; c++) { SRTrueInteractionPlaneInfo init; init.visE = 0.; init.nhit = 0; @@ -483,7 +483,7 @@ namespace caf { // total up the deposited energy for(int p = 0; p < 3; ++p) { - for (int i_cryo = 0; i_cryo < (int)active_volumes.size(); i_cryo++) { + for (int i_cryo = 0; i_cryo < 2; i_cryo++) { srneutrino.plane[i_cryo][p].visE += part.plane[i_cryo][p].visE; } } @@ -507,7 +507,7 @@ namespace caf { } for(int p = 0; p < 3; ++p) { - for (int i_cryo = 0; i_cryo < (int)active_volumes.size(); i_cryo++) { + for (int i_cryo = 0; i_cryo < 2; i_cryo++) { srneutrino.plane[i_cryo][p].nhitprim = planehitIDs[i_cryo][p].size(); } } @@ -529,7 +529,7 @@ namespace caf { } for(int p = 0; p < 3; ++p) { - for (int i_cryo = 0; i_cryo < (int)active_volumes.size(); i_cryo++) { + for (int i_cryo = 0; i_cryo < 2; i_cryo++) { srneutrino.plane[i_cryo][p].nhit = planehitIDs[i_cryo][p].size(); } } From c771df6530e07b90d767ef3e8381e36680153cbe Mon Sep 17 00:00:00 2001 From: kjplows Date: Fri, 16 Jan 2026 02:42:45 -0600 Subject: [PATCH 309/367] Update dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d6932da42..30d44276d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.14.02 LANGUAGES CXX) +project(sbncode VERSION 10.14.02.01 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 2ff8b27d9..ef50b16bb 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_14_02 - +larsoft v10_14_02_01 - sbnalg v10_14_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - From b34ca44e9435e77260a79be6c0999f0a3be43087 Mon Sep 17 00:00:00 2001 From: VCLanNguyen <74775793+VCLanNguyen@users.noreply.github.com> Date: Tue, 27 Jan 2026 12:09:31 -0800 Subject: [PATCH 310/367] Change flux type from kSimple_Flux to kNtuple --- sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc b/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc index 7d74a9942..b5d89027f 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc +++ b/sbncode/EventGenerator/MeVPrtl/Tools/BNBKaonGen_tool.cc @@ -311,7 +311,7 @@ simb::MCFlux BNBKaonGen::MakeMCFlux(const bsim::BooNe &boone) { << std::endl; } - flux.fFluxType = simb::kSimple_Flux; + flux.fFluxType = simb::kNtuple; flux.fnimpwt = fBooneNtp.beamwgt; flux.fvx = fBooneNtp.ini_pos[0][0]; //0 flux.fvy = fBooneNtp.ini_pos[0][1]; //0 From 769973563c8637c94d6f3dc242e3c14ad8b4bb0e Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 28 Jan 2026 11:49:10 -0600 Subject: [PATCH 311/367] Updated dependencies --- CMakeLists.txt | 4 +++- ups/product_deps | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30d44276d..04594c488 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,9 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.14.02.01 LANGUAGES CXX) +project(sbncode VERSION 10.14.02.02 LANGUAGES CXX) +# Explicitly set the project string +set(${PROJECT_NAME}_CMAKE_PROJECT_VERSION_STRING "10.14.02__02sbn2") message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index ef50b16bb..db6b158ad 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -252,14 +252,14 @@ libdir fq_dir lib # #################################### product version qual flags -genie_xsec v3_06_00 - +genie_xsec v3_06_02_sbn2 - larcv2 v2_2_6 - -larsoft v10_14_02_01 - -sbnalg v10_14_02 - +larsoft v10_14_02_01sbn2 - +sbnalg v10_14_02_01sbn2 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_10 - +nusystematics v1_05_10_sbn2 - geant4reweight v01_20_14 - cetmodules v3_24_01 - only_for_build end_product_list @@ -317,10 +317,10 @@ end_product_list # #################################### qualifier larsoft sbnalg sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics geant4reweight notes -c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug c14:debug:s131 -nq- -c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof c14:prof:s131 -nq- -e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug e26:debug:s131 -nq- -e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof e26:prof:s131 -nq- +c14:debug c14:debug c14:debug c14:s131:debug AR2520i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug c14:debug:s131 -nq- +c14:prof c14:prof c14:prof c14:s131:prof AR2520i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof c14:prof:s131 -nq- +e26:debug e26:debug e26:debug e26:s131:debug AR2520i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug e26:debug:s131 -nq- +e26:prof e26:prof e26:prof e26:s131:prof AR2520i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof e26:prof:s131 -nq- end_qualifier_list #################################### From 1c450951bcd37b1b004aad023c9f7112e21af6c8 Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 28 Jan 2026 12:14:05 -0600 Subject: [PATCH 312/367] Updated dependencies --- CMakeLists.txt | 2 -- ups/product_deps | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04594c488..ba83a63c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,6 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) project(sbncode VERSION 10.14.02.02 LANGUAGES CXX) -# Explicitly set the project string -set(${PROJECT_NAME}_CMAKE_PROJECT_VERSION_STRING "10.14.02__02sbn2") message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index db6b158ad..aa18b1188 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,12 +254,12 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_02_sbn2 - larcv2 v2_2_6 - -larsoft v10_14_02_01sbn2 - -sbnalg v10_14_02_01sbn2 - +larsoft v10_14_02_01 - +sbnalg v10_14_02_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_10_sbn2 - +nusystematics v1_05_10 - geant4reweight v01_20_14 - cetmodules v3_24_01 - only_for_build end_product_list From 4227f96cc9bd87b562b6cc94c253c1dc9c8df2a1 Mon Sep 17 00:00:00 2001 From: Seokju Chung Date: Fri, 30 Jan 2026 12:57:13 -0600 Subject: [PATCH 313/367] Filter was not working. Copied working RES structure and changed to DeltaRad filter --- ...tion_tpc_NCDeltaRadiative_filtered_sbnd.fcl | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/sbncode/SinglePhotonAnalysis/jobs/prodgenie_nu_singleinteraction_tpc_NCDeltaRadiative_filtered_sbnd.fcl b/sbncode/SinglePhotonAnalysis/jobs/prodgenie_nu_singleinteraction_tpc_NCDeltaRadiative_filtered_sbnd.fcl index 72716d7fd..9a5c117b4 100644 --- a/sbncode/SinglePhotonAnalysis/jobs/prodgenie_nu_singleinteraction_tpc_NCDeltaRadiative_filtered_sbnd.fcl +++ b/sbncode/SinglePhotonAnalysis/jobs/prodgenie_nu_singleinteraction_tpc_NCDeltaRadiative_filtered_sbnd.fcl @@ -1,26 +1,20 @@ # Simulates GENIE neutrino interactions from the BNB beam # forcing one interaction per event, inside the TPC volume # (with 10 cm padding on each side), -# selecting only NC events with photons coming out from the delta decay +# selecting only NC events with photons coming out from the Delta +#include "prodgenie_nu_singleinteraction_tpc_sbnd.fcl" + +#------ this could be a separated file # # services # -#include "services_sbnd.fcl" -#include "messages_sbnd.fcl" - # # modules # -#include "filters_sbnd.fcl" -#include "emptyevent_sbnd.fcl" -#include "genie_sbnd.fcl" - - - process_name: GenieGenFiltered @@ -108,5 +102,5 @@ outputs: # override # THIS DOES NOT WORK, CHECK! physics.producers.generator.TopVolume: "volTPCActive" -#physics.producers.generator.BeamName: "booster" -#physics.producers.generator.EventGeneratorList: "NCRES" +physics.producers.generator.BeamName: "booster" +physics.producers.generator.EventGeneratorList: "NCRES" From 78ed4004d01056f5655dd60057257e4045ac3977 Mon Sep 17 00:00:00 2001 From: Lynn Garren Date: Fri, 30 Jan 2026 14:04:39 -0600 Subject: [PATCH 314/367] building for geant4 4.11 --- sbncode/OpT0Finder/flashmatch/Algorithms/CMakeLists.txt | 2 +- sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt | 1 + ups/product_deps | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sbncode/OpT0Finder/flashmatch/Algorithms/CMakeLists.txt b/sbncode/OpT0Finder/flashmatch/Algorithms/CMakeLists.txt index c6ee1e2d3..eb08314d2 100644 --- a/sbncode/OpT0Finder/flashmatch/Algorithms/CMakeLists.txt +++ b/sbncode/OpT0Finder/flashmatch/Algorithms/CMakeLists.txt @@ -2,7 +2,7 @@ art_make_library( LIBRARIES larsim::PhotonPropagation larsim::PhotonPropagation_PhotonVisibilityService_service - larsim::LegacyLArG4 + #larsim::LegacyLArG4 #sbncode_OpT0Finder_flashmatch_GeoAlgo sbncode_OpT0Finder_flashmatch_Base larcorealg::GeoAlgo diff --git a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt index 568ecc7f6..b064daff0 100644 --- a/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt +++ b/sbncode/SBNEventWeight/Calculators/Geant4/CMakeLists.txt @@ -13,6 +13,7 @@ art_make_library( art_root_io::TFileService_service larcore::Geometry_Geometry_service cetlib_except::cetlib_except + Geant4::G4ptl ReweightBaseLib PropBaseLib ROOT::Tree diff --git a/ups/product_deps b/ups/product_deps index ef50b16bb..9247f5e20 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,13 +254,13 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_14_02_01 - +larsoft v10_17_00 - sbnalg v10_14_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_10 - -geant4reweight v01_20_14 - +nusystematics v1_05_11 - +geant4reweight v01_21_02 - cetmodules v3_24_01 - only_for_build end_product_list #################################### From 051277a84300656665d349a933436e5a6816a1ba Mon Sep 17 00:00:00 2001 From: kjplows Date: Wed, 4 Feb 2026 09:46:32 -0600 Subject: [PATCH 315/367] Updated dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba83a63c9..d797dc2d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.14.02.02 LANGUAGES CXX) +project(sbncode VERSION 10.14.02.03 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index aa18b1188..483437ae1 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,12 +254,12 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_02_sbn2 - larcv2 v2_2_6 - -larsoft v10_14_02_01 - +larsoft v10_14_02_02 - sbnalg v10_14_02_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_10 - +nusystematics v1_05_10sbn02 - geant4reweight v01_20_14 - cetmodules v3_24_01 - only_for_build end_product_list From 805020e6d45cfa7b0e81a6fad281358ddcce23b9 Mon Sep 17 00:00:00 2001 From: Michael Carrigan Date: Wed, 21 Jan 2026 15:54:23 -0600 Subject: [PATCH 316/367] update GaussHitFinderSBN_module to take per plane hit finding parameters --- sbncode/CAFMaker/RecoUtils/CMakeLists.txt | 2 ++ sbncode/HitFinder/GaussHitFinderSBN_module.cc | 16 ++++++------ sbncode/HitFinder/hitfindermodules_sbn.fcl | 26 ++++++++++--------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/sbncode/CAFMaker/RecoUtils/CMakeLists.txt b/sbncode/CAFMaker/RecoUtils/CMakeLists.txt index a992d7c63..545bdad69 100644 --- a/sbncode/CAFMaker/RecoUtils/CMakeLists.txt +++ b/sbncode/CAFMaker/RecoUtils/CMakeLists.txt @@ -11,4 +11,6 @@ art_make_library( LIBRARY_NAME caf_RecoUtils larsim::MCCheater_BackTrackerService_service larsim::MCCheater_ParticleInventoryService_service larcorealg::Geometry + sbnanaobj::StandardRecord + sbnanaobj::StandardRecordFlat ) diff --git a/sbncode/HitFinder/GaussHitFinderSBN_module.cc b/sbncode/HitFinder/GaussHitFinderSBN_module.cc index c0a91cc91..b7e952206 100644 --- a/sbncode/HitFinder/GaussHitFinderSBN_module.cc +++ b/sbncode/HitFinder/GaussHitFinderSBN_module.cc @@ -79,11 +79,11 @@ namespace hit { const std::vector fLongMaxHitsVec; /// fLongPulseWidthVec; /// fMaxMultiHit; /// fAreaNormsVec; /// fChi2NDF; ///maximum Chisquared / NDF allowed for a hit to be saved const std::vector fPulseHeightCuts; const std::vector fPulseWidthCuts; @@ -116,10 +116,10 @@ namespace hit { , fLongMaxHitsVec(pset.get>("LongMaxHits", std::vector() = {25, 25, 25})) , fLongPulseWidthVec( pset.get>("LongPulseWidth", std::vector() = {16, 16, 16})) - , fMaxMultiHit(pset.get("MaxMultiHit")) + , fMaxMultiHit(pset.get>("MaxMultiHitPerPlane", std::vector() = {5, 5, 5})) , fAreaMethod(pset.get("AreaMethod")) , fAreaNormsVec(FillOutHitParameterVector(pset.get>("AreaNorms"))) - , fChi2NDF(pset.get("Chi2NDF")) + , fChi2NDF(pset.get>("Chi2NDFPerPlane", std::vector() = {500.0, 500.0, 500.0})) , fPulseHeightCuts( pset.get>("PulseHeightCuts", std::vector() = {3.0, 3.0, 3.0})) , fPulseWidthCuts( @@ -365,13 +365,13 @@ namespace hit { // ####################################################### // ### If # requested Gaussians is too large then punt ### // ####################################################### - if (mergedCands.size() <= fMaxMultiHit) { + if (mergedCands.size() <= fMaxMultiHit.at(plane)) { fPeakFitterTool->findPeakParameters( range.data(), mergedCands, peakParamsVec, chi2PerNDF, NDF); // If the chi2 is infinite then there is a real problem so we bail if (!(chi2PerNDF < std::numeric_limits::infinity())) { - chi2PerNDF = 2. * fChi2NDF; + chi2PerNDF = 2. * fChi2NDF.at(plane); NDF = 2; } @@ -384,7 +384,7 @@ namespace hit { // ### depend on the fhicl parameter fLongPulseWidth ### // ### Also do this if chi^2 is too large ### // ####################################################### - if (mergedCands.size() > fMaxMultiHit || nGausForFit * chi2PerNDF > fChi2NDF) { + if (mergedCands.size() > fMaxMultiHit.at(plane) || nGausForFit * chi2PerNDF > fChi2NDF.at(plane)) { int longPulseWidth = fLongPulseWidthVec.at(plane); int nHitsThisPulse = (endT - startT) / longPulseWidth; @@ -401,7 +401,7 @@ namespace hit { peakParamsVec.clear(); nGausForFit = nHitsThisPulse; NDF = 1.; - chi2PerNDF = chi2PerNDF > fChi2NDF ? chi2PerNDF : -1.; + chi2PerNDF = chi2PerNDF > fChi2NDF.at(plane) ? chi2PerNDF : -1.; for (int hitIdx = 0; hitIdx < nHitsThisPulse; hitIdx++) { // This hit parameters diff --git a/sbncode/HitFinder/hitfindermodules_sbn.fcl b/sbncode/HitFinder/hitfindermodules_sbn.fcl index 868e5a2b8..099e784b4 100644 --- a/sbncode/HitFinder/hitfindermodules_sbn.fcl +++ b/sbncode/HitFinder/hitfindermodules_sbn.fcl @@ -11,17 +11,19 @@ gauss_hitfinder: { module_type: "GaussHitFinderSBN" CalDataModuleLabel: "caldata" - MaxMultiHit: 5 # maximum hits for multi gaussia fit attempt - AreaMethod: 0 # 0 = area by integral, 1 = area by gaussian area formula - AreaNorms: [ 1.0, 1.0, 1.0 ] # normalizations that put signal area in - # same scale as peak height. - TryNplus1Fits: false # Don't try to refit with extra peak if bad chisq - LongMaxHits: [ 25, 25, 25] # max number hits in long pulse trains - LongPulseWidth: [ 10, 10, 10] # max widths for hits in long pulse trains - Chi2NDF: 500. # maximum Chisquared / NDF allowed to store fit, if fail - # will use "long" pulse method to return hit - AllHitsInstanceName: "" # If non-null then this will be the instance name of all hits output to event - # in this case there will be two hit collections, one filtered and one containing all hits + MaxMultiHit: 5 # maximum hits for multi gaussian fit attempt + MaxMultiHitPerPlane: [ 10, 10, 8 ] # maximum hits per plane for multi gaussia fit attempt + AreaMethod: 0 # 0 = area by integral, 1 = area by gaussian area formula + AreaNorms: [ 1.0, 1.0, 1.0 ] # normalizations that put signal area in + # same scale as peak height. + TryNplus1Fits: false # Don't try to refit with extra peak if bad chisq + LongMaxHits: [ 25, 25, 25] # max number hits in long pulse trains + LongPulseWidth: [ 5, 5, 5] # max widths for hits in long pulse trains + Chi2NDF: 500. # maximum Chisquared / NDF allowed to store fit + Chi2NDFPerPlane: [ 2500., 1750., 2500.] # maximum Chisquared / NDF allowed per plane to store, if fail + # will use "long" pulse method to return hit + AllHitsInstanceName: "" # If non-null then this will be the instance name of all hits output to event + # in this case there will be two hit collections, one filtered and one containing all hits # Candididate peak finding done by tool, one tool instantiated per plane (but could be other divisions too) HitFinderToolVec: @@ -39,7 +41,7 @@ gauss_hitfinder: HitFilterAlg: { AlgName: "HitFilterAlg" - MinPulseHeight: [5.0, 5.0, 5.0] #minimum hit peak amplitude per plane + MinPulseHeight: [2.0, 2.0, 2.0] #minimum hit peak amplitude per plane MinPulseSigma: [1.0, 1.0, 1.0] #minimum hit rms per plane } # In addition to the filter alg we can also filter hits on the same pulse train From f41b6b8e890cbb9a018a848add07bda130f8fcfc Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Tue, 10 Feb 2026 11:21:24 -0600 Subject: [PATCH 317/367] fix typo --- sbncode/CAFMaker/FillBlip.cxx | 4 ++-- sbncode/CAFMaker/FillBlip.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index fb89174d1..5d71edb35 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -32,7 +32,7 @@ namespace caf } for(int iPlane=0; iPlane& LAr_Blips, std::vector& CAF_Blips); void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRTrueBlip &TrueCAF_Blip ); - void FillBlipRealtedHitCluster(blip::HitClust const & LAr_HitClust, caf::SRBlipHitClust &CAF_HitClust); + void FillBlipRelatedHitCluster(blip::HitClust const & LAr_HitClust, caf::SRBlipHitClust &CAF_HitClust); } #endif From 202064e567c2fcdf144ae94523bbd4f4348d6655 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Mon, 16 Feb 2026 11:30:47 -0600 Subject: [PATCH 318/367] clean up intermediate vectors --- sbncode/CAFMaker/CAFMaker_module.cc | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 5e91fccaf..6e9f4caca 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1445,15 +1445,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::fill_ptr_vector(simchannels, simchannel_handle); } - // get sim energy deposits if they're there - ::art::Handle> sed_handle; - GetByLabelStrict(evt, fParams.SimEnergyDepositLabel().encode(), sed_handle); - - std::vector> seds; - if (sed_handle.isValid()){ - art::fill_ptr_vector(seds, sed_handle); - } - art::Handle> mcflux_handle; GetByLabelStrict(evt, std::string("generator"), mcflux_handle); @@ -1648,6 +1639,9 @@ void CAFMaker::produce(art::Event& evt) noexcept { } // end for fm } // end for i (mctruths) + // get sim energy deposits if they're there + ::art::Handle> sed_handle; + GetByLabelStrict(evt, fParams.SimEnergyDepositLabel().encode(), sed_handle); if (!isRealData && sed_handle.isValid()){ art::ServiceHandle pi_serv; @@ -1661,18 +1655,17 @@ void CAFMaker::produce(art::Event& evt) noexcept { srtruthbranch.dep.push_back(init); } - for (size_t n_dep=0; n_dep < seds.size(); n_dep++){ - auto sed = seds[n_dep]; - const auto trackID = sed->TrackID(); + for (sim::SimEnergyDeposit const& sed: *sed_handle){ + const auto trackID = sed.TrackID(); art::Ptr mctruth = pi_serv->TrackIdToMCTruth_P(trackID); auto it = std::find(mctruths.begin(), mctruths.end(), mctruth); if (it == mctruths.end()) continue; auto idx = std::distance(mctruths.begin(), it); - srtruthbranch.dep.at(idx).energy += sed->Energy()*1e-3; // GeV - srtruthbranch.dep.at(idx).photons += sed->NumPhotons(); - srtruthbranch.dep.at(idx).electrons += sed->NumElectrons(); + srtruthbranch.dep.at(idx).energy += sed.Energy()*1e-3; // GeV + srtruthbranch.dep.at(idx).photons += sed.NumPhotons(); + srtruthbranch.dep.at(idx).electrons += sed.NumElectrons(); } } @@ -2091,10 +2084,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::FindOneP foLightCalo = FindOnePStrict(sliceList,evt, fParams.LightCaloLabel() + slice_tag_suff); - const sbn::LightCalo *slcLightCalo = nullptr; - if (foLightCalo.isValid()) { - slcLightCalo = foLightCalo.at(0).get(); - } + const sbn::LightCalo *slcLightCalo = foLightCalo.isValid()? foLightCalo.at(0).get() : nullptr; art::FindOneP foCVNResult = FindOnePStrict(sliceList, evt, From 960b575b92727421a4dfde449c744f7d5b265605 Mon Sep 17 00:00:00 2001 From: lynnt20 Date: Mon, 16 Feb 2026 11:36:10 -0600 Subject: [PATCH 319/367] Revert "Update dependencies" This reverts commit c771df6530e07b90d767ef3e8381e36680153cbe. --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30d44276d..d6932da42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.14.02.01 LANGUAGES CXX) +project(sbncode VERSION 10.14.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index ef50b16bb..2ff8b27d9 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_14_02_01 - +larsoft v10_14_02 - sbnalg v10_14_02 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - From e8db3c570aa6e6d82f0eb5f47c6a18a07b63ed3a Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Tue, 17 Feb 2026 04:54:40 -0600 Subject: [PATCH 320/367] Fill new fields for SBND CRT --- sbncode/CAFMaker/CAFMaker_module.cc | 39 +++++++++++++++++++++++++++-- sbncode/CAFMaker/FillReco.cxx | 9 ++++++- sbncode/CAFMaker/FillReco.h | 3 +++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 9f2c01590..b04dc631c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -352,6 +352,10 @@ class CAFMaker : public art::EDProducer { art::FindOneP FindOnePStrict(const U& from, const art::Event& evt, const art::InputTag& label) const; + template + art::FindOneP FindOnePStrictSingle(const U& from, const art::Event& evt, + const art::InputTag& label) const; + template art::FindOneP FindOnePDStrict(const U& from, const art::Event& evt, @@ -1299,6 +1303,27 @@ art::FindOneP CAFMaker::FindOnePStrict(const U& from, return ret; } +//...................................................................... +template +art::FindOneP CAFMaker::FindOnePStrictSingle(const U& from, + const art::Event& evt, + const art::InputTag& tag) const { + std::vector vec = { from }; + + art::FindOneP ret(vec, evt, tag); + + if (!tag.label().empty() && !ret.isValid() && fParams.StrictMode()) { + std::cout << "CAFMaker: No Assn from '" + << cet::demangle_symbol(typeid(from).name()) << "' to '" + << cet::demangle_symbol(typeid(T).name()) + << "' found under label '" << tag << "'. " + << "Set 'StrictMode: false' to continue anyway." << std::endl; + abort(); + } + + return ret; +} + //...................................................................... template art::FindOneP CAFMaker::FindOnePDStrict(const U& from, @@ -1791,12 +1816,15 @@ void CAFMaker::produce(art::Event& evt) noexcept { { art::Handle> crtspacepoints_handle; GetByLabelStrict(evt, fParams.CRTSpacePointLabel(), crtspacepoints_handle); + art::FindOneP foCRTCluster = + FindOnePStrict(crtspacepoints_handle, evt, fParams.CRTSpacePointLabel()); if (crtspacepoints_handle.isValid()) { const std::vector &crtspacepoints = *crtspacepoints_handle; for (unsigned i = 0; i < crtspacepoints.size(); i++) { srcrtspacepoints.emplace_back(); - FillCRTSpacePoint(crtspacepoints[i], srcrtspacepoints.back()); + const art::Ptr crtcluster = foCRTCluster.at(i); + FillCRTSpacePoint(crtspacepoints[i], crtcluster, srcrtspacepoints.back()); } } @@ -2239,6 +2267,9 @@ void CAFMaker::produce(art::Event& evt) noexcept { FindOnePDStrict(slcTracks, evt, fParams.CRTSpacePointMatchLabel() + slice_tag_suff); + art::Handle> crtspacepoints_handle; + GetByLabelStrict(evt, fParams.CRTSpacePointLabel(), crtspacepoints_handle); + art::FindOneP foSBNDCRTTrackMatch = FindOnePDStrict(slcTracks, evt, fParams.SBNDCRTTrackMatchLabel() + slice_tag_suff); @@ -2515,8 +2546,12 @@ void CAFMaker::produce(art::Event& evt) noexcept { { const art::Ptr crtspacepoint = foCRTSpacePointMatch.at(iPart); + art::FindOneP foCRTCluster = + FindOnePStrictSingle(crtspacepoint, evt, fParams.CRTSpacePointLabel()); + const art::Ptr crtcluster = foCRTCluster.at(0); + if(crtspacepoint.isNonnull()) - FillTrackCRTSpacePoint(foCRTSpacePointMatch.data(iPart).ref(), crtspacepoint, trk); + FillTrackCRTSpacePoint(foCRTSpacePointMatch.data(iPart).ref(), crtspacepoint, crtcluster, trk); } if(foSBNDCRTTrackMatch.isValid() && fDet == kSBND) { diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 46396a2c1..ba1b19b61 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -164,6 +164,7 @@ namespace caf } void FillCRTSpacePoint(const sbnd::crt::CRTSpacePoint &spacepoint, + const art::Ptr &cluster, caf::SRCRTSpacePoint &srspacepoint, bool allowEmpty) { @@ -173,6 +174,8 @@ namespace caf srspacepoint.time = spacepoint.Ts0(); srspacepoint.time_err = spacepoint.Ts0Err(); srspacepoint.complete = spacepoint.Complete(); + srspacepoint.nhits = cluster->NHits(); + srspacepoint.tagger = cluster->Tagger(); } void FillSBNDCRTTrack(const sbnd::crt::CRTTrack &track, @@ -186,6 +189,9 @@ namespace caf srsbndcrttrack.time_err = track.Ts0Err(); srsbndcrttrack.pe = track.PE(); srsbndcrttrack.tof = track.ToF(); + + for(auto const& tagger : track.Taggers()) + srsbndcrttrack.taggers.push_back(tagger); } void FillSBNDCRTVeto(const sbnd::crt::CRTVeto &veto, @@ -811,11 +817,12 @@ namespace caf void FillTrackCRTSpacePoint(const anab::T0 &t0match, const art::Ptr &spacepointmatch, + const art::Ptr &cluster, caf::SRTrack &srtrack, bool allowEmpty) { srtrack.crtspacepoint.score = t0match.fTriggerConfidence; - FillCRTSpacePoint(*spacepointmatch, srtrack.crtspacepoint.spacepoint); + FillCRTSpacePoint(*spacepointmatch, cluster, srtrack.crtspacepoint.spacepoint); } void FillTrackSBNDCRTTrack(const anab::T0 &t0match, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 46704181a..11cf7fcb8 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -41,6 +41,7 @@ #include "sbnobj/Common/CRT/CRTHit.hh" #include "sbnobj/Common/CRT/CRTTrack.hh" #include "sbnobj/SBND/CRT/CRTSpacePoint.hh" +#include "sbnobj/SBND/CRT/CRTCluster.hh" #include "sbnobj/SBND/CRT/CRTTrack.hh" #include "sbnobj/SBND/CRT/CRTVeto.hh" #include "sbnobj/Common/CRT/CRTPMTMatching.hh" @@ -206,6 +207,7 @@ namespace caf void FillTrackCRTSpacePoint(const anab::T0 &t0match, const art::Ptr &spacepointmatch, + const art::Ptr &cluster, caf::SRTrack &srtrack, bool allowEmpty = false); @@ -277,6 +279,7 @@ namespace caf bool allowEmpty = false); void FillCRTSpacePoint(const sbnd::crt::CRTSpacePoint &spacepoint, + const art::Ptr &cluster, caf::SRCRTSpacePoint &srspacepoint, bool allowEmpty = false); From 5530db9fc55f08bd6e22dba86563d4292cece98f Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Wed, 18 Feb 2026 06:30:23 -0600 Subject: [PATCH 321/367] Fill new field for easily flagging CRT-matched tracks in SBND --- sbncode/CAFMaker/FillReco.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index ba1b19b61..5f07bda27 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -821,7 +821,9 @@ namespace caf caf::SRTrack &srtrack, bool allowEmpty) { - srtrack.crtspacepoint.score = t0match.fTriggerConfidence; + srtrack.crtspacepoint.matched = true; + srtrack.crtspacepoint.score = t0match.fTriggerConfidence; + FillCRTSpacePoint(*spacepointmatch, cluster, srtrack.crtspacepoint.spacepoint); } @@ -830,7 +832,9 @@ namespace caf caf::SRTrack &srtrack, bool allowEmpty) { - srtrack.crtsbndtrack.score = t0match.fTriggerConfidence; + srtrack.crtsbndtrack.matched = true; + srtrack.crtsbndtrack.score = t0match.fTriggerConfidence; + FillSBNDCRTTrack(*trackmatch, srtrack.crtsbndtrack.track); } From 311aab221fa8da610e87e03cb93e234257e7fff8 Mon Sep 17 00:00:00 2001 From: Leonidas Aliaga Soplin Date: Mon, 23 Feb 2026 12:22:32 -0600 Subject: [PATCH 322/367] Updated dependencies --- CMakeLists.txt | 2 +- ups/product_deps | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d797dc2d1..cb8c49e67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.14.02.03 LANGUAGES CXX) +project(sbncode VERSION 10.15.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 483437ae1..bd64268c1 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -252,14 +252,14 @@ libdir fq_dir lib # #################################### product version qual flags -genie_xsec v3_06_02_sbn2 - +genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_14_02_02 - -sbnalg v10_14_02_01 - +larsoft v10_15_00 - +sbnalg v10_15_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - -nusystematics v1_05_10sbn02 - +nusystematics v1_05_10 - geant4reweight v01_20_14 - cetmodules v3_24_01 - only_for_build end_product_list @@ -317,10 +317,10 @@ end_product_list # #################################### qualifier larsoft sbnalg sbndaq_artdaq_core genie_xsec sbndata larcv2 systematicstools nusystematics geant4reweight notes -c14:debug c14:debug c14:debug c14:s131:debug AR2520i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug c14:debug:s131 -nq- -c14:prof c14:prof c14:prof c14:s131:prof AR2520i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof c14:prof:s131 -nq- -e26:debug e26:debug e26:debug e26:s131:debug AR2520i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug e26:debug:s131 -nq- -e26:prof e26:prof e26:prof e26:s131:prof AR2520i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof e26:prof:s131 -nq- +c14:debug c14:debug c14:debug c14:s131:debug AR2320i00000:e1000:k250 -nq- c14:debug:p3915 c14:debug c14:debug c14:debug:s131 -nq- +c14:prof c14:prof c14:prof c14:s131:prof AR2320i00000:e1000:k250 -nq- c14:p3915:prof c14:prof c14:prof c14:prof:s131 -nq- +e26:debug e26:debug e26:debug e26:s131:debug AR2320i00000:e1000:k250 -nq- debug:e26:p3915 e26:debug e26:debug e26:debug:s131 -nq- +e26:prof e26:prof e26:prof e26:s131:prof AR2320i00000:e1000:k250 -nq- e26:p3915:prof e26:prof e26:prof e26:prof:s131 -nq- end_qualifier_list #################################### From 761904f2035cafd63f0ae8d755ff5a62d2dc1eb3 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 23 Feb 2026 14:52:32 -0600 Subject: [PATCH 323/367] Updated blipreco label to blipReco --- sbncode/CAFMaker/CAFMakerParams.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index 6843b4ad9..f89a29ef0 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -638,7 +638,7 @@ namespace caf Atom fBlipTag { Name("BlipTag"), Comment("Provide a string to label the blip input"), - "blipreco" + "blipReco" }; }; } From 22cc8488b39bb07a767129daa961767480ac3932 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Tue, 24 Feb 2026 09:50:00 -0600 Subject: [PATCH 324/367] Trying to fix CI issues --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillBlip.cxx | 4 ++-- sbncode/CAFMaker/FillBlip.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 46c1d475c..8b6e3c1d3 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1930,7 +1930,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { } //Fill blips. art::handle for blips and then call fill blips for each one. Make a vector to hold all of them. I handle for loop in Fill blip - art::Handle> blipHandle; + art::Handle> blipHandle; std::vector srblips; if(evt.getByLabel( fParams.fBlipTag(), blipHandle)) //fill SR blips { diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index 5d71edb35..e72cb13a8 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -2,9 +2,9 @@ namespace caf { - void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips) + void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips) { - for(blip::Blip const& CurrentBlip: LAr_Blips) + for(blip::BlipReco const& CurrentBlip: LAr_Blips) { caf::SRBlip NewBlip; NewBlip.ID = CurrentBlip.ID; diff --git a/sbncode/CAFMaker/FillBlip.h b/sbncode/CAFMaker/FillBlip.h index 1a412b763..cec92e41d 100644 --- a/sbncode/CAFMaker/FillBlip.h +++ b/sbncode/CAFMaker/FillBlip.h @@ -14,7 +14,7 @@ namespace caf { - void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips); + void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips); void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRTrueBlip &TrueCAF_Blip ); void FillBlipRelatedHitCluster(blip::HitClust const & LAr_HitClust, caf::SRBlipHitClust &CAF_HitClust); } From a509692cad45c8f098f43226ad76fce89286eb1c Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Tue, 24 Feb 2026 10:31:04 -0600 Subject: [PATCH 325/367] Revert "Trying to fix CI issues" This reverts commit 22cc8488b39bb07a767129daa961767480ac3932. --- sbncode/CAFMaker/CAFMaker_module.cc | 2 +- sbncode/CAFMaker/FillBlip.cxx | 4 ++-- sbncode/CAFMaker/FillBlip.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 8b6e3c1d3..46c1d475c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1930,7 +1930,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { } //Fill blips. art::handle for blips and then call fill blips for each one. Make a vector to hold all of them. I handle for loop in Fill blip - art::Handle> blipHandle; + art::Handle> blipHandle; std::vector srblips; if(evt.getByLabel( fParams.fBlipTag(), blipHandle)) //fill SR blips { diff --git a/sbncode/CAFMaker/FillBlip.cxx b/sbncode/CAFMaker/FillBlip.cxx index e72cb13a8..5d71edb35 100644 --- a/sbncode/CAFMaker/FillBlip.cxx +++ b/sbncode/CAFMaker/FillBlip.cxx @@ -2,9 +2,9 @@ namespace caf { - void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips) + void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips) { - for(blip::BlipReco const& CurrentBlip: LAr_Blips) + for(blip::Blip const& CurrentBlip: LAr_Blips) { caf::SRBlip NewBlip; NewBlip.ID = CurrentBlip.ID; diff --git a/sbncode/CAFMaker/FillBlip.h b/sbncode/CAFMaker/FillBlip.h index cec92e41d..1a412b763 100644 --- a/sbncode/CAFMaker/FillBlip.h +++ b/sbncode/CAFMaker/FillBlip.h @@ -14,7 +14,7 @@ namespace caf { - void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips); + void FillBlip( const std::vector& LAr_Blips, std::vector& CAF_Blips); void FillMCTruthBlip( blip::TrueBlip const & TrueLAr_Blip, caf::SRTrueBlip &TrueCAF_Blip ); void FillBlipRelatedHitCluster(blip::HitClust const & LAr_HitClust, caf::SRBlipHitClust &CAF_HitClust); } From ebc6432f36e85328b629e9ef251d3b3a378ddfd0 Mon Sep 17 00:00:00 2001 From: Jacob McLaughlin Date: Mon, 2 Mar 2026 11:00:31 -0600 Subject: [PATCH 326/367] Revert "Updated blipreco label to blipReco" This reverts commit 761904f2035cafd63f0ae8d755ff5a62d2dc1eb3. --- sbncode/CAFMaker/CAFMakerParams.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/CAFMakerParams.h b/sbncode/CAFMaker/CAFMakerParams.h index f89a29ef0..6843b4ad9 100644 --- a/sbncode/CAFMaker/CAFMakerParams.h +++ b/sbncode/CAFMaker/CAFMakerParams.h @@ -638,7 +638,7 @@ namespace caf Atom fBlipTag { Name("BlipTag"), Comment("Provide a string to label the blip input"), - "blipReco" + "blipreco" }; }; } From 330f2785c7bbc7dcda10dc4e034d9380f789d8b9 Mon Sep 17 00:00:00 2001 From: VCLanNguyen Date: Tue, 3 Mar 2026 19:36:27 -0600 Subject: [PATCH 327/367] update comments in cafmaker --- sbncode/CAFMaker/CAFMaker_module.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index ccf324301..4d0d8368b 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2656,11 +2656,9 @@ void CAFMaker::produce(art::Event& evt) noexcept { // Fill trigger info FillTriggerSBND(srsbndtiminginfo, srtrigger); - //// Legacy: Timing correction is being done at decoding/reconstruction level - //// SBND: Fix the Reference time in data depending on the stream + //// Legacy code: Timing correction is now done at decoding/reconstruction level ////shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match //SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - ////shift reference frame for PMT objects: opflash, opt0 //SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); } From 5977b29257977f868ff15c7eed5838f845044fdd Mon Sep 17 00:00:00 2001 From: Michael Carrigan Date: Wed, 4 Mar 2026 15:06:06 -0600 Subject: [PATCH 328/367] Updates from Mattia to allow only one definition of MaxMultiHitPerPlane and Chi2PerPlane --- sbncode/HitFinder/GaussHitFinderSBN_module.cc | 29 ++++++++++++++----- sbncode/HitFinder/hitfindermodules_sbn.fcl | 2 -- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/sbncode/HitFinder/GaussHitFinderSBN_module.cc b/sbncode/HitFinder/GaussHitFinderSBN_module.cc index b7e952206..a8b1a0fa3 100644 --- a/sbncode/HitFinder/GaussHitFinderSBN_module.cc +++ b/sbncode/HitFinder/GaussHitFinderSBN_module.cc @@ -69,6 +69,18 @@ namespace hit { void beginJob(art::ProcessingFrame const&) override; std::vector FillOutHitParameterVector(const std::vector& input); + + template + inline std::vector getValueOrListOf(fhicl::ParameterSet const& pset, std::string const& key) { + + auto const& wireReadoutGeom = art::ServiceHandle()->Get(); + const unsigned int N_PLANES = wireReadoutGeom.Nplanes(); + + if (pset.is_key_to_sequence(key)) + return pset.get>(key); + else + return std::vector(N_PLANES, pset.get(key)); + } // getValueOrListOf() const bool fFilterHits; const bool fFillHists; @@ -76,14 +88,14 @@ namespace hit { const std::string fCalDataModuleLabel; const std::string fAllHitsInstanceName; - const std::vector fLongMaxHitsVec; /// fLongPulseWidthVec; /// fLongMaxHitsVec; ///< Maximum number hits on a really long pulse train + const std::vector fLongPulseWidthVec; ///< Sets width of hits used to describe long pulses - const std::vector fMaxMultiHit; /// fMaxMultiHit; ///< Maximum hits for multi fit + const int fAreaMethod; ///< Type of area calculation const std::vector - fAreaNormsVec; /// fChi2NDF; ///maximum Chisquared / NDF allowed for a hit to be saved + fAreaNormsVec; ///< Factors for converting area to same units as peak height + const std::vector fChi2NDF; ///< Maximum Chisquared / NDF allowed for a hit to be saved const std::vector fPulseHeightCuts; const std::vector fPulseWidthCuts; @@ -116,10 +128,10 @@ namespace hit { , fLongMaxHitsVec(pset.get>("LongMaxHits", std::vector() = {25, 25, 25})) , fLongPulseWidthVec( pset.get>("LongPulseWidth", std::vector() = {16, 16, 16})) - , fMaxMultiHit(pset.get>("MaxMultiHitPerPlane", std::vector() = {5, 5, 5})) + , fMaxMultiHit(getValueOrListOf(pset, "MaxMultiHit")) , fAreaMethod(pset.get("AreaMethod")) , fAreaNormsVec(FillOutHitParameterVector(pset.get>("AreaNorms"))) - , fChi2NDF(pset.get>("Chi2NDFPerPlane", std::vector() = {500.0, 500.0, 500.0})) + , fChi2NDF(getValueOrListOf(pset, "Chi2NDF")) , fPulseHeightCuts( pset.get>("PulseHeightCuts", std::vector() = {3.0, 3.0, 3.0})) , fPulseWidthCuts( @@ -127,6 +139,7 @@ namespace hit { , fPulseRatioCuts( pset.get>("PulseRatioCuts", std::vector() = {0.35, 0.40, 0.20})) { + if (fFillHists && art::Globals::instance()->nthreads() > 1u) { throw art::Exception(art::errors::Configuration) << "Cannot fill histograms when multiple threads configured, please set fFillHists to " diff --git a/sbncode/HitFinder/hitfindermodules_sbn.fcl b/sbncode/HitFinder/hitfindermodules_sbn.fcl index 099e784b4..f6def3d0a 100644 --- a/sbncode/HitFinder/hitfindermodules_sbn.fcl +++ b/sbncode/HitFinder/hitfindermodules_sbn.fcl @@ -12,7 +12,6 @@ gauss_hitfinder: module_type: "GaussHitFinderSBN" CalDataModuleLabel: "caldata" MaxMultiHit: 5 # maximum hits for multi gaussian fit attempt - MaxMultiHitPerPlane: [ 10, 10, 8 ] # maximum hits per plane for multi gaussia fit attempt AreaMethod: 0 # 0 = area by integral, 1 = area by gaussian area formula AreaNorms: [ 1.0, 1.0, 1.0 ] # normalizations that put signal area in # same scale as peak height. @@ -20,7 +19,6 @@ gauss_hitfinder: LongMaxHits: [ 25, 25, 25] # max number hits in long pulse trains LongPulseWidth: [ 5, 5, 5] # max widths for hits in long pulse trains Chi2NDF: 500. # maximum Chisquared / NDF allowed to store fit - Chi2NDFPerPlane: [ 2500., 1750., 2500.] # maximum Chisquared / NDF allowed per plane to store, if fail # will use "long" pulse method to return hit AllHitsInstanceName: "" # If non-null then this will be the instance name of all hits output to event # in this case there will be two hit collections, one filtered and one containing all hits From a64e6a4c442f40ddfd044aae488a495f43e3c060 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Tue, 10 Mar 2026 16:40:20 -0500 Subject: [PATCH 329/367] For larsoft v10_20_02. --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index f85c5cd4e..95cec9c87 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_15_00 - +larsoft v10_20_02 - sbnalg v10_15_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - From fa6d0fc37a5bdb6fe8f5f0bb148799fe3415687b Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Fri, 13 Mar 2026 10:59:29 +0000 Subject: [PATCH 330/367] Apply good suggestions from Gianluca Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/CAFMaker_module.cc | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index b04dc631c..cc071d581 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1308,20 +1308,7 @@ template art::FindOneP CAFMaker::FindOnePStrictSingle(const U& from, const art::Event& evt, const art::InputTag& tag) const { - std::vector vec = { from }; - - art::FindOneP ret(vec, evt, tag); - - if (!tag.label().empty() && !ret.isValid() && fParams.StrictMode()) { - std::cout << "CAFMaker: No Assn from '" - << cet::demangle_symbol(typeid(from).name()) << "' to '" - << cet::demangle_symbol(typeid(T).name()) - << "' found under label '" << tag << "'. " - << "Set 'StrictMode: false' to continue anyway." << std::endl; - abort(); - } - - return ret; + return FindOnePStrict(std::vector{ from }, evt, tag); } //...................................................................... @@ -2548,7 +2535,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { art::FindOneP foCRTCluster = FindOnePStrictSingle(crtspacepoint, evt, fParams.CRTSpacePointLabel()); - const art::Ptr crtcluster = foCRTCluster.at(0); + const art::Ptr& crtcluster = foCRTCluster.at(0); if(crtspacepoint.isNonnull()) FillTrackCRTSpacePoint(foCRTSpacePointMatch.data(iPart).ref(), crtspacepoint, crtcluster, trk); From 3ab25146b43d1375452e533ab64f276bb4f7eff9 Mon Sep 17 00:00:00 2001 From: Henry Lay Date: Fri, 13 Mar 2026 06:19:52 -0500 Subject: [PATCH 331/367] Make dereferencing work --- sbncode/CAFMaker/CAFMaker_module.cc | 6 +++--- sbncode/CAFMaker/FillReco.cxx | 12 ++++++------ sbncode/CAFMaker/FillReco.h | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index cc071d581..d2d2a0f0c 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -1308,7 +1308,7 @@ template art::FindOneP CAFMaker::FindOnePStrictSingle(const U& from, const art::Event& evt, const art::InputTag& tag) const { - return FindOnePStrict(std::vector{ from }, evt, tag); + return FindOnePStrict(std::vector{ from }, evt, tag); } //...................................................................... @@ -1811,7 +1811,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { for (unsigned i = 0; i < crtspacepoints.size(); i++) { srcrtspacepoints.emplace_back(); const art::Ptr crtcluster = foCRTCluster.at(i); - FillCRTSpacePoint(crtspacepoints[i], crtcluster, srcrtspacepoints.back()); + FillCRTSpacePoint(crtspacepoints[i], *crtcluster, srcrtspacepoints.back()); } } @@ -2538,7 +2538,7 @@ void CAFMaker::produce(art::Event& evt) noexcept { const art::Ptr& crtcluster = foCRTCluster.at(0); if(crtspacepoint.isNonnull()) - FillTrackCRTSpacePoint(foCRTSpacePointMatch.data(iPart).ref(), crtspacepoint, crtcluster, trk); + FillTrackCRTSpacePoint(foCRTSpacePointMatch.data(iPart).ref(), *crtspacepoint, *crtcluster, trk); } if(foSBNDCRTTrackMatch.isValid() && fDet == kSBND) { diff --git a/sbncode/CAFMaker/FillReco.cxx b/sbncode/CAFMaker/FillReco.cxx index 5f07bda27..86d56a6e2 100644 --- a/sbncode/CAFMaker/FillReco.cxx +++ b/sbncode/CAFMaker/FillReco.cxx @@ -164,7 +164,7 @@ namespace caf } void FillCRTSpacePoint(const sbnd::crt::CRTSpacePoint &spacepoint, - const art::Ptr &cluster, + const sbnd::crt::CRTCluster &cluster, caf::SRCRTSpacePoint &srspacepoint, bool allowEmpty) { @@ -174,8 +174,8 @@ namespace caf srspacepoint.time = spacepoint.Ts0(); srspacepoint.time_err = spacepoint.Ts0Err(); srspacepoint.complete = spacepoint.Complete(); - srspacepoint.nhits = cluster->NHits(); - srspacepoint.tagger = cluster->Tagger(); + srspacepoint.nhits = cluster.NHits(); + srspacepoint.tagger = cluster.Tagger(); } void FillSBNDCRTTrack(const sbnd::crt::CRTTrack &track, @@ -816,15 +816,15 @@ namespace caf } void FillTrackCRTSpacePoint(const anab::T0 &t0match, - const art::Ptr &spacepointmatch, - const art::Ptr &cluster, + const sbnd::crt::CRTSpacePoint &spacepointmatch, + const sbnd::crt::CRTCluster &cluster, caf::SRTrack &srtrack, bool allowEmpty) { srtrack.crtspacepoint.matched = true; srtrack.crtspacepoint.score = t0match.fTriggerConfidence; - FillCRTSpacePoint(*spacepointmatch, cluster, srtrack.crtspacepoint.spacepoint); + FillCRTSpacePoint(spacepointmatch, cluster, srtrack.crtspacepoint.spacepoint); } void FillTrackSBNDCRTTrack(const anab::T0 &t0match, diff --git a/sbncode/CAFMaker/FillReco.h b/sbncode/CAFMaker/FillReco.h index 11cf7fcb8..eafbd1842 100644 --- a/sbncode/CAFMaker/FillReco.h +++ b/sbncode/CAFMaker/FillReco.h @@ -206,8 +206,8 @@ namespace caf bool allowEmpty = false); void FillTrackCRTSpacePoint(const anab::T0 &t0match, - const art::Ptr &spacepointmatch, - const art::Ptr &cluster, + const sbnd::crt::CRTSpacePoint &spacepointmatch, + const sbnd::crt::CRTCluster &cluster, caf::SRTrack &srtrack, bool allowEmpty = false); @@ -279,7 +279,7 @@ namespace caf bool allowEmpty = false); void FillCRTSpacePoint(const sbnd::crt::CRTSpacePoint &spacepoint, - const art::Ptr &cluster, + const sbnd::crt::CRTCluster &cluster, caf::SRCRTSpacePoint &srspacepoint, bool allowEmpty = false); From 046b161a9787305f4adabf872f2485d0a49ed87e Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Fri, 13 Mar 2026 10:22:23 -0500 Subject: [PATCH 332/367] v10_20_03 --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb8c49e67..61bc982b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.15.00 LANGUAGES CXX) +project(sbncode VERSION 10.20.03 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 95cec9c87..50a46ba75 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_02 - -sbnalg v10_15_00 - +larsoft v10_20_03 - +sbnalg v10_20_03 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From 6742949840586b91b189fcae07d46f0f930fd4fa Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Tue, 7 Apr 2026 09:37:47 -0500 Subject: [PATCH 333/367] For larsoft v10_20_04. --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index 50a46ba75..6ac405b1d 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_03 - +larsoft v10_20_04 - sbnalg v10_20_03 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - From 774bcb0243c6d327f69e0f4082bef4eb415c7c28 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Tue, 7 Apr 2026 11:16:19 -0500 Subject: [PATCH 334/367] v10_20_04 --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61bc982b7..10cc0e6d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.03 LANGUAGES CXX) +project(sbncode VERSION 10.20.04 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 6ac405b1d..b4bd9ccbe 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - larsoft v10_20_04 - -sbnalg v10_20_03 - +sbnalg v10_20_04 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From c03a60b82d5b98e68805c8e546b331bea7a4b3aa Mon Sep 17 00:00:00 2001 From: Michael Carrigan Date: Fri, 10 Apr 2026 15:36:38 -0500 Subject: [PATCH 335/367] address PR comments round 1 --- sbncode/CAFMaker/RecoUtils/CMakeLists.txt | 2 -- sbncode/HitFinder/GaussHitFinderSBN_module.cc | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sbncode/CAFMaker/RecoUtils/CMakeLists.txt b/sbncode/CAFMaker/RecoUtils/CMakeLists.txt index 545bdad69..a992d7c63 100644 --- a/sbncode/CAFMaker/RecoUtils/CMakeLists.txt +++ b/sbncode/CAFMaker/RecoUtils/CMakeLists.txt @@ -11,6 +11,4 @@ art_make_library( LIBRARY_NAME caf_RecoUtils larsim::MCCheater_BackTrackerService_service larsim::MCCheater_ParticleInventoryService_service larcorealg::Geometry - sbnanaobj::StandardRecord - sbnanaobj::StandardRecordFlat ) diff --git a/sbncode/HitFinder/GaussHitFinderSBN_module.cc b/sbncode/HitFinder/GaussHitFinderSBN_module.cc index a8b1a0fa3..1446edd41 100644 --- a/sbncode/HitFinder/GaussHitFinderSBN_module.cc +++ b/sbncode/HitFinder/GaussHitFinderSBN_module.cc @@ -71,12 +71,18 @@ namespace hit { std::vector FillOutHitParameterVector(const std::vector& input); template - inline std::vector getValueOrListOf(fhicl::ParameterSet const& pset, std::string const& key) { + std::vector getValueOrListOf(fhicl::ParameterSet const& pset, std::string const& key) const { auto const& wireReadoutGeom = art::ServiceHandle()->Get(); const unsigned int N_PLANES = wireReadoutGeom.Nplanes(); if (pset.is_key_to_sequence(key)) + auto vec = pset.get>(key); + if (vec.size() != N_PLANES) { + throw cet::exception("Configuration") + << "Parameter '" << key << "' has size " << vec.size() + << " but expected " << N_PLANES << " (number of planes)"; + } return pset.get>(key); else return std::vector(N_PLANES, pset.get(key)); From 90384ac68d6299dbf713a84f9affe76ae38adec1 Mon Sep 17 00:00:00 2001 From: Michael Carrigan Date: Fri, 10 Apr 2026 18:27:55 -0500 Subject: [PATCH 336/367] fix brackets --- sbncode/HitFinder/GaussHitFinderSBN_module.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/HitFinder/GaussHitFinderSBN_module.cc b/sbncode/HitFinder/GaussHitFinderSBN_module.cc index 1446edd41..6d5147043 100644 --- a/sbncode/HitFinder/GaussHitFinderSBN_module.cc +++ b/sbncode/HitFinder/GaussHitFinderSBN_module.cc @@ -76,7 +76,7 @@ namespace hit { auto const& wireReadoutGeom = art::ServiceHandle()->Get(); const unsigned int N_PLANES = wireReadoutGeom.Nplanes(); - if (pset.is_key_to_sequence(key)) + if (pset.is_key_to_sequence(key)) { auto vec = pset.get>(key); if (vec.size() != N_PLANES) { throw cet::exception("Configuration") @@ -84,7 +84,7 @@ namespace hit { << " but expected " << N_PLANES << " (number of planes)"; } return pset.get>(key); - else + } else return std::vector(N_PLANES, pset.get(key)); } // getValueOrListOf() From d943ba0ae8ebc80af0d9815ce088374d133c370f Mon Sep 17 00:00:00 2001 From: nathanielerowe <70993723+nathanielerowe@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:27:16 -0500 Subject: [PATCH 337/367] Add install_headers() to CMakeLists.txt --- sbncode/CAFMaker/RecoUtils/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/sbncode/CAFMaker/RecoUtils/CMakeLists.txt b/sbncode/CAFMaker/RecoUtils/CMakeLists.txt index a992d7c63..b6abdbdb9 100644 --- a/sbncode/CAFMaker/RecoUtils/CMakeLists.txt +++ b/sbncode/CAFMaker/RecoUtils/CMakeLists.txt @@ -12,3 +12,4 @@ art_make_library( LIBRARY_NAME caf_RecoUtils larsim::MCCheater_ParticleInventoryService_service larcorealg::Geometry ) +install_headers() From fd7145ff58bae959f2af4654e8dfd5aa0b4e8bcf Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 16 Apr 2026 11:38:26 -0500 Subject: [PATCH 338/367] v10_20_05 --- CMakeLists.txt | 2 +- sbncode/CAFMaker/CMakeLists.txt | 2 +- ups/product_deps | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10cc0e6d0..917e826aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.04 LANGUAGES CXX) +project(sbncode VERSION 10.20.05 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 26836652b..1dbde57ed 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -52,7 +52,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker ${GENIE_LIB_LIST} nugen::EventGeneratorBase_GENIE sbndaq_artdaq_core::sbndaq-artdaq-core_Obj_SBND - sbn_POTTools + sbncode::sbn_POTTools ) cet_build_plugin ( CAFMaker art::module diff --git a/ups/product_deps b/ups/product_deps index b4bd9ccbe..40121dc78 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - larsoft v10_20_04 - -sbnalg v10_20_04 - +sbnalg v10_20_05 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - systematicstools v01_04_04 - From 851e176590514bd2a0e306d0b5896f4598fff85d Mon Sep 17 00:00:00 2001 From: Seokju Chung Date: Tue, 21 Apr 2026 09:07:23 -0500 Subject: [PATCH 339/367] Return false instead of exit --- sbncode/SinglePhotonAnalysis/NCDeltaRadiative_module.cc | 4 ++-- sbncode/SinglePhotonAnalysis/NCRadiativeResonant_module.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sbncode/SinglePhotonAnalysis/NCDeltaRadiative_module.cc b/sbncode/SinglePhotonAnalysis/NCDeltaRadiative_module.cc index aff90eb39..892d31f06 100644 --- a/sbncode/SinglePhotonAnalysis/NCDeltaRadiative_module.cc +++ b/sbncode/SinglePhotonAnalysis/NCDeltaRadiative_module.cc @@ -161,7 +161,7 @@ bool NCDeltaRadiative::filter(art::Event & e) { simb::MCParticle const & mcp = mct.GetParticle(i); if(mcp.TrackId() != i) { std::cout << "ERROR: " << __LINE__ << " " << __PRETTY_FUNCTION__ << "\nTrackId does not match index\n"; - exit(1); + return false; } if(!(mcp.StatusCode() == 1 && mcp.PdgCode() == 22)) continue; exiting_photon_parents.push_back(mcp.Mother()); @@ -173,7 +173,7 @@ bool NCDeltaRadiative::filter(art::Event & e) { //CHEKC hardcode, TPC filter: if(abs(mcp.Vx())>210 || abs(mcp.Vy())>210||mcp.Vz()>510 || mcp.Vz()<-1){ std::cout<<"OUTSIDE TPC x y z ="<210 || abs(mcp.Vy())>210||mcp.Vz()>510 || mcp.Vz()<-1){ std::cout<<"OUTSIDE TPC x y z ="< Date: Wed, 22 Apr 2026 12:31:15 -0500 Subject: [PATCH 340/367] v10_20_05. --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index 40121dc78..babf4b1db 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_04 - +larsoft v10_20_05 - sbnalg v10_20_05 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - From 3a24305a2275503d8e62dd5044c865b0d68f7184 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 23 Apr 2026 12:23:30 -0500 Subject: [PATCH 341/367] Fix cmake warnings. --- .../ICARUSBNBEXTRetriever/CMakeLists.txt | 2 +- .../ICARUSBNBRetriever/CMakeLists.txt | 2 +- .../NuMIEXTRetriever/CMakeLists.txt | 2 +- .../NuMIRetriever/CMakeLists.txt | 2 +- .../SBNDBNBEXTRetriever/CMakeLists.txt | 2 +- .../SBNDBNBRetriever/CMakeLists.txt | 2 +- .../SBNDBNBZEROBIASRetriever/CMakeLists.txt | 2 +- sbncode/CAFMaker/CMakeLists.txt | 2 +- sbncode/Calibration/CMakeLists.txt | 12 +- sbncode/Cluster3D/CMakeLists.txt | 4 +- sbncode/CosmicID/CMakeLists.txt | 2 +- sbncode/DetSim/CMakeLists.txt | 4 +- sbncode/EventGenerator/MeVPrtl/CMakeLists.txt | 4 +- .../MeVPrtl/Tools/ALP/CMakeLists.txt | 4 +- .../MeVPrtl/Tools/CMakeLists.txt | 17 +- .../MeVPrtl/Tools/HNL/CMakeLists.txt | 6 +- .../MeVPrtl/Tools/Higgs/CMakeLists.txt | 6 +- .../EventGenerator/WireModGen/CMakeLists.txt | 2 +- sbncode/FlashMatch/CMakeLists.txt | 2 +- sbncode/FluxReader/CMakeLists.txt | 6 +- sbncode/HitFinder/CMakeLists.txt | 6 +- sbncode/LArG4/CMakeLists.txt | 4 +- sbncode/LArRecoProducer/CMakeLists.txt | 24 +- sbncode/Metadata/FileCatalogMetadataSBN.cc | 110 +++++ .../FileCatalogMetadataSBN_service.cc | 111 +---- sbncode/Metadata/MetadataSBN.cc | 425 +++++++++++++++++ sbncode/Metadata/MetadataSBN_service.cc | 426 +----------------- sbncode/NuMuSelection/CMakeLists.txt | 6 +- sbncode/OpDet/CMakeLists.txt | 2 +- sbncode/OpDet/PDMapAlgSimple.cc | 39 ++ sbncode/PID/CMakeLists.txt | 6 +- sbncode/SBNEventWeight/App/CMakeLists.txt | 4 +- sbncode/SinglePhotonAnalysis/CMakeLists.txt | 6 +- sbncode/TPCReco/CMakeLists.txt | 4 +- .../CalorimetryAnalysis/CMakeLists.txt | 2 +- sbncode/TPCReco/TrackHit/CMakeLists.txt | 6 +- sbncode/TPCReco/TrackSplit/CMakeLists.txt | 4 +- sbncode/TPCReco/VertexStub/CMakeLists.txt | 8 +- 38 files changed, 659 insertions(+), 619 deletions(-) create mode 100644 sbncode/Metadata/FileCatalogMetadataSBN.cc create mode 100644 sbncode/Metadata/MetadataSBN.cc create mode 100644 sbncode/OpDet/PDMapAlgSimple.cc diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt index 1b1cbce80..b1433c96b 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBEXTRetriever/CMakeLists.txt @@ -1,6 +1,6 @@ cet_build_plugin(ICARUSBNBEXTRetriever art::module - LIBRARIES + LIBRARIES PRIVATE art::Persistency_Common art::Utilities canvas::canvas cetlib::cetlib cetlib_except::cetlib_except diff --git a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt index deeda3a5c..104109bc1 100644 --- a/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/ICARUSBNBRetriever/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(ifbeam) find_package(ifdh_art) cet_build_plugin(ICARUSBNBRetriever art::module - LIBRARIES + LIBRARIES PRIVATE sbn_POTTools sbn_getFOM SQLite::SQLite3 diff --git a/sbncode/BeamSpillInfoRetriever/NuMIEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/NuMIEXTRetriever/CMakeLists.txt index f11657b00..e323d253b 100644 --- a/sbncode/BeamSpillInfoRetriever/NuMIEXTRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/NuMIEXTRetriever/CMakeLists.txt @@ -1,6 +1,6 @@ cet_build_plugin(NuMIEXTRetriever art::module - LIBRARIES + LIBRARIES PRIVATE art::Persistency_Common art::Utilities canvas::canvas cetlib::cetlib cetlib_except::cetlib_except diff --git a/sbncode/BeamSpillInfoRetriever/NuMIRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/NuMIRetriever/CMakeLists.txt index d5fd24b7c..5f03fb618 100644 --- a/sbncode/BeamSpillInfoRetriever/NuMIRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/NuMIRetriever/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(ifbeam) find_package(ifdh_art) cet_build_plugin(NuMIRetriever art::module - LIBRARIES + LIBRARIES PRIVATE art::Persistency_Common art::Utilities canvas::canvas cetlib::cetlib cetlib_except::cetlib_except diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt index 8a16ef2e9..ff9aee2b3 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBEXTRetriever/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(ifbeam) find_package(ifdh_art) cet_build_plugin(SBNDBNBEXTRetriever art::module - LIBRARIES + LIBRARIES PRIVATE sbn_POTTools ) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt index efbf13789..a07fab958 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBRetriever/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(ifbeam) find_package(ifdh_art) cet_build_plugin(SBNDBNBRetriever art::module - LIBRARIES + LIBRARIES PRIVATE sbn_POTTools sbn_getFOM ) diff --git a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt index 7890fbd93..7187c8451 100644 --- a/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt +++ b/sbncode/BeamSpillInfoRetriever/SBNDBNBZEROBIASRetriever/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(ifbeam) find_package(ifdh_art) cet_build_plugin(SBNDBNBZEROBIASRetriever art::module - LIBRARIES + LIBRARIES PRIVATE sbn_POTTools sbn_getFOM ) diff --git a/sbncode/CAFMaker/CMakeLists.txt b/sbncode/CAFMaker/CMakeLists.txt index 1dbde57ed..4368ff48a 100644 --- a/sbncode/CAFMaker/CMakeLists.txt +++ b/sbncode/CAFMaker/CMakeLists.txt @@ -56,7 +56,7 @@ art_make_library( LIBRARY_NAME sbncode_CAFMaker ) cet_build_plugin ( CAFMaker art::module - LIBRARIES + LIBRARIES PRIVATE sbncode_CAFMaker sbnanaobj::StandardRecord larcorealg::Geometry diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index 64439a086..8b83d3f70 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -1,6 +1,6 @@ cet_build_plugin( TrackCaloSkimmer art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -28,7 +28,7 @@ cet_build_plugin( TrackCaloSkimmer art::module ) cet_build_plugin(TrackCaloSkimmerSelectStoppingTrack art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -47,7 +47,7 @@ cet_build_plugin(TrackCaloSkimmerSelectStoppingTrack art::tool ) cet_build_plugin(TrackCaloSkimmerSelectAnode2CathodeTrack art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -61,7 +61,7 @@ cet_build_plugin(TrackCaloSkimmerSelectAnode2CathodeTrack art::tool ) cet_build_plugin(TrackCaloSkimmerSelectAllTrack art::tool - LIBRARIES + LIBRARIES PRIVATE sbnobj::Common_Calibration_dict art::Persistency_Common art::Utilities canvas::canvas @@ -71,7 +71,7 @@ cet_build_plugin(TrackCaloSkimmerSelectAllTrack art::tool ) cet_build_plugin(TrackCaloSkimmerSelectClearCosmicMuon art::tool - LIBRARIES + LIBRARIES PRIVATE sbnobj::Common_Calibration_dict art::Persistency_Common art::Utilities canvas::canvas @@ -81,7 +81,7 @@ cet_build_plugin(TrackCaloSkimmerSelectClearCosmicMuon art::tool ) cet_build_plugin ( DataSelect art::module - LIBRARIES + LIBRARIES PRIVATE PRIVATE ifdh_art::IFDH_service art::Framework_Core art::Framework_Principal diff --git a/sbncode/Cluster3D/CMakeLists.txt b/sbncode/Cluster3D/CMakeLists.txt index dad21f80b..c7a8bfcaf 100644 --- a/sbncode/Cluster3D/CMakeLists.txt +++ b/sbncode/Cluster3D/CMakeLists.txt @@ -56,8 +56,8 @@ set( MODULE_LIBRARIES art_root_io::TFileService_service messagefacility::MF_MessageLogger ) -cet_build_plugin(Cluster3DSBN art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(SnippetHit3DBuilderSBN art::tool LIBRARIES ${TOOL_LIBRARIES} SOURCE SnippetHit3DBuilderSBN_tool.cc) +cet_build_plugin(Cluster3DSBN art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(SnippetHit3DBuilderSBN art::tool LIBRARIES PRIVATE ${TOOL_LIBRARIES}) set_property(SOURCE SnippetHit3DBuilderSBN_tool.cc APPEND PROPERTY COMPILE_DEFINITIONS EIGEN_FFTW_DEFAULT) install_headers() diff --git a/sbncode/CosmicID/CMakeLists.txt b/sbncode/CosmicID/CMakeLists.txt index 527721870..23b551470 100644 --- a/sbncode/CosmicID/CMakeLists.txt +++ b/sbncode/CosmicID/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin( CRUMBS art::module - LIBRARIES + LIBRARIES PRIVATE art_root_io::TFileService_service fhiclcpp::fhiclcpp art::Persistency_Provenance canvas::canvas diff --git a/sbncode/DetSim/CMakeLists.txt b/sbncode/DetSim/CMakeLists.txt index 113aa375a..805004f36 100644 --- a/sbncode/DetSim/CMakeLists.txt +++ b/sbncode/DetSim/CMakeLists.txt @@ -31,8 +31,8 @@ set( MODULE_LIBRARIES FFTW3::FFTW3 ) -cet_build_plugin(AdjustSimForTrigger art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(FilterSimEnergyDeposits art::module LIBRARIES ${MODULE_LIBRARIES}) +cet_build_plugin(AdjustSimForTrigger art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(FilterSimEnergyDeposits art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) add_subdirectory(fcl) diff --git a/sbncode/EventGenerator/MeVPrtl/CMakeLists.txt b/sbncode/EventGenerator/MeVPrtl/CMakeLists.txt index a4a480811..3d5655ef2 100644 --- a/sbncode/EventGenerator/MeVPrtl/CMakeLists.txt +++ b/sbncode/EventGenerator/MeVPrtl/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory(Tools) add_subdirectory(config) cet_build_plugin( MeVPrtlGen art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -24,7 +24,7 @@ cet_build_plugin( MeVPrtlGen art::module ) cet_build_plugin( MeVPrtlTestRayTrace art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/ALP/CMakeLists.txt b/sbncode/EventGenerator/MeVPrtl/Tools/ALP/CMakeLists.txt index 5b30f0ab8..a5aabb70f 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/ALP/CMakeLists.txt +++ b/sbncode/EventGenerator/MeVPrtl/Tools/ALP/CMakeLists.txt @@ -5,7 +5,7 @@ art_make_library( LIBRARY_NAME sbncode_EventGenerator_MeVPrtl_ALP_ThreeBodyInteg ) cet_build_plugin( Meson2ALP art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -25,7 +25,7 @@ cet_build_plugin( Meson2ALP art::tool ) cet_build_plugin( ALPMakeDecay art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/CMakeLists.txt b/sbncode/EventGenerator/MeVPrtl/Tools/CMakeLists.txt index e385350a6..b82d2ca4f 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/CMakeLists.txt +++ b/sbncode/EventGenerator/MeVPrtl/Tools/CMakeLists.txt @@ -11,7 +11,7 @@ art_make_library( LIBRARY_NAME sbncode_EventGenerator_MeVPrtl_Constants cet_build_plugin( EmptyKaonGen art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -34,7 +34,7 @@ cet_build_plugin( EmptyKaonGen art::tool cet_build_plugin( NuMiKaonGen art::tool - LIBRARIES + LIBRARIES PRIVATE ifdh_art::IFDH_service art::Framework_Core art::Framework_Services_Registry @@ -57,7 +57,7 @@ cet_build_plugin( NuMiKaonGen art::tool ) cet_build_plugin( TxtFileGen art::tool - LIBRARIES + LIBRARIES PRIVATE ifdh_art::IFDH_service art::Framework_Core art::Framework_Services_Registry @@ -80,8 +80,7 @@ cet_build_plugin( TxtFileGen art::tool ) cet_build_plugin( BNBKaonGen art::tool - - LIBRARIES + LIBRARIES PRIVATE ifdh_art::IFDH_service art::Framework_Core art::Framework_Services_Registry @@ -104,7 +103,7 @@ cet_build_plugin( BNBKaonGen art::tool ) cet_build_plugin( WeightedRayTraceBox art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -127,7 +126,7 @@ cet_build_plugin( WeightedRayTraceBox art::tool ) cet_build_plugin( MixedWeightRayTraceBox art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -153,7 +152,7 @@ cet_build_plugin( MixedWeightRayTraceBox art::tool cet_build_plugin( ReThrowRayTraceBox art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -175,7 +174,7 @@ cet_build_plugin( ReThrowRayTraceBox art::tool ) cet_build_plugin( RayTraceBox art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/HNL/CMakeLists.txt b/sbncode/EventGenerator/MeVPrtl/Tools/HNL/CMakeLists.txt index afc82c2b6..2232fdb22 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/HNL/CMakeLists.txt +++ b/sbncode/EventGenerator/MeVPrtl/Tools/HNL/CMakeLists.txt @@ -45,7 +45,7 @@ art_make_library( LIBRARY_NAME sbncode_EventGenerator_MeVPrtl_AnTwoBD cet_build_plugin( Kaon2HNLFlux art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -65,7 +65,7 @@ cet_build_plugin( Kaon2HNLFlux art::tool ) cet_build_plugin( Tau2HNLFlux art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -86,7 +86,7 @@ cet_build_plugin( Tau2HNLFlux art::tool ) cet_build_plugin( HNLMakeDecay art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/CMakeLists.txt b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/CMakeLists.txt index 867e62a1f..314e72967 100644 --- a/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/CMakeLists.txt +++ b/sbncode/EventGenerator/MeVPrtl/Tools/Higgs/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin( MonoEnergyHiggsFlux art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -17,7 +17,7 @@ cet_build_plugin( MonoEnergyHiggsFlux art::tool cet_build_plugin( Kaon2HiggsFlux art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -37,7 +37,7 @@ cet_build_plugin( Kaon2HiggsFlux art::tool ) cet_build_plugin( HiggsMakeDecay art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/EventGenerator/WireModGen/CMakeLists.txt b/sbncode/EventGenerator/WireModGen/CMakeLists.txt index c119741b6..dfd93844e 100644 --- a/sbncode/EventGenerator/WireModGen/CMakeLists.txt +++ b/sbncode/EventGenerator/WireModGen/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin(WireModMuon art::EDProducer - SOURCE CORSIKAGenSBN.cc WireModMuon_module.cc + REG_SOURCE CORSIKAGenSBN.cc WireModMuon_module.cc LIBRARIES PRIVATE larcore::Geometry_Geometry_service larcorealg::Geometry diff --git a/sbncode/FlashMatch/CMakeLists.txt b/sbncode/FlashMatch/CMakeLists.txt index 015322e49..9cfd8588b 100644 --- a/sbncode/FlashMatch/CMakeLists.txt +++ b/sbncode/FlashMatch/CMakeLists.txt @@ -36,7 +36,7 @@ set( MODULE_LIBRARIES ROOT::Gdml ) -cet_build_plugin(FlashPredict art::module LIBRARIES ${MODULE_LIBRARIES}) +cet_build_plugin(FlashPredict art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) install_headers() diff --git a/sbncode/FluxReader/CMakeLists.txt b/sbncode/FluxReader/CMakeLists.txt index ad70d3c22..0aa8b218c 100644 --- a/sbncode/FluxReader/CMakeLists.txt +++ b/sbncode/FluxReader/CMakeLists.txt @@ -4,7 +4,7 @@ cet_enable_asserts() file(GLOB INTERFACEFILES *Interface* ) cet_build_plugin( FluxReader art::source - LIBRARIES + LIBRARIES PRIVATE sbncode_FluxReader larcore::Geometry_Geometry_service nutools::EventGeneratorBase_CRY @@ -12,7 +12,7 @@ cet_build_plugin( FluxReader art::source ) cet_build_plugin ( FluxGeoFilter art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Principal art::Framework_Services_Registry @@ -71,7 +71,7 @@ cet_make_library( lardata::Utilities ) -cet_build_plugin(FluxReaderAna art::module LIBRARIES +cet_build_plugin(FluxReaderAna art::module LIBRARIES PRIVATE sbncode_FluxReader sbncode_FluxReader_FluxInterface nusimdata::SimulationBase diff --git a/sbncode/HitFinder/CMakeLists.txt b/sbncode/HitFinder/CMakeLists.txt index 1d4870cef..a150cc14c 100644 --- a/sbncode/HitFinder/CMakeLists.txt +++ b/sbncode/HitFinder/CMakeLists.txt @@ -43,13 +43,13 @@ set( MODULE_LIBRARIES ) cet_build_plugin(GaussHitFinderSBN art::module - LIBRARIES ${MODULE_LIBRARIES} + LIBRARIES PRIVATE ${MODULE_LIBRARIES} larreco::HitFinder larreco::CandidateHitFinderTool larreco::PeakFitterTool ) -cet_build_plugin(ChannelROIToWire art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(WireToChannelROI art::module LIBRARIES ${MODULE_LIBRARIES}) +cet_build_plugin(ChannelROIToWire art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(WireToChannelROI art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) install_headers() diff --git a/sbncode/LArG4/CMakeLists.txt b/sbncode/LArG4/CMakeLists.txt index f377b254d..4a00b17ef 100644 --- a/sbncode/LArG4/CMakeLists.txt +++ b/sbncode/LArG4/CMakeLists.txt @@ -25,7 +25,7 @@ set( sbncode_LArG4_PhysicsLists ) -cet_build_plugin(PhysListLoader art::module SOURCE PhysListLoader_module.cc LIBRARIES ${MODULE_LIBRARIES}) +cet_build_plugin(PhysListLoader art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) cet_make_library(SOURCE MergeSimSourcesLiteUtility.cxx LIBRARIES @@ -35,7 +35,7 @@ cet_make_library(SOURCE MergeSimSourcesLiteUtility.cxx ) cet_build_plugin(MergeSimSourcesSBN art::EDProducer - LIBRARIES + LIBRARIES PRIVATE sbncode::LArG4 larsim::MergeSimSources lardataobj::MCBase diff --git a/sbncode/LArRecoProducer/CMakeLists.txt b/sbncode/LArRecoProducer/CMakeLists.txt index 3f3fe7b4b..e0463b151 100644 --- a/sbncode/LArRecoProducer/CMakeLists.txt +++ b/sbncode/LArRecoProducer/CMakeLists.txt @@ -28,18 +28,18 @@ set( MODULE_LIBRARIES lardataobj::RecoBase ) -cet_build_plugin(CRTHitConverter art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(MCSFitAllPID art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(PMTFlashTriggerFilter art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(PMTFlashTriggerMaker art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(RangePAllPID art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(ShowerCosmicDistance art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(ShowerSelectionVars art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(TrackScatterClosestApproach art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(TrackStoppingChi2Fitter art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(TransferPFParticleFlashMatch art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(TransferPFParticleT0 art::module LIBRARIES ${MODULE_LIBRARIES}) -cet_build_plugin(TransferTrackT0 art::module LIBRARIES ${MODULE_LIBRARIES}) +cet_build_plugin(CRTHitConverter art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(MCSFitAllPID art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(PMTFlashTriggerFilter art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(PMTFlashTriggerMaker art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(RangePAllPID art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(ShowerCosmicDistance art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(ShowerSelectionVars art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(TrackScatterClosestApproach art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(TrackStoppingChi2Fitter art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(TransferPFParticleFlashMatch art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(TransferPFParticleT0 art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) +cet_build_plugin(TransferTrackT0 art::module LIBRARIES PRIVATE ${MODULE_LIBRARIES}) install_headers() install_fhicl() diff --git a/sbncode/Metadata/FileCatalogMetadataSBN.cc b/sbncode/Metadata/FileCatalogMetadataSBN.cc new file mode 100644 index 000000000..417ec09cc --- /dev/null +++ b/sbncode/Metadata/FileCatalogMetadataSBN.cc @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////////// +// Name: FileCatalogMetadataSBN_service.cc. +// +// Purpose: Implementation for FileCatalogMetadataSBN. +// +// Created: 28-Oct-2014, H. Greenlee +// +//////////////////////////////////////////////////////////////////////// + +#include "sbncode/Metadata/FileCatalogMetadataSBN.h" + +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "art/Framework/Services/System/FileCatalogMetadata.h" +#include "art/Framework/Principal/SubRun.h" +#include "art/Framework/Principal/Handle.h" +#include "cetlib_except/exception.h" +#include "larcoreobj/SummaryData/POTSummary.h" + +//-------------------------------------------------------------------- +// Constructor. + +util::FileCatalogMetadataSBN:: +FileCatalogMetadataSBN(fhicl::ParameterSet const& pset, art::ActivityRegistry& reg) : + fTotPOT(0.) +{ + // Insist on configuring Experiment from the fcl file (ideally) or the + // environment. + const char* expt = getenv("EXPERIMENT"); + if(expt) fExperiment = pset.get("Experiment", expt); else fExperiment = pset.get("Experiment"); + std::transform(fExperiment.begin(), fExperiment.end(), fExperiment.begin(), [](unsigned char c){return std::tolower(c);}); + + // Get parameters. + + fFCLName = pset.get("FCLName"); + fProjectName = pset.get("ProjectName"); + fProjectStage = pset.get("ProjectStage"); + fProjectVersion = pset.get("ProjectVersion"); + fProjectSoftware = pset.get("ProjectSoftware",""); + fProductionName = pset.get("ProductionName",""); //Leave as default value if not running a production + fProductionType = pset.get("ProductionType",""); //Leave as default value if not running a production + fMerge = pset.get("Merge", -1); + fParameters = pset.get>>("Parameters", std::vector>()); + fPOTModuleLabel = pset.get("POTModuleLabel", "generator"); + + // Register for callbacks. + + reg.sPostBeginJob.watch(this, &FileCatalogMetadataSBN::postBeginJob); + reg.sPostEndSubRun.watch(this, &FileCatalogMetadataSBN::postEndSubRun); + reg.sPreCloseOutputFile.watch(this, &FileCatalogMetadataSBN::preCloseOutputFile); +} + +//-------------------------------------------------------------------- +// PostBeginJob callback. +// Insert per-job metadata via FileCatalogMetadata service. +void util::FileCatalogMetadataSBN::postBeginJob() +{ + // Get art metadata service. + + art::ServiceHandle mds; + + // Add metadata. + + if (!fFCLName.empty()) mds->addMetadata("fcl.name", fFCLName); + if (!fProjectName.empty()) mds->addMetadata(fExperiment + "_project.name", fProjectName); + if (!fProjectStage.empty()) mds->addMetadata(fExperiment + "_project.stage", fProjectStage); + if (!fProjectVersion.empty()) mds->addMetadata(fExperiment + "_project.version", fProjectVersion); + if (!fProjectSoftware.empty()) mds->addMetadata(fExperiment + "_project.software", fProjectSoftware); + if (!fProductionName.empty()) mds->addMetadata("production.name", fProductionName); + if (!fProductionType.empty()) mds->addMetadata("production.type", fProductionType); + std::ostringstream ostr; + if(fMerge >= 0) { + if(fMerge > 0) + mds->addMetadata("merge.merge", "1"); + else + mds->addMetadata("merge.merge", "0"); + mds->addMetadata("merge.merged", "0"); + } + for(auto const& param : fParameters) + mds->addMetadata(param.first, param.second); +} + +//-------------------------------------------------------------------- +// PostEndSubrun callback. +void util::FileCatalogMetadataSBN::postEndSubRun(art::SubRun const& sr) +{ + + art::ServiceHandle mds; + + art::Handle< sumdata::POTSummary > potListHandle; + if(sr.getByLabel(fPOTModuleLabel,potListHandle)){ + std::lock_guard lock(fMutex); + fTotPOT+=potListHandle->totpot; + } +} + +// PreCloseOutputFile callback. +void util::FileCatalogMetadataSBN::preCloseOutputFile(const std::string& label) +{ + std::lock_guard lock(fMutex); + + art::ServiceHandle mds; + + if(fTotPOT > 0.) { + std::ostringstream streamObj; + streamObj << fTotPOT; + std::string strPOT = streamObj.str(); + mds->addMetadata("mc.pot", strPOT); + } + fTotPOT = 0.; +} diff --git a/sbncode/Metadata/FileCatalogMetadataSBN_service.cc b/sbncode/Metadata/FileCatalogMetadataSBN_service.cc index 97ed33d73..73c5ec7e4 100644 --- a/sbncode/Metadata/FileCatalogMetadataSBN_service.cc +++ b/sbncode/Metadata/FileCatalogMetadataSBN_service.cc @@ -1,113 +1,4 @@ -//////////////////////////////////////////////////////////////////////// -// Name: FileCatalogMetadataSBN_service.cc. -// -// Purpose: Implementation for FileCatalogMetadataSBN. -// -// Created: 28-Oct-2014, H. Greenlee -// -//////////////////////////////////////////////////////////////////////// - -#include "sbncode/Metadata/FileCatalogMetadataSBN.h" - -#include "art/Framework/Services/Registry/ServiceHandle.h" #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h" -#include "art/Framework/Services/System/FileCatalogMetadata.h" -#include "art/Framework/Principal/SubRun.h" -#include "art/Framework/Principal/Handle.h" -#include "cetlib_except/exception.h" -#include "larcoreobj/SummaryData/POTSummary.h" - -//-------------------------------------------------------------------- -// Constructor. - -util::FileCatalogMetadataSBN:: -FileCatalogMetadataSBN(fhicl::ParameterSet const& pset, art::ActivityRegistry& reg) : - fTotPOT(0.) -{ - // Insist on configuring Experiment from the fcl file (ideally) or the - // environment. - const char* expt = getenv("EXPERIMENT"); - if(expt) fExperiment = pset.get("Experiment", expt); else fExperiment = pset.get("Experiment"); - std::transform(fExperiment.begin(), fExperiment.end(), fExperiment.begin(), [](unsigned char c){return std::tolower(c);}); - - // Get parameters. - - fFCLName = pset.get("FCLName"); - fProjectName = pset.get("ProjectName"); - fProjectStage = pset.get("ProjectStage"); - fProjectVersion = pset.get("ProjectVersion"); - fProjectSoftware = pset.get("ProjectSoftware",""); - fProductionName = pset.get("ProductionName",""); //Leave as default value if not running a production - fProductionType = pset.get("ProductionType",""); //Leave as default value if not running a production - fMerge = pset.get("Merge", -1); - fParameters = pset.get>>("Parameters", std::vector>()); - fPOTModuleLabel = pset.get("POTModuleLabel", "generator"); - - // Register for callbacks. - - reg.sPostBeginJob.watch(this, &FileCatalogMetadataSBN::postBeginJob); - reg.sPostEndSubRun.watch(this, &FileCatalogMetadataSBN::postEndSubRun); - reg.sPreCloseOutputFile.watch(this, &FileCatalogMetadataSBN::preCloseOutputFile); -} - -//-------------------------------------------------------------------- -// PostBeginJob callback. -// Insert per-job metadata via FileCatalogMetadata service. -void util::FileCatalogMetadataSBN::postBeginJob() -{ - // Get art metadata service. - - art::ServiceHandle mds; - - // Add metadata. - - if (!fFCLName.empty()) mds->addMetadata("fcl.name", fFCLName); - if (!fProjectName.empty()) mds->addMetadata(fExperiment + "_project.name", fProjectName); - if (!fProjectStage.empty()) mds->addMetadata(fExperiment + "_project.stage", fProjectStage); - if (!fProjectVersion.empty()) mds->addMetadata(fExperiment + "_project.version", fProjectVersion); - if (!fProjectSoftware.empty()) mds->addMetadata(fExperiment + "_project.software", fProjectSoftware); - if (!fProductionName.empty()) mds->addMetadata("production.name", fProductionName); - if (!fProductionType.empty()) mds->addMetadata("production.type", fProductionType); - std::ostringstream ostr; - if(fMerge >= 0) { - if(fMerge > 0) - mds->addMetadata("merge.merge", "1"); - else - mds->addMetadata("merge.merge", "0"); - mds->addMetadata("merge.merged", "0"); - } - for(auto const& param : fParameters) - mds->addMetadata(param.first, param.second); -} - -//-------------------------------------------------------------------- -// PostEndSubrun callback. -void util::FileCatalogMetadataSBN::postEndSubRun(art::SubRun const& sr) -{ - - art::ServiceHandle mds; - - art::Handle< sumdata::POTSummary > potListHandle; - if(sr.getByLabel(fPOTModuleLabel,potListHandle)){ - std::lock_guard lock(fMutex); - fTotPOT+=potListHandle->totpot; - } -} - -// PreCloseOutputFile callback. -void util::FileCatalogMetadataSBN::preCloseOutputFile(const std::string& label) -{ - std::lock_guard lock(fMutex); - - art::ServiceHandle mds; - - if(fTotPOT > 0.) { - std::ostringstream streamObj; - streamObj << fTotPOT; - std::string strPOT = streamObj.str(); - mds->addMetadata("mc.pot", strPOT); - } - fTotPOT = 0.; -} +#include "sbncode/Metadata/FileCatalogMetadataSBN.h" DEFINE_ART_SERVICE(util::FileCatalogMetadataSBN) diff --git a/sbncode/Metadata/MetadataSBN.cc b/sbncode/Metadata/MetadataSBN.cc new file mode 100644 index 000000000..92e4489cc --- /dev/null +++ b/sbncode/Metadata/MetadataSBN.cc @@ -0,0 +1,425 @@ +//////////////////////////////////////////////////////////////////////// +// Name: MetadataSBN_service.cc. +// +// Purpose: generate SBN-specific sam metadata for root Tfiles (histogram or ntuple files). +// +// FCL parameters: Experiment: Experiment name ("sbnd" or "icarus"). +// JSONFileName: Name of generated .json file(s). +// dataTier: Data tier(s). +// for ntuples, dataTier = root-tuple; +// for histos, dataTier = root-histogram +// (default value: root-tuple) +// fileFormat: This is currently specified by the user, +// the fileFormat for Tfiles is "root" (default value: root) +// Merge: Merge flag. +// 1 - Set merge.merge = 1 and merge.merged = 0 +// 0 - Set merge.merge = 0 and merge.merged = 0 +// -1 - Do not generate merge parameters. +// POTModuleLabel - POTSummary module label (default "generator"). +// +// Parameters JSONFileName, dataTier, and fileFormat can be single +// stringss or sequences of strings. In case of sequences of length +// greater than one, multiple json files will be generated. Sequences +// must be equal length. +// +// Other notes: 1. This service uses the ART's standard file_catalog_metadata service +// to extract some of the common (common to both ART and TFile outputs) +// job-specific metadata parameters, so, it is important to call this +// service in your fcl file +// stick this line in your "services" section of fcl file: +// FileCatalogMetadata: @local::art_file_catalog_mc +// +// 2. When you call FileCatalogMetadata service in your fcl file, and if +// you have (art) root Output section in your fcl file, and if you do not +// have "dataTier" specified in that section, then this service will throw +// an exception. To avoid this, either remove the entire root Output section +// in your fcl file (and remove art stream output from your end_paths) or +// include appropriate dataTier information in the section.If you are only +// running analysis job, best way is to not include any art root Output section. +// +// 3. This service is exclusively written to work with production (in other +// words for jobs submitted through grid). Some of the metadata parameters +// (output TFileName, filesize, Project related details) are captured/updated +// during and/or after the workflow. +// +// +// Created: 21-Feb-2018, D. Brailsford +// based on the SBND version by T. Junk which is based on the +// based on the MicroBooNE example by S. Gollapinni +// +//////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sbncode/Metadata/MetadataSBN.h" +#include "sbncode/Metadata/FileCatalogMetadataSBN.h" +#include "larcoreobj/SummaryData/POTSummary.h" + +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/SubRun.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "art/Framework/Services/System/FileCatalogMetadata.h" +#include "art/Framework/Services/System/TriggerNamesService.h" +#include "art/Utilities/OutputFileInfo.h" +#include "cetlib_except/exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +#include "TROOT.h" +#include "TFile.h" +#include "TTimeStamp.h" + +using namespace std; + +//-------------------------------------------------------------------- + +// Constructor. +util::MetadataSBN::MetadataSBN(fhicl::ParameterSet const& pset, + art::ActivityRegistry& reg): + fFileStats{"", art::ServiceHandle{}->getProcessName()} +{ + // Insist on configuring Experiment from the fcl file (ideally) or the + // environment. + const char* expt = getenv("EXPERIMENT"); + if(expt) fExperiment = pset.get("Experiment", expt); else fExperiment = pset.get("Experiment"); + std::transform(fExperiment.begin(), fExperiment.end(), fExperiment.begin(), [](unsigned char c){return std::tolower(c);}); + + // Get scalar/vector parameters. + if(pset.is_key_to_atom("JSONFileName")) + fJSONFileName.push_back(pset.get("JSONFileName")); + else if(pset.is_key_to_sequence("JSONFileName")) + fJSONFileName = pset.get >("JSONFileName"); + + if(pset.is_key_to_atom("dataTier")) + fDataTier.push_back(pset.get("dataTier")); + else if(pset.is_key_to_sequence("dataTier")) + fDataTier = pset.get >("dataTier"); + if(fDataTier.size() != fJSONFileName.size()) + throw cet::exception("MetadataSBN") << "FCL sequence size mismatch.\n"; + + if(pset.is_key_to_atom("fileFormat")) + fFileFormat.push_back(pset.get("fileFormat")); + else if(pset.is_key_to_sequence("fileFormat")) + fFileFormat = pset.get >("fileFormat"); + if(fFileFormat.size() != fJSONFileName.size()) + throw cet::exception("MetadataSBN") << "FCL sequence size mismatch.\n"; + + if(pset.has_key("Merge")) { + if(pset.is_key_to_atom("Merge")) + fMerge.push_back(pset.get("Merge")); + else if(pset.is_key_to_sequence("Merge")) + fMerge = pset.get >("Merge"); + } + fPOTModuleLabel = pset.get("POTModuleLabel", "generator"); + + reg.sPostBeginJob.watch(this, &MetadataSBN::postBeginJob); + reg.sPostOpenFile.watch(this, &MetadataSBN::postOpenInputFile); + reg.sPostCloseFile.watch(this, &MetadataSBN::postCloseInputFile); + reg.sPostProcessEvent.watch(this, &MetadataSBN::postEvent); + reg.sPostBeginSubRun.watch(this, &MetadataSBN::postBeginSubRun); + reg.sPostEndSubRun.watch(this, &MetadataSBN::postEndSubRun); + + // get metadata from the FileCatalogMetadataSBN service, which is filled on its construction + art::ServiceHandle paramhandle; + md.fFCLName = paramhandle->GetFCLName(); + md.fProjectName = paramhandle->GetProjectName(); + md.fProjectStage = paramhandle->GetProjectStage(); + md.fProjectVersion = paramhandle->GetProjectVersion(); + md.fProjectSoftware = paramhandle->GetProjectSoftware(); + md.fProductionName = paramhandle->GetProductionName(); + md.fProductionType = paramhandle->GetProductionType(); + md.merge = -1; + md.fTotPOT = 0.; +} + +/// Un-quote quoted strings +std::string UnQuoteString(std::string s) +{ + if(s.size() < 2 || s[0] != '\"' || s[s.size()-1] != '\"') return s; + s.erase(0, 1); + s.erase(s.size()-1, 1); + return s; +} + +void MaybeCopyFromMap(const std::map& in, + const std::string& key, + std::string& out) +{ + const auto it = in.find(key); + if(it == in.end()){ + out = ""; + } + else{ + out = UnQuoteString(it->second); + } +} + +void MaybeCopyToMap(const std::string& in, + const std::string& key, + std::map& out) +{ + if(!in.empty()) out[key] = UnQuoteString(in); +} + +//-------------------------------------------------------------------- +// PostBeginJob callback. +// Insert per-job metadata via Metadata service. +void util::MetadataSBN::postBeginJob() +{ + // get the start time + md.fstart_time = time(0); + + // Get art metadata service and extract paramters from there + art::ServiceHandle artmds; + + art::FileCatalogMetadata::collection_type artmd; + artmds->getMetadata(artmd); + + std::map mdmap; + for(const auto& d: artmd) + mdmap[d.first] = UnQuoteString(d.second); + + // if a certain paramter/key is not found, assign an empty string value to it + MaybeCopyFromMap(mdmap, "application.family", std::get<0>(md.fapplication)); + MaybeCopyFromMap(mdmap, "art.process_name", std::get<1>(md.fapplication)); + MaybeCopyFromMap(mdmap, "application.version", std::get<2>(md.fapplication)); + MaybeCopyFromMap(mdmap, "group", md.fgroup); + MaybeCopyFromMap(mdmap, "file_type", md.ffile_type); + MaybeCopyFromMap(mdmap, "art.run_type", frunType); +} + + +//-------------------------------------------------------------------- +// PostOpenFile callback. +void util::MetadataSBN::postOpenInputFile(std::string const& fn) +{ + // save parent input files here + // 08/06 DBrailsford: Only save the parent string if the string is filled. The string still exists (with 0 characters) for generation stage files. See redmine issue 20124 + if (fn.length() > 0) md.fParents.insert(fn); + fFileStats.recordInputFile(fn); +} + +//-------------------------------------------------------------------- +// PostEvent callback. +void util::MetadataSBN::postEvent(art::Event const& evt, art::ScheduleContext) +{ + std::lock_guard lock(fMutex); + + art::RunNumber_t run = evt.run(); + art::SubRunNumber_t subrun = evt.subRun(); + art::EventNumber_t event = evt.event(); + art::SubRunID srid = evt.id().subRunID(); + + // save run, subrun and runType information once every subrun + if (fSubRunNumbers.count(srid) == 0){ + fSubRunNumbers.insert(srid); + md.fruns.push_back(make_tuple(run, subrun, frunType)); + } + + // save the first event + if (md.fevent_count == 0) md.ffirst_event = event; + md.flast_event = event; + // event counter + ++md.fevent_count; + +} + +//-------------------------------------------------------------------- +// PostSubRun callback. +void util::MetadataSBN::postBeginSubRun(art::SubRun const& sr) +{ + std::lock_guard lock(fMutex); + + art::RunNumber_t run = sr.run(); + art::SubRunNumber_t subrun = sr.subRun(); + art::SubRunID srid = sr.id(); + + // save run, subrun and runType information once every subrun + if (fSubRunNumbers.count(srid) == 0){ + fSubRunNumbers.insert(srid); + md.fruns.push_back(make_tuple(run, subrun, frunType)); + } +} + +//-------------------------------------------------------------------- +// PostEndSubRun callback. +void util::MetadataSBN::postEndSubRun(art::SubRun const& sr) +{ + std::lock_guard lock(fMutex); + + art::Handle< sumdata::POTSummary > potListHandle; + double fTotPOT = 0; + if(sr.getByLabel(fPOTModuleLabel,potListHandle)){ + fTotPOT+=potListHandle->totpot; + } + + md.fTotPOT += fTotPOT; +} + + +//-------------------------------------------------------------------- +std::string Escape(const std::string& s) +{ + // If it's formatted as a dict or list, trust it's already formatted + if(s.size() >= 2 && ((s[0] == '{' && s.back() == '}') || (s[0] == '[' && s.back() == ']'))) return s; + + // otherwise quote it + return "\""+s+"\""; +} + +//-------------------------------------------------------------------- +std::string util::MetadataSBN::GetParentsString() const +{ + if(md.fParents.empty()) return ""; + + unsigned int c = 0; + + std::string ret = "[\n"; + for(auto parent: md.fParents) { + std::cout<<"Parent " << c << ": " << parent << std::endl; + c++; + size_t n = parent.find_last_of('/'); + size_t f1 = (n == std::string::npos ? 0 : n+1); + ret += " {\n \"file_name\": \"" + parent.substr(f1) + "\"\n }"; + if(md.fParents.size() == 1 || c == md.fParents.size()) ret += "\n"; + else ret += ",\n"; + } + + ret += " ]"; + return ret; +} + +//-------------------------------------------------------------------- +std::string util::MetadataSBN::GetRunsString() const +{ + unsigned int c = 0; + + std::string ret = "[\n"; + for(auto&t :md.fruns){ + c++; + ret += " [\n " + std::to_string(std::get<0>(t)) + ",\n " + std::to_string(std::get<1>(t)) + ",\n \"" + std::get<2>(t) + "\"\n ]"; + if(md.fruns.size() == 1 || c == md.fruns.size()) ret += "\n"; + else ret += ",\n"; + } + ret += " ]"; + return ret; +} + +//-------------------------------------------------------------------- +void util::MetadataSBN::GetMetadataMaps(std::map& strs, + std::map& ints, + std::map& doubles, + std::map& objs) +{ + strs.clear(); ints.clear(); doubles.clear(); objs.clear(); + + objs["application"] = "{\"family\": \""+std::get<0>(md.fapplication)+"\", \"name\": \""+std::get<1>(md.fapplication)+"\", \"version\": \""+std::get<2>(md.fapplication)+"\"}"; + + if(!md.fParents.empty()) objs["parents"] = GetParentsString(); + if(!md.fruns.empty()) objs["runs"] = GetRunsString(); + + // convert start and end times into time format: Year-Month-DayTHours:Minutes:Seconds + char endbuf[80], startbuf[80]; + struct tm tstruct; + tstruct = *localtime(&md.fend_time); + strftime(endbuf,sizeof(endbuf),"%Y-%m-%dT%H:%M:%S",&tstruct); + tstruct = *localtime(&md.fstart_time); + strftime(startbuf,sizeof(startbuf),"%Y-%m-%dT%H:%M:%S",&tstruct); + + strs["start_time"] = startbuf; + strs["end_time"] = endbuf; + + strs["data_tier"] = md.fdata_tier; + ints["event_count"] = md.fevent_count; + strs["file_format"] = md.ffile_format; + ints["first_event"] = md.ffirst_event; + ints["last_event"] = md.flast_event; + + const std::string proj = fExperiment+"_project"; + MaybeCopyToMap(md.fFCLName, "fcl.name", strs); + MaybeCopyToMap(md.fProjectName, proj+".name", strs); + MaybeCopyToMap(md.fProjectStage, proj+".stage", strs); + MaybeCopyToMap(md.fProjectVersion, proj+".version", strs); + MaybeCopyToMap(md.fProjectSoftware, proj+".software", strs); + MaybeCopyToMap(md.fProductionName, "production.name", strs); + MaybeCopyToMap(md.fProductionType, "production.type", strs); + + MaybeCopyToMap(md.fgroup, "group", strs); + MaybeCopyToMap(md.ffile_type, "file_type", strs); + + if(md.merge >= 0) { + ints["merge.merge"] = (md.merge==0 ? 0 : 1); + ints["merge.merged"] = 0; + } + doubles["mc.pot"] = md.fTotPOT; +} + +//-------------------------------------------------------------------- +// PostCloseFile callback. +void util::MetadataSBN::postCloseInputFile() +{ + //update end time + md.fend_time = time(0); + + // Loop over files. + + for(unsigned int i=0; i i) + md.merge = fMerge[i]; + else + md.merge = -1; + + + std::map strs; + std::map ints; + std::map doubles; + std::map objs; + GetMetadataMaps(strs, ints, doubles, objs); + + // open a json file and write everything from the struct md complying to the + // samweb json format. This json file holds the below information temporarily. + // If you submitted a grid job invoking this service, the information from + // this file is appended to a final json file and this file will be removed + + if(!fJSONFileName[i].empty()){ + std::ofstream jsonfile; + jsonfile.open(fJSONFileName[i]); + jsonfile << "{\n"; + + bool once = true; + for(auto& it: objs){ + if(!once) jsonfile << ",\n"; + once = false; + jsonfile << " \"" << it.first << "\": " << it.second; + } + for(auto& it: strs){ + // Have to escape string outputs + jsonfile << ",\n \"" << it.first << "\": \"" << it.second << "\""; + } + for(auto& it: ints){ + jsonfile << ",\n \"" << it.first << "\": " << it.second; + } + for(auto& it: doubles){ + jsonfile << ",\n \"" << it.first << "\": " << it.second; + } + + jsonfile<<"\n}\n"; + jsonfile.close(); + } + } + + fFileStats.recordFileClose(); + //TODO figure out how to make the name identical to the TFile + //std::string new_name = fRenamer.maybeRenameFile("myjson.json",fJSONFileName); +} diff --git a/sbncode/Metadata/MetadataSBN_service.cc b/sbncode/Metadata/MetadataSBN_service.cc index fed3614ef..e4024421b 100644 --- a/sbncode/Metadata/MetadataSBN_service.cc +++ b/sbncode/Metadata/MetadataSBN_service.cc @@ -1,428 +1,4 @@ -//////////////////////////////////////////////////////////////////////// -// Name: MetadataSBN_service.cc. -// -// Purpose: generate SBN-specific sam metadata for root Tfiles (histogram or ntuple files). -// -// FCL parameters: Experiment: Experiment name ("sbnd" or "icarus"). -// JSONFileName: Name of generated .json file(s). -// dataTier: Data tier(s). -// for ntuples, dataTier = root-tuple; -// for histos, dataTier = root-histogram -// (default value: root-tuple) -// fileFormat: This is currently specified by the user, -// the fileFormat for Tfiles is "root" (default value: root) -// Merge: Merge flag. -// 1 - Set merge.merge = 1 and merge.merged = 0 -// 0 - Set merge.merge = 0 and merge.merged = 0 -// -1 - Do not generate merge parameters. -// POTModuleLabel - POTSummary module label (default "generator"). -// -// Parameters JSONFileName, dataTier, and fileFormat can be single -// stringss or sequences of strings. In case of sequences of length -// greater than one, multiple json files will be generated. Sequences -// must be equal length. -// -// Other notes: 1. This service uses the ART's standard file_catalog_metadata service -// to extract some of the common (common to both ART and TFile outputs) -// job-specific metadata parameters, so, it is important to call this -// service in your fcl file -// stick this line in your "services" section of fcl file: -// FileCatalogMetadata: @local::art_file_catalog_mc -// -// 2. When you call FileCatalogMetadata service in your fcl file, and if -// you have (art) root Output section in your fcl file, and if you do not -// have "dataTier" specified in that section, then this service will throw -// an exception. To avoid this, either remove the entire root Output section -// in your fcl file (and remove art stream output from your end_paths) or -// include appropriate dataTier information in the section.If you are only -// running analysis job, best way is to not include any art root Output section. -// -// 3. This service is exclusively written to work with production (in other -// words for jobs submitted through grid). Some of the metadata parameters -// (output TFileName, filesize, Project related details) are captured/updated -// during and/or after the workflow. -// -// -// Created: 21-Feb-2018, D. Brailsford -// based on the SBND version by T. Junk which is based on the -// based on the MicroBooNE example by S. Gollapinni -// -//////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sbncode/Metadata/MetadataSBN.h" -#include "sbncode/Metadata/FileCatalogMetadataSBN.h" -#include "larcoreobj/SummaryData/POTSummary.h" - -#include "art/Framework/Principal/Event.h" -#include "art/Framework/Principal/SubRun.h" -#include "art/Framework/Services/Registry/ServiceHandle.h" #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h" -#include "art/Framework/Services/System/FileCatalogMetadata.h" -#include "art/Framework/Services/System/TriggerNamesService.h" -#include "art/Utilities/OutputFileInfo.h" -#include "cetlib_except/exception.h" -#include "messagefacility/MessageLogger/MessageLogger.h" - -#include "TROOT.h" -#include "TFile.h" -#include "TTimeStamp.h" - -using namespace std; - -//-------------------------------------------------------------------- - -// Constructor. -util::MetadataSBN::MetadataSBN(fhicl::ParameterSet const& pset, - art::ActivityRegistry& reg): - fFileStats{"", art::ServiceHandle{}->getProcessName()} -{ - // Insist on configuring Experiment from the fcl file (ideally) or the - // environment. - const char* expt = getenv("EXPERIMENT"); - if(expt) fExperiment = pset.get("Experiment", expt); else fExperiment = pset.get("Experiment"); - std::transform(fExperiment.begin(), fExperiment.end(), fExperiment.begin(), [](unsigned char c){return std::tolower(c);}); - - // Get scalar/vector parameters. - if(pset.is_key_to_atom("JSONFileName")) - fJSONFileName.push_back(pset.get("JSONFileName")); - else if(pset.is_key_to_sequence("JSONFileName")) - fJSONFileName = pset.get >("JSONFileName"); - - if(pset.is_key_to_atom("dataTier")) - fDataTier.push_back(pset.get("dataTier")); - else if(pset.is_key_to_sequence("dataTier")) - fDataTier = pset.get >("dataTier"); - if(fDataTier.size() != fJSONFileName.size()) - throw cet::exception("MetadataSBN") << "FCL sequence size mismatch.\n"; - - if(pset.is_key_to_atom("fileFormat")) - fFileFormat.push_back(pset.get("fileFormat")); - else if(pset.is_key_to_sequence("fileFormat")) - fFileFormat = pset.get >("fileFormat"); - if(fFileFormat.size() != fJSONFileName.size()) - throw cet::exception("MetadataSBN") << "FCL sequence size mismatch.\n"; - - if(pset.has_key("Merge")) { - if(pset.is_key_to_atom("Merge")) - fMerge.push_back(pset.get("Merge")); - else if(pset.is_key_to_sequence("Merge")) - fMerge = pset.get >("Merge"); - } - fPOTModuleLabel = pset.get("POTModuleLabel", "generator"); - - reg.sPostBeginJob.watch(this, &MetadataSBN::postBeginJob); - reg.sPostOpenFile.watch(this, &MetadataSBN::postOpenInputFile); - reg.sPostCloseFile.watch(this, &MetadataSBN::postCloseInputFile); - reg.sPostProcessEvent.watch(this, &MetadataSBN::postEvent); - reg.sPostBeginSubRun.watch(this, &MetadataSBN::postBeginSubRun); - reg.sPostEndSubRun.watch(this, &MetadataSBN::postEndSubRun); - - // get metadata from the FileCatalogMetadataSBN service, which is filled on its construction - art::ServiceHandle paramhandle; - md.fFCLName = paramhandle->GetFCLName(); - md.fProjectName = paramhandle->GetProjectName(); - md.fProjectStage = paramhandle->GetProjectStage(); - md.fProjectVersion = paramhandle->GetProjectVersion(); - md.fProjectSoftware = paramhandle->GetProjectSoftware(); - md.fProductionName = paramhandle->GetProductionName(); - md.fProductionType = paramhandle->GetProductionType(); - md.merge = -1; - md.fTotPOT = 0.; -} - -/// Un-quote quoted strings -std::string UnQuoteString(std::string s) -{ - if(s.size() < 2 || s[0] != '\"' || s[s.size()-1] != '\"') return s; - s.erase(0, 1); - s.erase(s.size()-1, 1); - return s; -} - -void MaybeCopyFromMap(const std::map& in, - const std::string& key, - std::string& out) -{ - const auto it = in.find(key); - if(it == in.end()){ - out = ""; - } - else{ - out = UnQuoteString(it->second); - } -} - -void MaybeCopyToMap(const std::string& in, - const std::string& key, - std::map& out) -{ - if(!in.empty()) out[key] = UnQuoteString(in); -} - -//-------------------------------------------------------------------- -// PostBeginJob callback. -// Insert per-job metadata via Metadata service. -void util::MetadataSBN::postBeginJob() -{ - // get the start time - md.fstart_time = time(0); - - // Get art metadata service and extract paramters from there - art::ServiceHandle artmds; - - art::FileCatalogMetadata::collection_type artmd; - artmds->getMetadata(artmd); - - std::map mdmap; - for(const auto& d: artmd) - mdmap[d.first] = UnQuoteString(d.second); - - // if a certain paramter/key is not found, assign an empty string value to it - MaybeCopyFromMap(mdmap, "application.family", std::get<0>(md.fapplication)); - MaybeCopyFromMap(mdmap, "art.process_name", std::get<1>(md.fapplication)); - MaybeCopyFromMap(mdmap, "application.version", std::get<2>(md.fapplication)); - MaybeCopyFromMap(mdmap, "group", md.fgroup); - MaybeCopyFromMap(mdmap, "file_type", md.ffile_type); - MaybeCopyFromMap(mdmap, "art.run_type", frunType); -} - - -//-------------------------------------------------------------------- -// PostOpenFile callback. -void util::MetadataSBN::postOpenInputFile(std::string const& fn) -{ - // save parent input files here - // 08/06 DBrailsford: Only save the parent string if the string is filled. The string still exists (with 0 characters) for generation stage files. See redmine issue 20124 - if (fn.length() > 0) md.fParents.insert(fn); - fFileStats.recordInputFile(fn); -} - -//-------------------------------------------------------------------- -// PostEvent callback. -void util::MetadataSBN::postEvent(art::Event const& evt, art::ScheduleContext) -{ - std::lock_guard lock(fMutex); - - art::RunNumber_t run = evt.run(); - art::SubRunNumber_t subrun = evt.subRun(); - art::EventNumber_t event = evt.event(); - art::SubRunID srid = evt.id().subRunID(); - - // save run, subrun and runType information once every subrun - if (fSubRunNumbers.count(srid) == 0){ - fSubRunNumbers.insert(srid); - md.fruns.push_back(make_tuple(run, subrun, frunType)); - } - - // save the first event - if (md.fevent_count == 0) md.ffirst_event = event; - md.flast_event = event; - // event counter - ++md.fevent_count; - -} - -//-------------------------------------------------------------------- -// PostSubRun callback. -void util::MetadataSBN::postBeginSubRun(art::SubRun const& sr) -{ - std::lock_guard lock(fMutex); - - art::RunNumber_t run = sr.run(); - art::SubRunNumber_t subrun = sr.subRun(); - art::SubRunID srid = sr.id(); - - // save run, subrun and runType information once every subrun - if (fSubRunNumbers.count(srid) == 0){ - fSubRunNumbers.insert(srid); - md.fruns.push_back(make_tuple(run, subrun, frunType)); - } -} - -//-------------------------------------------------------------------- -// PostEndSubRun callback. -void util::MetadataSBN::postEndSubRun(art::SubRun const& sr) -{ - std::lock_guard lock(fMutex); - - art::Handle< sumdata::POTSummary > potListHandle; - double fTotPOT = 0; - if(sr.getByLabel(fPOTModuleLabel,potListHandle)){ - fTotPOT+=potListHandle->totpot; - } - - md.fTotPOT += fTotPOT; -} - - -//-------------------------------------------------------------------- -std::string Escape(const std::string& s) -{ - // If it's formatted as a dict or list, trust it's already formatted - if(s.size() >= 2 && ((s[0] == '{' && s.back() == '}') || (s[0] == '[' && s.back() == ']'))) return s; - - // otherwise quote it - return "\""+s+"\""; -} - -//-------------------------------------------------------------------- -std::string util::MetadataSBN::GetParentsString() const -{ - if(md.fParents.empty()) return ""; - - unsigned int c = 0; - - std::string ret = "[\n"; - for(auto parent: md.fParents) { - std::cout<<"Parent " << c << ": " << parent << std::endl; - c++; - size_t n = parent.find_last_of('/'); - size_t f1 = (n == std::string::npos ? 0 : n+1); - ret += " {\n \"file_name\": \"" + parent.substr(f1) + "\"\n }"; - if(md.fParents.size() == 1 || c == md.fParents.size()) ret += "\n"; - else ret += ",\n"; - } - - ret += " ]"; - return ret; -} - -//-------------------------------------------------------------------- -std::string util::MetadataSBN::GetRunsString() const -{ - unsigned int c = 0; - - std::string ret = "[\n"; - for(auto&t :md.fruns){ - c++; - ret += " [\n " + std::to_string(std::get<0>(t)) + ",\n " + std::to_string(std::get<1>(t)) + ",\n \"" + std::get<2>(t) + "\"\n ]"; - if(md.fruns.size() == 1 || c == md.fruns.size()) ret += "\n"; - else ret += ",\n"; - } - ret += " ]"; - return ret; -} - -//-------------------------------------------------------------------- -void util::MetadataSBN::GetMetadataMaps(std::map& strs, - std::map& ints, - std::map& doubles, - std::map& objs) -{ - strs.clear(); ints.clear(); doubles.clear(); objs.clear(); - - objs["application"] = "{\"family\": \""+std::get<0>(md.fapplication)+"\", \"name\": \""+std::get<1>(md.fapplication)+"\", \"version\": \""+std::get<2>(md.fapplication)+"\"}"; - - if(!md.fParents.empty()) objs["parents"] = GetParentsString(); - if(!md.fruns.empty()) objs["runs"] = GetRunsString(); - - // convert start and end times into time format: Year-Month-DayTHours:Minutes:Seconds - char endbuf[80], startbuf[80]; - struct tm tstruct; - tstruct = *localtime(&md.fend_time); - strftime(endbuf,sizeof(endbuf),"%Y-%m-%dT%H:%M:%S",&tstruct); - tstruct = *localtime(&md.fstart_time); - strftime(startbuf,sizeof(startbuf),"%Y-%m-%dT%H:%M:%S",&tstruct); - - strs["start_time"] = startbuf; - strs["end_time"] = endbuf; - - strs["data_tier"] = md.fdata_tier; - ints["event_count"] = md.fevent_count; - strs["file_format"] = md.ffile_format; - ints["first_event"] = md.ffirst_event; - ints["last_event"] = md.flast_event; - - const std::string proj = fExperiment+"_project"; - MaybeCopyToMap(md.fFCLName, "fcl.name", strs); - MaybeCopyToMap(md.fProjectName, proj+".name", strs); - MaybeCopyToMap(md.fProjectStage, proj+".stage", strs); - MaybeCopyToMap(md.fProjectVersion, proj+".version", strs); - MaybeCopyToMap(md.fProjectSoftware, proj+".software", strs); - MaybeCopyToMap(md.fProductionName, "production.name", strs); - MaybeCopyToMap(md.fProductionType, "production.type", strs); - - MaybeCopyToMap(md.fgroup, "group", strs); - MaybeCopyToMap(md.ffile_type, "file_type", strs); - - if(md.merge >= 0) { - ints["merge.merge"] = (md.merge==0 ? 0 : 1); - ints["merge.merged"] = 0; - } - doubles["mc.pot"] = md.fTotPOT; -} - -//-------------------------------------------------------------------- -// PostCloseFile callback. -void util::MetadataSBN::postCloseInputFile() -{ - //update end time - md.fend_time = time(0); - - // Loop over files. - - for(unsigned int i=0; i i) - md.merge = fMerge[i]; - else - md.merge = -1; - - - std::map strs; - std::map ints; - std::map doubles; - std::map objs; - GetMetadataMaps(strs, ints, doubles, objs); - - // open a json file and write everything from the struct md complying to the - // samweb json format. This json file holds the below information temporarily. - // If you submitted a grid job invoking this service, the information from - // this file is appended to a final json file and this file will be removed - - if(!fJSONFileName[i].empty()){ - std::ofstream jsonfile; - jsonfile.open(fJSONFileName[i]); - jsonfile << "{\n"; - - bool once = true; - for(auto& it: objs){ - if(!once) jsonfile << ",\n"; - once = false; - jsonfile << " \"" << it.first << "\": " << it.second; - } - for(auto& it: strs){ - // Have to escape string outputs - jsonfile << ",\n \"" << it.first << "\": \"" << it.second << "\""; - } - for(auto& it: ints){ - jsonfile << ",\n \"" << it.first << "\": " << it.second; - } - for(auto& it: doubles){ - jsonfile << ",\n \"" << it.first << "\": " << it.second; - } - - jsonfile<<"\n}\n"; - jsonfile.close(); - } - } - - fFileStats.recordFileClose(); - //TODO figure out how to make the name identical to the TFile - //std::string new_name = fRenamer.maybeRenameFile("myjson.json",fJSONFileName); -} +#include "sbncode/Metadata/MetadataSBN.h" DEFINE_ART_SERVICE(util::MetadataSBN) diff --git a/sbncode/NuMuSelection/CMakeLists.txt b/sbncode/NuMuSelection/CMakeLists.txt index c188909b9..485fa77a0 100644 --- a/sbncode/NuMuSelection/CMakeLists.txt +++ b/sbncode/NuMuSelection/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin( MuPVertexStudy art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -25,7 +25,7 @@ cet_build_plugin( MuPVertexStudy art::module larreco::RecoAlg ) cet_build_plugin( MuonS2NStudy art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -51,7 +51,7 @@ cet_build_plugin( MuonS2NStudy art::module larreco::RecoAlg ) cet_build_plugin( NuMuEfficiencyStudy art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/OpDet/CMakeLists.txt b/sbncode/OpDet/CMakeLists.txt index 8eb4378a4..4949e7afe 100644 --- a/sbncode/OpDet/CMakeLists.txt +++ b/sbncode/OpDet/CMakeLists.txt @@ -1,6 +1,6 @@ cet_enable_asserts() -cet_build_plugin(PDMapAlgSimple art::tool LIBRARIES +cet_build_plugin(PDMapAlgSimple art::tool LIBRARIES PRIVATE art::Utilities ) diff --git a/sbncode/OpDet/PDMapAlgSimple.cc b/sbncode/OpDet/PDMapAlgSimple.cc new file mode 100644 index 000000000..4801bac70 --- /dev/null +++ b/sbncode/OpDet/PDMapAlgSimple.cc @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////// +/// +/// \file PDMapAlg.h +/// +/// \brief This is the interface class for a tool to handle PD mapping +/// in SBN detectors, used for flash matching. +/// +/// \author Laura Paulucci, Franciole Marinho, Iker de Icaza, and W. Ketchum +/// +//////////////////////////////////////////////////////////////////////// + +#include "PDMapAlg.h" +#include "art/Utilities/ToolMacros.h" +#include "art/Utilities/make_tool.h" + +#include + +namespace opdet { + + //a default dummy one + class PDMapAlgSimple : PDMapAlg + { + public: + explicit PDMapAlgSimple(const fhicl::ParameterSet& pset) + { fType = pset.get("Type","pmt"); } + + ~PDMapAlgSimple(){} + + std::string pdType(size_t ch) const override { return fType; } + + private: + std::string fType; + + }; + + + DEFINE_ART_CLASS_TOOL(PDMapAlgSimple) +} // namespace + diff --git a/sbncode/PID/CMakeLists.txt b/sbncode/PID/CMakeLists.txt index 1d5da7ad7..b63ec1cf4 100644 --- a/sbncode/PID/CMakeLists.txt +++ b/sbncode/PID/CMakeLists.txt @@ -1,6 +1,6 @@ cet_build_plugin( Dazzle art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -27,7 +27,7 @@ cet_build_plugin( Dazzle art::module ) cet_build_plugin( Razzle art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -54,7 +54,7 @@ cet_build_plugin( Razzle art::module ) cet_build_plugin( Razzled art::module - LIBRARIES + LIBRARIES PRIVATE ROOT::TMVA canvas::canvas art_root_io::TFileService_service diff --git a/sbncode/SBNEventWeight/App/CMakeLists.txt b/sbncode/SBNEventWeight/App/CMakeLists.txt index 335a19557..6bb912864 100644 --- a/sbncode/SBNEventWeight/App/CMakeLists.txt +++ b/sbncode/SBNEventWeight/App/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin(SBNEventWeight art::module - LIBRARIES + LIBRARIES PRIVATE sbnobj::Common_SBNEventWeight sbncode_SBNEventWeight_Base sbncode_SBNEventWeight_Calculators_CrossSection @@ -9,7 +9,7 @@ cet_build_plugin(SBNEventWeight art::module ROOT::Geom) cet_build_plugin(SystToolsEventWeight art::module - LIBRARIES + LIBRARIES PRIVATE sbnobj::Common_SBNEventWeight sbncode_SBNEventWeight_Base systematicstools::interface systematicstools::interpreters diff --git a/sbncode/SinglePhotonAnalysis/CMakeLists.txt b/sbncode/SinglePhotonAnalysis/CMakeLists.txt index 35f24c2bb..1d2a7af6a 100644 --- a/sbncode/SinglePhotonAnalysis/CMakeLists.txt +++ b/sbncode/SinglePhotonAnalysis/CMakeLists.txt @@ -23,21 +23,21 @@ art_make_library( BASENAME_ONLY ROOT::Core ) -cet_build_plugin(NCDeltaRadiative art::module BASENAME_ONLY LIBRARIES +cet_build_plugin(NCDeltaRadiative art::module BASENAME_ONLY LIBRARIES PRIVATE sbncode_SinglePhotonAnalysis_Libraries sbncode_SinglePhotonAnalysis_SEAview art_root_io::TFileService_service ROOT::Tree ) -cet_build_plugin(NCRadiativeResonant art::module BASENAME_ONLY LIBRARIES +cet_build_plugin(NCRadiativeResonant art::module BASENAME_ONLY LIBRARIES PRIVATE sbncode_SinglePhotonAnalysis_Libraries sbncode_SinglePhotonAnalysis_SEAview art_root_io::TFileService_service ROOT::Tree ) -cet_build_plugin(SinglePhoton art::module BASENAME_ONLY LIBRARIES +cet_build_plugin(SinglePhoton art::module BASENAME_ONLY LIBRARIES PRIVATE sbncode_SinglePhotonAnalysis_Libraries sbncode_SinglePhotonAnalysis_SEAview art_root_io::TFileService_service diff --git a/sbncode/TPCReco/CMakeLists.txt b/sbncode/TPCReco/CMakeLists.txt index 9ff783574..c5f85eba3 100644 --- a/sbncode/TPCReco/CMakeLists.txt +++ b/sbncode/TPCReco/CMakeLists.txt @@ -8,7 +8,7 @@ endif() cet_build_plugin(NuVertexChargeTree art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -38,7 +38,7 @@ cet_build_plugin(NuVertexChargeTree art::module cet_build_plugin( EventSelect art::module - LIBRARIES + LIBRARIES PRIVATE ifdh_art::IFDH_service art::Framework_Core art::Framework_Principal diff --git a/sbncode/TPCReco/CalorimetryAnalysis/CMakeLists.txt b/sbncode/TPCReco/CalorimetryAnalysis/CMakeLists.txt index 608bbee0a..b9ad49157 100644 --- a/sbncode/TPCReco/CalorimetryAnalysis/CMakeLists.txt +++ b/sbncode/TPCReco/CalorimetryAnalysis/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin( CalorimetryAnalysis art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/TPCReco/TrackHit/CMakeLists.txt b/sbncode/TPCReco/TrackHit/CMakeLists.txt index 339a71168..cc8661ab3 100644 --- a/sbncode/TPCReco/TrackHit/CMakeLists.txt +++ b/sbncode/TPCReco/TrackHit/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin(TrackAreaHit art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -20,7 +20,7 @@ cet_build_plugin(TrackAreaHit art::module ) cet_build_plugin(TrackHitFilter art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Core art::Framework_Services_Registry @@ -40,7 +40,7 @@ cet_build_plugin(TrackHitFilter art::module ) cet_build_plugin(TrackHitDumper art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Core art::Framework_Services_Registry diff --git a/sbncode/TPCReco/TrackSplit/CMakeLists.txt b/sbncode/TPCReco/TrackSplit/CMakeLists.txt index a359034d4..a2f2decb0 100644 --- a/sbncode/TPCReco/TrackSplit/CMakeLists.txt +++ b/sbncode/TPCReco/TrackSplit/CMakeLists.txt @@ -1,5 +1,5 @@ cet_build_plugin(TrackSplitter art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -18,7 +18,7 @@ cet_build_plugin(TrackSplitter art::module ) cet_build_plugin(MergedTrackIdentifier art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service diff --git a/sbncode/TPCReco/VertexStub/CMakeLists.txt b/sbncode/TPCReco/VertexStub/CMakeLists.txt index 19377e502..58b8e6f55 100644 --- a/sbncode/TPCReco/VertexStub/CMakeLists.txt +++ b/sbncode/TPCReco/VertexStub/CMakeLists.txt @@ -18,7 +18,7 @@ cet_make_library( larevt::SpaceCharge ) cet_build_plugin(VertexChargeVacuum art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Principal art::Framework_Services_Registry @@ -38,7 +38,7 @@ cet_build_plugin(VertexChargeVacuum art::module ) cet_build_plugin(VertexStubTracker art::module - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -60,7 +60,7 @@ cet_build_plugin(VertexStubTracker art::module ) cet_build_plugin(PlaneStubMerge art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service @@ -82,7 +82,7 @@ cet_build_plugin(PlaneStubMerge art::tool ) cet_build_plugin(TwoPlaneStubMerge art::tool - LIBRARIES + LIBRARIES PRIVATE art::Framework_Core art::Framework_Services_Registry art_root_io::TFileService_service From fc4ce053b552ee4c9b38a68c12dd023814bb3902 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Fri, 24 Apr 2026 15:24:11 -0500 Subject: [PATCH 342/367] Larsoft v10_20_06. --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index babf4b1db..32c947ea0 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_05 - +larsoft v10_20_06 - sbnalg v10_20_05 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - From 5794d9d80db66f6a2f056389310a6be481f37370 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Fri, 24 Apr 2026 15:54:19 -0500 Subject: [PATCH 343/367] v10_20_06 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 917e826aa..b9aad28a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.05 LANGUAGES CXX) +project(sbncode VERSION 10.20.06 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") From 82261dc1648172ca17220c6a65da507bb329e3f0 Mon Sep 17 00:00:00 2001 From: VCLanNguyen <74775793+VCLanNguyen@users.noreply.github.com> Date: Wed, 6 May 2026 08:31:03 -0700 Subject: [PATCH 344/367] Update sbncode/CAFMaker/FillTrigger.cxx Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/FillTrigger.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 70f33b231..6dbe66421 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -55,7 +55,7 @@ namespace caf double diff_ts = std::numeric_limits::max(); - if ((triggerInfo.global_trigger_time != std::numeric_limits::max()) & (triggerInfo.beam_gate_time_abs != std::numeric_limits::max())){ + if ((triggerInfo.global_trigger_time != std::numeric_limits::max()) && (triggerInfo.beam_gate_time_abs != std::numeric_limits::max())){ if (triggerInfo.global_trigger_time > triggerInfo.beam_gate_time_abs){ diff_ts = triggerInfo.global_trigger_time - triggerInfo.beam_gate_time_abs; From f93157640bd4218003cd6a8e7575d724d26668dd Mon Sep 17 00:00:00 2001 From: VCLanNguyen <74775793+VCLanNguyen@users.noreply.github.com> Date: Wed, 6 May 2026 08:32:14 -0700 Subject: [PATCH 345/367] Update sbncode/CAFMaker/FillTrigger.cxx Co-authored-by: Gianluca Petrillo --- sbncode/CAFMaker/FillTrigger.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/CAFMaker/FillTrigger.cxx b/sbncode/CAFMaker/FillTrigger.cxx index 6dbe66421..525bb1dba 100644 --- a/sbncode/CAFMaker/FillTrigger.cxx +++ b/sbncode/CAFMaker/FillTrigger.cxx @@ -61,7 +61,7 @@ namespace caf diff_ts = triggerInfo.global_trigger_time - triggerInfo.beam_gate_time_abs; } else{ - diff_ts = (triggerInfo.beam_gate_time_abs - triggerInfo.global_trigger_time)*(double)-1; + diff_ts = -1.0 * (triggerInfo.beam_gate_time_abs - triggerInfo.global_trigger_time); } } triggerInfo.trigger_within_gate = diff_ts; From 3f47621a917029c01769116a3fb52f016e833e91 Mon Sep 17 00:00:00 2001 From: VCLanNguyen <74775793+VCLanNguyen@users.noreply.github.com> Date: Wed, 6 May 2026 08:41:48 -0700 Subject: [PATCH 346/367] Remove legacy timing correction for SBND Removed legacy timing correction code for SBND. --- sbncode/CAFMaker/CAFMaker_module.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sbncode/CAFMaker/CAFMaker_module.cc b/sbncode/CAFMaker/CAFMaker_module.cc index 4d0d8368b..052274eaf 100644 --- a/sbncode/CAFMaker/CAFMaker_module.cc +++ b/sbncode/CAFMaker/CAFMaker_module.cc @@ -2655,12 +2655,6 @@ void CAFMaker::produce(art::Event& evt) noexcept { { // Fill trigger info FillTriggerSBND(srsbndtiminginfo, srtrigger); - - //// Legacy code: Timing correction is now done at decoding/reconstruction level - ////shift reference frame for CRT objects: crt trk, crt sp, crt sp match, crt trk match - //SBNDShiftCRTReference(rec, rec.sbnd_frames.frameApplyAtCaf); - ////shift reference frame for PMT objects: opflash, opt0 - //SBNDShiftPMTReference(rec, rec.sbnd_frames.frameApplyAtCaf); } // Get metadata information for header From fcd989af0714925fb84c55e0c2c43b5996acf10c Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Mon, 11 May 2026 15:31:03 -0500 Subject: [PATCH 347/367] v10_20_07 --- CMakeLists.txt | 2 +- ups/product_deps | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9aad28a0..1db70866d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.06 LANGUAGES CXX) +project(sbncode VERSION 10.20.07 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 32c947ea0..9bd8dcc4a 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,13 +254,13 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_06 - -sbnalg v10_20_05 - +larsoft v10_20_07 - +sbnalg v10_20_07 - sbndaq_artdaq_core v1_10_06 - sbndata v01_08 - -systematicstools v01_04_04 - -nusystematics v1_05_11 - -geant4reweight v01_21_02 - +systematicstools v01_04_05 - +nusystematics v1_05_13 - +geant4reweight v01_21_03 - cetmodules v3_24_01 - only_for_build end_product_list #################################### From f890ebf85c9d8adef55d49ed8d19d3b49689392a Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Mon, 11 May 2026 15:33:44 -0500 Subject: [PATCH 348/367] Update sbndata version to v01_10. --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index 9bd8dcc4a..c68f0404b 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -257,7 +257,7 @@ larcv2 v2_2_6 - larsoft v10_20_07 - sbnalg v10_20_07 - sbndaq_artdaq_core v1_10_06 - -sbndata v01_08 - +sbndata v01_10 - systematicstools v01_04_05 - nusystematics v1_05_13 - geant4reweight v01_21_03 - From 8f3ab0bfb9045a3cd6329cc18383aae377f7d4d0 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Wed, 13 May 2026 15:08:40 -0500 Subject: [PATCH 349/367] v10_20_08 --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1db70866d..6314d5dae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.07 LANGUAGES CXX) +project(sbncode VERSION 10.20.08 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index c68f0404b..a2f070707 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_07 - +larsoft v10_20_08 - sbnalg v10_20_07 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - From e0366f7917907bcf8b6e60f17bbe0533ad115aad Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Tue, 26 May 2026 11:44:35 -0500 Subject: [PATCH 350/367] Larsoft v10_20_09. --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index a2f070707..eb94be7c4 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_08 - +larsoft v10_20_09 - sbnalg v10_20_07 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - From fba3cb70eda0a7155b8a682419329aaa97f310d7 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Wed, 27 May 2026 10:50:20 -0500 Subject: [PATCH 351/367] v10_20_09 --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6314d5dae..c65810f35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.08 LANGUAGES CXX) +project(sbncode VERSION 10.20.09 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index eb94be7c4..7c8b934a0 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - larsoft v10_20_09 - -sbnalg v10_20_07 - +sbnalg v10_20_09 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - systematicstools v01_04_05 - From bd52c2884f139fbfb9abf302399ddd534f015089 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Fri, 12 Jun 2026 16:35:00 -0500 Subject: [PATCH 352/367] v10_21_00 --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index 7c8b934a0..c8edf139b 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_20_09 - +larsoft v10_21_00 - sbnalg v10_20_09 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - From cb5ee0df19c77480e48d3df0cdfade0ea695292c Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Mon, 15 Jun 2026 11:27:03 -0500 Subject: [PATCH 353/367] v10_21_00 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c65810f35..11db9b346 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.20.09 LANGUAGES CXX) +project(sbncode VERSION 10.21.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") From d474e79bab92885fb5519cdb58b577866fd457c0 Mon Sep 17 00:00:00 2001 From: Patrick Gartung Date: Thu, 18 Jun 2026 13:33:57 -0500 Subject: [PATCH 354/367] Add CMakePresets.json needed by spack mpd --- CMakePresets.json | 140 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 CMakePresets.json diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..dbdc04e58 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,140 @@ +{ + "configurePresets" : [ + { + "cacheVariables" : { + "CMAKE_BUILD_TYPE" : { + "type" : "STRING", + "value" : "RelWithDebInfo" + }, + "CMAKE_CXX_EXTENSIONS" : { + "type" : "BOOL", + "value" : "OFF" + }, + "CMAKE_CXX_STANDARD_REQUIRED" : { + "type" : "BOOL", + "value" : "ON" + }, + "sbncode_ADD_ARCH_DIRS_INIT" : { + "type" : "INTERNAL", + "value" : "LIBRARY_DIR;BIN_DIR" + }, + "sbncode_ADD_NOARCH_DIRS_INIT" : { + "type" : "INTERNAL", + "value" : "GDML_DIR;INCLUDE_DIR;FHICL_DIR;FW_DIR" + }, + "sbncode_BIN_DIR_INIT" : { + "type" : "STRING", + "value" : "bin" + }, + "sbncode_FHICL_DIR_INIT" : { + "type" : "STRING", + "value" : "fcl" + }, + "sbncode_FW_DIR_INIT" : { + "type" : "STRING", + "value" : "scripts" + }, + "sbncode_INCLUDE_DIR_INIT" : { + "type" : "STRING", + "value" : "include" + }, + "sbncode_LIBRARY_DIR_INIT" : { + "type" : "STRING", + "value" : "lib" + } + }, + "description" : "Configuration settings translated from ups/product_deps", + "displayName" : "Configuration from product_deps", + "hidden" : true, + "name" : "from_product_deps" + }, + { + "cacheVariables" : { + "CMAKE_CXX_COMPILER" : { + "type" : "STRING", + "value" : "$env{CETPKG_CXX_COMPILER}" + }, + "CMAKE_CXX_STANDARD" : { + "type" : "STRING", + "value" : "$env{CETPKG_CXX_STANDARD}" + }, + "CMAKE_C_COMPILER" : { + "type" : "STRING", + "value" : "$env{CETPKG_C_COMPILER}" + }, + "CMAKE_Fortran_COMPILER" : { + "type" : "STRING", + "value" : "$env{CETPKG_Fortran_COMPILER}" + }, + "UPS_CXX_COMPILER_ID" : { + "type" : "STRING", + "value" : "$env{CETPKG_CXX_COMPILER_ID}" + }, + "UPS_CXX_COMPILER_VERSION" : { + "type" : "STRING", + "value" : "$env{CETPKG_CXX_COMPILER_VERSION}" + }, + "UPS_C_COMPILER_ID" : { + "type" : "STRING", + "value" : "$env{CETPKG_C_COMPILER_ID}" + }, + "UPS_C_COMPILER_VERSION" : { + "type" : "STRING", + "value" : "$env{CETPKG_C_COMPILER_VERSION}" + }, + "UPS_Fortran_COMPILER_ID" : { + "type" : "STRING", + "value" : "$env{CETPKG_Fortran_COMPILER_ID}" + }, + "UPS_Fortran_COMPILER_VERSION" : { + "type" : "STRING", + "value" : "$env{CETPKG_Fortran_COMPILER_VERSION}" + }, + "WANT_UPS" : { + "type" : "BOOL", + "value" : true + }, + "sbncode_EXEC_PREFIX_INIT" : { + "type" : "STRING", + "value" : "$env{CETPKG_FQ_DIR}" + }, + "sbncode_UPS_BUILD_ONLY_DEPENDENCIES_INIT" : { + "type" : "STRING", + "value" : "cetmodules" + }, + "sbncode_UPS_PRODUCT_FLAVOR_INIT" : { + "type" : "STRING", + "value" : "$env{CETPKG_FLAVOR}" + }, + "sbncode_UPS_PRODUCT_NAME_INIT" : { + "type" : "STRING", + "value" : "sbncode" + }, + "sbncode_UPS_QUALIFIER_STRING_INIT" : { + "type" : "STRING", + "value" : "$env{CETPKG_QUALSPEC}" + } + }, + "description" : "Extra configuration for UPS package generation", + "displayName" : "UPS extra configuration", + "hidden" : true, + "name" : "extra_for_UPS" + }, + { + "description" : "Default configuration including settings from ups/product_deps", + "displayName" : "Default configuration", + "inherits" : "from_product_deps", + "name" : "default" + }, + { + "description" : "Default configuration for UPS package generation", + "displayName" : "Default configuration for UPS", + "inherits" : [ + "default", + "extra_for_UPS" + ], + "name" : "for_UPS" + } + ], + "version" : 3 +} From 2bb5966d86f31ac50d7d1b09b7306e5093e742a3 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 25 Jun 2026 13:26:07 -0500 Subject: [PATCH 355/367] Remove duplicate "PRIVATE." --- sbncode/Calibration/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/Calibration/CMakeLists.txt b/sbncode/Calibration/CMakeLists.txt index 8b83d3f70..ae1d41421 100644 --- a/sbncode/Calibration/CMakeLists.txt +++ b/sbncode/Calibration/CMakeLists.txt @@ -81,7 +81,7 @@ cet_build_plugin(TrackCaloSkimmerSelectClearCosmicMuon art::tool ) cet_build_plugin ( DataSelect art::module - LIBRARIES PRIVATE PRIVATE + LIBRARIES PRIVATE ifdh_art::IFDH_service art::Framework_Core art::Framework_Principal From 84def665ba9d1833c2db44dfb3514a4089297e11 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 25 Jun 2026 13:30:27 -0500 Subject: [PATCH 356/367] Remove duplicate PDMapAlgSimple.cc. --- sbncode/OpDet/PDMapAlgSimple.cc | 39 --------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 sbncode/OpDet/PDMapAlgSimple.cc diff --git a/sbncode/OpDet/PDMapAlgSimple.cc b/sbncode/OpDet/PDMapAlgSimple.cc deleted file mode 100644 index 4801bac70..000000000 --- a/sbncode/OpDet/PDMapAlgSimple.cc +++ /dev/null @@ -1,39 +0,0 @@ -/////////////////////////////////////////////////////////////////////// -/// -/// \file PDMapAlg.h -/// -/// \brief This is the interface class for a tool to handle PD mapping -/// in SBN detectors, used for flash matching. -/// -/// \author Laura Paulucci, Franciole Marinho, Iker de Icaza, and W. Ketchum -/// -//////////////////////////////////////////////////////////////////////// - -#include "PDMapAlg.h" -#include "art/Utilities/ToolMacros.h" -#include "art/Utilities/make_tool.h" - -#include - -namespace opdet { - - //a default dummy one - class PDMapAlgSimple : PDMapAlg - { - public: - explicit PDMapAlgSimple(const fhicl::ParameterSet& pset) - { fType = pset.get("Type","pmt"); } - - ~PDMapAlgSimple(){} - - std::string pdType(size_t ch) const override { return fType; } - - private: - std::string fType; - - }; - - - DEFINE_ART_CLASS_TOOL(PDMapAlgSimple) -} // namespace - From 001314af002b88fda80505572bdb60d495a055f9 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 25 Jun 2026 14:12:08 -0500 Subject: [PATCH 357/367] v10_21_01 --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index c8edf139b..7afc40869 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_21_00 - +larsoft v10_21_01 - sbnalg v10_20_09 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - From cacc522554f5f97b41f2f24f864935fb44eec7fb Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 25 Jun 2026 14:25:25 -0500 Subject: [PATCH 358/367] Revert cmake updates. --- sbncode/OpDet/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbncode/OpDet/CMakeLists.txt b/sbncode/OpDet/CMakeLists.txt index 4949e7afe..8eb4378a4 100644 --- a/sbncode/OpDet/CMakeLists.txt +++ b/sbncode/OpDet/CMakeLists.txt @@ -1,6 +1,6 @@ cet_enable_asserts() -cet_build_plugin(PDMapAlgSimple art::tool LIBRARIES PRIVATE +cet_build_plugin(PDMapAlgSimple art::tool LIBRARIES art::Utilities ) From 6d343ec947e8e6a42118831eacde3b3f9ed3c200 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 25 Jun 2026 14:44:10 -0500 Subject: [PATCH 359/367] v10_21_01 --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11db9b346..cc93b7898 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.21.00 LANGUAGES CXX) +project(sbncode VERSION 10.21.01 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index c8edf139b..3cbda6ea6 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,8 +254,8 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_21_00 - -sbnalg v10_20_09 - +larsoft v10_21_01 - +sbnalg v10_21_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - systematicstools v01_04_05 - From e21a3c045f6821ff5557267962e636c67d0b5a67 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 2 Jul 2026 12:03:23 -0500 Subject: [PATCH 360/367] Add interface library for PDMapAlg. Remove unnecessary include dependency in PDMapAlg.h. --- sbncode/OpDet/CMakeLists.txt | 8 +++++++- sbncode/OpDet/PDMapAlg.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sbncode/OpDet/CMakeLists.txt b/sbncode/OpDet/CMakeLists.txt index 8eb4378a4..445995f0e 100644 --- a/sbncode/OpDet/CMakeLists.txt +++ b/sbncode/OpDet/CMakeLists.txt @@ -1,6 +1,12 @@ cet_enable_asserts() -cet_build_plugin(PDMapAlgSimple art::tool LIBRARIES +cet_make_library( + LIBRARY_NAME OpDet_PDMapAlg INTERFACE + SOURCE + PDMapAlg.h +) + +cet_build_plugin(PDMapAlgSimple art::tool LIBRARIES PRIVATE art::Utilities ) diff --git a/sbncode/OpDet/PDMapAlg.h b/sbncode/OpDet/PDMapAlg.h index e0b79fae1..d9a9f687e 100644 --- a/sbncode/OpDet/PDMapAlg.h +++ b/sbncode/OpDet/PDMapAlg.h @@ -12,7 +12,7 @@ #ifndef SBN_OpDet_PDMapAlg_H #define SBN_OpDet_PDMapAlg_H -#include "fhiclcpp/ParameterSet.h" +//#include "fhiclcpp/ParameterSet.h" //#include "art/Utilities/ToolMacros.h" #include From a097a22e3a7d2e9b0f15d1e5819511b6124b15aa Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Thu, 2 Jul 2026 12:33:42 -0500 Subject: [PATCH 361/367] Update file name comment. --- sbncode/Metadata/FileCatalogMetadataSBN.cc | 2 +- sbncode/Metadata/MetadataSBN.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sbncode/Metadata/FileCatalogMetadataSBN.cc b/sbncode/Metadata/FileCatalogMetadataSBN.cc index 417ec09cc..7c4d8f613 100644 --- a/sbncode/Metadata/FileCatalogMetadataSBN.cc +++ b/sbncode/Metadata/FileCatalogMetadataSBN.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// Name: FileCatalogMetadataSBN_service.cc. +// Name: FileCatalogMetadataSBN.cc. // // Purpose: Implementation for FileCatalogMetadataSBN. // diff --git a/sbncode/Metadata/MetadataSBN.cc b/sbncode/Metadata/MetadataSBN.cc index 92e4489cc..0cb7d5f11 100644 --- a/sbncode/Metadata/MetadataSBN.cc +++ b/sbncode/Metadata/MetadataSBN.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// Name: MetadataSBN_service.cc. +// Name: MetadataSBN.cc. // // Purpose: generate SBN-specific sam metadata for root Tfiles (histogram or ntuple files). // From 8d0a4753606887cba82e837bf5c2a74b8144e4a7 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Mon, 6 Jul 2026 12:00:07 -0500 Subject: [PATCH 362/367] v10_21_02 --- CMakeLists.txt | 2 +- ups/product_deps | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc93b7898..9a0aaa953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.21.01 LANGUAGES CXX) +project(sbncode VERSION 10.21.02 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 3cbda6ea6..fa2b737d2 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,12 +254,12 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_21_01 - +larsoft v10_21_02 - sbnalg v10_21_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - systematicstools v01_04_05 - -nusystematics v1_05_13 - +nusystematics v1_05_14 - geant4reweight v01_21_03 - cetmodules v3_24_01 - only_for_build end_product_list From b2de351535b8a836b854ce51d70ff605e1fd30b3 Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Fri, 10 Jul 2026 13:35:59 -0500 Subject: [PATCH 363/367] Larsoft v10_22_00 --- ups/product_deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ups/product_deps b/ups/product_deps index fa2b737d2..48cb0ab2f 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -254,7 +254,7 @@ libdir fq_dir lib product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - -larsoft v10_21_02 - +larsoft v10_22_00 - sbnalg v10_21_01 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - From 35baeab91adc59530dda776ecf104ca59429feed Mon Sep 17 00:00:00 2001 From: Herbert Greenlee Date: Fri, 10 Jul 2026 14:16:06 -0500 Subject: [PATCH 364/367] v10_22_00 --- CMakeLists.txt | 2 +- ups/product_deps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a0aaa953..5e122a6b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) find_package(cetmodules 3.20.00 REQUIRED) -project(sbncode VERSION 10.21.02 LANGUAGES CXX) +project(sbncode VERSION 10.22.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") diff --git a/ups/product_deps b/ups/product_deps index 48cb0ab2f..d98b3dc81 100644 --- a/ups/product_deps +++ b/ups/product_deps @@ -255,7 +255,7 @@ product version qual flags genie_xsec v3_06_00 - larcv2 v2_2_6 - larsoft v10_22_00 - -sbnalg v10_21_01 - +sbnalg v10_22_00 - sbndaq_artdaq_core v1_10_06 - sbndata v01_10 - systematicstools v01_04_05 - From 761a43e5a54caa8879823e527d952f52070f6471 Mon Sep 17 00:00:00 2001 From: Gianluca Petrillo Date: Sat, 18 Jan 2025 14:25:27 -0600 Subject: [PATCH 365/367] SBN job metadata: full system implementation and documentation, and sbncode GIT version --- CMakeLists.txt | 2 +- fcl/CMakeLists.txt | 1 + fcl/util/CMakeLists.txt | 1 + fcl/util/dump_sbnjobmetadata.fcl | 41 ++ sbncode/Metadata/CMakeLists.txt | 45 +++ sbncode/Metadata/DumpJobEnvironment_module.cc | 176 +++++++++ sbncode/Metadata/GITrepoVersion.cxx.in | 16 + sbncode/Metadata/GITrepoVersion.h.in | 18 + sbncode/Metadata/GlobalMetadataRegistry.cxx | 69 ++++ sbncode/Metadata/GlobalMetadataRegistry.h | 88 +++++ .../Metadata/JobEnvironmentInfoExtractor.cxx | 149 +++++++ .../Metadata/JobEnvironmentInfoExtractor.h | 146 +++++++ .../Metadata/RepositoryVersionReportUtils.cpp | 71 ++++ .../Metadata/RepositoryVersionReportUtils.h | 60 +++ sbncode/Metadata/RepositoryVersionReporter.h | 75 ++++ sbncode/Metadata/SBNsourceMetadataSystem.dox | 367 ++++++++++++++++++ sbncode/Metadata/SaveJobEnvironment_plugin.cc | 331 ++++++++++++++++ .../Metadata/sbncodeRepositoryVersion_tool.cc | 62 +++ 18 files changed, 1717 insertions(+), 1 deletion(-) create mode 100644 fcl/util/CMakeLists.txt create mode 100644 fcl/util/dump_sbnjobmetadata.fcl create mode 100644 sbncode/Metadata/DumpJobEnvironment_module.cc create mode 100644 sbncode/Metadata/GITrepoVersion.cxx.in create mode 100644 sbncode/Metadata/GITrepoVersion.h.in create mode 100644 sbncode/Metadata/GlobalMetadataRegistry.cxx create mode 100644 sbncode/Metadata/GlobalMetadataRegistry.h create mode 100644 sbncode/Metadata/JobEnvironmentInfoExtractor.cxx create mode 100644 sbncode/Metadata/JobEnvironmentInfoExtractor.h create mode 100644 sbncode/Metadata/RepositoryVersionReportUtils.cpp create mode 100644 sbncode/Metadata/RepositoryVersionReportUtils.h create mode 100644 sbncode/Metadata/RepositoryVersionReporter.h create mode 100644 sbncode/Metadata/SBNsourceMetadataSystem.dox create mode 100644 sbncode/Metadata/SaveJobEnvironment_plugin.cc create mode 100644 sbncode/Metadata/sbncodeRepositoryVersion_tool.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e122a6b3..6e7b55f8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,6 @@ project(sbncode VERSION 10.22.00 LANGUAGES CXX) message(STATUS "\n\n ========================== ${PROJECT_NAME} ==========================") - include(CetCMakeEnv) cet_cmake_env() @@ -84,6 +83,7 @@ find_package( geant4reweight REQUIRED ) include(ArtDictionary) include(ArtMake) include(BuildPlugins) +include(SBNutils) add_subdirectory(sbncode) add_subdirectory(fcl) diff --git a/fcl/CMakeLists.txt b/fcl/CMakeLists.txt index 3b6d71246..9a1d7be80 100644 --- a/fcl/CMakeLists.txt +++ b/fcl/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(gen) add_subdirectory(g4) add_subdirectory(caf) +add_subdirectory(util) install_fhicl() diff --git a/fcl/util/CMakeLists.txt b/fcl/util/CMakeLists.txt new file mode 100644 index 000000000..13355789a --- /dev/null +++ b/fcl/util/CMakeLists.txt @@ -0,0 +1 @@ +install_fhicl() diff --git a/fcl/util/dump_sbnjobmetadata.fcl b/fcl/util/dump_sbnjobmetadata.fcl new file mode 100644 index 000000000..2b14d3c68 --- /dev/null +++ b/fcl/util/dump_sbnjobmetadata.fcl @@ -0,0 +1,41 @@ +# +# File: dump_sbnjobmetadata.fcl +# Purpose: Prints on screen all the job SBN metadata stored in an input file. +# Author: Gianluca Petrillo (petrillo@slac.stanford.edu) +# Date: January 20, 2025 +# +# Reads and prints on screen the SBN job environment information from the input +# file. +# +# Changes +# -------- +# +# [20250120] (petrillo@slac.stanford.edu) +# original version +# + +#include "messages_icarus.fcl" + +process_name: JobMeta + +# use `icarus_message_services_interactive` to see dump on screen +services.message: @local::icarus_message_services_prod + +services.message.destinations.MetadataLog: { + type: file + filename: "JobEnvironment.log" + append: false + threshold: INFO + categories: { + DumpJobEnvironment: { limit: -1 } + default: { limit: 0 } + } +} + +outputs.metadataDumper: { + module_type: "DumpJobEnvironment" +} + +physics: { + streams: [ metadataDumper ] +} diff --git a/sbncode/Metadata/CMakeLists.txt b/sbncode/Metadata/CMakeLists.txt index 6cf9127e5..67cc0d27a 100644 --- a/sbncode/Metadata/CMakeLists.txt +++ b/sbncode/Metadata/CMakeLists.txt @@ -1,5 +1,21 @@ cet_enable_asserts() +GenerateRepoVersionSource(${CMAKE_PROJECT_NAME}) + +message(DEBUG "Generated source file '${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h'") + +art_make_library( + LIBRARIES + sbnobj::Common_Metadata + larcorealg::headers + art::Persistency_Provenance + art::Utilities + canvas::canvas + messagefacility::MF_MessageLogger + fhiclcpp::fhiclcpp + ) + + set( sbn_meta_lib_list art::Framework_Core art::Framework_Principal art::Framework_Services_Registry @@ -21,6 +37,35 @@ cet_build_plugin( MetadataSBN art::service art::Framework_IO_detail ) +cet_build_plugin(SaveJobEnvironment art::ResultsProducer + LIBRARIES + sbncode::Metadata + sbnobj::Common_Metadata + art_root_io::TFileService_service + art_root_io::tfile_support + art::Framework_Services_Registry + ) + +# cet_build_plugin(DumpJobEnvironment art::ResultsProducer +# LIBRARIES +# sbnobj::Common_Metadata +# ) + +cet_build_plugin(DumpJobEnvironment art::Output + LIBRARIES + sbnobj::Common_Metadata + ) + +cet_build_plugin(sbncodeRepositoryVersion art::tool + LIBRARIES + sbncode::Metadata + sbnobj::Metadata + sbnobj::Common_Metadata + ) + + +install_headers(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h") +install_source(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.cxx") install_headers() install_fhicl() install_source() diff --git a/sbncode/Metadata/DumpJobEnvironment_module.cc b/sbncode/Metadata/DumpJobEnvironment_module.cc new file mode 100644 index 000000000..93e4b8eb8 --- /dev/null +++ b/sbncode/Metadata/DumpJobEnvironment_module.cc @@ -0,0 +1,176 @@ +/** + * @file sbncode/Metadata/DumpJobEnvironment_module.cc + * @brief Producer module writing job environment information into output. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + */ + +// local libraries +#include "sbnobj/Common/Metadata/JobEnvironmentInfo.h" + +// framework libraries +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/OutputModule.h" +#include "art/Framework/Principal/ResultsPrincipal.h" +#include "art/Framework/Principal/Results.h" +#include "art/Framework/Principal/Provenance.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Persistency/Provenance/ModuleContext.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/types/ConfigurationTable.h" // fhicl::WrappedTable +#include "fhiclcpp/types/TableFragment.h" +#include "fhiclcpp/types/Atom.h" + +// C++ standard libraries +#include +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { class DumpJobEnvironment; } +/** + * @brief Output module dumping input versions to screen. + * + * The output module can be added to any of the end paths of an _art_ job to + * get a complete dump of the SBN job environment metadata stored into the input + * file. + * + * For example: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * process_name: JobMeta + * + * services.message.destinations.MetadataLog: { + * type: file + * filename: "JobEnvironment.log" + * append: false + * threshold: INFO + * categories: { + * DumpJobEnvironment: { limit: -1 } + * default: { limit: 0 } + * } + * } + * + * outputs.metadataDumper: { module_type: "DumpJobEnvironment" } + * + * physics.streams: [ metadataDumper ] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * will dump the metadata into a text file named `JobEnvironment.log`. + * + */ +class sbn::DumpJobEnvironment: public art::OutputModule { + public: + + /// Module configuration. + struct Config { + + using Name = fhicl::Name; + using Comment = fhicl::Comment; + + fhicl::TableFragment OutputModuleConfig; + + fhicl::Atom LogCategory { + Name{ "LogCategory" }, + Comment{ "name of the messagefacility output category to be used" }, + "DumpJobEnvironment" + }; + + }; // Config + + using Parameters + = fhicl::WrappedTable; + + explicit DumpJobEnvironment(Parameters const& params); + + private: + + // --- BEGIN --- Configuration ----------------------------------------------- + + std::string const fLogCategory; ///< Messagefacility category for the output. + + // --- END ----- Configuration ----------------------------------------------- + + + /// Dumps the information from an handle into the output stream. + template + void dumpInformation( + Stream& out, + art::Handle> const& infoHandle + ) const; + + + + void write(art::EventPrincipal&) override {} + void writeRun(art::RunPrincipal&) override {} + void writeSubRun(art::SubRunPrincipal&) override {} + + /// Reads and prints all the metadata data products. + void readResults(art::ResultsPrincipal const& results) override; + +}; // sbn::DumpJobEnvironment + + +// ----------------------------------------------------------------------------- +// --- Implementation +// ----------------------------------------------------------------------------- +sbn::DumpJobEnvironment::DumpJobEnvironment(Parameters const& params) + : OutputModule{ params().OutputModuleConfig } + , fLogCategory{ params().LogCategory() } +{} + + +// ----------------------------------------------------------------------------- +void sbn::DumpJobEnvironment::readResults + (art::ResultsPrincipal const& principal) +{ + if (!principal.size()) return; + + art::ModuleContext const moduleContext{ moduleDescription() }; + art::Results const& results = principal.makeResults(moduleContext); + + std::vector>> infoHandles + = results.getMany>(); + + mf::LogInfo out{ fLogCategory }; + out << "Found " << infoHandles.size() << " job information entries in input."; + + for (art::Handle> const& infoHandle + : infoHandles + ) { + out << '\n' << std::string(80, '*') << '\n'; + dumpInformation(out, infoHandle); + } + +} // sbn::DumpJobEnvironment::readResults() + + +// ----------------------------------------------------------------------------- +template +void sbn::DumpJobEnvironment::dumpInformation( + Stream& out, + art::Handle> const& infoHandle +) const { + + art::Provenance const* provenance = infoHandle.provenance(); + if (provenance) { + out << "Information from '" << provenance->inputTag().encode() << "'"; + } + else { + out << "Information with unknown provenance"; + } + + if (infoHandle.isValid()) { + out << " from " << infoHandle->size() << " sources\n"; + for (sbn::JobEnvironmentInfo const& info: *infoHandle) { + out << std::string(80, '=') << '\n' << info; + } + } + else out << "\n[information not available]\n"; + +} // sbn::DumpJobEnvironment::dumpInformation() + + +// ----------------------------------------------------------------------------- +DEFINE_ART_MODULE(sbn::DumpJobEnvironment) + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GITrepoVersion.cxx.in b/sbncode/Metadata/GITrepoVersion.cxx.in new file mode 100644 index 000000000..0d2a35157 --- /dev/null +++ b/sbncode/Metadata/GITrepoVersion.cxx.in @@ -0,0 +1,16 @@ +/** + * @file ${gitRepoVersionSourceStem}.cxx + * @brief GIT version for repository `${gitRepoName}`. + * @author automatically generated; + * template: Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see ${gitRepoVersionSourceStem}.h + */ + +#include "${gitRepoVersionSourceStem}.h" + +// ----------------------------------------------------------------------------- +const char RepositoryVersion_${gitRepoName}[] = "${gitRepoVersion}"; + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GITrepoVersion.h.in b/sbncode/Metadata/GITrepoVersion.h.in new file mode 100644 index 000000000..a3210703d --- /dev/null +++ b/sbncode/Metadata/GITrepoVersion.h.in @@ -0,0 +1,18 @@ +/** + * @file ${gitRepoVersionSourceStem}.h + * @brief GIT version for repository `${gitRepoName}`. + * @author automatically generated; + * template: Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see ${gitRepoVersionSourceStem}.cxx + */ + +#ifndef ${gitRepoName}_${gitRepoVersionSourceStem}_H +#define ${gitRepoName}_${gitRepoVersionSourceStem}_H + + +/// Repository version for ${gitRepoName}. +extern const char RepositoryVersion_${gitRepoName}[]; + + +#endif // ${gitRepoName}_${gitRepoVersionSourceStem}_H diff --git a/sbncode/Metadata/GlobalMetadataRegistry.cxx b/sbncode/Metadata/GlobalMetadataRegistry.cxx new file mode 100644 index 000000000..139e0e941 --- /dev/null +++ b/sbncode/Metadata/GlobalMetadataRegistry.cxx @@ -0,0 +1,69 @@ +/** + * @file sbncode/Metadata/GlobalMetadataRegistry.cxx + * @brief Centralized metadata tracker (implementation file). + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @file sbncode/Metadata/GlobalMetadataRegistry.h + */ + +// library header +#include "sbncode/Metadata/GlobalMetadataRegistry.h" + +// ----------------------------------------------------------------------------- +// global instance: +sbn::GlobalMetadataRegistry sbn::GlobalMetadataRegistry::GlobalRegistry; + + +// ----------------------------------------------------------------------------- +std::lock_guard sbn::GlobalMetadataRegistry::readAccess() const { + return std::lock_guard{ fAccessMutex }; +} + + +// ----------------------------------------------------------------------------- +std::lock_guard sbn::GlobalMetadataRegistry::writeAccess() const { + return std::lock_guard{ fAccessMutex }; +} + + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::registerMetadata + (Name_t name, Value_t value) -> GlobalMetadataRegistry& +{ + + auto const accessGrant = writeAccess(); + + fRegistry.insert(std::move(name), std::move(value)); + + return *this; + +} // sbn::GlobalMetadataRegistry::registerMetadata() + + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::getPtr(Name_t const& name) const + -> Value_t const* +{ + auto const accessGrant = readAccess(); + return registry().getPtr(name); +} + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::get(Name_t const& name) const + -> std::optional +{ + auto const accessGrant = readAccess(); + return registry().get(name); +} + + +// ----------------------------------------------------------------------------- +auto sbn::GlobalMetadataRegistry::get + (Name_t const& name, Value_t const& defValue) const -> Value_t +{ + auto const accessGrant = readAccess(); + return registry().get(name, defValue); +} + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GlobalMetadataRegistry.h b/sbncode/Metadata/GlobalMetadataRegistry.h new file mode 100644 index 000000000..a0484a9f0 --- /dev/null +++ b/sbncode/Metadata/GlobalMetadataRegistry.h @@ -0,0 +1,88 @@ +/** + * @file sbncode/Metadata/GlobalMetadataRegistry.h + * @brief Centralized metadata tracker. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + */ + + +#ifndef SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H +#define SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H + + +// SBN libraries +#include "sbnobj/Common/Metadata/OrderedPairList.h" + +// C++ standard libraries +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { class GlobalMetadataRegistry; } +/** + * @brief A simple class with singleton access storing data in concurrent way. + * + * The registry is a simple key-value (string-string) sorted list (implemented + * from `OrderedPairList`). + * + * It provides a singleton instance (`instance()`) and it is designed to be + * thread-safe (by blunt mutex'ing). + * + */ +class sbn::GlobalMetadataRegistry { + + static GlobalMetadataRegistry GlobalRegistry; ///< Singleton instance. + + mutable std::mutex fAccessMutex; + + sbn::OrderedPairList fRegistry; + + + /// Grant read access. + [[nodiscard]] std::lock_guard readAccess() const; + + /// Grants (exclusive) write access. + [[nodiscard]] std::lock_guard writeAccess() const; + + + public: + + // These types need to match the ones in sbn::OrderedPairList + using Name_t = std::string; ///< Type of metadata name. + using Value_t = std::string; ///< Type of metadata value. + + + /// Adds a key-value pair to the registry + /// @return this object + GlobalMetadataRegistry& registerMetadata(Name_t name, Value_t value); + + + // --- BEGIN --- Queries --------------------------------------------------- + /// @name Queries + /// @{ + + /// Returns the complete registry of metadata. **This is not thread-safe!** + sbn::OrderedPairList const& registry() const + { return fRegistry; } + + /// Returns a pointer to the value of the requested metadata `name`, + /// or `nullptr` if none. + Value_t const* getPtr(Name_t const& name) const; + + /// Returns the value of requested metadata `name`, `std::nullopt` if none. + std::optional get(Name_t const& name) const; + + /// Returns the value of the requested metadata `name`, or `defValue` if none. + Value_t get(Name_t const& name, Value_t const& defValue) const; + + /// @} + // --- END ----- Queries --------------------------------------------------- + + + /// Returns the global instance of this class (read/write). + static GlobalMetadataRegistry& instance() { return GlobalRegistry; } + +}; // GlobalMetadataRegistry + + +#endif // SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H diff --git a/sbncode/Metadata/JobEnvironmentInfoExtractor.cxx b/sbncode/Metadata/JobEnvironmentInfoExtractor.cxx new file mode 100644 index 000000000..4a7ec971f --- /dev/null +++ b/sbncode/Metadata/JobEnvironmentInfoExtractor.cxx @@ -0,0 +1,149 @@ +/** + * @file sbncode/Metadata/JobEnvironmentInfoExtractor.cxx + * @brief Algorithm extracting information from the job execution environment. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + * @see sbncode/Metadata/JobEnvironmentInfoExtractor.h + */ + +// library header +#include "sbncode/Metadata/JobEnvironmentInfoExtractor.h" + +// SBN libraries +#include "sbncode/Metadata/RepositoryVersionReportUtils.h" +#include "sbncode/Metadata/RepositoryVersionReporter.h" + +// LArSoft libraries +#include "larcorealg/CoreUtils/enumerate.h" + +// framework libraries +#include "art/Persistency/Provenance/ModuleDescription.h" +#include "art/Utilities/make_tool.h" +#include "canvas/Utilities/Exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/ParameterSet.h" + +// C/C++ standard library +#include +#include +#include // std::move() + +// system libraries +#include // strchr() +#include // environ + + +// ----------------------------------------------------------------------------- +std::vector const +sbn::JobEnvironmentInfoExtractor::Config::DefaultDropVars = { + R"|(.*%%$)|" // BASH function pattern + , R"|(.*\(\)$)|" // another BASH function pattern +}; + + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfoExtractor::JobEnvironmentInfoExtractor + (Config const& config /* = Config{} */) + : fDropVars{ prepareRegEx(config.dropVars) } + , fRepositoryReports{ config.repositories } + , fLogCategory{ config.logCategory } +{ + +} + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfo sbn::JobEnvironmentInfoExtractor::extract + (art::ModuleDescription const& moduleInfo) +{ + + sbn::JobEnvironmentInfo info; + + info.processName = moduleInfo.processName(); + info.artVersion = moduleInfo.releaseVersion(); + + info.sources = extractSourceVersions(); + + info.variables = extractEnvironmentVariables(); + + return info; + +} // sbn::JobEnvironmentInfoExtractor::extract() + + +// ----------------------------------------------------------------------------- +auto sbn::JobEnvironmentInfoExtractor::extractSourceVersions() const + -> sbn::OrderedPairList +{ + + // take advantage of the basic + sbn::OrderedPairList sourceVersions; + addVersionFromRepositories(sourceVersions, fRepositoryReports); + sourceVersions.finish(); + + return sourceVersions; + +} // sbn::JobEnvironmentInfoExtractor::extractSourceVersions() + + +// ----------------------------------------------------------------------------- +auto sbn::JobEnvironmentInfoExtractor::extractEnvironmentVariables() const + -> sbn::OrderedPairList +{ + + sbn::OrderedPairList vars; + + char** itemPtr = environ; + while (const char* item = *(itemPtr++)) { + + const char* sep = strchr(item, '='); + + std::string name, value; + if (sep) { + name = std::string{ item, sep++ }; + value = std::string{ sep }; + } + else { + mf::LogDebug{ fLogCategory } + << "Environment element '" << item << "' is not in name=value form."; + name = item; + } + + // apply drop filters + if (matchPatterns(name, fDropVars) < fDropVars.size()) + continue; + + vars.items.emplace_back(std::move(name), std::move(value)); + + } // while + + vars.finish(); + + return vars; + +} // sbn::JobEnvironmentInfoExtractor::extractEnvironmentVariables() + + +// ----------------------------------------------------------------------------- +std::size_t sbn::JobEnvironmentInfoExtractor::matchPatterns + (std::string const& value, std::vector const& patterns) +{ + for (auto const& [ iPattern, pattern ]: util::enumerate(patterns)) + if (std::regex_match(value, pattern)) return iPattern; + return patterns.size(); +} + + +// ----------------------------------------------------------------------------- +std::vector sbn::JobEnvironmentInfoExtractor::prepareRegEx + (std::vector const& patterns) +{ + std::vector regex; + regex.reserve(patterns.size()); + for (std::string const& pattern: patterns) regex.emplace_back(pattern); + return regex; +} + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/JobEnvironmentInfoExtractor.h b/sbncode/Metadata/JobEnvironmentInfoExtractor.h new file mode 100644 index 000000000..4c480a3a2 --- /dev/null +++ b/sbncode/Metadata/JobEnvironmentInfoExtractor.h @@ -0,0 +1,146 @@ +/** + * @file sbncode/Metadata/JobEnvironmentInfoExtractor.h + * @brief Algorithm extracting information from the job execution environment. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + * @see sbncode/Metadata/JobEnvironmentInfoExtractor.cxx + */ + +#ifndef SBNCODE_METADATA_JOBENVIRONMENTINFOEXTRACTOR_H +#define SBNCODE_METADATA_JOBENVIRONMENTINFOEXTRACTOR_H + + +// local libraries +#include "sbnobj/Common/Metadata/JobEnvironmentInfo.h" + +// C++ standard libraries +#include +#include +#include + + +// ----------------------------------------------------------------------------- +namespace art { class ModuleDescription; } // forward declarations + +// ----------------------------------------------------------------------------- +namespace sbn { class JobEnvironmentInfoExtractor; } +/** + * @brief Extracts job execution environment information. + * + * In its simplest form, the information is saved into a + * `sbn::JobEnvironmentInfo` object: + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + * sbn::JobEnvironmentInfoExtractor extractor; + * sbn::JobEnvironmentInfo const info = extractor(moduleDescription()); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * The `moduleDescription()` is a _art_ module member function, and as such this + * call is bound to the _art_ framework. However, if the context does not allow + * for a `art::ModuleDescription` object, partial information can still be + * retrieved which does not need that object. + * + * + * Configuration + * -------------- + * + * The configuration object, `Config`, includes the following configurable + * elements: + * * `dropVars`: a list of regular expression (`std::regex`) patterns to be + * matched to the environment variable names; if the name of a variable + * matches any of the the full patterns specified here, its value is not + * included in the metadata. This is useful to exclude known irrelevant + * variables (for example, shell functions). + * * `repositories`: a list of names of repositories to query for their + * version. For each repository ``, an attempt to load a _art_ tool + * named `RepositoryVersion` with an empty configuration parameter + * set is attempted, and on success all the information obtained from the + * tool is integrated into the metadata. + * * `logCategory`: this algorithm uses messagefacility library to emit + * messages to console. This is the category these messages are assigned to. + * + * + */ +class sbn::JobEnvironmentInfoExtractor { + + public: + + /// Configuration record. + struct Config { + + /// Default value of `dropVars`. + static std::vector const DefaultDropVars; + + /// Remove environment variables with names matching these patterns. + std::vector dropVars = DefaultDropVars; + + /// Look for the GIT version of these repositories. + std::vector repositories{ "sbncode" }; + + std::string logCategory = "JobEnvironmentInfoExtractor"; + + // needed because of compiler bugs + // https://bugs.llvm.org/show_bug.cgi?id=36684 + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645 + Config() {} + + }; // Config + + + /// Constructor with configuration. + JobEnvironmentInfoExtractor(Config const& config = Config{}); + + /// Extracts all the information from the environment. + sbn::JobEnvironmentInfo extract + (art::ModuleDescription const& moduleInfo); // not guaranteed to be const! + + /** + * @brief Extracts all the information from the environment. + * @param moduleInfo information about the _art_ module being executed + * @return an object with all extracted metadata + */ + sbn::JobEnvironmentInfo operator() (art::ModuleDescription const& moduleInfo) + { return extract(moduleInfo); } + + // --- BEGIN --- Partial metadata extraction ------------------------------- + /** + * @name Partial metadata extraction + * + * The member functions in this group allow the extraction of part of the job + * metadata. The function `extract()` includes the information from all of + * them, plus some more. + */ + /// @{ + + /// Returns the environment variables. + sbn::OrderedPairList extractEnvironmentVariables() const; + + /// Returns the version of the source repositories. + sbn::OrderedPairList extractSourceVersions() const; + + /// @} + // --- END ----- Partial metadata extraction ------------------------------- + + private: + + std::vector fDropVars; ///< Remove variables with matching names. + + ///< Names of the repositories to ask for a version report to. + std::vector fRepositoryReports; + + std::string fLogCategory; + + /// Converts all the patterns into regular expression objects. + static std::vector prepareRegEx + (std::vector const& patterns); + + /// @brief Returns the index of the first pattern `value` matches. + /// @return index of the first matched pattern, `patterns.size()` if none + static std::size_t matchPatterns + (std::string const& value, std::vector const& patterns); + +}; // sbn::JobEnvironmentInfoExtractor + + +// ----------------------------------------------------------------------------- + +#endif // SBNCODE_METADATA_JOBENVIRONMENTINFOEXTRACTOR_H diff --git a/sbncode/Metadata/RepositoryVersionReportUtils.cpp b/sbncode/Metadata/RepositoryVersionReportUtils.cpp new file mode 100644 index 000000000..5e9665657 --- /dev/null +++ b/sbncode/Metadata/RepositoryVersionReportUtils.cpp @@ -0,0 +1,71 @@ +/** + * @file sbncode/Metadata/RepositoryVersionReportUtils.cxx + * @brief Interface for _art_ tool reporting the version of packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see sbncode/Metadata/RepositoryVersionReportUtils.h + */ + +// library header +#include "sbncode/Metadata/RepositoryVersionReportUtils.h" + +// SBN libraries +#include "sbncode/Metadata/RepositoryVersionReporter.h" + +// framework libraries +#include "art/Utilities/make_tool.h" +#include "canvas/Utilities/Exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/ParameterSet.h" + +// C/C++ standard library +#include // std::unique_ptr<> + + +// ----------------------------------------------------------------------------- +bool sbn::addVersionFromRepository + (sbn::OrderedPairList& versionList, std::string const& repoName) +{ + + std::string const toolName = repoName + "RepositoryVersion"; + + fhicl::ParameterSet config; + config.put("tool_type", toolName); + + std::unique_ptr reportTool; + try { + reportTool = art::make_tool(config); + } + catch(cet::exception const& e) { + mf::LogWarning{ "RepositoryVersionReporter" } + << "No report from repository '" << repoName << "': tool not found."; + mf::LogDebug{ "RepositoryVersionReporter" } << "Error:\n" << e; + return false; + } + + // blindly add everything + versionList.items.insert + (versionList.items.end(), reportTool->begin(), reportTool->end()); + + return true; + +} // sbn::addVersionFromRepository() + + +// ----------------------------------------------------------------------------- +std::vector sbn::addVersionFromRepositories( + sbn::OrderedPairList& versionList, std::vector const& repoNames +) { + + std::vector missingRepos; + for (std::string const& repoName: repoNames) { + if (addVersionFromRepository(versionList, repoName)) continue; + missingRepos.push_back(repoName); + } + + return repoNames; + +} // sbn::addVersionFromRepositories() + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/RepositoryVersionReportUtils.h b/sbncode/Metadata/RepositoryVersionReportUtils.h new file mode 100644 index 000000000..1c7cea867 --- /dev/null +++ b/sbncode/Metadata/RepositoryVersionReportUtils.h @@ -0,0 +1,60 @@ +/** + * @file sbncode/Metadata/RepositoryVersionReportUtils.h + * @brief Interface for _art_ tool reporting the version of packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * @see sbncode/Metadata/RepositoryVersionReportUtils.cxx + */ + +#ifndef SBNCODE_METADATA_REPOSITORYVERSIONREPORTUTILS_H +#define SBNCODE_METADATA_REPOSITORYVERSIONREPORTUTILS_H + + +// SBN libraries +#include "sbnobj/Common/Metadata/OrderedPairList.h" + +// C/C++ standard library +#include +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { + + /** + * @brief Adds versions from the specified repository. + * @param[out] versionList version list to add to + * @param repoName name of the repository to be queried + * @return whether the repository plugin could be loaded + * + * The plugin with name `repoName + "RepositoryVersion"` is loaded and its + * report is appended to `versionList`. + * It will be necessary to call `versionList.finish()` after all the additions + * are done. + * + * This utility is used in the + * @ref SBNsourceMetadataSystem "repository version tracking system". + */ + bool addVersionFromRepository + (sbn::OrderedPairList& versionList, std::string const& repoName); + + + /** + * @brief Adds versions from the specified repositories. + * @param[out] versionList version list to add to + * @param repoNames name of the repositories to be queried + * @return which repositories which could not be reached + * @see addVersionFromRepository + * + * This is equivalent to repeatedly calling `addVersionFromRepository()`. + */ + std::vector addVersionFromRepositories( + sbn::OrderedPairList& versionList, std::vector const& repoNames + ); + +} // namespace sbn + + +// ----------------------------------------------------------------------------- + +#endif // SBNCODE_METADATA_REPOSITORYVERSIONREPORTUTILS_H diff --git a/sbncode/Metadata/RepositoryVersionReporter.h b/sbncode/Metadata/RepositoryVersionReporter.h new file mode 100644 index 000000000..55e2e05bf --- /dev/null +++ b/sbncode/Metadata/RepositoryVersionReporter.h @@ -0,0 +1,75 @@ +/** + * @file sbncode/Metadata/RepositoryVersionReporter.h + * @brief Interface for _art_ tool reporting the version of packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * + */ + +#ifndef SBNCODE_METADATA_REPOSITORYVERSIONREPORTER_H +#define SBNCODE_METADATA_REPOSITORYVERSIONREPORTER_H + + +// SBN libraries +#include "sbnobj/Common/Metadata/OrderedPairList.h" + +// C/C++ standard library +#include // std::distance() + + +// ----------------------------------------------------------------------------- +namespace sbn { class RepositoryVersionReporter; } +/** + * @brief Interface for _art_ tool reporting the version of packages. + * + * An object reporting package versions will return them as a range of pairs + * package name/package version, each element being a string. + * + * This interface is not at all generic, and the iterators that are returned + * are exactly `const_iterator` ones defined in this interface, which are + * iterators of the collection `vector_t` also defined here, which is exactly + * a `std::vector`. + * + * @note At this point there is no polymorphic interface: derived classes will + * fetch their data at construction time and keep it for anybody curious + * to learn it. In the future an actual virtual interface could become + * necessary, and at that point it would be clearer what it should + * contain. + * + */ +struct sbn::RepositoryVersionReporter { + + /// Type of the name of a package (a `std::string`). + using PackageName_t = sbn::OrderedPairList::Key_t; + + /// Type of the version of a package (a `std::string`). + using PackegaVersion_t = sbn::OrderedPairList::Value_t; + + // standard C++ container types + using value_type = sbn::OrderedPairList::value_type; + using size_type = sbn::OrderedPairList::size_type; + using const_iterator = sbn::OrderedPairList::const_iterator; + + + /// Collected packages and their versions. + sbn::OrderedPairList packageVersions; + + + /// Begin-iterator for the package-version pairs. + const_iterator begin() const { return packageVersions.begin(); } + + /// End-iterator for the package-version pairs. + const_iterator end() const { return packageVersions.end(); } + + /// Returns whether there is no entry in the report. + bool empty() const noexcept { return begin() == end(); } + + /// Returns the number of items in the report. + size_type size() const { return std::distance(begin(), end()); } + +}; // sbn::RepositoryVersionReporter + + +// ----------------------------------------------------------------------------- + +#endif // SBNCODE_METADATA_REPOSITORYVERSIONREPORTER_H diff --git a/sbncode/Metadata/SBNsourceMetadataSystem.dox b/sbncode/Metadata/SBNsourceMetadataSystem.dox new file mode 100644 index 000000000..fa843ba25 --- /dev/null +++ b/sbncode/Metadata/SBNsourceMetadataSystem.dox @@ -0,0 +1,367 @@ +/** @page SBNsourceMetadataSystem Source code and execution environment metadata system in SBN code +@author Gianluca Petrillo (petrillo@slac.stanford.edu) + + +At highest level, the plugin `SaveJobEnvironment` allows storage of metadata +into the _art_/ROOT and `TFileService` files, and the output module +`DumpJobEnvironment` prints the information saved in a _art_/ROOT file on +console. + +The system to achieve that result is quite convoluted, and this documentation +will describe that in detail. + + +Which information is extracted +=============================== + +The extraction algorithm, `sbn::JobEnvironmentInfoExtractor`, includes +information ("metadata") about: + * The execution environment of the job: + * the complete dump of environment variables (except the ones identified as + shell functions); when using UPS, this can be used to track the version + of the products (UPS packages) set up during the job. + * The GIT version of the repositories used during the build process of the + code for some selected source code repositories. + * Information from the software being executed: + * _art_ process name; + * _art_ version. + +This information is extracted for each _art_ process; since typically each final +output file is the result of a sequence of jobs, the output files will contain +multiple metadata sets, for each of the input and job that ended into the file +data. + + +How the information is stored for later use +============================================ + +The goal of the system is to save the metadata into each output file, so that it +is always known wherever the data is. + +Our current data system includes four output carriers: + 1. _art_/ROOT files, managed directly by _art_ and with a rigid format; + 2. `TFileService` supplemental ROOT file, also managed by _art_ but with a + format that is freer; + 3. LArCV files shipped to SPINE reconstruction framework; + 4. Common Analysis Format (CAF), managed by SBN via a _art_ module. + +At the moment of writing (at the inception of this system), the metadata is only +written into the _art_/ROOT and the `TFileService` output files. + +In addition, the system needs a way to store some of the information that would +not be available at run time: an example is the version of the software included +in the build, which is usually a GIT tag that does not survive to the +distributed binary code. +The options of where to keep this information include: as a executable code +(library) that software can link to and call/read; FHiCL configuration that jobs +can include; simple text files that jobs can read. + +There are limitations and shortcomings in each of the options. +The choice of this system was to include the version into an executable library. +The reason why the text file was not chosen is that it requires a convention of +where the file can be found, which is not trivial given the relocation of +distributed code. +The reason why FHiCL configuration was not preferred is that only _art_/ROOT +files automatically include that information. In addition, each job +configuration needs to know _exactly_ which repositories are being included, +since FHiCL parser does not tolerate missing information. The first limitation +can be worked around, for example with the experimental `icaruscode` module +`SaveConfigurationIntoTFile`, which was never fully completed or tested. +The selected option, library code, has ways to address these issues. There is +already a tracking system in place for the libraries, and _art_ has a "factory" +system that can find by name libraries (plug-ins) to be loaded dynamically. +As for the comparison with FHiCL, the code can be configured to look for a large +number of repository libraries, and if one is missing, the resulting error +(for example a thrown C++ exception) can be programmatically caught and handled. +The limitation of this option will be discussed later in this section. + +The difficulty of this system is that it needs to connect very heterogeneous +information sources, which never available all at the same time. +The source repository is available only in the build stage, while the execution +environment is present only... well, during the job execution. +The strategy is then to create one shared library for each repository, with +a standard name (`RepositoryVersion_\`), with the repository +version information, and to have some modular software that can read these +libraries, collect their information in a single place and then write it. +This is how it was implemented for the single repository named : + 1. CMake discovers the name of the repository from its remote source + (`git remote origin get-url`). + 2. CMake executes a `git describe` call (`git` executable must be available). + 3. CMake generates a C++ header and source file via `configure_file()` starting + from two template files (`GITrepoVersion.{h,cxx}.in`), and creates the + source files `RepositoryVersion_.{h,cxx}`. + 4. CMake creates the local directory library as usual + (e.g. `art_make_library`), which will include the two generated files too. + 5. The two generated files are added to the list of files to install. + +This happens in the source directory that is going to be hosting the library, by +convention `/Metadata` (e.g. in `sbncode/Metadata/CMakeLists.txt`). +The first three steps are collected in macros saved in `SBNutils.cmake`, which +must be included. + +A relevant question with this method is where the `SBNutils.cmake` macro library +should be hosted. The chosen repository must be at the root of the dependencies +of all the repositories that we need to version, but there is not such a root: +`sbnobj` (hosting _art_/ROOT data products) depends only on `lardataobj`, and +`sbnanaobj` (CAF data objects) depends only on ROOT (so, ironically, the root +dependency in our source tree _is_ in fact ROOT, but unfortunately it does not +make sense to add this infrastructure in there). The practical workaround to +this riddle is to duplicate the macro file, which obvious maintenance +consequences. + +@note An **important limitation** of this system is that the information is + extracted by CMake, when the build system decides to run CMake and when + CMake decides to (re)generate the files -- which may be never: at the + moment of writing, the details are not yet clear. + To make sure that the GIT versions are correct, the only safe way is to + zap the area (`mrb z`) and build everything from scratch. This is always + a good idea anyway after one thinks the code is ready for prime time. + Again, remember: after code is committed to GIT, an integral rebuild is + likely needed for the code version metadata to reflect the new repository + status. + +@note The presence of an actual library do be dynamically linked to is necessary + and can't be replaced by inline definitions in the header files. + The reason is that the system needs to support some level of delegation + (see the next section) where a package needs to provide information of + a different one which can't on its own. For example, `sbnobj` can extract + and store its own version, but it lacks the dependencies necessary to + provide it to _art_. Therefore, `sbncode` will be in charge of saving + `sbnobj` metadata in addition to its own. Given this structure, if + `sbnobj` version is stored in a header, `sbncode` will learn it at compile + time and keep it hard-coded. It is possible though that the job loads an + updated `sbnobj` instead of the one used during `sbncode` build, in which + case `sbncode` would still report the version hard-coded at the time of + its own build. + This practice is prone to many issues (the scenario described here + outlines a common one) and should be avoided; however, the metadata system + implemented here is a diagnostic tools and as such should be designed to + be more resilient than average. + + +How to arrange a repository with a version library +--------------------------------------------------- + +1. `SBNutils.cmake` needs to be included. It is stored, willy-nilly, in + `sbnobj`. The most obvious option is to add things into the main + `CMakeLists.txt` file of the repository; namely: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + find_package( sbnobj REQUIRED ) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + in the `find_package` section not present already, and + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + include(SBNutils) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + just after the inclusion of CETmodules/_art_ macro files and definitely + _before_ the `add_subdirectory()` calls. +2. Check the directory `/Metadata`. + 1. If it does not exist or does not contain a `CMakeLists.txt`: + 1. create it, and add the line + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + add_subdirectory(Metadata) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + to the `/CMakeLists.txt` (in the same directory where + the new `Metadata` directory is); + 2. copy into there from `sbnobj/Metadata` the file `CMakeLists.txt`, + which should be portable enough; or add lines as below. + 2. If it does exist, add to its `CMakeLists.txt`: + 1. at the top of the file (before the build commands): + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + GenerateRepoVersionSource(${CMAKE_PROJECT_NAME}) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + which calls the source generation macro from SBNutils; + 2. at the end add to the usual `install_Xxxx()` calls these ones: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + install_headers(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h") + install_source(LIST "${CMAKE_CURRENT_BINARY_DIR}/${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.cxx") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + which add the `.cxx` and `.h` files to the files to install; + 3. make sure that there is a `art_make_library()` call or equivalent + build command in the file; if there is none, or if there are only + plugin or dictionary build calls (`e.g. `cet_build_plugin()`), add + explicitly a + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + art_make_library() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + or a more explicit (and _art_-independent) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + cet_make_library( + SOURCE + "${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h" + "${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.cxx" + ) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + which will create a library with only the source file generated here. +3. Copy into there from `sbnobj/Metadata` the files `GITrepoVersion.{h,cxx}.in`. + Or write some custom ones (but remember that the _art_ tool needs the + implementation details). + +Note that in principle every `${CMAKE_PROJECT_NAME}` above can be replaced with +the actual CMake project name, hard-coded (e.g. `sbncode`). The only drawback is +that such lines need a further editing when copied into other repositories. + + + +How the information is extracted and serialized in the output +============================================================== + +When a job is executed, the version of all the repositories should ideally be +loaded and then saved into all the relevant output files. +The strategy for _art_ jobs (`lar`) is no less complex than the one described in +the previous paragraph. The choice was to save the information into a _art_ data +product. +Among the complications: + * The data product should be stored to have the least possible duplication. + * Metadata from the input files needs to be propagated into the output files; + and there can be multiple input files, multiple output files, and not in a + one-to-one correspondence. + +This is the general strategy: + + 1. Metadata is stored into a _results-level data product_, which is an + output-file-level data product (as opposed to run-level, subrun-level or + event-level) bound to the output module (e.g. `RootOutput`). + The class of the data product is defined in `sbnobj`. + 2. A plugin will take care of writing the metadata as a data product. This + plugin is specific to output modules like `RootOutput` and is somehow + different, but similar, to _art_ modules. The plugin has also the task of + attempting to collect the relevant information from all the possible + source repositories, as listed in the FHiCL configuration of the plugin. + If the information from a source repository is not available, that source is + simply not included in the metadata. The output plugin is defined in + `sbncode`, which is the lowest _art_-aware repository under our control. + 3. The plugin, called `SaveJobEnvironment`, calls an extractor utility, + `sbn::JobEnvironmentInfoExtractor`, which utilizes _art_ tools to + dynamically load information from all the source repositories. + Tools have conventional names (`RepositoryVersion`). + 4. Each tool is given the chance to provide arbitrary metadata, but they are + expected to fill in with the name and version of their repository. + +The factorization of the extractor utility from the output plugin allows to use +the utility also on other contexts, for example when running CAF maker. However, +because of the use of the _art_ tool infrastructure, it stills requires _art_ to +be functional. In addition, some of the information is extracted from _art_ +itself (e.g. the process name), so _art_ is also necessary as information source +if the full information is desired. + +A limitation of the _art_-tool-based strategy is that the repository containing +the tool must depend on _art_. Several source repositories do not fulfil this +requirement, by design; e.g. `sbnobj` and `icarusalg`. These repositories still +need to be instrumented with CMake instructions to generate the repository +version library (repositories which do not create libraries are very rare), and +one of the plugins of the dependent repositories must be in charge of reading +the version of these repositories together with their own. So for example +`sbnobj` will generate a `sbnobj_Metadata` library, and _art_ tool +`sbnobjRepositoryVersion` in `sbncode` will link to both `sbncode::Metadata` +for the version of `sbncode`, and to `sbnobj::Metadata` for the version of +non-art-aware repository it depends on, `sbnobj`. Since the dependencies of +each repository are known and quite stable, the tool can hard-code them. +In addition, if a dependency is _art_-aware, the tool can take care of the +dependency subtree for that dependency recursively, by call the tool of that +dependency (duplicate metadata entries will be expected to be the same anyway). + + +### Results-level products + +Results-level products were introduced in _art_ as a mean to have data products +spanning multiple runs. While some interface is similar to the other principals +(`art::Event`, `art::Run`), their usage and accessibility is deeply different. + +The key point is this: **only output modules can access Results-level data +products** (not only `RootOutput` specifically). +This comes with a list of obvious and explicit clumsiness: there is no such a +thing like an _art_ module writing a Results-level data product. In fact, no +such a thing like an _art_ module _reading_ that data product either. +The `DumpJobEnvironment` facility offered here is in fact an _output module_: +producer and analysis modules can't learn the versions that the version +data products in the input files hold. They can however use the same algorithm +as `SaveJobEnvironment` uses (that is another output plugin) to extract the +versions it then saved in the Results-type data product: the information +extraction algorithm is factorized as `sbn::JobEnvironmentInfoExtractor` and its +return type is a class `sbn::JobEnvironmentInfo` (`sbnobj`) well suited to be +a _art_ data product. + + + +How to arrange a repository with the tool +------------------------------------------ + +The tools will depend on the repository version libraries of the current package +and its dependencies, and on _art_. It is recommended to place their source code +in the same directory as the repository version library. +Step by step: + + 1. Utilize the `/Metadata` directory where the version library + source code should already be. In that case, the name of that library for + linking will be `::Metadata`. + 2. Create the tool source `RepositoryVersion_tool.cc` by + copying the source code from + `sbncode/Metadata/sbncodeRepositoryVersion_tool.cc` or + `icaruscode/Metadata/icaruscodeRepositoryVersion_tool.cc`. + 3. Add to the `CMakeLists.txt` file instructions to build the tool: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} + cet_build_plugin(RepositoryVersion art::tool + LIBRARIES + ::Metadata + sbncode::Metadata + sbnobj::Common_Metadata + ) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Additional libraries may be needed for the dependencies. + 4. Customize the tool source. + * If this repository _has_ dependent non-art repositories, add them to the + tool (the one in `icaruscode`, `icaruscodeRepositoryVersion`, already + shows how, with `icarusalg`): link to the dependent version libraries, + and add metadata entries for them. + * If this repository _is_ a dependency of another _art_-aware repository, + considering updating the tool in that repository to load this one and + store information from it. The tool in `icaruscode`, + `icaruscodeRepositoryVersion`, shows how (with `sbncode`). + 5. In the relevant configurations of the output plugin `SaveJobEnvironment`, + add the name of the repository the tool is covering (the `` + above). + + +How metadata can be accessed from the input files +================================================== + +The plugin `SaveJobEnvironment` can write the metadata into the _art_/ROOT file +and into the `TFileService` output file. + +The metadata in the _art_/ROOT file is stored as a Results-level data product, +and can therefore be read only by output modules. That does mean that producer +and analyzer _art_ modules will not be able to access that metadata. +However, an output module `DumpJobEnvironment` is provided that dumps the full +metadata on console output (configurable via `message` service). +The configuration of that module is as simple as: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +outputs.metadataDumper: { + module_type: "DumpJobEnvironment" +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +and, as usual, `metadataDumper` must be added in one of the end paths in the +`physics` configuration table. This type of configuration is provided in +`sbncode` as `dump_jobmetadata.fcl`. + +Metadata saved into a `TFileService` ROOT file will be in the main ROOT +directory of the file. See the documentation of `SaveJobEnvironment` plugin +for the details. + + + +Future improvements +==================== + +* Currently the metadata seen from all input so far is stored into the current + output file; it may happen then that an output file stores metadata from an + input file that was already closed when the output file started been filled. + That metadata has no reason to reside in that output file. +* There is going to be a large amount of duplication: all input files likely + have almost identical metadata, but we save each individually. A system to + collect the shared metadata in a single list may be desirable to reduce the + metadata size. +* If there is demand, the system can be extended to create also a FHiCL + configuration with the version of the repository. + + + */ diff --git a/sbncode/Metadata/SaveJobEnvironment_plugin.cc b/sbncode/Metadata/SaveJobEnvironment_plugin.cc new file mode 100644 index 000000000..70364dc4d --- /dev/null +++ b/sbncode/Metadata/SaveJobEnvironment_plugin.cc @@ -0,0 +1,331 @@ +/** + * @file sbncode/Metadata/SaveJobEnvironment_plugin.cc + * @brief Producer module writing job environment information into output. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 16, 2025 + */ + +// SBN libraries +#include "sbncode/Metadata/JobEnvironmentInfoExtractor.h" +#include "sbnobj/Common/Metadata/JobEnvironmentInfo.h" + +// framework libraries +#include "art_root_io/TFileService.h" +#include "art_root_io/TFileDirectory.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Core/ResultsProducer.h" +#include "art/Framework/Principal/Results.h" +#include "art/Framework/Principal/Handle.h" +#include "canvas/Utilities/Exception.h" +#include "messagefacility/MessageLogger/MessageLogger.h" +#include "fhiclcpp/types/Sequence.h" +#include "fhiclcpp/types/OptionalAtom.h" + +// ROOT libraries +#include "TFile.h" +#include "TDirectory.h" + +// C/C++ libraries +#include // std::back_inserter() +#include // std::make_unique() +#include +#include // std::move() +#include + + + +// ----------------------------------------------------------------------------- +namespace sbn { class SaveJobEnvironment; } +/** + * @brief Writes information from the job execution environment into output. + * + * This result-level module writes into the `art::Results` an object with + * information about the environment where the job is being executed. + * + * Information is extracted by the `sbn::JobEnvironmentInfoExtractor` algorithm. + * + * To add a new repository to the source of metadata collected by this plugin, + * see the instructions and explanations in + * @ref SBNsourceMetadataSystem "the SBN metadata system documentation". + * + * + * Output + * ------- + * + * In _art_/ROOT output file, `art::Results` level: + * * `std::vector` objects including all the ones + * found in the input files, and in addition, for this job: + * * a snapshot of the full environment (like in `getEnv()` C function), + * lexicographically sorted as for the object requirement. + * + * The information from this job is also saved in the `TFileService` output + * file, if that service is configured. Input information is currently not + * written into the `TFileService` output. Also note that the information is + * saved in the main directory of the file, as opposed to the usual subdirectory + * named after the module. The name of the object is `EnvInfo`, and, if + * `sbn::JobEnvironmentInfo` dictionary library is available to ROOT, one simple + * way to see it is to open the ROOT file with the ROOT interpreter and execute + * `EvtInfo->dump(std::cout);`. + * + * + * Module configuration + * --------------------- + * + * * `Repositories` (list of strings; default: see `DefaultRepositories`): + * the list of repositories whose version reporting tool will be queried. + * Directly passed as `JobEnvironmentInfoExtractor::Config::repositories` + * (see) to the exctraction algorithm. + * * `WriteToTFileService` (flag, optional): if set to `false`, the information + * will not be written into the `TFileService` output file; if it is set to + * `true`, it will be written into the output of file the service, which is + * required to be configured; if the parameter is omitted, the information + * will be written only if the service is available. + * + * + * Service dependencies + * --------------------- + * + * * `TFileService` (required only if `WriteToTFileService` is set to `true`) + * for output into the `TFile` managed by that service. + * + */ +class sbn::SaveJobEnvironment: public art::ResultsProducer { + + public: + + /// List of repository tools to be loaded by default. + static std::vector const DefaultRepositories; + + struct Config { + + using Name = fhicl::Name; + using Comment = fhicl::Comment; + + fhicl::Sequence Repositories{ + Name{ "Repositories" }, + Comment{ "Names of the repositories with version reporting tools" }, + DefaultRepositories + }; + + fhicl::OptionalAtom WriteToTFileService{ + Name{ "WriteToTFileService" }, + Comment + { "enables or disables writing to TFileService (default: if available)" } + }; + + }; // Config + + using Parameters = Table; + + + /// Constructor. + SaveJobEnvironment(Parameters const& params); + + /// Fetches the information. + virtual void beginJob() override; + + /// Reads the information on each new input file. + virtual void readResults(art::Results const& results) override; + + /// Writes the information at output closure time. + virtual void writeResults(art::Results& results) override; + + /// Clears after writing: does nothing. + virtual void clear() override; + + /// Write information to `TFileService` file if available. + virtual void endJob() override; + + + private: + + // --- BEGIN --- Configuration ----------------------------------------------- + + /// Names of the repositories to query for version metadata. + std::vector const fRepositoryNames; + + bool const fWriteToTFileService; ///< Whether to write info to `TFileService`. + + // --- END ----- Configuration ----------------------------------------------- + + + sbn::JobEnvironmentInfoExtractor fInfoExtractor; ///< Extraction algorithm. + + ///< All information from the input to be written, in the order it was read. + std::vector fInputInfo; + + /// Information from this job to be written. + sbn::JobEnvironmentInfo fJobInfo; + + + /// Fetches and returns all the information. + sbn::JobEnvironmentInfo fetchInformation(); + + + /// Writes the current information into `outDir`. + void writeInformationToTFile(TDirectory& outDir) const; + + /// Returns a correctly configured information extractor algorithm. + sbn::JobEnvironmentInfoExtractor makeInfoExtractor() const; + + + /// Returns whether we should write to `TFileService`. + static bool parseWriteToTFileService + (std::optional writeToTFileService); + + +}; // sbn::SaveJobEnvironment + + +// ----------------------------------------------------------------------------- +// --- Implementation +// ----------------------------------------------------------------------------- +std::vector const sbn::SaveJobEnvironment::DefaultRepositories { + "sbncode", "sbndcode", "icaruscode" +}; + + +// ----------------------------------------------------------------------------- +sbn::SaveJobEnvironment::SaveJobEnvironment(Parameters const& params) + : fRepositoryNames{ params().Repositories() } + , fWriteToTFileService + { parseWriteToTFileService(params().WriteToTFileService()) } + , fInfoExtractor{ makeInfoExtractor() } +{ + + produces>(); + + if (fWriteToTFileService) { + mf::LogInfo{ "SaveJobEnvironment" } + << "Will also save information into TFileService output file."; + } + +} // sbn::SaveJobEnvironment::SaveJobEnvironment() + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::beginJob() { + + fJobInfo = fetchInformation(); + +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::readResults(art::Results const& results) { + + std::vector const infoHandles + = results.getMany>(); + + mf::LogDebug{ "SaveJobEnvironment" } + << "Found " << infoHandles.size() << " job information products in input."; + + for (art::Handle> const& infoHandle + : infoHandles) + { + if (!infoHandle.isValid()) continue; + std::copy + (infoHandle->begin(), infoHandle->end(), back_inserter(fInputInfo)); + } // for + +} // sbn::SaveJobEnvironment::readResults() + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::writeResults(art::Results& results) { + + mf::LogDebug{ "SaveJobEnvironment" } + << "Information saved into art/ROOT output file:\n\n" << fJobInfo; + + auto allInfo + = std::make_unique>(fInputInfo); + allInfo->push_back(fJobInfo); + + // one copy each call + results.put(std::move(allInfo)); + +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::clear() { +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::endJob() { + + if (fWriteToTFileService) { + + writeInformationToTFile(art::ServiceHandle()->file()); + + } + +} // sbn::SaveJobEnvironment::endJob() + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfo sbn::SaveJobEnvironment::fetchInformation() { + + return fInfoExtractor.extract(moduleDescription()); + +} + + +// ----------------------------------------------------------------------------- +void sbn::SaveJobEnvironment::writeInformationToTFile(TDirectory& outDir) const +{ + + // assuming copy constructor will be used + outDir.WriteObject(&fJobInfo, "EnvInfo"); + +} // sbn::SaveJobEnvironment::writeInformationToTFile() + + +// ----------------------------------------------------------------------------- +bool sbn::SaveJobEnvironment::parseWriteToTFileService + (std::optional writeToTFileService) +{ + // if is requested that we don't write it to TFileService, stop it here: + if (!writeToTFileService.value_or(true)) return false; + + // so either there is no explicit request, or that request is to use it: + // at this point, we do need to know if TFileService is available + // and if it's there, we'll want to write into it + try { + art::ServiceHandle(); + return true; + } + catch(art::Exception& e) { + if (e.categoryCode() != art::errors::ServiceNotFound) + throw; // something else entirely is happening: propagate the exception + + // not available: do we need it? + if (!writeToTFileService) return false; // no explicit request, so no + + // there is a request (and if we are here it was positive): complain! + throw art::Exception{ art::errors::Configuration, "", e } + << "SaveJobEnvironment explicitly requested saving into TFileService" + " output, but TFileService is not configured.\n"; + + } + +} // sbn::SaveJobEnvironment::parseWriteToTFileService() + + +// ----------------------------------------------------------------------------- +sbn::JobEnvironmentInfoExtractor +sbn::SaveJobEnvironment::makeInfoExtractor() const { + + JobEnvironmentInfoExtractor::Config config; + config.repositories = fRepositoryNames; + return JobEnvironmentInfoExtractor{ config }; + +} // sbn::SaveJobEnvironment::makeInfoExtractor() + + +// ----------------------------------------------------------------------------- +DEFINE_ART_RESULTS_PLUGIN(sbn::SaveJobEnvironment) + + +// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/sbncodeRepositoryVersion_tool.cc b/sbncode/Metadata/sbncodeRepositoryVersion_tool.cc new file mode 100644 index 000000000..8941ac4e2 --- /dev/null +++ b/sbncode/Metadata/sbncodeRepositoryVersion_tool.cc @@ -0,0 +1,62 @@ +/** + * @file RepositoryVersion_sbncode_tool.cc + * @brief _art_ tool reporting the version of `sbncode`-related packages. + * @author Gianluca Petrillo (petrillo@slac.stanford.edu) + * @date January 18, 2025 + * + */ + +// SBN libraries +#include "sbncode/Metadata/RepositoryVersionReporter.h" +#include "sbncode/Metadata/RepositoryVersion_sbncode.h" +#include "sbnobj/Metadata/RepositoryVersion_sbnobj.h" + +// framework libraries +#include "art/Utilities/ToolMacros.h" +#include "art/Utilities/ToolConfigTable.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +// C++ standard libraries +#include +#include + + +// ----------------------------------------------------------------------------- +namespace sbn { struct sbncodeRepositoryVersion; } +/** + * @brief Implements the `sbn::RepositoryVersionReporter` interface for + * `sbncode`. + * + * It collects information from the following repositories: `sbncode` and + * `sbnobj`. + * + */ +struct sbn::sbncodeRepositoryVersion: public sbn::RepositoryVersionReporter { + + struct Config {}; + + using Parameters = art::ToolConfigTable; + + sbncodeRepositoryVersion(Parameters const&); + +}; // sbn::sbncodeRepositoryVersion() + + +// ----------------------------------------------------------------------------- +// --- implementation +// ----------------------------------------------------------------------------- +sbn::sbncodeRepositoryVersion::sbncodeRepositoryVersion(Parameters const&) { + + packageVersions.items.emplace_back("sbnobj", ::RepositoryVersion_sbnobj); + packageVersions.items.emplace_back("sbncode", ::RepositoryVersion_sbncode); + + packageVersions.finish(); + +} + + +// ----------------------------------------------------------------------------- +DEFINE_ART_CLASS_TOOL(sbn::sbncodeRepositoryVersion) + + +// ----------------------------------------------------------------------------- From 65d02c440ac2f79cf336bd8c56573dcb3f0a81fa Mon Sep 17 00:00:00 2001 From: Gianluca Petrillo Date: Tue, 21 Jan 2025 20:39:22 -0600 Subject: [PATCH 366/367] Removed unused class. These were written when I thought that libraries would register the repository versions as soon as loaded. Eventually I moved to dynamic loading plugin objects when the information is needed. --- sbncode/Metadata/GlobalMetadataRegistry.cxx | 69 ---------------- sbncode/Metadata/GlobalMetadataRegistry.h | 88 --------------------- 2 files changed, 157 deletions(-) delete mode 100644 sbncode/Metadata/GlobalMetadataRegistry.cxx delete mode 100644 sbncode/Metadata/GlobalMetadataRegistry.h diff --git a/sbncode/Metadata/GlobalMetadataRegistry.cxx b/sbncode/Metadata/GlobalMetadataRegistry.cxx deleted file mode 100644 index 139e0e941..000000000 --- a/sbncode/Metadata/GlobalMetadataRegistry.cxx +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file sbncode/Metadata/GlobalMetadataRegistry.cxx - * @brief Centralized metadata tracker (implementation file). - * @author Gianluca Petrillo (petrillo@slac.stanford.edu) - * @date January 18, 2025 - * @file sbncode/Metadata/GlobalMetadataRegistry.h - */ - -// library header -#include "sbncode/Metadata/GlobalMetadataRegistry.h" - -// ----------------------------------------------------------------------------- -// global instance: -sbn::GlobalMetadataRegistry sbn::GlobalMetadataRegistry::GlobalRegistry; - - -// ----------------------------------------------------------------------------- -std::lock_guard sbn::GlobalMetadataRegistry::readAccess() const { - return std::lock_guard{ fAccessMutex }; -} - - -// ----------------------------------------------------------------------------- -std::lock_guard sbn::GlobalMetadataRegistry::writeAccess() const { - return std::lock_guard{ fAccessMutex }; -} - - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::registerMetadata - (Name_t name, Value_t value) -> GlobalMetadataRegistry& -{ - - auto const accessGrant = writeAccess(); - - fRegistry.insert(std::move(name), std::move(value)); - - return *this; - -} // sbn::GlobalMetadataRegistry::registerMetadata() - - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::getPtr(Name_t const& name) const - -> Value_t const* -{ - auto const accessGrant = readAccess(); - return registry().getPtr(name); -} - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::get(Name_t const& name) const - -> std::optional -{ - auto const accessGrant = readAccess(); - return registry().get(name); -} - - -// ----------------------------------------------------------------------------- -auto sbn::GlobalMetadataRegistry::get - (Name_t const& name, Value_t const& defValue) const -> Value_t -{ - auto const accessGrant = readAccess(); - return registry().get(name, defValue); -} - - -// ----------------------------------------------------------------------------- diff --git a/sbncode/Metadata/GlobalMetadataRegistry.h b/sbncode/Metadata/GlobalMetadataRegistry.h deleted file mode 100644 index a0484a9f0..000000000 --- a/sbncode/Metadata/GlobalMetadataRegistry.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file sbncode/Metadata/GlobalMetadataRegistry.h - * @brief Centralized metadata tracker. - * @author Gianluca Petrillo (petrillo@slac.stanford.edu) - * @date January 18, 2025 - */ - - -#ifndef SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H -#define SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H - - -// SBN libraries -#include "sbnobj/Common/Metadata/OrderedPairList.h" - -// C++ standard libraries -#include - - -// ----------------------------------------------------------------------------- -namespace sbn { class GlobalMetadataRegistry; } -/** - * @brief A simple class with singleton access storing data in concurrent way. - * - * The registry is a simple key-value (string-string) sorted list (implemented - * from `OrderedPairList`). - * - * It provides a singleton instance (`instance()`) and it is designed to be - * thread-safe (by blunt mutex'ing). - * - */ -class sbn::GlobalMetadataRegistry { - - static GlobalMetadataRegistry GlobalRegistry; ///< Singleton instance. - - mutable std::mutex fAccessMutex; - - sbn::OrderedPairList fRegistry; - - - /// Grant read access. - [[nodiscard]] std::lock_guard readAccess() const; - - /// Grants (exclusive) write access. - [[nodiscard]] std::lock_guard writeAccess() const; - - - public: - - // These types need to match the ones in sbn::OrderedPairList - using Name_t = std::string; ///< Type of metadata name. - using Value_t = std::string; ///< Type of metadata value. - - - /// Adds a key-value pair to the registry - /// @return this object - GlobalMetadataRegistry& registerMetadata(Name_t name, Value_t value); - - - // --- BEGIN --- Queries --------------------------------------------------- - /// @name Queries - /// @{ - - /// Returns the complete registry of metadata. **This is not thread-safe!** - sbn::OrderedPairList const& registry() const - { return fRegistry; } - - /// Returns a pointer to the value of the requested metadata `name`, - /// or `nullptr` if none. - Value_t const* getPtr(Name_t const& name) const; - - /// Returns the value of requested metadata `name`, `std::nullopt` if none. - std::optional get(Name_t const& name) const; - - /// Returns the value of the requested metadata `name`, or `defValue` if none. - Value_t get(Name_t const& name, Value_t const& defValue) const; - - /// @} - // --- END ----- Queries --------------------------------------------------- - - - /// Returns the global instance of this class (read/write). - static GlobalMetadataRegistry& instance() { return GlobalRegistry; } - -}; // GlobalMetadataRegistry - - -#endif // SBNCODE_METADATA_GLOBALMETADATAREGISTRY_H From e080aedee68b367fabb997c5a79b3f2df4d52c5f Mon Sep 17 00:00:00 2001 From: Gianluca Petrillo Date: Tue, 20 Oct 2026 00:46:31 -0500 Subject: [PATCH 367/367] Changes related to SBN source metadata serialisation system ... which I don't remember the reason about. Plus some documentation fixes. --- sbncode/Metadata/CMakeLists.txt | 11 +++++------ sbncode/Metadata/SBNsourceMetadataSystem.dox | 16 ++++++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/sbncode/Metadata/CMakeLists.txt b/sbncode/Metadata/CMakeLists.txt index 67cc0d27a..0d5111601 100644 --- a/sbncode/Metadata/CMakeLists.txt +++ b/sbncode/Metadata/CMakeLists.txt @@ -5,9 +5,13 @@ GenerateRepoVersionSource(${CMAKE_PROJECT_NAME}) message(DEBUG "Generated source file '${${CMAKE_PROJECT_NAME}_GIT_REPO_VERSION_SOURCE}.h'") art_make_library( + SOURCE + RepositoryVersion_sbncode.cxx # generated by GenerateRepoVersionSource() above + JobEnvironmentInfoExtractor.cxx + RepositoryVersionReportUtils.cpp LIBRARIES sbnobj::Common_Metadata - larcorealg::headers + larcorealg::CoreUtils art::Persistency_Provenance art::Utilities canvas::canvas @@ -46,11 +50,6 @@ cet_build_plugin(SaveJobEnvironment art::ResultsProducer art::Framework_Services_Registry ) -# cet_build_plugin(DumpJobEnvironment art::ResultsProducer -# LIBRARIES -# sbnobj::Common_Metadata -# ) - cet_build_plugin(DumpJobEnvironment art::Output LIBRARIES sbnobj::Common_Metadata diff --git a/sbncode/Metadata/SBNsourceMetadataSystem.dox b/sbncode/Metadata/SBNsourceMetadataSystem.dox index fa843ba25..eb56ef233 100644 --- a/sbncode/Metadata/SBNsourceMetadataSystem.dox +++ b/sbncode/Metadata/SBNsourceMetadataSystem.dox @@ -8,7 +8,7 @@ into the _art_/ROOT and `TFileService` files, and the output module console. The system to achieve that result is quite convoluted, and this documentation -will describe that in detail. +describes it in detail. Which information is extracted @@ -63,7 +63,7 @@ where the file can be found, which is not trivial given the relocation of distributed code. The reason why FHiCL configuration was not preferred is that only _art_/ROOT files automatically include that information. In addition, each job -configuration needs to know _exactly_ which repositories are being included, +configuration would need to know _exactly_ which repositories are being included, since FHiCL parser does not tolerate missing information. The first limitation can be worked around, for example with the experimental `icaruscode` module `SaveConfigurationIntoTFile`, which was never fully completed or tested. @@ -76,9 +76,9 @@ number of repository libraries, and if one is missing, the resulting error The limitation of this option will be discussed later in this section. The difficulty of this system is that it needs to connect very heterogeneous -information sources, which never available all at the same time. -The source repository is available only in the build stage, while the execution -environment is present only... well, during the job execution. +information sources, which are never all available at the same time. +The source repository is available only at build stage, while the execution +environment is present only... well, during job execution. The strategy is then to create one shared library for each repository, with a standard name (`RepositoryVersion_\`), with the repository version information, and to have some modular software that can read these @@ -106,7 +106,7 @@ of all the repositories that we need to version, but there is not such a root: `sbnanaobj` (CAF data objects) depends only on ROOT (so, ironically, the root dependency in our source tree _is_ in fact ROOT, but unfortunately it does not make sense to add this infrastructure in there). The practical workaround to -this riddle is to duplicate the macro file, which obvious maintenance +this riddle is to duplicate the macro file, with obvious maintenance consequences. @note An **important limitation** of this system is that the information is @@ -115,7 +115,7 @@ consequences. moment of writing, the details are not yet clear. To make sure that the GIT versions are correct, the only safe way is to zap the area (`mrb z`) and build everything from scratch. This is always - a good idea anyway after one thinks the code is ready for prime time. + a good idea anyway once the code is ready for prime time. Again, remember: after code is committed to GIT, an integral rebuild is likely needed for the code version metadata to reflect the new repository status. @@ -148,7 +148,7 @@ How to arrange a repository with a version library ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} find_package( sbnobj REQUIRED ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - in the `find_package` section not present already, and + if the `find_package` section not present already, and ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cmake} include(SBNutils) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~