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