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()
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() ,
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
00239
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
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 ;
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 }