CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/SimCalorimetry/EcalSimAlgos/src/EBHitResponse.cc

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 //   std::cout<<"******** Input APD Npe="<<npe<<", Efactor="<<energyFac
00088 //          <<", Energy="<<npe*energyFac
00089 //          <<", nonlFunc="<<nonlFunc( npe*energyFac )<<std::endl ;
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    // do we need to do Poisson statistics for the photoelectrons?
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 //   edm::LogError( "EBHitResponse" ) << "--- # photoelectrons for "
00133 /*   std::cout << "--- # photoelectrons for "
00134              << EBDetId( hit.id() ) 
00135              <<" is " << npe //;
00136              <<std::endl ;*/
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() ) // for now take only nonAPD hits
00203          {
00204             if( !m_apdOnly ) putAnalogSignal( hit ) ;
00205          }
00206          else // APD hits here
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             // now zero out for next time
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 }