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