Go to the documentation of this file.00001 #include "SimCalorimetry/EcalSimAlgos/interface/EBHitResponse.h"
00002 #include "SimCalorimetry/EcalSimAlgos/interface/APDSimParameters.h"
00003 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVSimParameterMap.h"
00004 #include "SimCalorimetry/CaloSimAlgos/interface/CaloSimParameters.h"
00005 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitFilter.h"
00006 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVShape.h"
00007 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00008 #include "CLHEP/Random/RandPoissonQ.h"
00009 #include "CLHEP/Random/RandGaussQ.h"
00010 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00011 #include "FWCore/Utilities/interface/isFinite.h"
00012
00013
00014 EBHitResponse::EBHitResponse( const CaloVSimParameterMap* parameterMap ,
00015 const CaloVShape* shape ,
00016 bool apdOnly ,
00017 const APDSimParameters* apdPars = 0 ,
00018 const CaloVShape* apdShape = 0 ) :
00019
00020 EcalHitResponse( parameterMap, shape ) ,
00021
00022 m_apdOnly ( apdOnly ) ,
00023 m_apdPars ( apdPars ) ,
00024 m_apdShape ( apdShape ) ,
00025 m_timeOffVec ( kNOffsets, apdParameters()->timeOffset() ) ,
00026 pcub ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[0] ) ,
00027 pqua ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[1] ) ,
00028 plin ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[2] ) ,
00029 pcon ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[3] ) ,
00030 pelo ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[4] ) ,
00031 pehi ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[5] ) ,
00032 pasy ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[6] ) ,
00033 pext ( 0 == apdPars ? 0 : nonlFunc1( pelo ) ) ,
00034 poff ( 0 == apdPars ? 0 : nonlFunc1( pehi ) ) ,
00035 pfac ( 0 == apdPars ? 0 : ( pasy - poff )*2./M_PI )
00036 {
00037 for( unsigned int i ( 0 ) ; i != kNOffsets ; ++i )
00038 {
00039 m_timeOffVec[ i ] +=
00040 ranGauss()->fire( 0 , apdParameters()->timeOffWidth() ) ;
00041 }
00042
00043 const EBDetId detId ( EBDetId::detIdFromDenseIndex( 0 ) ) ;
00044 const CaloSimParameters& parameters ( parameterMap->simParameters( detId ) ) ;
00045
00046 const unsigned int rSize ( parameters.readoutFrameSize() ) ;
00047 const unsigned int nPre ( parameters.binOfMaximum() - 1 ) ;
00048
00049 const unsigned int size ( EBDetId::kSizeForDenseIndexing ) ;
00050
00051 m_vSam.reserve( size ) ;
00052
00053 for( unsigned int i ( 0 ) ; i != size ; ++i )
00054 {
00055 m_vSam.emplace_back(CaloGenericDetId( detId.det(), detId.subdetId(), i ) ,
00056 rSize, nPre );
00057 }
00058 }
00059
00060 EBHitResponse::~EBHitResponse()
00061 {
00062 }
00063
00064 const APDSimParameters*
00065 EBHitResponse::apdParameters() const
00066 {
00067 assert ( 0 != m_apdPars ) ;
00068 return m_apdPars ;
00069 }
00070
00071 const CaloVShape*
00072 EBHitResponse::apdShape() const
00073 {
00074 assert( 0 != m_apdShape ) ;
00075 return m_apdShape ;
00076 }
00077
00078 void
00079 EBHitResponse::putAPDSignal( const DetId& detId ,
00080 double npe ,
00081 double time )
00082 {
00083 const CaloSimParameters& parameters ( *params( detId ) ) ;
00084
00085 const double energyFac ( 1./parameters.simHitToPhotoelectrons( detId ) ) ;
00086
00087
00088
00089
00090
00091 const double signal ( npe*nonlFunc( npe*energyFac ) ) ;
00092
00093 const double jitter ( time - timeOfFlight( detId ) ) ;
00094
00095 const double tzero ( apdShape()->timeToRise()
00096 - jitter
00097 - offsets()[ EBDetId( detId ).denseIndex()%kNOffsets ]
00098 - BUNCHSPACE*( parameters.binOfMaximum()
00099 - phaseShift() ) ) ;
00100
00101 double binTime ( tzero ) ;
00102
00103 EcalSamples& result ( *findSignal( detId ) );
00104
00105 for( unsigned int bin ( 0 ) ; bin != result.size(); ++bin )
00106 {
00107 result[bin] += (*apdShape())(binTime)*signal ;
00108 binTime += BUNCHSPACE ;
00109 }
00110 }
00111
00112 double
00113 EBHitResponse::apdSignalAmplitude( const PCaloHit& hit ) const
00114 {
00115 assert( 1 == hit.depth() ||
00116 2 == hit.depth() ) ;
00117
00118 double npe ( hit.energy()*( 2 == hit.depth() ?
00119 apdParameters()->simToPELow() :
00120 apdParameters()->simToPEHigh() ) ) ;
00121
00122
00123 if( apdParameters()->doPEStats() &&
00124 !m_apdOnly ) npe = ranPois()->fire( npe ) ;
00125
00126 assert( 0 != m_intercal ) ;
00127 double fac ( 1 ) ;
00128 findIntercalibConstant( hit.id(), fac ) ;
00129
00130 npe *= fac ;
00131
00132
00133
00134
00135
00136
00137
00138 return npe ;
00139 }
00140
00141 void
00142 EBHitResponse::setIntercal( const EcalIntercalibConstantsMC* ical )
00143 {
00144 m_intercal = ical ;
00145 }
00146
00147 void
00148 EBHitResponse::findIntercalibConstant( const DetId& detId,
00149 double& icalconst ) const
00150 {
00151 EcalIntercalibConstantMC thisconst ( 1. ) ;
00152
00153 if( 0 == m_intercal )
00154 {
00155 edm::LogError( "EBHitResponse" ) <<
00156 "No intercal constant defined for EBHitResponse" ;
00157 }
00158 else
00159 {
00160 const EcalIntercalibConstantMCMap& icalMap ( m_intercal->getMap() ) ;
00161 EcalIntercalibConstantMCMap::const_iterator icalit ( icalMap.find( detId ) ) ;
00162 if( icalit != icalMap.end() )
00163 {
00164 thisconst = *icalit ;
00165 if ( thisconst == 0. ) thisconst = 1. ;
00166 }
00167 else
00168 {
00169 edm::LogError("EBHitResponse") << "No intercalib const found for xtal "
00170 << detId.rawId()
00171 << "! something wrong with EcalIntercalibConstants in your DB? ";
00172 }
00173 }
00174 icalconst = thisconst ;
00175 }
00176
00177 void
00178 EBHitResponse::initializeHits() {
00179 if( 0 != index().size() ) blankOutUsedSamples() ;
00180
00181 const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
00182
00183 if( 0 == m_apdNpeVec.size() )
00184 {
00185 m_apdNpeVec = std::vector<double>( bSize, (double)0.0 ) ;
00186 m_apdTimeVec = std::vector<double>( bSize, (double)0.0 ) ;
00187 }
00188 }
00189
00190 void
00191 EBHitResponse::finalizeHits() {
00192 const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
00193 if( apdParameters()->addToBarrel() ||
00194 m_apdOnly )
00195 {
00196 for( unsigned int i ( 0 ) ; i != bSize ; ++i )
00197 {
00198 if( 0 < m_apdNpeVec[i] )
00199 {
00200 putAPDSignal( EBDetId::detIdFromDenseIndex( i ),
00201 m_apdNpeVec[i] ,
00202 m_apdTimeVec[i] ) ;
00203
00204
00205 m_apdNpeVec[i] = 0. ;
00206 m_apdTimeVec[i] = 0. ;
00207 }
00208 }
00209 }
00210 }
00211
00212 void
00213 EBHitResponse::add( const PCaloHit& hit )
00214 {
00215 if (!edm::isNotFinite( hit.time() ) && ( 0 == hitFilter() || hitFilter()->accepts( hit ) ) ) {
00216 if( 0 == hit.depth() )
00217 {
00218 if( !m_apdOnly ) putAnalogSignal( hit ) ;
00219 }
00220 else
00221 {
00222 if( apdParameters()->addToBarrel() ||
00223 m_apdOnly )
00224 {
00225 const unsigned int icell ( EBDetId( hit.id() ).denseIndex() ) ;
00226 m_apdNpeVec[ icell ] += apdSignalAmplitude( hit ) ;
00227 if( 0 == m_apdTimeVec[ icell ] ) m_apdTimeVec[ icell ] = hit.time() ;
00228 }
00229 }
00230 }
00231 }
00232
00233 void
00234 EBHitResponse::run( MixCollection<PCaloHit>& hits )
00235 {
00236 if( 0 != index().size() ) blankOutUsedSamples() ;
00237
00238 const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
00239
00240 if( 0 == m_apdNpeVec.size() )
00241 {
00242 m_apdNpeVec = std::vector<double>( bSize, (double)0.0 ) ;
00243 m_apdTimeVec = std::vector<double>( bSize, (double)0.0 ) ;
00244 }
00245
00246 for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
00247 hitItr != hits.end() ; ++hitItr )
00248 {
00249 const PCaloHit& hit ( *hitItr ) ;
00250 const int bunch ( hitItr.bunch() ) ;
00251 if( minBunch() <= bunch &&
00252 maxBunch() >= bunch &&
00253 !edm::isNotFinite( hit.time() ) &&
00254 ( 0 == hitFilter() ||
00255 hitFilter()->accepts( hit ) ) )
00256 {
00257 if( 0 == hit.depth() )
00258 {
00259 if( !m_apdOnly ) putAnalogSignal( hit ) ;
00260 }
00261 else
00262 {
00263 if( apdParameters()->addToBarrel() ||
00264 m_apdOnly )
00265 {
00266 const unsigned int icell ( EBDetId( hit.id() ).denseIndex() ) ;
00267 m_apdNpeVec[ icell ] += apdSignalAmplitude( hit ) ;
00268 if( 0 == m_apdTimeVec[ icell ] ) m_apdTimeVec[ icell ] = hit.time() ;
00269 }
00270 }
00271 }
00272 }
00273
00274 if( apdParameters()->addToBarrel() ||
00275 m_apdOnly )
00276 {
00277 for( unsigned int i ( 0 ) ; i != bSize ; ++i )
00278 {
00279 if( 0 < m_apdNpeVec[i] )
00280 {
00281 putAPDSignal( EBDetId::detIdFromDenseIndex( i ),
00282 m_apdNpeVec[i] ,
00283 m_apdTimeVec[i] ) ;
00284
00285
00286 m_apdNpeVec[i] = 0. ;
00287 m_apdTimeVec[i] = 0. ;
00288 }
00289 }
00290 }
00291 }
00292
00293 unsigned int
00294 EBHitResponse::samplesSize() const
00295 {
00296 return m_vSam.size() ;
00297 }
00298
00299 unsigned int
00300 EBHitResponse::samplesSizeAll() const
00301 {
00302 return m_vSam.size() ;
00303 }
00304
00305 const EcalHitResponse::EcalSamples*
00306 EBHitResponse::operator[]( unsigned int i ) const
00307 {
00308 return &m_vSam[ i ] ;
00309 }
00310
00311 EcalHitResponse::EcalSamples*
00312 EBHitResponse::operator[]( unsigned int i )
00313 {
00314 return &m_vSam[ i ] ;
00315 }
00316
00317 EcalHitResponse::EcalSamples*
00318 EBHitResponse::vSam( unsigned int i )
00319 {
00320 return &m_vSam[ i ] ;
00321 }
00322
00323 EcalHitResponse::EcalSamples*
00324 EBHitResponse::vSamAll( unsigned int i )
00325 {
00326 return &m_vSam[ i ] ;
00327 }
00328
00329 const EcalHitResponse::EcalSamples*
00330 EBHitResponse::vSamAll( unsigned int i ) const
00331 {
00332 return &m_vSam[ i ] ;
00333 }