CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/SimCalorimetry/CaloSimAlgos/src/CaloHitRespoNew.cc

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()  // blank out previously used elements
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() ,    // done and make ready to start over
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    // OK, the "energy" in the hit could be a real energy, deposited energy,
00268    // or pe count.  This factor converts to photoelectrons
00269 
00270    double npe ( hit.energy()*parameters.simHitToPhotoelectrons( detId ) ) ;
00271 
00272    // do we need to doPoisson statistics for the photoelectrons?
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 ; // Units of c_light: mm/ns
00286 }