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
00012
00013 EBHitResponse::EBHitResponse( const CaloVSimParameterMap* parameterMap ,
00014 const CaloVShape* shape ,
00015 bool apdOnly ,
00016 const APDSimParameters* apdPars = 0 ,
00017 const CaloVShape* apdShape = 0 ) :
00018
00019 EcalHitResponse( parameterMap, shape ) ,
00020
00021 m_apdOnly ( apdOnly ) ,
00022 m_apdPars ( apdPars ) ,
00023 m_apdShape ( apdShape ) ,
00024 m_timeOffVec ( kNOffsets, apdParameters()->timeOffset() ) ,
00025 pcub ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[0] ) ,
00026 pqua ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[1] ) ,
00027 plin ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[2] ) ,
00028 pcon ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[3] ) ,
00029 pelo ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[4] ) ,
00030 pehi ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[5] ) ,
00031 pasy ( 0 == apdPars ? 0 : apdParameters()->nonlParms()[6] ) ,
00032 pext ( 0 == apdPars ? 0 : nonlFunc1( pelo ) ) ,
00033 poff ( 0 == apdPars ? 0 : nonlFunc1( pehi ) ) ,
00034 pfac ( 0 == apdPars ? 0 : ( pasy - poff )*2./M_PI )
00035 {
00036 for( unsigned int i ( 0 ) ; i != kNOffsets ; ++i )
00037 {
00038 m_timeOffVec[ i ] +=
00039 ranGauss()->fire( 0 , apdParameters()->timeOffWidth() ) ;
00040 }
00041
00042 const EBDetId detId ( EBDetId::detIdFromDenseIndex( 0 ) ) ;
00043 const CaloSimParameters& parameters ( parameterMap->simParameters( detId ) ) ;
00044
00045 const unsigned int rSize ( parameters.readoutFrameSize() ) ;
00046 const unsigned int nPre ( parameters.binOfMaximum() - 1 ) ;
00047
00048 const unsigned int size ( EBDetId::kSizeForDenseIndexing ) ;
00049
00050 m_vSam.reserve( size ) ;
00051
00052 for( unsigned int i ( 0 ) ; i != size ; ++i )
00053 {
00054 m_vSam.push_back(
00055 EBSamples( 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
00178 void
00179 EBHitResponse::run( MixCollection<PCaloHit>& hits )
00180 {
00181 if( 0 != index().size() ) blankOutUsedSamples() ;
00182
00183 const unsigned int bSize ( EBDetId::kSizeForDenseIndexing ) ;
00184
00185 if( 0 == m_apdNpeVec.size() )
00186 {
00187 m_apdNpeVec = std::vector<double>( bSize, (double)0.0 ) ;
00188 m_apdTimeVec = std::vector<double>( bSize, (double)0.0 ) ;
00189 }
00190
00191 for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
00192 hitItr != hits.end() ; ++hitItr )
00193 {
00194 const PCaloHit& hit ( *hitItr ) ;
00195 const int bunch ( hitItr.bunch() ) ;
00196 if( minBunch() <= bunch &&
00197 maxBunch() >= bunch &&
00198 !isnan( hit.time() ) &&
00199 ( 0 == hitFilter() ||
00200 hitFilter()->accepts( hit ) ) )
00201 {
00202 if( 0 == hit.depth() )
00203 {
00204 if( !m_apdOnly ) putAnalogSignal( hit ) ;
00205 }
00206 else
00207 {
00208 if( apdParameters()->addToBarrel() ||
00209 m_apdOnly )
00210 {
00211 const unsigned int icell ( EBDetId( hit.id() ).denseIndex() ) ;
00212 m_apdNpeVec[ icell ] += apdSignalAmplitude( hit ) ;
00213 if( 0 == m_apdTimeVec[ icell ] ) m_apdTimeVec[ icell ] = hit.time() ;
00214 }
00215 }
00216 }
00217 }
00218
00219 if( apdParameters()->addToBarrel() ||
00220 m_apdOnly )
00221 {
00222 for( unsigned int i ( 0 ) ; i != bSize ; ++i )
00223 {
00224 if( 0 < m_apdNpeVec[i] )
00225 {
00226 putAPDSignal( EBDetId::detIdFromDenseIndex( i ),
00227 m_apdNpeVec[i] ,
00228 m_apdTimeVec[i] ) ;
00229
00230
00231 m_apdNpeVec[i] = 0. ;
00232 m_apdTimeVec[i] = 0. ;
00233 }
00234 }
00235 }
00236 }
00237
00238 unsigned int
00239 EBHitResponse::samplesSize() const
00240 {
00241 return m_vSam.size() ;
00242 }
00243
00244 unsigned int
00245 EBHitResponse::samplesSizeAll() const
00246 {
00247 return m_vSam.size() ;
00248 }
00249
00250 const EcalHitResponse::EcalSamples*
00251 EBHitResponse::operator[]( unsigned int i ) const
00252 {
00253 return &m_vSam[ i ] ;
00254 }
00255
00256 EcalHitResponse::EcalSamples*
00257 EBHitResponse::operator[]( unsigned int i )
00258 {
00259 return &m_vSam[ i ] ;
00260 }
00261
00262 EcalHitResponse::EcalSamples*
00263 EBHitResponse::vSam( unsigned int i )
00264 {
00265 return &m_vSam[ i ] ;
00266 }
00267
00268 EcalHitResponse::EcalSamples*
00269 EBHitResponse::vSamAll( unsigned int i )
00270 {
00271 return &m_vSam[ i ] ;
00272 }
00273
00274 const EcalHitResponse::EcalSamples*
00275 EBHitResponse::vSamAll( unsigned int i ) const
00276 {
00277 return &m_vSam[ i ] ;
00278 }