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
00076
00077 PU_Study_ = false;
00078 Study_type_ = "";
00079
00080 Study_type_ = pset.getUntrackedParameter<std::string>("Special_Pileup_Studies", "");
00081
00082 if(Study_type_ == "Fixed_ITPU_Vary_OOTPU") {
00083
00084 PU_Study_ = true;
00085 intFixed_ITPU_ = pset.getUntrackedParameter<int>("intFixed_ITPU", 0);
00086
00087 }
00088
00089 if(manage_OOT_) {
00090
00091
00092
00093
00094 std::string OOT_type = pset.getUntrackedParameter<std::string>("OOT_type");
00095
00096 if(OOT_type == "Poisson" || OOT_type == "poisson") {
00097 poisson_OOT_ = true;
00098 poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00099 }
00100 else if(OOT_type == "Fixed" || OOT_type == "fixed") {
00101 fixed_OOT_ = true;
00102
00103 intFixed_OOT_ = pset.getUntrackedParameter<int>("intFixed_OOT", -1);
00104 if(intFixed_OOT_ < 0) {
00105 throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00106 << " Fixed out-of-time pileup requested, but no fixed value given ";
00107 }
00108 }
00109 else {
00110 throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
00111 << "'OOT_type' parameter (a string) has a value of '" << OOT_type << "'.\n"
00112 << "Legal values are 'poisson' or 'fixed'\n";
00113 }
00114 edm::LogInfo("MixingModule") <<" Out-of-time pileup will be generated with a " << OOT_type << " distribution. " ;
00115 }
00116 }
00117
00118 }
00119
00120 void PileUp::reload(const edm::EventSetup & setup){
00121
00122 edm::ESHandle<MixingModuleConfig> configM;
00123 setup.get<MixingRcd>().get(configM);
00124
00125 const MixingInputConfig & config=configM->config(inputType_);
00126
00127
00128 type_=config.type();
00129
00130 histoDistribution_=type_ == "histo";
00131 probFunctionDistribution_=type_ == "probFunction";
00132 poisson_=type_ == "poisson";
00133 fixed_=type_ == "fixed";
00134 none_=type_ == "none";
00135
00136 if (histoDistribution_) edm::LogError("MisConfiguration")<<"type histo cannot be reloaded from DB, yet";
00137
00138 if (fixed_){
00139 averageNumber_=averageNumber();
00140 }
00141 else if (poisson_)
00142 {
00143 averageNumber_=config.averageNumber();
00144 edm::Service<edm::RandomNumberGenerator> rng;
00145 CLHEP::HepRandomEngine& engine = rng->getEngine();
00146 delete poissonDistribution_;
00147 poissonDistribution_ = new CLHEP::RandPoissonQ(engine, averageNumber_);
00148 }
00149 else if (probFunctionDistribution_)
00150 {
00151
00152 const std::vector<int> & dataProbFunctionVar = config.probFunctionVariable();
00153 std::vector<double> dataProb = config.probValue();
00154
00155 int varSize = (int) dataProbFunctionVar.size();
00156 int probSize = (int) dataProb.size();
00157
00158 if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1)))
00159 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;
00160
00161
00162
00163 if (probSize < varSize){
00164 edm::LogWarning("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize) <<" values 0.";
00165
00166 for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
00167
00168 probSize = dataProb.size();
00169 edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
00170 }
00171
00172
00173 int xmin = (int) dataProbFunctionVar[0];
00174 int xmax = (int) dataProbFunctionVar[varSize-1]+1;
00175 int numBins = varSize;
00176
00177 edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
00178
00179 if (histo_) delete histo_;
00180 histo_ = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax);
00181
00182 LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
00183
00184 for (int j=0; j < numBins ; j++){
00185 LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
00186 histo_->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]);
00187 }
00188
00189
00190 if ( ((histo_->Integral() - 1) > 1.0e-02) && ((histo_->Integral() - 1) < -1.0e-02)){
00191 throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << std::endl;
00192 }
00193 averageNumber_=histo_->GetMean();
00194 }
00195
00196 int oot=config.outOfTime();
00197 manage_OOT_=false;
00198 if (oot==1)
00199 {
00200 manage_OOT_=true;
00201 poisson_OOT_ = false;
00202 if (poissonDistr_OOT_){delete poissonDistr_OOT_; poissonDistr_OOT_=0; }
00203 fixed_OOT_ = true;
00204 intFixed_OOT_=config.fixedOutOfTime();
00205 }
00206 else if (oot==2)
00207 {
00208 manage_OOT_=true;
00209 poisson_OOT_ = true;
00210 fixed_OOT_ = false;
00211 if (!poissonDistr_OOT_) {
00212
00213 edm::Service<edm::RandomNumberGenerator> rng;
00214 CLHEP::HepRandomEngine& engine = rng->getEngine();
00215 poissonDistr_OOT_ = new CLHEP::RandPoisson(engine);
00216 }
00217 }
00218
00219
00220 }
00221 PileUp::~PileUp() {
00222 delete poissonDistribution_;
00223 delete poissonDistr_OOT_ ;
00224 }
00225
00226 void PileUp::CalculatePileup(int MinBunch, int MaxBunch, std::vector<int>& PileupSelection, std::vector<float>& TrueNumInteractions) {
00227
00228
00229
00230
00231 int nzero_crossing = -1;
00232 double Fnzero_crossing = -1;
00233
00234 if(manage_OOT_) {
00235 if (none_){
00236 nzero_crossing = 0;
00237 }else if (poisson_){
00238 nzero_crossing = poissonDistribution_->fire() ;
00239 }else if (fixed_){
00240 nzero_crossing = intAverage_ ;
00241 }else if (histoDistribution_ || probFunctionDistribution_){
00242 double d = histo_->GetRandom();
00243
00244 Fnzero_crossing = d;
00245 nzero_crossing = int(d);
00246 }
00247
00248 }
00249
00250 for(int bx = MinBunch; bx < MaxBunch+1; ++bx) {
00251
00252 if(manage_OOT_) {
00253 if(bx==0 && !poisson_OOT_) {
00254 PileupSelection.push_back(nzero_crossing) ;
00255 TrueNumInteractions.push_back( nzero_crossing );
00256 }
00257 else{
00258 if(poisson_OOT_) {
00259 if(PU_Study_ && (Study_type_ == "Fixed_ITPU_Vary_OOTPU" ) && bx==0 ) {
00260 PileupSelection.push_back(intFixed_ITPU_) ;
00261 }
00262 else{
00263 PileupSelection.push_back(poissonDistr_OOT_->fire(Fnzero_crossing)) ;
00264 }
00265 TrueNumInteractions.push_back( Fnzero_crossing );
00266 }
00267 else {
00268 PileupSelection.push_back(intFixed_OOT_) ;
00269 TrueNumInteractions.push_back( intFixed_OOT_ );
00270 }
00271 }
00272 }
00273 else {
00274 if (none_){
00275 PileupSelection.push_back(0);
00276 TrueNumInteractions.push_back( 0. );
00277 }else if (poisson_){
00278 PileupSelection.push_back(poissonDistribution_->fire());
00279 TrueNumInteractions.push_back( averageNumber_ );
00280 }else if (fixed_){
00281 PileupSelection.push_back(intAverage_);
00282 TrueNumInteractions.push_back( intAverage_ );
00283 }else if (histoDistribution_ || probFunctionDistribution_){
00284 double d = histo_->GetRandom();
00285 PileupSelection.push_back(int(d));
00286 TrueNumInteractions.push_back( d );
00287 }
00288 }
00289
00290 }
00291 }
00292
00293
00294 }