CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2_patch1/src/SimTracker/SiStripDigitizer/plugins/SiTrivialInduceChargeOnStrips.cc

Go to the documentation of this file.
00001 #include "SiTrivialInduceChargeOnStrips.h"
00002 
00003 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h"
00004 #include "Geometry/CommonTopologies/interface/StripTopology.h"
00005 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetType.h"
00006 #include "DataFormats/Math/interface/approx_erf.h"
00007 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00008 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00009 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00010 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00011 #include "FWCore/Utilities/interface/Exception.h"
00012 
00013 #include <algorithm>
00014 #include <iostream>
00015 
00016 const int
00017 SiTrivialInduceChargeOnStrips::
00018 Ntypes = 14;
00019 
00020 const  std::string 
00021 SiTrivialInduceChargeOnStrips::
00022 type[Ntypes] = { "IB1", "IB2","OB1","OB2","W1a","W2a","W3a","W1b","W2b","W3b","W4","W5","W6","W7"};
00023 
00024 static 
00025 std::vector<std::vector<double> >
00026 fillSignalCoupling(const edm::ParameterSet& conf, int nTypes, const std::string* typeArray) {
00027   std::vector<std::vector<double> > signalCoupling;
00028   signalCoupling.reserve(nTypes);
00029   std::string mode = conf.getParameter<bool>("APVpeakmode") ? "Peak" : "Dec";
00030   for(int i=0; i<nTypes; ++i) {
00031     signalCoupling.push_back(conf.getParameter<std::vector<double> >("CouplingConstant"+mode+typeArray[i]));
00032   }
00033   return signalCoupling;
00034 }
00035 
00036 inline unsigned int 
00037 SiTrivialInduceChargeOnStrips::
00038 indexOf(const std::string& t) { return std::find( type, type + Ntypes, t) - type;}
00039 
00040 inline unsigned int
00041 SiTrivialInduceChargeOnStrips::
00042 typeOf(const StripGeomDetUnit& det) {
00043   DetId id = det.geographicalId();
00044   switch (det.specificType().subDetector()) {
00045   case GeomDetEnumerators::TIB: {return (TIBDetId(id).layer() < 3) ? indexOf("IB1") : indexOf("IB2");}
00046   case GeomDetEnumerators::TOB: {return (TOBDetId(id).layer() > 4) ? indexOf("OB1") : indexOf("OB2");}
00047   case GeomDetEnumerators::TID: {return indexOf("W1a") -1 + TIDDetId(id).ring();} //fragile: relies on ordering of 'type'
00048   case GeomDetEnumerators::TEC: {return indexOf("W1b") -1 + TECDetId(id).ring();} //fragile: relies on ordering of 'type'
00049   default: throw cms::Exception("Invalid subdetector") << id();
00050   }
00051 }
00052 
00053 SiTrivialInduceChargeOnStrips::
00054 SiTrivialInduceChargeOnStrips(const edm::ParameterSet& conf,double g) 
00055   : signalCoupling(fillSignalCoupling(conf, Ntypes, type)), Nsigma(3.), geVperElectron(g)  {
00056 }
00057 
00058 void 
00059 SiTrivialInduceChargeOnStrips::
00060 induce(const SiChargeCollectionDrifter::collection_type& collection_points, 
00061        const StripGeomDetUnit& det, 
00062        std::vector<double>& localAmplitudes, 
00063        size_t& recordMinAffectedStrip, 
00064        size_t& recordMaxAffectedStrip) const {
00065 
00066   const std::vector<double>& coupling = signalCoupling.at(typeOf(det));
00067   const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
00068   size_t Nstrips =  topology.nstrips();
00069 
00070   for (SiChargeCollectionDrifter::collection_type::const_iterator 
00071          signalpoint = collection_points.begin();  signalpoint != collection_points.end();  signalpoint++ ) {
00072     
00073     //In strip coordinates:
00074     double chargePosition = topology.strip(signalpoint->position());
00075     double chargeSpread = signalpoint->sigma() / topology.localPitch(signalpoint->position());
00076     
00077     size_t fromStrip  = size_t(std::max( 0,          int(std::floor( chargePosition - Nsigma*chargeSpread))));
00078     size_t untilStrip = size_t(std::min( Nstrips, size_t(std::ceil( chargePosition + Nsigma*chargeSpread) )));
00079     for (size_t strip = fromStrip;  strip < untilStrip; strip++) {
00080 
00081       double chargeDepositedOnStrip = chargeDeposited( strip, Nstrips, signalpoint->amplitude(), chargeSpread, chargePosition);
00082 
00083       size_t affectedFromStrip  = size_t(std::max( 0, int(strip - coupling.size() + 1)));
00084       size_t affectedUntilStrip = size_t(std::min( Nstrips, strip + coupling.size())   );  
00085       for (size_t affectedStrip = affectedFromStrip;  affectedStrip < affectedUntilStrip;  affectedStrip++) {
00086         localAmplitudes.at( affectedStrip ) += chargeDepositedOnStrip * coupling.at(abs( affectedStrip - strip )) ;
00087       }
00088 
00089       if( affectedFromStrip  < recordMinAffectedStrip ) recordMinAffectedStrip = affectedFromStrip;
00090       if( affectedUntilStrip > recordMaxAffectedStrip ) recordMaxAffectedStrip = affectedUntilStrip;
00091     }
00092   }
00093   return;
00094 }
00095 
00096 inline double
00097 SiTrivialInduceChargeOnStrips::
00098 chargeDeposited(size_t strip, size_t Nstrips, double amplitude, double chargeSpread, double chargePosition) const {
00099 
00100   double integralUpToStrip = (strip == 0)         ? 0. : ( approx_erf(   (strip-chargePosition)/chargeSpread/1.41421356237309515 ) );
00101   double integralUpToNext  = (strip+1 == Nstrips) ? 1. : ( approx_erf(   (strip+1-chargePosition)/chargeSpread/1.41421356237309515 ) );
00102   
00103   return  0.5 * (integralUpToNext - integralUpToStrip) * amplitude / geVperElectron;
00104 }