00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "SimCalorimetry/HcalSimAlgos/interface/HPDNoiseLibraryReader.h"
00018
00019 using namespace edm;
00020 using namespace std;
00021
00022 HPDNoiseLibraryReader::HPDNoiseLibraryReader(const edm::ParameterSet & iConfig)
00023 :theDischargeNoiseRate(0),
00024 theIonFeedbackFirstPeakRate(0),
00025 theIonFeedbackSecondPeakRate(0),
00026 theNoisyPhi(0),
00027 theRandFlat(0),
00028 theRandGaussQ(0) {
00029 setRandomEngine();
00030
00031 ParameterSet pSet = iConfig.getParameter < edm::ParameterSet > ("HPDNoiseLibrary");
00032 FileInPath filepath = pSet.getParameter < edm::FileInPath > ("FileName");
00033
00034 theHPDName = pSet.getUntrackedParameter < string > ("HPDName", "HPD");
00035 string pName = filepath.fullPath();
00036
00037 if (pName.find(".") == 0)
00038 pName.erase(0, 2);
00039 theReader = new HPDNoiseReader(pName);
00040 theNames = theReader->allNames();
00041
00042 fillRates();
00043 }
00044
00045 HPDNoiseLibraryReader::~HPDNoiseLibraryReader() {
00046 if (theRandFlat)
00047 delete theRandFlat;
00048
00049 if (theRandGaussQ)
00050 delete theRandGaussQ;
00051 }
00052
00053 void HPDNoiseLibraryReader::initializeServices() {
00054 if (not edmplugin::PluginManager::isAvailable()) {
00055 edmplugin::PluginManager::configure(edmplugin::standard::config());
00056 }
00057
00058 std::string config =
00059 "process CorrNoise = {"
00060 "service = RandomNumberGeneratorService" "{" "untracked uint32 sourceSeed = 123456789" "}" "}";
00061
00062
00063 edm::ServiceToken tempToken = edm::ServiceRegistry::createServicesFromConfig(config);
00064
00065
00066 edm::ServiceRegistry::Operate operate(tempToken);
00067 }
00068 void HPDNoiseLibraryReader::setRandomEngine() {
00069 edm::Service < edm::RandomNumberGenerator > rng;
00070 if (!rng.isAvailable()) {
00071 throw cms::Exception("Configuration") << "HcalHPDNoiseLibrary requires the RandomNumberGeneratorService\n"
00072 "which is not present in the configuration file. You must add the service\n"
00073 "in the configuration file or remove the modules that require it.";
00074 }
00075 setRandomEngine(rng->getEngine());
00076 }
00077 void HPDNoiseLibraryReader::setRandomEngine(CLHEP::HepRandomEngine & engine) {
00078 if (theRandGaussQ)
00079 delete theRandGaussQ;
00080
00081 if (theRandFlat)
00082 delete theRandFlat;
00083
00084 theRandGaussQ = new CLHEP::RandGaussQ(engine);
00085 theRandFlat = new CLHEP::RandFlat(engine);
00086 }
00087
00088 void HPDNoiseLibraryReader::fillRates() {
00089 for (size_t i = 0; i < theNames.size(); ++i) {
00090 HPDNoiseReader::Handle hpdObj = theReader->getHandle(theNames[i]);
00091 if (theReader->valid(hpdObj)) {
00092 theDischargeNoiseRate.push_back(theReader->dischargeRate(hpdObj));
00093 theIonFeedbackFirstPeakRate.push_back(theReader->ionFeedbackFirstPeakRate(hpdObj));
00094 theIonFeedbackSecondPeakRate.push_back(theReader->ionFeedbackSecondPeakRate(hpdObj));
00095 } else {
00096 std::cerr << "HPD Handle Object is not valid!" << endl;
00097 }
00098 }
00099 }
00100
00101 HPDNoiseData *HPDNoiseLibraryReader::getNoiseData(int iphi) {
00102
00103
00104 HPDNoiseData *data = 0;
00105
00106
00107
00108
00109 if (!(IsNoiseApplicable(iphi)))
00110 return data;
00111
00112 int zside = 1;
00113
00114 if (iphi > 72) {
00115 iphi = iphi - 72;
00116 zside = -1;
00117 }
00118 std::string name;
00119 if (zside == 1) {
00120 name = "ZPlus" + theHPDName + itos(iphi);
00121 } else if (zside == -1) {
00122 name = "ZMinus" + theHPDName + itos(iphi);
00123 } else {
00124 cerr << " ZSide Calculation Error." << endl;
00125 }
00126 HPDNoiseReader::Handle hpdObj = theReader->getHandle(name);
00127 if (theReader->valid(hpdObj)) {
00128
00129 unsigned long entry = theRandFlat->fireInt(theReader->totalEntries(hpdObj));
00130
00131 theReader->getEntry(hpdObj, entry, &data);
00132 } else {
00133 std::cerr << " HPD Name in the library is not valid." << std::endl;
00134 }
00135 return data;
00136 }
00137
00138
00139 void HPDNoiseLibraryReader::getNoisyPhis() {
00140
00141 clearPhi();
00142 double rndm[144];
00143
00144 theRandFlat->shootArray(144, rndm);
00145
00146 for (int i = 0; i < 144; ++i) {
00147 if (rndm[i] < theDischargeNoiseRate[i]) {
00148 theNoisyPhi.push_back(i + 1);
00149 }
00150 }
00151 }
00152
00153 void HPDNoiseLibraryReader::getBiasedNoisyPhis() {
00154
00155 clearPhi();
00156 double rndm[144];
00157
00158 theRandFlat->shootArray(144, rndm);
00159 for (int i = 0; i < 144; ++i) {
00160 if (rndm[i] < theDischargeNoiseRate[i]) {
00161 theNoisyPhi.push_back(i + 1);
00162 }
00163 }
00164
00165 if (theNoisyPhi.size() == 0) {
00166 int iPhi = (theRandFlat->fireInt(144)) + 1;
00167
00168 theNoisyPhi.push_back(iPhi);
00169 }
00170 }
00171
00172 vector <pair<HcalDetId, const float *> >HPDNoiseLibraryReader::getNoisyHcalDetIds() {
00173
00174 vector <pair< HcalDetId, const float *> >result;
00175
00176
00177
00178 getNoisyPhis();
00179 for (int i = 0; i < int (theNoisyPhi.size()); ++i) {
00180 int iphi = theNoisyPhi[i];
00181 HPDNoiseData *data;
00182
00183 data = getNoiseData(iphi);
00184 for (unsigned int i = 0; i < data->size(); ++i) {
00185
00186 result.emplace_back(data->getDataFrame(i).id(), data->getDataFrame(i).getFrame());
00187 }
00188 }
00189 return result;
00190 }
00191
00192 vector <pair<HcalDetId, const float *> >HPDNoiseLibraryReader::getNoisyHcalDetIds(int timeSliceId)
00193 {
00194 vector <pair< HcalDetId, const float *> >result;
00195
00196
00197 getNoisyPhis();
00198 for (int i = 0; i < int (theNoisyPhi.size()); ++i) {
00199 int iphi = theNoisyPhi[i];
00200 HPDNoiseData *data;
00201
00202 data = getNoiseData(iphi);
00203 for (unsigned int i = 0; i < data->size(); ++i) {
00204 float* data_ = const_cast<float*>(data->getDataFrame(i).getFrame());
00205 shuffleData(timeSliceId, data_);
00206 const float* _data_ =const_cast<const float*>(data_);
00207 result.emplace_back(data->getDataFrame(i).id(), _data_);
00208 }
00209 }
00210 return result;
00211
00212 }
00213 vector < pair < HcalDetId, const float *> >HPDNoiseLibraryReader::getBiasedNoisyHcalDetIds(int timeSliceId) {
00214
00215 vector < pair < HcalDetId, const float *> >result;
00216
00217
00218
00219
00220 getBiasedNoisyPhis();
00221 for (int i = 0; i < int (theNoisyPhi.size()); ++i) {
00222 int iphi = theNoisyPhi[i];
00223 HPDNoiseData *data;
00224
00225 data = getNoiseData(iphi);
00226 for (unsigned int i = 0; i < data->size(); ++i) {
00227 float* data_ = const_cast<float*>(data->getDataFrame(i).getFrame());
00228 shuffleData(timeSliceId, data_);
00229 const float* _data_ =const_cast<const float*>(data_);
00230 result.emplace_back(data->getDataFrame(i).id(), _data_);
00231 }
00232 }
00233 return result;
00234 }
00235
00236 vector < pair < HcalDetId, const float *> >HPDNoiseLibraryReader::getBiasedNoisyHcalDetIds() {
00237
00238 vector < pair < HcalDetId, const float *> >result;
00239
00240
00241
00242
00243 getBiasedNoisyPhis();
00244 for (int i = 0; i < int (theNoisyPhi.size()); ++i) {
00245 int iphi = theNoisyPhi[i];
00246 HPDNoiseData *data;
00247
00248 data = getNoiseData(iphi);
00249 for (unsigned int i = 0; i < data->size(); ++i) {
00250 result.emplace_back(data->getDataFrame(i).id(), data->getDataFrame(i).getFrame());
00251 }
00252 }
00253 return result;
00254 }
00255
00256 double HPDNoiseLibraryReader::getIonFeedbackNoise(HcalDetId id, double energy, double bias) {
00257
00258
00259 double pe2Charge = 0.333333;
00260 double GeVperfC = 0.177;
00261 double PedSigma = 0.8;
00262 double noise = 0.;
00263
00264 int iphi = (id.ieta() > 0) ? (id.iphi()) : (id.iphi() + 72);
00265 double rateInTail = theIonFeedbackFirstPeakRate[iphi - 1];
00266 double rateInSecondTail = theIonFeedbackSecondPeakRate[iphi - 1];
00267
00268 if (bias != 0.) {
00269 rateInTail = rateInTail * bias;
00270 rateInSecondTail = rateInSecondTail * bias;
00271 } else {
00272 edm::LogError("HPDNoise") << "HPDNoise: ion feedback error (biased or unbiased selection)." << bias << " failed";
00273 throw cms::Exception("Unknown", "biase selection ")
00274 << "Usage of " << bias << " fails\n";
00275 }
00276 double Charge = energy / GeVperfC;
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 double p4 = 2.06117e+01;
00290 double p5 = 1.09239e+01;
00291
00292
00293
00294 double p7 = 5.45548e+01;
00295 double p8 = 1.59696e+01;
00296
00297 if (Charge > 3 * PedSigma) {
00298 int npe = int (Charge / pe2Charge);
00299 double a = 0.;
00300 double b = 0.;
00301
00302 for (int j = 0; j < npe; ++j) {
00303 double probability = theRandFlat->shoot();
00304
00305 if (probability < rateInTail) {
00306 if (probability < rateInSecondTail) {
00307 Rannor(a, b);
00308 noise += b * p8 + p7;
00309 } else {
00310 Rannor(a, b);
00311 noise += b * p5 + p4;
00312 }
00313 }
00314 }
00315
00316 if (noise > 0.)
00317 noise += theRandGaussQ->fire(0, 2 * PedSigma);
00318 }
00319 return (noise * GeVperfC);
00320
00321 }
00322
00323 bool HPDNoiseLibraryReader::IsNoiseApplicable(int iphi) {
00324
00325 bool isAccepted = false;
00326 vector < int >::iterator phi_iter;
00327
00328 phi_iter = find(theNoisyPhi.begin(), theNoisyPhi.end(), iphi);
00329 if (phi_iter != theNoisyPhi.end()) {
00330 isAccepted = true;
00331 }
00332 return isAccepted;
00333 }
00334 void HPDNoiseLibraryReader::shuffleData(int timeSliceId, float* &data)
00335 {
00336 if(timeSliceId == -1 || (timeSliceId>=10)) return;
00337
00338 float Data[10] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
00339 for(int i=0;i<10;++i){
00340 Data[i] = data[i];
00341 }
00342 int ts_max = -1;
00343 float max = -999.;
00344 for(int i=0;i<10;++i){
00345 if(Data[i]>max){
00346 max = data[i];
00347 ts_max = i;
00348 }
00349 }
00350 if((ts_max == -1)){
00351 return;
00352 }else{
00353
00354
00355 int k = -1;
00356 for(int i=0;i<10;++i){
00357 data[i] = 0.;
00358 int newIdx = timeSliceId+k;
00359 float dd = 0.;
00360 if(newIdx < 10){
00361 data[newIdx] = Data[ts_max+k];
00362 dd = Data[ts_max+k];
00363 i = newIdx;
00364 }
00365 data[i] = dd;
00366 ++k;
00367 }
00368
00369 }
00370 }
00371
00372
00373 void HPDNoiseLibraryReader::Rannor(double &a, double &b) {
00374 double r,
00375 x,
00376 y,
00377 z;
00378
00379 y = theRandFlat->shoot();
00380 z = theRandFlat->shoot();
00381 x = z * 6.28318530717958623;
00382 r = TMath::Sqrt(-2 * TMath::Log(y));
00383 a = r * TMath::Sin(x);
00384 b = r * TMath::Cos(x);
00385 }
00386 string HPDNoiseLibraryReader::itos(int i) {
00387 stringstream s;
00388
00389 s << i;
00390 return s.str();
00391 }
00392
00393 void HPDNoiseLibraryReader::clearPhi() {
00394 theNoisyPhi.clear();
00395 }