Go to the documentation of this file.00001 #include "FWCore/Framework/interface/Event.h"
00002 #include "FWCore/Framework/interface/MakerMacros.h"
00003 #include "FWCore/ServiceRegistry/interface/Service.h"
00004 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00005
00006 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
00007
00008 #include "FastSimDataFormats/PileUpEvents/interface/PUEvent.h"
00009
00010 #include "FastSimulation/PileUpProducer/plugins/PileUpProducer.h"
00011 #include "FastSimulation/Event/interface/BetaFuncPrimaryVertexGenerator.h"
00012 #include "FastSimulation/Event/interface/GaussianPrimaryVertexGenerator.h"
00013 #include "FastSimulation/Event/interface/FlatPrimaryVertexGenerator.h"
00014 #include "FastSimulation/Event/interface/NoPrimaryVertexGenerator.h"
00015 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00016
00017 #include "HepMC/GenEvent.h"
00018 #include "TFile.h"
00019 #include "TTree.h"
00020 #include "TROOT.h"
00021
00022 #include <iostream>
00023 #include <memory>
00024 #include <sys/stat.h>
00025 #include <cmath>
00026
00027 PileUpProducer::PileUpProducer(edm::ParameterSet const & p) : hprob(0)
00028 {
00029
00030
00031 produces<PileupMixingContent>();
00032
00033 produces<edm::HepMCProduct>("PileUpEvents");
00034
00035
00036 edm::Service<edm::RandomNumberGenerator> rng;
00037 if ( ! rng.isAvailable() ) {
00038 throw cms::Exception("Configuration")
00039 << "PileUpProducer requires the RandomGeneratorService\n"
00040 "which is not present in the configuration file.\n"
00041 "You must add the service in the configuration file\n"
00042 "or remove the module that requires it";
00043 }
00044 random = new RandomEngine(&(*rng));
00045
00046
00047 const edm::ParameterSet& pu = p.getParameter<edm::ParameterSet>("PileUpSimulator");
00048 usePoisson_ = pu.getParameter<bool>("usePoisson");
00049 averageNumber_ = 0.;
00050 if (usePoisson_) {
00051 std::cout << " FastSimulation/PileUpProducer -> poissonian distribution" << std::endl;
00052 averageNumber_ = pu.getParameter<double>("averageNumber");
00053 } else {
00054 dataProbFunctionVar = pu.getParameter<std::vector<int> >("probFunctionVariable");
00055 dataProb = pu.getParameter<std::vector<double> >("probValue");
00056 varSize = (int) dataProbFunctionVar.size();
00057 probSize = (int) dataProb.size();
00058
00059
00060
00061 std::cout << " FastSimulation/PileUpProducer -> distribution from configuration file " << std::endl;
00062 if (probSize < varSize){
00063 for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
00064 edm::LogWarning("") << " The probability function data will be completed with "
00065 << (varSize - probSize) <<" values `0';"
00066 << " the number of the P(x) data set after adding those 0's is " << dataProb.size();
00067 probSize = dataProb.size();
00068 }
00069
00070 int xmin = (int) dataProbFunctionVar[0];
00071 int xmax = (int) dataProbFunctionVar[varSize-1]+1;
00072 int numBins = varSize;
00073 std::cout << " FastSimulation/PileUpProducer -> An histogram will be created with " << numBins
00074 << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
00075 hprob = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax);
00076 LogDebug("") << " FastSimulation/PileUpProducer -> Filling histogram with the following data:";
00077 for (int j=0; j < numBins ; j++){
00078 LogDebug("") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
00079 hprob->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]);
00080 }
00081
00082
00083 if (((hprob->Integral() - 1) > 1.0e-02) && ((hprob->Integral() - 1) < -1.0e-02)) throw cms::Exception("BadHistoDistribution") << "The histogram should be normalized!" << std::endl;
00084
00085
00086 averageNumber_ = hprob->GetMean();
00087 }
00088 theFileNames = pu.getUntrackedParameter<std::vector<std::string> >("fileNames");
00089 inputFile = pu.getUntrackedParameter<std::string>("inputFile");
00090 theNumberOfFiles = theFileNames.size();
00091 theFiles.resize(theNumberOfFiles);
00092 theTrees.resize(theNumberOfFiles);
00093 theBranches.resize(theNumberOfFiles);
00094 thePUEvents.resize(theNumberOfFiles);
00095 theCurrentEntry.resize(theNumberOfFiles);
00096 theCurrentMinBiasEvt.resize(theNumberOfFiles);
00097 theNumberOfEntries.resize(theNumberOfFiles);
00098 theNumberOfMinBiasEvts.resize(theNumberOfFiles);
00099
00100
00101 const edm::ParameterSet& vtx = p.getParameter<edm::ParameterSet>("VertexGenerator");
00102 std::string vtxType = vtx.getParameter<std::string>("type");
00103 if ( vtxType == "Gaussian" )
00104 theVertexGenerator = new GaussianPrimaryVertexGenerator(vtx,random);
00105 else if ( vtxType == "Flat" )
00106 theVertexGenerator = new FlatPrimaryVertexGenerator(vtx,random);
00107 else if ( vtxType == "BetaFunc" )
00108 theVertexGenerator = new BetaFuncPrimaryVertexGenerator(vtx,random);
00109 else
00110 theVertexGenerator = new NoPrimaryVertexGenerator();
00111
00112
00113
00114 if (averageNumber_ > 0.)
00115 {
00116 std::cout << " FastSimulation/PileUpProducer -> MinBias events taken from " << theFileNames[0] << " et al., " ;
00117 std::cout << " with an average number of events of " << averageNumber_ << std::endl;
00118 }
00119 else std::cout << " FastSimulation/PileUpProducer -> No pileup " << std::endl;
00120
00121
00122 }
00123
00124 PileUpProducer::~PileUpProducer() {
00125
00126 delete theVertexGenerator;
00127 if (hprob) delete hprob;
00128
00129 }
00130
00131 void PileUpProducer::beginRun(edm::Run & run, edm::EventSetup const& es)
00132 {
00133
00134 gROOT->cd();
00135
00136 std::string fullPath;
00137
00138
00139 bool input = this->read(inputFile);
00140 if ( input )
00141 std::cout << "***WARNING*** You are reading pile-up information from the file "
00142 << inputFile << " created in an earlier run."
00143 << std::endl;
00144
00145
00146 myOutputFile.open ("PileUpOutputFile.txt");
00147 myOutputBuffer = 0;
00148
00149
00150 for ( unsigned file=0; file<theNumberOfFiles; ++file ) {
00151
00152 if (theFileNames[file].find("file:")==0) {
00153 fullPath = theFileNames[file].erase(0,5);
00154 }
00155 else {
00156 edm::FileInPath myDataFile("FastSimulation/PileUpProducer/data/"+theFileNames[file]);
00157 fullPath = myDataFile.fullPath();
00158 }
00159
00160 theFiles[file] = TFile::Open(fullPath.c_str());
00161 if ( !theFiles[file] ) throw cms::Exception("FastSimulation/PileUpProducer")
00162 << "File " << theFileNames[file] << " " << fullPath << " not found ";
00163
00164 theTrees[file] = (TTree*) theFiles[file]->Get("MinBiasEvents");
00165 if ( !theTrees[file] ) throw cms::Exception("FastSimulation/PileUpProducer")
00166 << "Tree with name MinBiasEvents not found in " << theFileNames[file];
00167
00168 theBranches[file] = theTrees[file]->GetBranch("puEvent");
00169 if ( !theBranches[file] ) throw cms::Exception("FastSimulation/PileUpProducer")
00170 << "Branch with name puEvent not found in " << theFileNames[file];
00171
00172 thePUEvents[file] = new PUEvent();
00173 theBranches[file]->SetAddress(&thePUEvents[file]);
00174
00175 theNumberOfEntries[file] = theTrees[file]->GetEntries();
00176
00177 if ( !input )
00178 theCurrentEntry[file]
00179 = (unsigned) (theNumberOfEntries[file] * random->flatShoot());
00180
00181 theTrees[file]->GetEntry(theCurrentEntry[file]);
00182 unsigned NMinBias = thePUEvents[file]->nMinBias();
00183 theNumberOfMinBiasEvts[file] = NMinBias;
00184
00185 if ( !input )
00186 theCurrentMinBiasEvt[file] =
00187 (unsigned) (theNumberOfMinBiasEvts[file] * random->flatShoot());
00188
00189
00190
00191
00192
00193
00194
00195
00196 }
00197
00198
00199 gROOT->cd();
00200
00201 }
00202
00203 void PileUpProducer::endRun()
00204 {
00205
00206
00207
00208 for ( unsigned file=0; file<theFiles.size(); ++file ) {
00209
00210
00211 theFiles[file]->Close();
00212
00213 }
00214
00215
00216 myOutputFile.close();
00217
00218
00219 gROOT->cd();
00220
00221 }
00222
00223 void PileUpProducer::produce(edm::Event & iEvent, const edm::EventSetup & es)
00224 {
00225
00226
00227 std::auto_ptr<edm::HepMCProduct> pu_product(new edm::HepMCProduct());
00228 HepMC::GenEvent* evt = new HepMC::GenEvent();
00229
00230
00231 int PUevts = usePoisson_ ? (int) random->poissonShoot(averageNumber_) : (int) hprob->GetRandom();
00232
00233
00234
00235
00236 std::auto_ptr< PileupMixingContent > PileupMixing_;
00237
00238 std::vector<int> bunchCrossingList;
00239 bunchCrossingList.push_back(0);
00240
00241 std::vector<int> numInteractionList;
00242 numInteractionList.push_back(PUevts);
00243
00244 std::vector<float> trueInteractionList;
00245 trueInteractionList.push_back((float)averageNumber_);
00246
00247 PileupMixing_ = std::auto_ptr< PileupMixingContent >(new PileupMixingContent(bunchCrossingList,numInteractionList,trueInteractionList));
00248 iEvent.put(PileupMixing_);
00249
00250
00251 for ( int ievt=0; ievt<PUevts; ++ievt ) {
00252
00253
00254 unsigned file = (unsigned) (theNumberOfFiles * random->flatShoot());
00255
00256
00257
00258
00259
00260
00261
00262 theVertexGenerator->generate();
00263 HepMC::FourVector smearedVertex =
00264 HepMC::FourVector(theVertexGenerator->X()*10.,
00265 theVertexGenerator->Y()*10.,
00266 theVertexGenerator->Z()*10.,
00267 0.);
00268 HepMC::GenVertex* aVertex = new HepMC::GenVertex(smearedVertex);
00269 evt->add_vertex(aVertex);
00270
00271
00272 double theAngle = random->flatShoot() * 2. * 3.14159265358979323;
00273 double cAngle = std::cos(theAngle);
00274 double sAngle = std::sin(theAngle);
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 if ( theCurrentMinBiasEvt[file] == theNumberOfMinBiasEvts[file] ) {
00289
00290 ++theCurrentEntry[file];
00291
00292 theCurrentMinBiasEvt[file] = 0;
00293 if ( theCurrentEntry[file] == theNumberOfEntries[file] ) {
00294 theCurrentEntry[file] = 0;
00295
00296 }
00297
00298 thePUEvents[file]->reset();
00299 unsigned myEntry = theCurrentEntry[file];
00300
00301
00302
00303
00304 theTrees[file]->GetEntry(myEntry);
00305
00306
00307
00308
00309 theNumberOfMinBiasEvts[file] = thePUEvents[file]->nMinBias();
00310
00311 }
00312
00313
00314 const PUEvent::PUMinBiasEvt& aMinBiasEvt
00315 = thePUEvents[file]->thePUMinBiasEvts()[theCurrentMinBiasEvt[file]];
00316
00317
00318 unsigned firstTrack = aMinBiasEvt.first;
00319 unsigned trackSize = firstTrack + aMinBiasEvt.size;
00320
00321
00322
00323
00324
00325
00326 for ( unsigned iTrack=firstTrack; iTrack<trackSize; ++iTrack ) {
00327
00328 const PUEvent::PUParticle& aParticle
00329 = thePUEvents[file]->thePUParticles()[iTrack];
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 double energy = std::sqrt( aParticle.px*aParticle.px
00343 + aParticle.py*aParticle.py
00344 + aParticle.pz*aParticle.pz
00345 + aParticle.mass*aParticle.mass );
00346
00347 HepMC::FourVector myPart(cAngle * aParticle.px + sAngle * aParticle.py,
00348 -sAngle * aParticle.px + cAngle * aParticle.py,
00349 aParticle.pz, energy);
00350
00351
00352 HepMC::GenParticle* aGenParticle = new HepMC::GenParticle(myPart,aParticle.id);
00353 aVertex->add_particle_out(aGenParticle);
00354
00355 }
00356
00357
00358
00359 ++theCurrentMinBiasEvt[file];
00360
00361 }
00362
00363
00364
00365
00366
00367 if ( evt ) {
00368 pu_product->addHepMCData( evt );
00369
00370 TMatrixD* boost = theVertexGenerator->boost();
00371 if ( boost ) pu_product->boostToLab(boost,"momentum");
00372 }
00373
00374
00375 iEvent.put(pu_product,"PileUpEvents");
00376
00377
00378
00379 this->save();
00380
00381 }
00382
00383 void
00384 PileUpProducer::save() {
00385
00386
00387 ++myOutputBuffer;
00388
00389
00390 if ( myOutputBuffer/1000*1000 == myOutputBuffer ) {
00391 myOutputFile.close();
00392 myOutputFile.open ("PileUpOutputFile.txt");
00393
00394 }
00395
00396
00397 myOutputFile.write((const char*)(&theCurrentEntry.front()),
00398 theCurrentEntry.size()*sizeof(unsigned));
00399 myOutputFile.write((const char*)&theCurrentMinBiasEvt.front(),
00400 theCurrentMinBiasEvt.size()*sizeof(unsigned));
00401 myOutputFile.flush();
00402
00403 }
00404
00405 bool
00406 PileUpProducer::read(std::string inputFile) {
00407
00408 ifstream myInputFile;
00409 struct stat results;
00410 unsigned size1 = theCurrentEntry.size()*sizeof(unsigned);
00411 unsigned size2 = theCurrentMinBiasEvt.size()*sizeof(unsigned);
00412 unsigned size = 0;
00413
00414
00415
00416 myInputFile.open (inputFile.c_str());
00417 if ( myInputFile.is_open() ) {
00418
00419
00420 if ( stat(inputFile.c_str(), &results) == 0 ) size = results.st_size;
00421 else return false;
00422
00423
00424 myInputFile.seekg(size-size1-size2);
00425
00426
00427 myInputFile.read((char*)(&theCurrentEntry.front()),size1);
00428 myInputFile.read((char*)&theCurrentMinBiasEvt.front(),size2);
00429 myInputFile.close();
00430
00431 return true;
00432
00433 }
00434
00435 return false;
00436
00437 }
00438
00439 DEFINE_FWK_MODULE(PileUpProducer);