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