Go to the documentation of this file.00001 #include "SimCalorimetry/HcalSimAlgos/interface/HcalAmplifier.h"
00002 #include "SimCalorimetry/HcalSimAlgos/interface/HcalSimParameters.h"
00003 #include "SimCalorimetry/HcalSimAlgos/interface/HPDIonFeedbackSim.h"
00004 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVSimParameterMap.h"
00005 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVNoiseSignalGenerator.h"
00006 #include "CalibFormats/HcalObjects/interface/HcalDbService.h"
00007 #include "CondFormats/HcalObjects/interface/HcalPedestal.h"
00008 #include "CondFormats/HcalObjects/interface/HcalGain.h"
00009 #include "CondFormats/HcalObjects/interface/HcalPedestalWidth.h"
00010 #include "CondFormats/HcalObjects/interface/HcalGainWidth.h"
00011 #include "CalibFormats/CaloObjects/interface/CaloSamples.h"
00012 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014
00015 #include "CalibFormats/HcalObjects/interface/HcalCalibrations.h"
00016
00017 #include<iostream>
00018 #include <cmath>
00019 #include <math.h>
00020
00021 HcalAmplifier::HcalAmplifier(const CaloVSimParameterMap * parameters, bool addNoise) :
00022 theDbService(0),
00023 theRandGaussQ(0),
00024 theRandFlat(0),
00025 theParameterMap(parameters),
00026 theNoiseSignalGenerator(0),
00027 theIonFeedbackSim(0),
00028 theStartingCapId(0),
00029 addNoise_(addNoise),
00030 useOldHB(false),
00031 useOldHE(false),
00032 useOldHF(false),
00033 useOldHO(false)
00034 {
00035 }
00036
00037
00038 void HcalAmplifier::setDbService(const HcalDbService * service) {
00039 theDbService = service;
00040 if(theIonFeedbackSim) theIonFeedbackSim->setDbService(service);
00041 }
00042
00043
00044 void HcalAmplifier::setRandomEngine(CLHEP::HepRandomEngine & engine)
00045 {
00046 theRandGaussQ = new CLHEP::RandGaussQ(engine);
00047 theRandFlat = new CLHEP::RandFlat(engine);
00048 if(theIonFeedbackSim) theIonFeedbackSim->setRandomEngine(engine);
00049 }
00050
00051
00052 void HcalAmplifier::amplify(CaloSamples & frame) const {
00053 if(theIonFeedbackSim)
00054 {
00055 theIonFeedbackSim->addThermalNoise(frame);
00056 }
00057 pe2fC(frame);
00058 if(theNoiseSignalGenerator==0 || !theNoiseSignalGenerator->contains(frame.id()))
00059 {
00060 addPedestals(frame);
00061 }
00062 LogDebug("HcalAmplifier") << frame;
00063 }
00064
00065
00066 void HcalAmplifier::pe2fC(CaloSamples & frame) const
00067 {
00068 const CaloSimParameters & parameters = theParameterMap->simParameters(frame.id());
00069 frame *= parameters.photoelectronsToAnalog(frame.id());
00070 }
00071
00072 void HcalAmplifier::setHBtuningParameter(double tp) { HB_ff = tp; }
00073 void HcalAmplifier::setHEtuningParameter(double tp) { HE_ff = tp; }
00074 void HcalAmplifier::setHFtuningParameter(double tp) { HF_ff = tp; }
00075 void HcalAmplifier::setHOtuningParameter(double tp) { HO_ff = tp; }
00076 void HcalAmplifier::setUseOldHB(bool useOld) { useOldHB = useOld; }
00077 void HcalAmplifier::setUseOldHE(bool useOld) { useOldHE = useOld; }
00078 void HcalAmplifier::setUseOldHF(bool useOld) { useOldHF = useOld; }
00079 void HcalAmplifier::setUseOldHO(bool useOld) { useOldHO = useOld; }
00080
00081 void HcalAmplifier::addPedestals(CaloSamples & frame) const
00082 {
00083 assert(theDbService != 0);
00084 HcalGenericDetId hcalGenDetId(frame.id());
00085 HcalGenericDetId::HcalGenericSubdetector hcalSubDet = hcalGenDetId.genericSubdet();
00086
00087 bool useOld=false;
00088 if(hcalSubDet==HcalGenericDetId::HcalGenBarrel) useOld = useOldHB;
00089 if(hcalSubDet==HcalGenericDetId::HcalGenEndcap) useOld = useOldHE;
00090 if(hcalSubDet==HcalGenericDetId::HcalGenForward) useOld = useOldHF;
00091 if(hcalSubDet==HcalGenericDetId::HcalGenOuter) useOld = useOldHO;
00092
00093 if(useOld)
00094 {
00095 const HcalCalibrationWidths & calibWidths =
00096 theDbService->getHcalCalibrationWidths(hcalGenDetId);
00097 const HcalCalibrations& calibs = theDbService->getHcalCalibrations(hcalGenDetId);
00098
00099 double noise [32] = {0.};
00100 if(addNoise_)
00101 {
00102 double gauss [32];
00103 for (int i = 0; i < frame.size(); i++) gauss[i] = theRandGaussQ->fire(0., 1.);
00104 makeNoiseOld(hcalSubDet, calibWidths, frame.size(), gauss, noise);
00105 }
00106
00107 for (int tbin = 0; tbin < frame.size(); ++tbin) {
00108 int capId = (theStartingCapId + tbin)%4;
00109 double pedestal = calibs.pedestal(capId) + noise[tbin];
00110 frame[tbin] += pedestal;
00111 }
00112 return;
00113 }
00114
00115
00116 double fudgefactor = 1;
00117 if(hcalSubDet==HcalGenericDetId::HcalGenBarrel) fudgefactor = HB_ff;
00118 if(hcalSubDet==HcalGenericDetId::HcalGenEndcap) fudgefactor = HE_ff;
00119 if(hcalSubDet==HcalGenericDetId::HcalGenForward) fudgefactor = HF_ff;
00120 if(hcalSubDet==HcalGenericDetId::HcalGenOuter) fudgefactor = HO_ff;
00121 if(hcalGenDetId.isHcalCastorDetId()) return;
00122 if(hcalGenDetId.isHcalZDCDetId()) return;
00123
00124 const HcalCholeskyMatrix * thisChanCholesky = myCholeskys->getValues(hcalGenDetId);
00125 const HcalPedestal * thisChanADCPeds = myADCPeds->getValues(hcalGenDetId);
00126 int theStartingCapId_2 = (int)floor(theRandFlat->fire(0.,4.));
00127
00128 double noise [32] = {0.};
00129 if(addNoise_)
00130 {
00131 double gauss [32];
00132 for (int i = 0; i < frame.size(); i++) gauss[i] = theRandGaussQ->fire(0., 1.);
00133 makeNoise(*thisChanCholesky, frame.size(), gauss, noise, (int)theStartingCapId_2);
00134 }
00135
00136 const HcalQIECoder* coder = theDbService->getHcalCoder(hcalGenDetId);
00137 const HcalQIEShape* shape = theDbService->getHcalShape();
00138
00139 for (int tbin = 0; tbin < frame.size(); ++tbin) {
00140 int capId = (theStartingCapId_2 + tbin)%4;
00141 double x = noise[tbin] * fudgefactor + thisChanADCPeds->getValue(capId);
00142 int x1=(int)std::floor(x);
00143 int x2=(int)std::floor(x+1);
00144 float y2=coder->charge(*shape,x2,capId);
00145 float y1=coder->charge(*shape,x1,capId);
00146 frame[tbin] = (y2-y1)*(x-x1)+y1;
00147 }
00148 }
00149
00150 void HcalAmplifier::makeNoise (const HcalCholeskyMatrix & thisChanCholesky, int fFrames, double* fGauss, double* fNoise, int m) const {
00151 if(fFrames > 10) return;
00152
00153 for(int i = 0; i != 10; i++){
00154 for(int j = 0; j != 10; j++){
00155 fNoise[i] += thisChanCholesky.getValue(m,i,j) * fGauss[j];
00156 }
00157 }
00158 }
00159
00160 void HcalAmplifier::makeNoiseOld (HcalGenericDetId::HcalGenericSubdetector hcalSubDet, const HcalCalibrationWidths& width, int fFrames, double* fGauss, double* fNoise) const
00161 {
00162
00163
00164
00165
00166
00167 double s_xx_mean = 0.25 * (width.pedestal(0)*width.pedestal(0) +
00168 width.pedestal(1)*width.pedestal(1) +
00169 width.pedestal(2)*width.pedestal(2) +
00170 width.pedestal(3)*width.pedestal(3));
00171
00172
00173
00174
00175
00176 double s_xy_mean = -0.5 * s_xx_mean;
00177
00178
00179 if (hcalSubDet == HcalGenericDetId::HcalGenForward) s_xy_mean = 0.08 * s_xx_mean;
00180
00181 double term = s_xx_mean*s_xx_mean - 2.*s_xy_mean*s_xy_mean;
00182
00183 if (term < 0.) term = 1.e-50 ;
00184 double sigma = sqrt (0.5 * (s_xx_mean + sqrt(term)));
00185 double corr = sigma == 0. ? 0. : 0.5*s_xy_mean / sigma;
00186
00187 for (int i = 0; i < fFrames; i++) {
00188 fNoise [i] = fGauss[i]*sigma;
00189 if (i > 0) fNoise [i] += fGauss[i-1]*corr;
00190 if (i < fFrames-1) fNoise [i] += fGauss[i+1]*corr;
00191 }
00192 }
00193