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
00129 if ( !( (frame.id().subdetId()==HcalGenericDetId::HcalGenBarrel) ||
00130 (frame.id().subdetId()==HcalGenericDetId::HcalGenEndcap) ||
00131 (frame.id().subdetId()==HcalGenericDetId::HcalGenForward) ||
00132 (frame.id().subdetId()==HcalGenericDetId::HcalGenOuter) ) ) return;
00133
00134 if(hcalGenDetId.isHcalCastorDetId()) return;
00135 if(hcalGenDetId.isHcalZDCDetId()) return;
00136
00137 const HcalCholeskyMatrix * thisChanCholesky = myCholeskys->getValues(hcalGenDetId,false);
00138 if ( !thisChanCholesky) {
00139 std::cout << "no Cholesky " << hcalSubDet << " " << hcalGenDetId.rawId() << " " << frame.id().subdetId() <<std::endl;
00140 return;
00141 }
00142 const HcalPedestal * thisChanADCPeds = myADCPeds->getValues(hcalGenDetId);
00143 int theStartingCapId_2 = (int)floor(theRandFlat->fire(0.,4.));
00144
00145 double noise [32] = {0.};
00146 if(addNoise_)
00147 {
00148 double gauss [32];
00149 for (int i = 0; i < frame.size(); i++) gauss[i] = theRandGaussQ->fire(0., 1.);
00150 makeNoise(*thisChanCholesky, frame.size(), gauss, noise, (int)theStartingCapId_2);
00151 }
00152
00153 const HcalQIECoder* coder = theDbService->getHcalCoder(hcalGenDetId);
00154 const HcalQIEShape* shape = theDbService->getHcalShape(coder);
00155
00156 for (int tbin = 0; tbin < frame.size(); ++tbin) {
00157 int capId = (theStartingCapId_2 + tbin)%4;
00158 double x = noise[tbin] * fudgefactor + thisChanADCPeds->getValue(capId);
00159 int x1=(int)std::floor(x);
00160 int x2=(int)std::floor(x+1);
00161 float y2=coder->charge(*shape,x2,capId);
00162 float y1=coder->charge(*shape,x1,capId);
00163 frame[tbin] = (y2-y1)*(x-x1)+y1;
00164 }
00165 }
00166
00167 void HcalAmplifier::makeNoise (const HcalCholeskyMatrix & thisChanCholesky, int fFrames, double* fGauss, double* fNoise, int m) const {
00168 if(fFrames > 10) return;
00169
00170 for(int i = 0; i != 10; i++){
00171 for(int j = 0; j != 10; j++){
00172 fNoise[i] += thisChanCholesky.getValue(m,i,j) * fGauss[j];
00173 }
00174 }
00175 }
00176
00177 void HcalAmplifier::makeNoiseOld (HcalGenericDetId::HcalGenericSubdetector hcalSubDet, const HcalCalibrationWidths& width, int fFrames, double* fGauss, double* fNoise) const
00178 {
00179
00180
00181
00182
00183
00184 double s_xx_mean = 0.25 * (width.pedestal(0)*width.pedestal(0) +
00185 width.pedestal(1)*width.pedestal(1) +
00186 width.pedestal(2)*width.pedestal(2) +
00187 width.pedestal(3)*width.pedestal(3));
00188
00189
00190
00191
00192
00193 double s_xy_mean = -0.5 * s_xx_mean;
00194
00195
00196 if (hcalSubDet == HcalGenericDetId::HcalGenForward) s_xy_mean = 0.08 * s_xx_mean;
00197
00198 double term = s_xx_mean*s_xx_mean - 2.*s_xy_mean*s_xy_mean;
00199
00200 if (term < 0.) term = 1.e-50 ;
00201 double sigma = sqrt (0.5 * (s_xx_mean + sqrt(term)));
00202 double corr = sigma == 0. ? 0. : 0.5*s_xy_mean / sigma;
00203
00204 for (int i = 0; i < fFrames; i++) {
00205 fNoise [i] = fGauss[i]*sigma;
00206 if (i > 0) fNoise [i] += fGauss[i-1]*corr;
00207 if (i < fFrames-1) fNoise [i] += fGauss[i+1]*corr;
00208 }
00209 }
00210