CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/SimCalorimetry/HcalSimAlgos/src/HcalAmplifier.cc

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.}; //big enough
00100      if(addNoise_)
00101      {
00102        double gauss [32]; //big enough
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.}; //big enough
00129   if(addNoise_)
00130   {
00131     double gauss [32]; //big enough
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);//*(values+capId); //*.70 goes here!
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++){ //fNoise is initialized to zero in function above! Must be zero before this step
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   // This is a simplified noise generation scheme using only the diagonal elements
00163   // (proposed by Salavat Abduline).
00164   // This is direct adaptation of the code in HcalPedestalWidth.cc
00165   
00166   // average over capId's
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   // Off-diagonal element approximation
00174   // In principle should come from averaging the values of elements (0.1), (1,2), (2,3), (3,0)
00175   // For now use the definition below (but keep structure of the code structure for development) 
00176   double s_xy_mean = -0.5 * s_xx_mean;
00177   // Use different parameter for HF to reproduce the noise rate after zero suppression.
00178   // Steven Won/Jim Hirschauer/Radek Ofierzynski 18.03.2010
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