Go to the documentation of this file.00001 #include "SimCalorimetry/CaloSimAlgos/interface/CaloHitRespoNew.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 "FWCore/ServiceRegistry/interface/Service.h"
00012 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00013 #include "CLHEP/Random/RandPoissonQ.h"
00014 #include "CLHEP/Random/RandGaussQ.h"
00015 #include "FWCore/Utilities/interface/Exception.h"
00016 #include "FWCore/Utilities/interface/isFinite.h"
00017
00018 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00019 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00020 #include<iostream>
00021
00022
00023
00024 CaloHitRespoNew::CaloHitRespoNew( const CaloVSimParameterMap* parameterMap ,
00025 const CaloVShape* shape ,
00026 DetId detId ) :
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_RandPoisson ( 0 ) ,
00034 m_RandGauss ( 0 ) ,
00035 m_minBunch ( -10 ) ,
00036 m_maxBunch ( 10 ) ,
00037 m_phaseShift ( 1 )
00038 {
00039 setupSamples( detId ) ;
00040 }
00041
00042 CaloHitRespoNew::~CaloHitRespoNew()
00043 {
00044 delete m_RandPoisson ;
00045 delete m_RandGauss ;
00046 }
00047
00048 CLHEP::RandPoissonQ*
00049 CaloHitRespoNew::ranPois() const
00050 {
00051 if( 0 == m_RandPoisson )
00052 {
00053 edm::Service<edm::RandomNumberGenerator> rng ;
00054 if ( !rng.isAvailable() )
00055 {
00056 throw cms::Exception("Configuration")
00057 << "CaloHitRespoNew requires the RandomNumberGeneratorService\n"
00058 "which is not present in the configuration file. You must add the service\n"
00059 "in the configuration file or remove the modules that require it.";
00060 }
00061 m_RandPoisson = new CLHEP::RandPoissonQ( rng->getEngine() );
00062 }
00063 return m_RandPoisson ;
00064 }
00065
00066 CLHEP::RandGaussQ*
00067 CaloHitRespoNew::ranGauss() const
00068 {
00069 if( 0 == m_RandGauss )
00070 {
00071 edm::Service<edm::RandomNumberGenerator> rng ;
00072 if ( !rng.isAvailable() )
00073 {
00074 throw cms::Exception("Configuration")
00075 << "CaloHitRespoNew requires the RandomNumberGeneratorService\n"
00076 "which is not present in the configuration file. You must add the service\n"
00077 "in the configuration file or remove the modules that require it.";
00078 }
00079 m_RandGauss = new CLHEP::RandGaussQ( rng->getEngine() );
00080 }
00081 return m_RandGauss ;
00082 }
00083
00084 const CaloSimParameters*
00085 CaloHitRespoNew::params( const DetId& detId ) const
00086 {
00087 assert( 0 != m_parameterMap ) ;
00088 return &m_parameterMap->simParameters( detId ) ;
00089 }
00090
00091 const CaloVShape*
00092 CaloHitRespoNew::shape() const
00093 {
00094 assert( 0 != m_shape ) ;
00095 return m_shape ;
00096 }
00097
00098 const CaloSubdetectorGeometry*
00099 CaloHitRespoNew::geometry() const
00100 {
00101 assert( 0 != m_geometry ) ;
00102 return m_geometry ;
00103 }
00104
00105 void
00106 CaloHitRespoNew::setBunchRange( int minBunch ,
00107 int maxBunch )
00108 {
00109 m_minBunch = minBunch ;
00110 m_maxBunch = maxBunch ;
00111 }
00112
00113 void
00114 CaloHitRespoNew::setGeometry( const CaloSubdetectorGeometry* geometry )
00115 {
00116 m_geometry = geometry ;
00117 }
00118
00119 void
00120 CaloHitRespoNew::setPhaseShift( double phaseShift )
00121 {
00122 m_phaseShift = phaseShift ;
00123 }
00124
00125 double
00126 CaloHitRespoNew::phaseShift() const
00127 {
00128 return m_phaseShift ;
00129 }
00130
00131 void
00132 CaloHitRespoNew::setHitFilter( const CaloVHitFilter* filter)
00133 {
00134 m_hitFilter = filter ;
00135 }
00136
00137 void
00138 CaloHitRespoNew::setHitCorrection( const CaloVHitCorrection* hitCorrection)
00139 {
00140 m_hitCorrection = hitCorrection ;
00141 }
00142
00143 void
00144 CaloHitRespoNew::setPECorrection( const CaloVPECorrection* peCorrection )
00145 {
00146 m_PECorrection = peCorrection ;
00147 }
00148
00149 void
00150 CaloHitRespoNew::setRandomEngine( CLHEP::HepRandomEngine& engine ) const
00151 {
00152 m_RandPoisson = new CLHEP::RandPoissonQ( engine ) ;
00153 m_RandGauss = new CLHEP::RandGaussQ( engine ) ;
00154 }
00155
00156 const CaloSamples&
00157 CaloHitRespoNew::operator[]( unsigned int i ) const
00158 {
00159 assert( i < m_vSamp.size() ) ;
00160 return m_vSamp[ i ] ;
00161 }
00162
00163 unsigned int
00164 CaloHitRespoNew::samplesSize() const
00165 {
00166 return m_vSamp.size() ;
00167 }
00168
00169 void
00170 CaloHitRespoNew::setupSamples( const DetId& detId )
00171 {
00172 const CaloSimParameters& parameters ( *params( detId ) ) ;
00173
00174 const unsigned int rSize ( parameters.readoutFrameSize() ) ;
00175 const unsigned int nPre ( parameters.binOfMaximum() - 1 ) ;
00176
00177 m_vSamp = VecSam( CaloGenericDetId( detId ).sizeForDenseIndexing() ) ;
00178
00179 const unsigned int size ( m_vSamp.size() ) ;
00180
00181 for( unsigned int i ( 0 ) ; i != size ; ++i )
00182 {
00183 m_vSamp[ i ].setDetId( CaloGenericDetId( detId.det(), detId.subdetId(), i ) ) ;
00184 m_vSamp[ i ].setSize( rSize ) ;
00185 m_vSamp[ i ].setPresamples( nPre ) ;
00186 }
00187 }
00188
00189 void
00190 CaloHitRespoNew::blankOutUsedSamples()
00191 {
00192 const unsigned int size ( m_index.size() ) ;
00193
00194 for( unsigned int i ( 0 ) ; i != size ; ++i )
00195 {
00196 m_vSamp[ m_index[i] ].setBlank() ;
00197 }
00198 m_index.erase( m_index.begin() ,
00199 m_index.end() ) ;
00200 }
00201
00202 void
00203 CaloHitRespoNew::run( MixCollection<PCaloHit>& hits )
00204 {
00205 if( 0 != m_index.size() ) blankOutUsedSamples() ;
00206
00207 for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
00208 hitItr != hits.end() ; ++hitItr )
00209 {
00210 if(withinBunchRange(hitItr.bunch())) {
00211 add(*hitItr);
00212 }
00213
00214 }
00215 }
00216
00217 void
00218 CaloHitRespoNew::add( const PCaloHit& hit )
00219 {
00220 if( !edm::isNotFinite( hit.time() ) &&
00221 ( 0 == m_hitFilter ||
00222 m_hitFilter->accepts( hit ) ) ) putAnalogSignal( hit ) ;
00223 }
00224
00225 void
00226 CaloHitRespoNew::putAnalogSignal( const PCaloHit& hit )
00227 {
00228 const DetId detId ( hit.id() ) ;
00229
00230 const CaloSimParameters* parameters ( params( detId ) ) ;
00231
00232 const double signal ( analogSignalAmplitude( detId, hit.energy() ) ) ;
00233
00234 double time = hit.time();
00235
00236 if( m_hitCorrection ) {
00237 time += m_hitCorrection->delay( hit ) ;
00238 }
00239
00240 const double jitter ( time - timeOfFlight( detId ) ) ;
00241
00242 const double tzero = ( shape()->timeToRise()
00243 + parameters->timePhase()
00244 - jitter
00245 - BUNCHSPACE*( parameters->binOfMaximum()
00246 - m_phaseShift ) ) ;
00247 double binTime ( tzero ) ;
00248
00249 CaloSamples& result ( *findSignal( detId ) ) ;
00250
00251 const unsigned int rsize ( result.size() ) ;
00252
00253 for( unsigned int bin ( 0 ) ; bin != rsize ; ++bin )
00254 {
00255 result[ bin ] += (*shape())( binTime )*signal ;
00256 binTime += BUNCHSPACE;
00257 }
00258 }
00259
00260 CaloSamples*
00261 CaloHitRespoNew::findSignal( const DetId& detId )
00262 {
00263 CaloSamples& result ( m_vSamp[ CaloGenericDetId( detId ).denseIndex() ] ) ;
00264 if( result.isBlank() ) m_index.push_back( &result - &m_vSamp.front() ) ;
00265 return &result ;
00266 }
00267
00268 double
00269 CaloHitRespoNew::analogSignalAmplitude( const DetId& detId, float energy ) const
00270 {
00271 const CaloSimParameters& parameters ( *params( detId ) ) ;
00272
00273
00274
00275
00276 double npe ( energy*parameters.simHitToPhotoelectrons( detId ) ) ;
00277
00278
00279 if( parameters.doPhotostatistics() ) npe = ranPois()->fire( npe ) ;
00280
00281 if( 0 != m_PECorrection ) npe = m_PECorrection->correctPE( detId, npe ) ;
00282
00283 return npe ;
00284 }
00285
00286 double
00287 CaloHitRespoNew::timeOfFlight( const DetId& detId ) const
00288 {
00289 const CaloCellGeometry* cellGeometry ( geometry()->getGeometry( detId ) ) ;
00290 assert( 0 != cellGeometry ) ;
00291 return cellGeometry->getPosition().mag()*cm/c_light ;
00292 }