Go to the documentation of this file.00001 #include "RecoLocalTracker/SiStripRecHitConverter/interface/StripCPE.h"
00002 #include "Geometry/CommonTopologies/interface/StripTopology.h"
00003 #include "Geometry/CommonTopologies/interface/RadialStripTopology.h"
00004 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetType.h"
00005 #include "boost/bind.hpp"
00006 #include "boost/lambda/lambda.hpp"
00007 #include <algorithm>
00008 #include<cmath>
00009 #include<cassert>
00010
00011 StripCPE::StripCPE( edm::ParameterSet & conf,
00012 const MagneticField& mag,
00013 const TrackerGeometry& geom,
00014 const SiStripLorentzAngle& LorentzAngle,
00015 const SiStripConfObject& confObj,
00016 const SiStripLatency& latency)
00017 : peakMode_(latency.singleReadOutMode() == 1),
00018 geom_(geom),
00019 magfield_(mag),
00020 LorentzAngleMap_(LorentzAngle)
00021 {
00022 typedef std::map<std::string,SiStripDetId::ModuleGeometry> map_t;
00023 map_t modules;
00024 modules["IB1"]=SiStripDetId::IB1;
00025 modules["IB2"]=SiStripDetId::IB2;
00026 modules["OB1"]=SiStripDetId::OB1;
00027 modules["OB2"]=SiStripDetId::OB2;
00028 modules["W1A"]=SiStripDetId::W1A;
00029 modules["W2A"]=SiStripDetId::W2A;
00030 modules["W3A"]=SiStripDetId::W3A;
00031 modules["W1B"]=SiStripDetId::W1B;
00032 modules["W2B"]=SiStripDetId::W2B;
00033 modules["W3B"]=SiStripDetId::W3B;
00034 modules["W4"] =SiStripDetId::W4;
00035 modules["W5"] =SiStripDetId::W5;
00036 modules["W6"] =SiStripDetId::W6;
00037 modules["W7"] =SiStripDetId::W7;
00038
00039 const unsigned size = max_element( modules.begin(),modules.end(),
00040 boost::bind(&map_t::value_type::second,boost::lambda::_1) <
00041 boost::bind(&map_t::value_type::second,boost::lambda::_2) )->second + 1;
00042 shift.resize(size);
00043 xtalk1.resize(size);
00044 xtalk2.resize(size);
00045
00046 for(map_t::const_iterator it=modules.begin(); it!=modules.end(); it++) {
00047 const std::string
00048 modeS(peakMode_?"Peak":"Deco"),
00049 shiftS( "shift_" + it->first + modeS ),
00050 xtalk1S("xtalk1_" + it->first + modeS ),
00051 xtalk2S("xtalk2_" + it->first + modeS );
00052
00053 if(!confObj.isParameter(shiftS)) throw cms::Exception("SiStripConfObject does not contain: ") << shiftS;
00054 if(!confObj.isParameter(xtalk1S)) throw cms::Exception("SiStripConfObject does not contain: ") << xtalk1S;
00055 if(!confObj.isParameter(xtalk2S)) throw cms::Exception("SiStripConfObject does not contain: ") << xtalk2S;
00056
00057 shift[it->second] = confObj.get<double>(shiftS);
00058 xtalk1[it->second] = confObj.get<double>(xtalk1S);
00059 xtalk2[it->second] = confObj.get<double>(xtalk2S);
00060 }
00061
00062 fillParams();
00063
00064 }
00065
00066 StripClusterParameterEstimator::LocalValues StripCPE::
00067 localParameters( const SiStripCluster& cluster, const GeomDetUnit& det) const {
00068 StripCPE::Param const & p = param(det);
00069 const float barycenter = cluster.barycenter();
00070 const float fullProjection = p.coveredStrips( p.drift + LocalVector(0,0,-p.thickness), LocalPoint(barycenter,0,0));
00071 const float strip = barycenter - 0.5f * (1-shift[p.moduleGeom]) * fullProjection;
00072
00073 return std::make_pair( p.topology->localPosition(strip),
00074 p.topology->localError(strip, 1.f/12.f) );
00075 }
00076
00077 float StripCPE::Param::
00078 coveredStrips(const LocalVector& lvec, const LocalPoint& lpos) const {
00079 return
00080 ( topology->measurementPosition(lpos + 0.5f*lvec)
00081 - topology->measurementPosition(lpos - 0.5f*lvec)).x();
00082 }
00083
00084 LocalVector StripCPE::
00085 driftDirection(const StripGeomDetUnit* det) const {
00086 LocalVector lbfield = (det->surface()).toLocal(magfield_.inTesla(det->surface().position()));
00087
00088 float tanLorentzAnglePerTesla = LorentzAngleMap_.getLorentzAngle(det->geographicalId().rawId());
00089
00090 float dir_x = -tanLorentzAnglePerTesla * lbfield.y();
00091 float dir_y = tanLorentzAnglePerTesla * lbfield.x();
00092 float dir_z = 1.f;
00093
00094 return LocalVector(dir_x,dir_y,dir_z);
00095 }
00096
00097
00098 void
00099 StripCPE::fillParams() {
00100 m_off = geom_.offsetDU(GeomDetEnumerators::TIB);
00101 auto const & dus = geom_.detUnits();
00102 m_Params.resize(dus.size()-m_off);
00103 for (auto i=m_off; i!=dus.size();++i) {
00104 auto & p= m_Params[i-m_off];
00105 const StripGeomDetUnit * stripdet=(const StripGeomDetUnit*)(dus[i]);
00106 assert(stripdet->index()==int(i));
00107 assert(stripdet->geographicalId().subdetId()>1);
00108
00109 const Bounds& bounds = stripdet->specificSurface().bounds();
00110 p.maxLength = std::sqrt( std::pow(bounds.length(),2.f)+std::pow(bounds.width(),2.f) );
00111 p.thickness = bounds.thickness();
00112 p.drift = driftDirection(stripdet) * p.thickness;
00113 p.topology=(StripTopology*)(&stripdet->topology());
00114 p.nstrips = p.topology->nstrips();
00115 p.moduleGeom = SiStripDetId(stripdet->geographicalId()).moduleGeometry();
00116
00117 const RadialStripTopology* rtop = dynamic_cast<const RadialStripTopology*>(&stripdet->specificType().specificTopology());
00118 p.pitch_rel_err2 = (rtop)
00119 ? pow( 0.5f * rtop->angularWidth() * rtop->stripLength()/rtop->localPitch(LocalPoint(0,0,0)), 2.f) / 12.f
00120 : 0.f;
00121 }
00122 }