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