CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/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    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()  // 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( !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    // OK, the "energy" in the hit could be a real energy, deposited energy,
00271    // or pe count.  This factor converts to photoelectrons
00272 
00273    double npe ( hit.energy()*parameters.simHitToPhotoelectrons( detId ) ) ;
00274 
00275    // do we need to doPoisson statistics for the photoelectrons?
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 ; // Units of c_light: mm/ns
00289 }