CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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 #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()  // blank out previously used elements
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() ,    // done and make ready to start over
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    // OK, the "energy" in the hit could be a real energy, deposited energy,
00274    // or pe count.  This factor converts to photoelectrons
00275 
00276    double npe ( energy*parameters.simHitToPhotoelectrons( detId ) ) ;
00277 
00278    // do we need to doPoisson statistics for the photoelectrons?
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 ; // Units of c_light: mm/ns
00292 }