Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "SimCalorimetry/HcalSimAlgos/interface/HPDIonFeedbackSim.h"
00013 #include "SimCalorimetry/HcalSimAlgos/interface/HcalShapes.h"
00014 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVShape.h"
00015 #include "CondFormats/HcalObjects/interface/HcalGain.h"
00016 #include "CondFormats/HcalObjects/interface/HcalGainWidth.h"
00017 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00020 #include "FWCore/ServiceRegistry/interface/Service.h"
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 #include "FWCore/PluginManager/interface/PluginManager.h"
00023 #include "FWCore/PluginManager/interface/standard.h"
00024
00025
00026 using namespace edm;
00027 using namespace std;
00028
00029
00030 double pe2Charge = 0.333333;
00031
00032 HPDIonFeedbackSim::HPDIonFeedbackSim(const edm::ParameterSet & iConfig, const CaloShapes * shapes)
00033 : theDbService(0), theShapes(shapes),
00034 theRandBinomial(0), theRandFlat(0), theRandGauss(0), theRandPoissonQ(0)
00035 {
00036 }
00037
00038 HPDIonFeedbackSim::~HPDIonFeedbackSim()
00039 {
00040 if(theRandBinomial) delete theRandBinomial;
00041 if (theRandFlat) delete theRandFlat;
00042 if (theRandGauss) delete theRandGauss;
00043 if (theRandPoissonQ) delete theRandPoissonQ;
00044 }
00045
00046
00047 void HPDIonFeedbackSim::setRandomEngine(CLHEP::HepRandomEngine & engine)
00048 {
00049 if(theRandBinomial) delete theRandBinomial;
00050 if (theRandFlat) delete theRandFlat;
00051 if (theRandGauss) delete theRandGauss;
00052 if (theRandPoissonQ) delete theRandPoissonQ;
00053
00054 theRandBinomial = new CLHEP::RandBinomial(engine);
00055 theRandFlat = new CLHEP::RandFlat(engine);
00056 theRandGauss = new CLHEP::RandGaussQ(engine);
00057 theRandPoissonQ = new CLHEP::RandPoissonQ(engine);
00058 }
00059
00060 double HPDIonFeedbackSim::getIonFeedback(DetId detId, double signal, double pedWidth, bool doThermal, bool isInGeV)
00061 {
00062
00063
00064
00065 double GeVperfC = 1.;
00066 if(isInGeV) GeVperfC = 1./fCtoGeV(detId);
00067
00068 double charge = signal / GeVperfC;
00069
00070 double noise = 0.;
00071 if (charge > 3. * pedWidth) {
00072 int npe = int (charge / pe2Charge);
00073 if(doThermal) {
00074 double electronEmission = 0.08;
00075 npe += theRandPoissonQ->fire(electronEmission);
00076 }
00077
00078 noise = correctPE(detId, npe) - npe;
00079 }
00080 return (noise * GeVperfC);
00081
00082 }
00083
00084
00085 double HPDIonFeedbackSim::correctPE(const DetId & detId, double npe) const
00086 {
00087 double rateInTail = 0.000211988;
00088 double rateInSecondTail = 4.61579e-06;
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 double p4 = 2.06117e+01;
00100 double p5 = 1.09239e+01;
00101
00102
00103
00104 double p7 = 5.45548e+01;
00105 double p8 = 1.59696e+01;
00106
00107 double noise = 0.;
00108 int nFirst = (int)(theRandBinomial->fire(npe, rateInTail));
00109 int nSecond = (int)(theRandBinomial->fire(npe, rateInSecondTail));
00110
00111 for (int j = 0; j < nFirst; ++j) {
00112 noise += theRandGauss->fire(p4, p5);
00113 }
00114 for (int j = 0; j < nSecond; ++j) {
00115 noise += theRandGauss->fire(p7, p8);
00116 }
00117
00118 return npe + std::max(noise/pe2Charge, 0.);
00119 }
00120
00121
00122 void HPDIonFeedbackSim::addThermalNoise(CaloSamples & samples)
00123 {
00124
00125
00126 double meanPE = 0.02;
00127 DetId detId(samples.id());
00128 int nSamples = samples.size();
00129 const CaloVShape * shape = theShapes->shape(detId);
00130 for(int i = 0; i < nSamples; ++i)
00131 {
00132 double npe = theRandPoissonQ->fire(meanPE);
00133
00134 if(npe > 0.)
00135 {
00136
00137 npe = correctPE(detId, npe);
00138 for(int j = i; j < nSamples; ++j)
00139 {
00140 double timeFromPE = (j-i) * 25.;
00141 samples[j] += (*shape)(timeFromPE) * npe;
00142 }
00143 }
00144 }
00145 }
00146
00147
00148 double HPDIonFeedbackSim::fCtoGeV(const DetId & detId) const
00149 {
00150 assert(theDbService != 0);
00151 HcalGenericDetId hcalGenDetId(detId);
00152 const HcalGain* gains = theDbService->getGain(hcalGenDetId);
00153 const HcalGainWidth* gwidths = theDbService->getGainWidth(hcalGenDetId);
00154 if (!gains || !gwidths )
00155 {
00156 edm::LogError("HcalAmplifier") << "Could not fetch HCAL conditions for channel " << hcalGenDetId;
00157 }
00158
00159 double result = gains->getValue(0);
00160 return result;
00161 }