/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FastSimulation/MaterialEffects/src/NuclearInteractionSimulator.cc
639 строк
27 KB
Kevin Pedro
code checks and format
06 дек 2025, 01:59
06 дек 2025, 01:59
6cee54b
Код
Авторство
О чём код?
//Framework Headers #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/ParameterSet/interface/FileInPath.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FastSimulation/MaterialEffects/interface/NuclearInteractionSimulator.h" #include "FastSimulation/Particle/interface/makeParticle.h" #include "FastSimulation/Utilities/interface/RandomEngineAndDistribution.h" #include "FastSimDataFormats/NuclearInteractions/interface/NUEvent.h" //#include "DQMServices/Core/interface/DaqMonitorBEInterface.h" //#include "FWCore/ServiceRegistry/interface/Service.h" #include <iostream> #include <sys/stat.h> #include <cmath> #include "TFile.h" #include "TTree.h" #include "TROOT.h" // Internal variable and vectors with name started frm "thePion" means // vectors/variable not only for pions but for all type of hadrons // treated inside this code NuclearInteractionSimulator::NuclearInteractionSimulator(std::vector<double>& hadronEnergies, std::vector<int>& hadronTypes, std::vector<std::string>& hadronNames, std::vector<double>& hadronMasses, std::vector<double>& hadronPMin, double pionEnergy, std::vector<double>& lengthRatio, std::vector<std::vector<double> >& ratios, std::map<int, int>& idMap, std::string inputFile, unsigned int distAlgo, double distCut, bool saveOutput) : MaterialEffectsSimulator(), thePionEN(hadronEnergies), thePionID(hadronTypes), thePionNA(hadronNames), thePionMA(hadronMasses), thePionPMin(hadronPMin), thePionEnergy(pionEnergy), theLengthRatio(lengthRatio), theRatios(ratios), theIDMap(idMap), theDistAlgo(distAlgo), theDistCut(distCut), mySaveOutput(saveOutput), currentValuesWereSet(false) { std::string fullPath; // Prepare the map of files // Loop over the particle names TFile* aVFile = nullptr; std::vector<TTree*> aVTree(thePionEN.size(), static_cast<TTree*>(nullptr)); std::vector<TBranch*> aVBranch(thePionEN.size(), static_cast<TBranch*>(nullptr)); std::vector<NUEvent*> aVNUEvents(thePionEN.size(), static_cast<NUEvent*>(nullptr)); std::vector<unsigned> aVCurrentEntry(thePionEN.size(), static_cast<unsigned>(0)); std::vector<unsigned> aVCurrentInteraction(thePionEN.size(), static_cast<unsigned>(0)); std::vector<unsigned> aVNumberOfEntries(thePionEN.size(), static_cast<unsigned>(0)); std::vector<unsigned> aVNumberOfInteractions(thePionEN.size(), static_cast<unsigned>(0)); std::vector<std::string> aVFileName(thePionEN.size(), static_cast<std::string>("")); std::vector<double> aVPionCM(thePionEN.size(), static_cast<double>(0)); theTrees.resize(thePionNA.size()); theBranches.resize(thePionNA.size()); theNUEvents.resize(thePionNA.size()); theCurrentEntry.resize(thePionNA.size()); theCurrentInteraction.resize(thePionNA.size()); theNumberOfEntries.resize(thePionNA.size()); theNumberOfInteractions.resize(thePionNA.size()); theFileNames.resize(thePionNA.size()); thePionCM.resize(thePionNA.size()); theFile = aVFile; for (unsigned iname = 0; iname < thePionNA.size(); ++iname) { theTrees[iname] = aVTree; theBranches[iname] = aVBranch; theNUEvents[iname] = aVNUEvents; theCurrentEntry[iname] = aVCurrentEntry; theCurrentInteraction[iname] = aVCurrentInteraction; theNumberOfEntries[iname] = aVNumberOfEntries; theNumberOfInteractions[iname] = aVNumberOfInteractions; theFileNames[iname] = aVFileName; thePionCM[iname] = aVPionCM; } // Read the information from a previous run (to keep reproducibility) currentValuesWereSet = this->read(inputFile); if (currentValuesWereSet) edm::LogWarning("FastSimulation/MaterialEffects") << "You are reading nuclear-interaction information from the file " << inputFile << " created in an earlier run." << std::endl; // Open the file for saving the information of the current run if (mySaveOutput) { myOutputFile.open("NuclearInteractionOutputFile.txt"); myOutputBuffer = 0; } // Open the root files // for ( unsigned file=0; file<theFileNames.size(); ++file ) { edm::FileInPath myDataFile("FastSimulation/MaterialEffects/data/NuclearInteractions.root"); fullPath = myDataFile.fullPath(); theFile = TFile::Open(fullPath.c_str()); for (unsigned iname = 0; iname < thePionNA.size(); ++iname) { for (unsigned iene = 0; iene < thePionEN.size(); ++iene) { //std::cout << "iname/iene " << iname << " " << iene << std::endl; std::ostringstream filename; double theEne = thePionEN[iene]; filename << "NuclearInteractionsVal_" << thePionNA[iname] << "_E" << theEne << ".root"; theFileNames[iname][iene] = filename.str(); //std::cout << "thePid/theEne " << thePionID[iname] << " " << theEne << std::endl; std::string treeName = "NuclearInteractions_" + thePionNA[iname] + "_E" + std::to_string(int(theEne)); // theTrees[iname][iene] = (TTree*)theFile->Get(treeName.c_str()); if (!theTrees[iname][iene]) throw cms::Exception("FastSimulation/MaterialEffects") << "Tree with name " << treeName << " not found "; // theBranches[iname][iene] = theTrees[iname][iene]->GetBranch("nuEvent"); //std::cout << "The branch = " << theBranches[iname][iene] << std::endl; if (!theBranches[iname][iene]) throw cms::Exception("FastSimulation/MaterialEffects") << "Branch with name nuEvent not found in " << theFileNames[iname][iene]; // theNUEvents[iname][iene] = new NUEvent(); //std::cout << "The branch = " << theBranches[iname][iene] << std::endl; theBranches[iname][iene]->SetAddress(&theNUEvents[iname][iene]); // theNumberOfEntries[iname][iene] = theTrees[iname][iene]->GetEntries(); if (currentValuesWereSet) { theTrees[iname][iene]->GetEntry(theCurrentEntry[iname][iene]); unsigned NInteractions = theNUEvents[iname][iene]->nInteractions(); theNumberOfInteractions[iname][iene] = NInteractions; } // // Compute the corresponding cm energies of the nuclear interactions XYZTLorentzVector Proton(0., 0., 0., 0.986); XYZTLorentzVector Reference( 0., 0., std::sqrt(thePionEN[iene] * thePionEN[iene] - thePionMA[iname] * thePionMA[iname]), thePionEN[iene]); thePionCM[iname][iene] = (Reference + Proton).M(); } } // Find the index for which EN = 4. (or thereabout) ien4 = 0; while (thePionEN[ien4] < 4.0) ++ien4; gROOT->cd(); // dbe = edm::Service<DaqMonitorBEInterface>().operator->(); // htot = dbe->book1D("Total", "All particles",150,0.,150.); // helas = dbe->book1D("Elastic", "Elastic interactions",150,0.,150.); // hinel = dbe->book1D("Inelastic", "Inelastic interactions",150,0.,150.); // hscatter = dbe->book1D("Scattering","Elastic Scattering angle",200,0.,2.); // hscatter2 = dbe->book2D("Scattering2","Elastic Scattering angle vs p",100,0.,10.,200,0.,2.); // hAfter = dbe->book1D("eAfter","Energy after collision",200,0.,4.); // hAfter2 = dbe->book2D("eAfter2","Energy after collision",100,-2.5,2.5,100,0.,4); // hAfter3 = dbe->book2D("eAfter3","Energy after collision",100,0.,1000.,100,0.,4); } NuclearInteractionSimulator::~NuclearInteractionSimulator() { // Close all local files // Among other things, this allows the TROOT destructor to end up // without crashing, while trying to close these files from outside theFile->Close(); delete theFile; for (auto& vEvents : theNUEvents) { for (auto evtPtr : vEvents) { delete evtPtr; } } // Close the output file if (mySaveOutput) myOutputFile.close(); } void NuclearInteractionSimulator::compute(ParticlePropagator& Particle, RandomEngineAndDistribution const* random) { if (!currentValuesWereSet) { currentValuesWereSet = true; for (unsigned iname = 0; iname < thePionNA.size(); ++iname) { for (unsigned iene = 0; iene < thePionEN.size(); ++iene) { theCurrentEntry[iname][iene] = (unsigned)(theNumberOfEntries[iname][iene] * random->flatShoot()); theTrees[iname][iene]->GetEntry(theCurrentEntry[iname][iene]); unsigned NInteractions = theNUEvents[iname][iene]->nInteractions(); theNumberOfInteractions[iname][iene] = NInteractions; theCurrentInteraction[iname][iene] = (unsigned)(theNumberOfInteractions[iname][iene] * random->flatShoot()); } } } // Read a Nuclear Interaction in a random manner double pHadron = std::sqrt(Particle.particle().Vect().Mag2()); // htot->Fill(pHadron); // The hadron has enough momentum to create some relevant final state if (pHadron > thePionEnergy) { // The particle type std::map<int, int>::const_iterator thePit = theIDMap.find(Particle.particle().pid()); int thePid = thePit != theIDMap.end() ? thePit->second : Particle.particle().pid(); // Is this particle type foreseen? unsigned fPid = abs(thePid); if (fPid != 211 && fPid != 130 && fPid != 321 && fPid != 2112 && fPid != 2212) { return; //std::cout << "Unknown particle type = " << thePid << std::endl; //thePid = 211; } // The inelastic interaction length at p(pion) = 5 GeV/c unsigned thePidIndex = index(thePid); double theInelasticLength = radLengths * theLengthRatio[thePidIndex]; // The elastic interaction length // The baroque parameterization is a fit to Fig. 40.13 of the PDG double ee = pHadron > 0.6 ? exp(-std::sqrt((pHadron - 0.6) / 1.122)) : exp(std::sqrt((0.6 - pHadron) / 1.122)); double theElasticLength = (0.8753 * ee + 0.15) // double theElasticLength = ( 0.15 + 0.195 / log(pHadron/0.4) ) // double theElasticLength = ( 0.15 + 0.305 / log(pHadron/0.35) ) * theInelasticLength; // The total interaction length double theTotalInteractionLength = theInelasticLength + theElasticLength; // Probability to interact is dl/L0 (maximum for 4 GeV pion) double aNuclInteraction = -std::log(random->flatShoot()); if (aNuclInteraction < theTotalInteractionLength) { // The elastic part double elastic = random->flatShoot(); if (elastic < theElasticLength / theTotalInteractionLength) { // helas->Fill(pHadron); // Characteristic scattering angle for the elastic part double theta0 = std::sqrt(3.) / std::pow(theA(), 1. / 3.) * Particle.particle().mass() / pHadron; // Draw an angle with theta/theta0*exp[(-theta/2theta0)**2] shape double theta = theta0 * std::sqrt(-2. * std::log(random->flatShoot())); double phi = 2. * 3.14159265358979323 * random->flatShoot(); // Rotate the particle accordingly RawParticle::Rotation rotation1(orthogonal(Particle.particle().Vect()), theta); RawParticle::Rotation rotation2(Particle.particle().Vect(), phi); Particle.particle().rotate(rotation1); Particle.particle().rotate(rotation2); // Distance double distance = std::sin(theta); // Create a daughter if the kink is large engough if (distance > theDistCut) { _theUpdatedState.reserve(1); _theUpdatedState.clear(); _theUpdatedState.emplace_back(Particle.particle()); } // hscatter->Fill(myTheta); // hscatter2->Fill(pHadron,myTheta); } // The inelastic part else { // Avoid multiple map access const std::vector<double>& aPionCM = thePionCM[thePidIndex]; const std::vector<double>& aRatios = theRatios[thePidIndex]; // Find the file with the closest c.m energy // The target nucleon XYZTLorentzVector Proton(0., 0., 0., 0.939); // The current particle const XYZTLorentzVector& Hadron = (const XYZTLorentzVector&)Particle; // The smallest momentum for inelastic interactions double pMin = thePionPMin[thePidIndex]; // The correspong smallest four vector XYZTLorentzVector Hadron0(0., 0., pMin, std::sqrt(pMin * pMin + Particle.particle().M2())); // The current centre-of-mass energy double ecm = (Proton + Hadron).M(); //std::cout << "Proton = " << Proton << std::endl; //std::cout << "Hadron = " << Hadron << std::endl; //std::cout << "ecm = " << ecm << std::endl; // Get the files of interest (closest c.m. energies) unsigned ene1 = 0; unsigned ene2 = 0; // The smallest centre-of-mass energy // double ecm1=1.63; double ecm1 = (Proton + Hadron0).M(); //std::cout << "ecm1 = " << ecm1 << std::endl; //std::cout << "ecm[0] = " << aPionCM[0] << std::endl; //std::cout << "ecm[11] = " << aPionCM [ aPionCM.size()-1 ] << std::endl; double ecm2 = aPionCM[0]; double ratio1 = 0.; double ratio2 = aRatios[0]; if (ecm > aPionCM[0] && ecm < aPionCM[aPionCM.size() - 1]) { for (unsigned ene = 1; ene < aPionCM.size() && ecm > aPionCM[ene - 1]; ++ene) { if (ecm < aPionCM[ene]) { ene2 = ene; ene1 = ene2 - 1; ecm1 = aPionCM[ene1]; ecm2 = aPionCM[ene2]; ratio1 = aRatios[ene1]; ratio2 = aRatios[ene2]; } } } else if (ecm > aPionCM[aPionCM.size() - 1]) { ene1 = aPionCM.size() - 1; ene2 = aPionCM.size() - 2; ecm1 = aPionCM[ene1]; ecm2 = aPionCM[ene2]; ratio1 = aRatios[ene2]; ratio2 = aRatios[ene2]; } // The inelastic part of the cross section depends cm energy double slope = (std::log10(ecm) - std::log10(ecm1)) / (std::log10(ecm2) - std::log10(ecm1)); double inelastic = ratio1 + (ratio2 - ratio1) * slope; double inelastic4 = pHadron < 4. ? aRatios[ien4] : 1.; //std::cout << "Inelastic = " << ratio1 << " " << ratio2 << " " << inelastic << std::endl; // std::cout << "Energy/Inelastic : " // << Hadron.e() << " " << inelastic << std::endl; // Simulate an inelastic interaction if (elastic > 1. - (inelastic * theInelasticLength) / theTotalInteractionLength) { // Avoid mutliple map access std::vector<unsigned>& aCurrentInteraction = theCurrentInteraction[thePidIndex]; std::vector<unsigned>& aNumberOfInteractions = theNumberOfInteractions[thePidIndex]; std::vector<NUEvent*>& aNUEvents = theNUEvents[thePidIndex]; // hinel->Fill(pHadron); // std::cout << "INELASTIC INTERACTION ! " // << pHadron << " " << theInelasticLength << " " // << inelastic * theInelasticLength << std::endl; // Choice of the file to read according the the log10(ecm) distance // and protection against low momentum proton and neutron that never interacts // (i.e., empty files) unsigned ene; if (random->flatShoot() < slope || aNumberOfInteractions[ene1] == 0) ene = ene2; else ene = ene1; //std::cout << "Ecm1/2 = " << ecm1 << " " << ecm2 << std::endl; //std::cout << "Ratio1/2 = " << ratio1 << " " << ratio2 << std::endl; //std::cout << "Ene = " << ene << " slope = " << slope << std::endl; //std::cout << "Pion energy = " << Hadron.E() // << "File chosen " << theFileNames[thePidIndex][ene] // << std::endl; // The boost characteristics XYZTLorentzVector theBoost = Proton + Hadron; theBoost /= theBoost.e(); // std::cout << "File chosen : " << thePid << "/" << ene // << " Current interaction = " << aCurrentInteraction[ene] // << " Total interactions = " << aNumberOfInteractions[ene] // << std::endl; // theFiles[thePidIndex][ene]->cd(); // gDirectory->ls(); // Check we are not either at the end of an interaction bunch // or at the end of a file if (aCurrentInteraction[ene] == aNumberOfInteractions[ene]) { // std::cout << "End of interaction bunch ! "; std::vector<unsigned>& aCurrentEntry = theCurrentEntry[thePidIndex]; std::vector<unsigned>& aNumberOfEntries = theNumberOfEntries[thePidIndex]; std::vector<TTree*>& aTrees = theTrees[thePidIndex]; ++aCurrentEntry[ene]; // std::cerr << "Read the next entry " // << aCurrentEntry[ene] << std::endl; aCurrentInteraction[ene] = 0; if (aCurrentEntry[ene] == aNumberOfEntries[ene]) { aCurrentEntry[ene] = 0; // std::cout << "End of file - Rewind! " << std::endl; } unsigned myEntry = aCurrentEntry[ene]; // std::cout << "The new entry " << myEntry // << " is read ... in TTree " << aTrees[ene] << " "; aTrees[ene]->GetEntry(myEntry); // std::cout << "The number of interactions in the new entry is ... "; aNumberOfInteractions[ene] = aNUEvents[ene]->nInteractions(); // std::cout << aNumberOfInteractions[ene] << std::endl; } // Read the interaction NUEvent::NUInteraction anInteraction = aNUEvents[ene]->theNUInteractions()[aCurrentInteraction[ene]]; unsigned firstTrack = anInteraction.first; unsigned lastTrack = anInteraction.last; // std::cout << "First and last tracks are " << firstTrack << " " << lastTrack << std::endl; _theUpdatedState.reserve(lastTrack - firstTrack + 1); _theUpdatedState.clear(); double distMin = 1E99; // Some rotation around the boost axis, for more randomness XYZVector theAxis = theBoost.Vect().Unit(); double theAngle = random->flatShoot() * 2. * 3.14159265358979323; RawParticle::Rotation axisRotation(theAxis, theAngle); RawParticle::Boost axisBoost(theBoost.x(), theBoost.y(), theBoost.z()); // A rotation to bring the particles back to the pion direction XYZVector zAxis(0., 0., 1.); XYZVector orthAxis = (zAxis.Cross(theBoost.Vect())).Unit(); double orthAngle = acos(theBoost.Vect().Unit().Z()); RawParticle::Rotation orthRotation(orthAxis, orthAngle); // A few checks // double eAfter = 0.; // Loop on the nuclear interaction products for (unsigned iTrack = firstTrack; iTrack <= lastTrack; ++iTrack) { unsigned idaugh = iTrack - firstTrack; NUEvent::NUParticle aParticle = aNUEvents[ene]->theNUParticles()[iTrack]; // std::cout << "Track " << iTrack // << " id/px/py/pz/mass " // << aParticle.id << " " // << aParticle.px << " " // << aParticle.py << " " // << aParticle.pz << " " // << aParticle.mass << " " << endl; // Add a RawParticle with the proper energy in the c.m frame of // the nuclear interaction double energy = std::sqrt(aParticle.px * aParticle.px + aParticle.py * aParticle.py + aParticle.pz * aParticle.pz + aParticle.mass * aParticle.mass / (ecm * ecm)); RawParticle& aDaughter = _theUpdatedState.emplace_back(makeParticle( Particle.particleDataTable(), aParticle.id, XYZTLorentzVector(aParticle.px * ecm, aParticle.py * ecm, aParticle.pz * ecm, energy * ecm))); // Rotate to the collision axis aDaughter.rotate(orthRotation); // Rotate around the boost axis for more randomness aDaughter.rotate(axisRotation); // Boost it in the lab frame aDaughter.boost(axisBoost); // Store the closest daughter index (for later tracking purposes, so charged particles only) double distance = distanceToPrimary(Particle.particle(), aDaughter); // Find the closest daughter, if closer than a given upper limit. if (distance < distMin && distance < theDistCut) { distMin = distance; theClosestChargedDaughterId = idaugh; } // eAfter += aDaughter.E(); } /* double eBefore = Particle.E(); double rapid = Particle.momentum().Eta(); if ( eBefore > 0. ) { hAfter->Fill(eAfter/eBefore); hAfter2->Fill(rapid,eAfter/eBefore); hAfter3->Fill(eBefore,eAfter/eBefore); } */ // ERROR The way this loops through the events breaks // replay. Which events are retrieved depends on // which previous events were processed. // Increment for next time ++aCurrentInteraction[ene]; // Simulate a stopping hadron (low momentum) } else if (pHadron < 4. && elastic > 1. - (inelastic4 * theInelasticLength) / theTotalInteractionLength) { // A fake particle with 0 momentum as a daughter! _theUpdatedState.reserve(1); _theUpdatedState.clear(); _theUpdatedState.emplace_back( makeParticle(Particle.particleDataTable(), 22, XYZTLorentzVector(0., 0., 0., 0.))); } } } } } double NuclearInteractionSimulator::distanceToPrimary(const RawParticle& Particle, const RawParticle& aDaughter) const { double distance = 2E99; // Compute the distance only for charged primaries if (fabs(Particle.charge()) > 1E-12) { // The secondary must have the same charge double chargeDiff = fabs(aDaughter.charge() - Particle.charge()); if (fabs(chargeDiff) < 1E-12) { // Here are two distance definitions * to be tuned * switch (theDistAlgo) { case 1: // sin(theta12) distance = (aDaughter.Vect().Unit().Cross(Particle.Vect().Unit())).R(); break; case 2: // sin(theta12) * p1/p2 distance = (aDaughter.Vect().Cross(Particle.Vect())).R() / aDaughter.Vect().Mag2(); break; default: // Should not happen distance = 2E99; break; } } } return distance; } void NuclearInteractionSimulator::save() { if (!mySaveOutput) return; // Size of buffer ++myOutputBuffer; // Periodically close the current file and open a new one if (myOutputBuffer / 1000 * 1000 == myOutputBuffer) { myOutputFile.close(); myOutputFile.open("NuclearInteractionOutputFile.txt"); // myOutputFile.seekp(0); // No need to rewind in that case } // unsigned size1 = theCurrentEntry.size() * theCurrentEntry.begin()->size(); std::vector<unsigned> theCurrentEntries; theCurrentEntries.resize(size1); size1 *= sizeof(unsigned); // unsigned size2 = theCurrentInteraction.size() * theCurrentInteraction.begin()->size(); std::vector<unsigned> theCurrentInteractions; theCurrentInteractions.resize(size2); size2 *= sizeof(unsigned); // Save the current entries std::vector<std::vector<unsigned> >::const_iterator aCurrentEntry = theCurrentEntry.begin(); std::vector<std::vector<unsigned> >::const_iterator lastCurrentEntry = theCurrentEntry.end(); unsigned allEntries = 0; for (; aCurrentEntry != lastCurrentEntry; ++aCurrentEntry) { unsigned size = aCurrentEntry->size(); for (unsigned iene = 0; iene < size; ++iene) theCurrentEntries[allEntries++] = (*aCurrentEntry)[iene]; } // Save the current interactions std::vector<std::vector<unsigned> >::const_iterator aCurrentInteraction = theCurrentInteraction.begin(); std::vector<std::vector<unsigned> >::const_iterator lastCurrentInteraction = theCurrentInteraction.end(); unsigned allInteractions = 0; for (; aCurrentInteraction != lastCurrentInteraction; ++aCurrentInteraction) { unsigned size = aCurrentInteraction->size(); for (unsigned iene = 0; iene < size; ++iene) theCurrentInteractions[allInteractions++] = (*aCurrentInteraction)[iene]; } // myOutputFile.write((const char*)(&theCurrentEntries.front()), size1); myOutputFile.write((const char*)(&theCurrentInteractions.front()), size2); myOutputFile.flush(); } bool NuclearInteractionSimulator::read(std::string inputFile) { std::ifstream myInputFile; struct stat results; // unsigned size1 = theCurrentEntry.size() * theCurrentEntry.begin()->size(); std::vector<unsigned> theCurrentEntries; theCurrentEntries.resize(size1); size1 *= sizeof(unsigned); // unsigned size2 = theCurrentInteraction.size() * theCurrentInteraction.begin()->size(); std::vector<unsigned> theCurrentInteractions; theCurrentInteractions.resize(size2); size2 *= sizeof(unsigned); // unsigned size = 0; // Open the file (if any) myInputFile.open(inputFile.c_str()); if (myInputFile.is_open()) { // Get the size of the file if (stat(inputFile.c_str(), &results) == 0) size = results.st_size; else return false; // Something is wrong with that file ! // Position the pointer just before the last record myInputFile.seekg(size - size1 - size2); myInputFile.read((char*)(&theCurrentEntries.front()), size1); myInputFile.read((char*)(&theCurrentInteractions.front()), size2); myInputFile.close(); // Read the current entries std::vector<std::vector<unsigned> >::iterator aCurrentEntry = theCurrentEntry.begin(); std::vector<std::vector<unsigned> >::iterator lastCurrentEntry = theCurrentEntry.end(); unsigned allEntries = 0; for (; aCurrentEntry != lastCurrentEntry; ++aCurrentEntry) { unsigned size = aCurrentEntry->size(); for (unsigned iene = 0; iene < size; ++iene) (*aCurrentEntry)[iene] = theCurrentEntries[allEntries++]; } // Read the current interactions std::vector<std::vector<unsigned> >::iterator aCurrentInteraction = theCurrentInteraction.begin(); std::vector<std::vector<unsigned> >::iterator lastCurrentInteraction = theCurrentInteraction.end(); unsigned allInteractions = 0; for (; aCurrentInteraction != lastCurrentInteraction; ++aCurrentInteraction) { unsigned size = aCurrentInteraction->size(); for (unsigned iene = 0; iene < size; ++iene) (*aCurrentInteraction)[iene] = theCurrentInteractions[allInteractions++]; } return true; } return false; } unsigned NuclearInteractionSimulator::index(int thePid) { unsigned myIndex = 0; while (thePid != thePionID[myIndex]) ++myIndex; // std::cout << "pid/index = " << thePid << " " << myIndex << std::endl; return myIndex; }