CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/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 #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 //   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 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             // now zero out for next time
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() ) // for now take only nonAPD hits
00217      {
00218         if( !m_apdOnly ) putAnalogSignal( hit ) ;
00219      }
00220      else // APD hits here
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() ) // for now take only nonAPD hits
00258          {
00259             if( !m_apdOnly ) putAnalogSignal( hit ) ;
00260          }
00261          else // APD hits here
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             // now zero out for next time
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 }