Go to the documentation of this file.00001 #include "Mixing/Base/interface/PileUp.h"
00002 #include "FWCore/Framework/interface/EventPrincipal.h"
00003 #include "FWCore/Framework/interface/InputSourceDescription.h"
00004 #include "FWCore/Sources/interface/VectorInputSourceFactory.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "FWCore/Utilities/interface/Exception.h"
00008
00009 #include "FWCore/ServiceRegistry/interface/Service.h"
00010 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00011
00012 #include "FWCore/Framework/interface/ESHandle.h"
00013 #include "FWCore/Framework/interface/EventSetup.h"
00014 #include "CondFormats/DataRecord/interface/MixingRcd.h"
00015 #include "CondFormats/RunInfo/interface/MixingModuleConfig.h"
00016
00017 #include <algorithm>
00018
00019 namespace edm {
00020 PileUp::PileUp(ParameterSet const& pset, double averageNumber, TH1F * const histo, const bool playback) :
00021 type_(pset.getParameter<std::string>("type")),
00022 averageNumber_(averageNumber),
00023 intAverage_(static_cast<int>(averageNumber)),
00024 histo_(histo),
00025 histoDistribution_(type_ == "histo"),
00026 probFunctionDistribution_(type_ == "probFunction"),
00027 poisson_(type_ == "poisson"),
00028 fixed_(type_ == "fixed"),
00029 none_(type_ == "none"),
00030 input_(VectorInputSourceFactory::get()->makeVectorInputSource(pset, InputSourceDescription()).release()),
00031 poissonDistribution_(0),
00032 poissonDistr_OOT_(0),
00033 playback_(playback),
00034 sequential_(pset.getUntrackedParameter<bool>("sequential", false)),
00035 samelumi_(pset.getUntrackedParameter<bool>("sameLumiBlock", false)),
00036 seed_(0)
00037 {
00038 if (pset.exists("nbPileupEvents"))
00039 seed_=pset.getParameter<edm::ParameterSet>("nbPileupEvents").getUntrackedParameter<int>("seed",0);
00040
00041 bool DB=type_=="readDB";
00042
00043 edm::Service<edm::RandomNumberGenerator> rng;
00044 if (!rng.isAvailable()) {
00045 throw cms::Exception("Configuration")
00046 << "PileUp requires the RandomNumberGeneratorService\n"
00047 "which is not present in the configuration file. You must add the service\n"
00048 "in the configuration file or remove the modules that require it.";
00049 }
00050
00051 CLHEP::HepRandomEngine& engine = rng->getEngine();
00052 poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);
00053
00054
00055 if (histoDistribution_ || probFunctionDistribution_ || DB){
00056 if(seed_ !=0) {
00057 gRandom->SetSeed(seed_);
00058 LogInfo("MixingModule") << " Change seed for " << type_ << " mode. The seed is set to " << seed_;
00059 }
00060 else {
00061 gRandom->SetSeed(engine.getSeed());
00062 }
00063 }
00064
00065
00066 if (!(histoDistribution_ || probFunctionDistribution_ || poisson_ || fixed_ || none_) && !DB) {
00067 throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00068 << "'type' parameter (a string) has a value of '" << type_ << "'.\n"
00069 << "Legal values are 'poisson', 'fixed', or 'none'\n";
00070 }
00071
00072 if (!DB){
00073 manage_OOT_ = pset.getUntrackedParameter<bool>("manage_OOT", false);
00074
00075 if(manage_OOT_) {
00076
00077
00078
00079
00080 std::string OOT_type = pset.getUntrackedParameter<std::string>("OOT_type");
00081
00082 if(OOT_type == "Poisson" || OOT_type == "poisson") {
00083 poisson_OOT_ = true;
00084 poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00085 }
00086 else if(OOT_type == "Fixed" || OOT_type == "fixed") {
00087 fixed_OOT_ = true;
00088
00089 intFixed_OOT_ = pset.getUntrackedParameter<int>("intFixed_OOT", -1);
00090 if(intFixed_OOT_ < 0) {
00091 throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00092 << " Fixed out-of-time pileup requested, but no fixed value given ";
00093 }
00094 }
00095 else {
00096 throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00097 << "'OOT_type' parameter (a string) has a value of '" << OOT_type << "'.\n"
00098 << "Legal values are 'poisson' or 'fixed'\n";
00099 }
00100 edm::LogInfo("MixingModule") <<" Out-of-time pileup will be generated with a " << OOT_type << " distribution. " ;
00101 }
00102 }
00103
00104 }
00105
00106 void PileUp::reload(const edm::EventSetup & setup){
00107
00108 edm::ESHandle<MixingModuleConfig> configM;
00109 setup.get<MixingRcd>().get(configM);
00110
00111 const MixingInputConfig & config=configM->config(inputType_);
00112
00113
00114 type_=config.type();
00115
00116 histoDistribution_=type_ == "histo";
00117 probFunctionDistribution_=type_ == "probFunction";
00118 poisson_=type_ == "poisson";
00119 fixed_=type_ == "fixed";
00120 none_=type_ == "none";
00121
00122 if (histoDistribution_) edm::LogError("MisConfiguration")<<"type histo cannot be reloaded from DB, yet";
00123
00124 if (fixed_){
00125 averageNumber_=averageNumber();
00126 }
00127 else if (poisson_)
00128 {
00129 averageNumber_=config.averageNumber();
00130 edm::Service<edm::RandomNumberGenerator> rng;
00131 CLHEP::HepRandomEngine& engine = rng->getEngine();
00132 delete poissonDistribution_;
00133 poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);
00134 }
00135 else if (probFunctionDistribution_)
00136 {
00137
00138 const std::vector<int> & dataProbFunctionVar = config.probFunctionVariable();
00139 std::vector<double> dataProb = config.probValue();
00140
00141 int varSize = (int) dataProbFunctionVar.size();
00142 int probSize = (int) dataProb.size();
00143
00144 if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1)))
00145 throw cms::Exception("BadProbFunction") << "Please, check the variables of the probability function! The first variable should be 0 and the difference between two variables should be 1." << std::endl;
00146
00147
00148
00149 if (probSize < varSize){
00150 edm::LogWarning("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize) <<" values 0.";
00151
00152 for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
00153
00154 probSize = dataProb.size();
00155 edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
00156 }
00157
00158
00159 int xmin = (int) dataProbFunctionVar[0];
00160 int xmax = (int) dataProbFunctionVar[varSize-1]+1;
00161 int numBins = varSize;
00162
00163 edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
00164
00165 if (histo_) delete histo_;
00166 histo_ = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax);
00167
00168 LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
00169
00170 for (int j=0; j < numBins ; j++){
00171 LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
00172 histo_->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]);
00173 }
00174
00175
00176 if ( ((histo_->Integral() - 1) > 1.0e-02) && ((histo_->Integral() - 1) < -1.0e-02)){
00177 throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << std::endl;
00178 }
00179 averageNumber_=histo_->GetMean();
00180 }
00181
00182 int oot=config.outOfTime();
00183 manage_OOT_=false;
00184 if (oot==1)
00185 {
00186 manage_OOT_=true;
00187 poisson_OOT_ = false;
00188 if (poissonDistr_OOT_){delete poissonDistr_OOT_; poissonDistr_OOT_=0; }
00189 fixed_OOT_ = true;
00190 intFixed_OOT_=config.fixedOutOfTime();
00191 }
00192 else if (oot==2)
00193 {
00194 manage_OOT_=true;
00195 poisson_OOT_ = true;
00196 fixed_OOT_ = false;
00197 if (!poissonDistr_OOT_) {
00198
00199 edm::Service<edm::RandomNumberGenerator> rng;
00200 CLHEP::HepRandomEngine& engine = rng->getEngine();
00201 poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00202 }
00203 }
00204
00205
00206 }
00207 PileUp::~PileUp() {
00208 delete poissonDistribution_;
00209 delete poissonDistr_OOT_ ;
00210 }
00211
00212 void PileUp::CalculatePileup(int MinBunch, int MaxBunch, std::vector<int>& PileupSelection, std::vector<float>& TrueNumInteractions) {
00213
00214
00215
00216
00217 int nzero_crossing = -1;
00218 double Fnzero_crossing = -1;
00219
00220 if(manage_OOT_) {
00221 if (none_){
00222 nzero_crossing = 0;
00223 }else if (poisson_){
00224 nzero_crossing = poissonDistribution_->fire() ;
00225 }else if (fixed_){
00226 nzero_crossing = intAverage_ ;
00227 }else if (histoDistribution_ || probFunctionDistribution_){
00228 double d = histo_->GetRandom();
00229
00230 Fnzero_crossing = d;
00231 }
00232
00233 }
00234
00235 for(int bx = MinBunch; bx < MaxBunch+1; ++bx) {
00236
00237 if(manage_OOT_) {
00238 if(bx==0 && !poisson_OOT_) {
00239 PileupSelection.push_back(nzero_crossing) ;
00240 TrueNumInteractions.push_back( nzero_crossing );
00241 }
00242 else{
00243 if(poisson_OOT_) {
00244 PileupSelection.push_back(poissonDistr_OOT_->fire(Fnzero_crossing)) ;
00245 TrueNumInteractions.push_back( Fnzero_crossing );
00246 }
00247 else {
00248 PileupSelection.push_back(intFixed_OOT_) ;
00249 TrueNumInteractions.push_back( intFixed_OOT_ );
00250 }
00251 }
00252 }
00253 else {
00254 if (none_){
00255 PileupSelection.push_back(0);
00256 TrueNumInteractions.push_back( 0. );
00257 }else if (poisson_){
00258 PileupSelection.push_back(poissonDistribution_->fire());
00259 TrueNumInteractions.push_back( averageNumber_ );
00260 }else if (fixed_){
00261 PileupSelection.push_back(intAverage_);
00262 TrueNumInteractions.push_back( intAverage_ );
00263 }else if (histoDistribution_ || probFunctionDistribution_){
00264 double d = histo_->GetRandom();
00265 PileupSelection.push_back(int(d));
00266 TrueNumInteractions.push_back( d );
00267 }
00268 }
00269
00270 }
00271 }
00272
00273
00274 }