CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch2/src/SimCalorimetry/EcalSimAlgos/src/EcalHitResponse.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/EcalSimAlgos/interface/EcalHitResponse.h" 
00002 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVSimParameterMap.h"
00003 #include "SimCalorimetry/CaloSimAlgos/interface/CaloSimParameters.h"
00004 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVShape.h"
00005 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitCorrection.h"
00006 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitFilter.h"
00007 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVPECorrection.h"
00008 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00009 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00010 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00011 #include "CalibCalorimetry/EcalLaserCorrection/interface/EcalLaserDbService.h"
00012 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00013 #include "FWCore/ServiceRegistry/interface/Service.h"
00014 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00015 #include "CLHEP/Random/RandPoissonQ.h"
00016 #include "CLHEP/Random/RandGaussQ.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 
00019 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00020 #include "CLHEP/Units/GlobalSystemOfUnits.h" 
00021 #include <iostream>
00022 
00023 
00024 
00025 EcalHitResponse::EcalHitResponse( const CaloVSimParameterMap* parameterMap ,
00026                                   const CaloVShape*           shape         ) :
00027    m_parameterMap    ( parameterMap ) ,
00028    m_shape           ( shape        ) ,
00029    m_hitCorrection   ( 0            ) ,
00030    m_PECorrection    ( 0            ) ,
00031    m_hitFilter       ( 0            ) ,
00032    m_geometry        ( 0            ) ,
00033    m_lasercals       ( 0            ) ,
00034    m_RandPoisson     ( 0            ) ,
00035    m_RandGauss       ( 0            ) ,
00036    m_minBunch        ( -10          ) ,
00037    m_maxBunch        (  10          ) ,
00038    m_phaseShift      ( 1            ) ,
00039    m_iTime           ( 0            ) ,
00040    m_useLCcorrection ( 0            )
00041 {
00042    edm::Service<edm::RandomNumberGenerator> rng ;
00043    if ( !rng.isAvailable() ) 
00044    {
00045       throw cms::Exception("Configuration")
00046          << "EcalHitResponse requires the RandomNumberGeneratorService\n"
00047          "which is not present in the configuration file.  You must add the service\n"
00048          "in the configuration file or remove the modules that require it.";
00049    }
00050    m_RandPoisson = new CLHEP::RandPoissonQ( rng->getEngine() ) ;
00051    m_RandGauss   = new CLHEP::RandGaussQ(   rng->getEngine() ) ;
00052 }
00053 
00054 EcalHitResponse::~EcalHitResponse()
00055 {
00056    delete m_RandPoisson ;
00057    delete m_RandGauss   ;
00058 }
00059 
00060 CLHEP::RandPoissonQ* 
00061 EcalHitResponse::ranPois() const
00062 {
00063    return m_RandPoisson ;
00064 }
00065 
00066 CLHEP::RandGaussQ* 
00067 EcalHitResponse::ranGauss() const
00068 {
00069    return m_RandGauss ;
00070 }
00071 
00072 const CaloSimParameters*
00073 EcalHitResponse::params( const DetId& detId ) const
00074 {
00075    assert( 0 != m_parameterMap ) ;
00076    return &m_parameterMap->simParameters( detId ) ;
00077 }
00078 
00079 const CaloVShape*
00080 EcalHitResponse::shape() const
00081 {
00082    assert( 0 != m_shape ) ;
00083    return m_shape ;
00084 }
00085 
00086 const CaloSubdetectorGeometry*
00087 EcalHitResponse::geometry() const
00088 {
00089    assert( 0 != m_geometry ) ;
00090    return m_geometry ;
00091 }
00092 
00093 void 
00094 EcalHitResponse::setBunchRange( int minBunch , 
00095                                 int maxBunch  ) 
00096 {
00097    m_minBunch = minBunch ;
00098    m_maxBunch = maxBunch ;
00099 }
00100 
00101 void 
00102 EcalHitResponse::setGeometry( const CaloSubdetectorGeometry* geometry )
00103 {
00104    m_geometry = geometry ;
00105 }
00106 
00107 void 
00108 EcalHitResponse::setPhaseShift( double phaseShift )
00109 {
00110    m_phaseShift = phaseShift ;
00111 }
00112 
00113 double
00114 EcalHitResponse::phaseShift() const
00115 {
00116    return m_phaseShift ;
00117 }
00118 
00119 void 
00120 EcalHitResponse::setHitFilter( const CaloVHitFilter* filter)
00121 {
00122    m_hitFilter = filter ;
00123 }
00124 
00125 void 
00126 EcalHitResponse::setHitCorrection( const CaloVHitCorrection* hitCorrection)
00127 {
00128    m_hitCorrection = hitCorrection ;
00129 }
00130 
00131 void 
00132 EcalHitResponse::setPECorrection( const CaloVPECorrection* peCorrection )
00133 {
00134    m_PECorrection = peCorrection ;
00135 }
00136 
00137 void
00138 EcalHitResponse::setEventTime(const edm::TimeValue_t& iTime)
00139 {
00140   m_iTime = iTime;
00141 }
00142 
00143 void
00144 EcalHitResponse::setLaserConstants(const EcalLaserDbService* laser, bool& useLCcorrection)
00145 {
00146   m_lasercals = laser;
00147   m_useLCcorrection = useLCcorrection;
00148 }
00149 
00150 void 
00151 EcalHitResponse::blankOutUsedSamples()  // blank out previously used elements
00152 {
00153    const unsigned int size ( m_index.size() ) ;
00154 
00155    for( unsigned int i ( 0 ) ; i != size ; ++i )
00156    {
00157       vSamAll( m_index[i] )->setZero() ;
00158    }
00159    m_index.erase( m_index.begin() ,    // done and make ready to start over
00160                   m_index.end()    ) ;
00161 }
00162 
00163 void 
00164 EcalHitResponse::run( MixCollection<PCaloHit>& hits ) 
00165 {
00166    blankOutUsedSamples() ;
00167 
00168    for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
00169         hitItr != hits.end() ; ++hitItr )
00170    {
00171       const PCaloHit& hit ( *hitItr ) ;
00172       const int bunch ( hitItr.bunch() ) ;
00173       if( m_minBunch <= bunch  &&
00174           m_maxBunch >= bunch  &&
00175           !isnan( hit.time() ) &&
00176           ( 0 == m_hitFilter ||
00177             m_hitFilter->accepts( hit ) ) ) putAnalogSignal( hit ) ;
00178    }
00179 }
00180 
00181 void
00182 EcalHitResponse::putAnalogSignal( const PCaloHit& inputHit )
00183 {
00184    PCaloHit hit ( inputHit ) ;
00185 
00186    if( 0 != m_hitCorrection ) m_hitCorrection->correct( hit ) ;
00187 
00188    const DetId detId ( hit.id() ) ;
00189 
00190    const CaloSimParameters* parameters ( params( detId ) ) ;
00191 
00192    const double signal ( analogSignalAmplitude( hit ) ) ;
00193 
00194    const double jitter ( hit.time() - timeOfFlight( detId ) ) ;
00195 
00196    const double tzero = ( shape()->timeToRise()
00197                           + parameters->timePhase() 
00198                           - jitter 
00199                           - BUNCHSPACE*( parameters->binOfMaximum()
00200                                          - m_phaseShift             ) ) ;
00201    double binTime ( tzero ) ;
00202 
00203    EcalSamples& result ( *findSignal( detId ) ) ;
00204 
00205    const unsigned int rsize ( result.size() ) ;
00206 
00207    for( unsigned int bin ( 0 ) ; bin != rsize ; ++bin )
00208    {
00209       result[ bin ] += (*shape())( binTime )*signal ;
00210       binTime += BUNCHSPACE ;
00211    }
00212 }
00213 
00214 double
00215 EcalHitResponse::findLaserConstant(const DetId& detId) const
00216 {
00217   const edm::Timestamp& evtTimeStamp = edm::Timestamp(m_iTime);
00218   return (m_lasercals->getLaserCorrection(detId, evtTimeStamp));
00219 }
00220 
00221 
00222 EcalHitResponse::EcalSamples* 
00223 EcalHitResponse::findSignal( const DetId& detId )
00224 {
00225    const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
00226    EcalSamples* result ( vSamAll( di ) ) ;
00227    if( result->zero() ) m_index.push_back( di ) ;
00228    return result ;
00229 }
00230 
00231 double 
00232 EcalHitResponse::analogSignalAmplitude( const PCaloHit& hit ) const
00233 {
00234    const DetId& detId ( hit.id() ) ;
00235 
00236    const CaloSimParameters& parameters ( *params( detId ) ) ;
00237 
00238    // OK, the "energy" in the hit could be a real energy, deposited energy,
00239    // or pe count.  This factor converts to photoelectrons
00240 
00241    float lasercalib = 1.;
00242    if(m_useLCcorrection == true && detId.subdetId() != 3) {
00243      lasercalib = findLaserConstant(detId);
00244    }
00245 
00246    double npe ( hit.energy()/lasercalib*parameters.simHitToPhotoelectrons( detId ) ) ;
00247 
00248    // do we need to doPoisson statistics for the photoelectrons?
00249    if( parameters.doPhotostatistics() ) npe = ranPois()->fire( npe ) ;
00250 
00251    if( 0 != m_PECorrection ) npe = m_PECorrection->correctPE( detId, npe ) ;
00252 
00253    return npe ;
00254 }
00255 
00256 double 
00257 EcalHitResponse::timeOfFlight( const DetId& detId ) const 
00258 {
00259    const CaloCellGeometry* cellGeometry ( geometry()->getGeometry( detId ) ) ;
00260    assert( 0 != cellGeometry ) ;
00261    return cellGeometry->getPosition().mag()*cm/c_light ; // Units of c_light: mm/ns
00262 }
00263 
00264 void 
00265 EcalHitResponse::add( const EcalSamples* pSam )
00266 {
00267    EcalSamples& sam ( *findSignal( pSam->id() ) ) ;
00268    sam += (*pSam) ;
00269 }
00270 
00271 int 
00272 EcalHitResponse::minBunch() const 
00273 {
00274    return m_minBunch ; 
00275 }
00276 
00277 int 
00278 EcalHitResponse::maxBunch() const 
00279 {
00280    return m_maxBunch ; 
00281 }
00282 
00283 EcalHitResponse::VecInd& 
00284 EcalHitResponse::index() 
00285 {
00286    return m_index ; 
00287 }
00288 
00289 const EcalHitResponse::VecInd& 
00290 EcalHitResponse::index() const
00291 {
00292    return m_index ; 
00293 }
00294 
00295 const CaloVHitFilter* 
00296 EcalHitResponse::hitFilter() const 
00297 { 
00298    return m_hitFilter ; 
00299 }
00300 
00301 const EcalHitResponse::EcalSamples* 
00302 EcalHitResponse::findDetId( const DetId& detId ) const
00303 {
00304    const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
00305    return vSamAll( di ) ;
00306 }