Go to the documentation of this file.00001
00002
00003
00004
00005
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <memory>
00025 #include "DataFormats/Common/interface/ValueMap.h"
00026
00027 #include "RecoTracker/DeDx/interface/DeDxEstimatorProducer.h"
00028
00029 #include "DataFormats/TrackReco/interface/DeDxData.h"
00030 #include "DataFormats/TrackReco/interface/TrackDeDxHits.h"
00031 #include "DataFormats/TrackReco/interface/DeDxHit.h"
00032 #include "DataFormats/TrackReco/interface/Track.h"
00033 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00034
00035 #include "RecoTracker/DeDx/interface/GenericAverageDeDxEstimator.h"
00036 #include "RecoTracker/DeDx/interface/TruncatedAverageDeDxEstimator.h"
00037 #include "RecoTracker/DeDx/interface/MedianDeDxEstimator.h"
00038 #include "RecoTracker/DeDx/interface/UnbinnedFitDeDxEstimator.h"
00039
00040 #include "FWCore/Framework/interface/ESHandle.h"
00041 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00042 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00043
00044 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00045 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1D.h"
00046
00047
00048 using namespace reco;
00049 using namespace std;
00050 using namespace edm;
00051
00052 DeDxEstimatorProducer::DeDxEstimatorProducer(const edm::ParameterSet& iConfig)
00053 {
00054
00055 produces<ValueMap<DeDxData> >();
00056
00057
00058 string estimatorName = iConfig.getParameter<string>("estimator");
00059 if(estimatorName == "median") m_estimator = new MedianDeDxEstimator(-2.);
00060 if(estimatorName == "generic") m_estimator = new GenericAverageDeDxEstimator (iConfig.getParameter<double>("exponent"));
00061 if(estimatorName == "truncated") m_estimator = new TruncatedAverageDeDxEstimator(iConfig.getParameter<double>("fraction"));
00062 if(estimatorName == "unbinnedFit") m_estimator = new UnbinnedFitDeDxEstimator();
00063
00064 MaxNrStrips = iConfig.getUntrackedParameter<unsigned>("maxNrStrips" , 255);
00065 MinTrackHits = iConfig.getUntrackedParameter<unsigned>("MinTrackHits" , 4);
00066
00067 m_tracksTag = iConfig.getParameter<edm::InputTag>("tracks");
00068 m_trajTrackAssociationTag = iConfig.getParameter<edm::InputTag>("trajectoryTrackAssociation");
00069
00070 usePixel = iConfig.getParameter<bool>("UsePixel");
00071 useStrip = iConfig.getParameter<bool>("UseStrip");
00072 MeVperADCPixel = iConfig.getParameter<double>("MeVperADCPixel");
00073 MeVperADCStrip = iConfig.getParameter<double>("MeVperADCStrip");
00074
00075 shapetest = iConfig.getParameter<bool>("ShapeTest");
00076 useCalibration = iConfig.getParameter<bool>("UseCalibration");
00077 m_calibrationPath = iConfig.getParameter<string>("calibrationPath");
00078
00079 if(!usePixel && !useStrip)
00080 edm::LogWarning("DeDxHitsProducer") << "Pixel Hits AND Strip Hits will not be used to estimate dEdx --> BUG, Please Update the config file";
00081 }
00082
00083
00084 DeDxEstimatorProducer::~DeDxEstimatorProducer()
00085 {
00086 delete m_estimator;
00087 }
00088
00089
00090
00091
00092 void DeDxEstimatorProducer::beginRun(edm::Run & run, const edm::EventSetup& iSetup)
00093 {
00094 if(MODsColl.size()!=0)return;
00095
00096
00097 edm::ESHandle<TrackerGeometry> tkGeom;
00098 iSetup.get<TrackerDigiGeometryRecord>().get( tkGeom );
00099
00100 vector<GeomDet*> Det = tkGeom->dets();
00101 for(unsigned int i=0;i<Det.size();i++){
00102 DetId Detid = Det[i]->geographicalId();
00103
00104 StripGeomDetUnit* StripDetUnit = dynamic_cast<StripGeomDetUnit*> (Det[i]);
00105 PixelGeomDetUnit* PixelDetUnit = dynamic_cast<PixelGeomDetUnit*> (Det[i]);
00106
00107 double Thick=-1, Dist=-1, Norma=-1;
00108 if(StripDetUnit){
00109 Dist = StripDetUnit->position().mag();
00110 Thick = StripDetUnit->surface().bounds().thickness();
00111 Norma = MeVperADCStrip/Thick;
00112 }else if(PixelDetUnit){
00113 Dist = PixelDetUnit->position().mag();
00114 Thick = PixelDetUnit->surface().bounds().thickness();
00115 Norma = MeVperADCPixel/Thick;
00116 }
00117
00118 stModInfo* MOD = new stModInfo;
00119 MOD->DetId = Detid.rawId();
00120 MOD->Thickness = Thick;
00121 MOD->Distance = Dist;
00122 MOD->Normalization = Norma;
00123 MOD->Gain = 1;
00124 MODsColl[MOD->DetId] = MOD;
00125 }
00126
00127 MakeCalibrationMap();
00128 }
00129
00130
00131 void DeDxEstimatorProducer::endJob(){
00132 MODsColl.clear();
00133 }
00134
00135
00136
00137
00138 void DeDxEstimatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00139 {
00140 auto_ptr<ValueMap<DeDxData> > trackDeDxEstimateAssociation(new ValueMap<DeDxData> );
00141 ValueMap<DeDxData>::Filler filler(*trackDeDxEstimateAssociation);
00142
00143 Handle<TrajTrackAssociationCollection> trajTrackAssociationHandle;
00144 iEvent.getByLabel(m_trajTrackAssociationTag, trajTrackAssociationHandle);
00145 const TrajTrackAssociationCollection & TrajToTrackMap = *trajTrackAssociationHandle.product();
00146
00147 edm::Handle<reco::TrackCollection> trackCollectionHandle;
00148 iEvent.getByLabel(m_tracksTag,trackCollectionHandle);
00149
00150 size_t n = TrajToTrackMap.size();
00151 std::vector<DeDxData> dedxEstimate(n);
00152
00153
00154 int j=0;
00155 for(TrajTrackAssociationCollection::const_iterator cit=TrajToTrackMap.begin(); cit!=TrajToTrackMap.end(); cit++,j++){
00156
00157 const edm::Ref<std::vector<Trajectory> > traj = cit->key;
00158 const reco::TrackRef track = cit->val;
00159
00160 DeDxHitCollection dedxHits;
00161 vector<DeDxTools::RawHits> hits;
00162
00163
00164 const vector<TrajectoryMeasurement> & measurements = traj->measurements();
00165 for(vector<TrajectoryMeasurement>::const_iterator it = measurements.begin(); it!=measurements.end(); it++){
00166 TrajectoryStateOnSurface trajState=it->updatedState();
00167 if( !trajState.isValid()) continue;
00168
00169 const TrackingRecHit * recHit=(*it->recHit()).hit();
00170 LocalVector trackDirection = trajState.localDirection();
00171 double cosine = trackDirection.z()/trackDirection.mag();
00172
00173 if(const SiStripMatchedRecHit2D* matchedHit=dynamic_cast<const SiStripMatchedRecHit2D*>(recHit)){
00174 if(!useStrip) continue;
00175 DeDxTools::RawHits mono,stereo;
00176 mono.trajectoryMeasurement = &(*it);
00177 stereo.trajectoryMeasurement = &(*it);
00178 mono.angleCosine = cosine;
00179 stereo.angleCosine = cosine;
00180
00181 mono.charge = getCharge((matchedHit->monoHit()->cluster()).get(),mono.NSaturating);
00182 stereo.charge = getCharge((matchedHit->stereoHit()->cluster()).get(),stereo.NSaturating);
00183
00184 mono.detId= matchedHit->monoHit()->geographicalId();
00185 stereo.detId= matchedHit->stereoHit()->geographicalId();
00186
00187 if(shapetest && !(DeDxTools::shapeSelection(((matchedHit->stereoHit()->cluster()).get())->amplitudes()))) hits.push_back(stereo);
00188 if(shapetest && !(DeDxTools::shapeSelection(((matchedHit->monoHit ()->cluster()).get())->amplitudes()))) hits.push_back(mono);
00189 }else if(const ProjectedSiStripRecHit2D* projectedHit=dynamic_cast<const ProjectedSiStripRecHit2D*>(recHit)) {
00190 if(!useStrip) continue;
00191 const SiStripRecHit2D* singleHit=&(projectedHit->originalHit());
00192 DeDxTools::RawHits mono;
00193
00194 mono.trajectoryMeasurement = &(*it);
00195 mono.angleCosine = cosine;
00196 mono.charge = getCharge((singleHit->cluster()).get(),mono.NSaturating);
00197 mono.detId= singleHit->geographicalId();
00198 if(shapetest && !(DeDxTools::shapeSelection(((singleHit->cluster()).get())->amplitudes()))) continue;
00199 hits.push_back(mono);
00200 }else if(const SiStripRecHit2D* singleHit=dynamic_cast<const SiStripRecHit2D*>(recHit)){
00201 if(!useStrip) continue;
00202 DeDxTools::RawHits mono;
00203
00204 mono.trajectoryMeasurement = &(*it);
00205 mono.angleCosine = cosine;
00206 mono.charge = getCharge((singleHit->cluster()).get(),mono.NSaturating);
00207 mono.detId= singleHit->geographicalId();
00208 if(shapetest && !(DeDxTools::shapeSelection(((singleHit->cluster()).get())->amplitudes()))) continue;
00209 hits.push_back(mono);
00210 }else if(const SiStripRecHit1D* single1DHit=dynamic_cast<const SiStripRecHit1D*>(recHit)){
00211 if(!useStrip) continue;
00212 DeDxTools::RawHits mono;
00213
00214 mono.trajectoryMeasurement = &(*it);
00215 mono.angleCosine = cosine;
00216 mono.charge = getCharge((single1DHit->cluster()).get(),mono.NSaturating);
00217 mono.detId= single1DHit->geographicalId();
00218 if(shapetest && !(DeDxTools::shapeSelection(((single1DHit->cluster()).get())->amplitudes()))) continue;
00219 hits.push_back(mono);
00220 }else if(const SiPixelRecHit* pixelHit=dynamic_cast<const SiPixelRecHit*>(recHit)){
00221 if(!usePixel) continue;
00222
00223 DeDxTools::RawHits pixel;
00224
00225 pixel.trajectoryMeasurement = &(*it);
00226 pixel.angleCosine = cosine;
00227 pixel.charge = pixelHit->cluster()->charge();
00228 pixel.NSaturating=-1;
00229 pixel.detId= pixelHit->geographicalId();
00230 hits.push_back(pixel);
00231 }
00232 }
00234
00235 int NClusterSaturating = 0;
00236 for(size_t i=0; i < hits.size(); i++)
00237 {
00238 stModInfo* MOD = MODsColl[hits[i].detId];
00239 float pathLen = MOD->Thickness/std::abs(hits[i].angleCosine);
00240 float charge = MOD->Normalization*hits[i].charge*std::abs(hits[i].angleCosine);
00241 dedxHits.push_back( DeDxHit( charge, MOD->Distance, pathLen, hits[i].detId) );
00242
00243 if(hits[i].NSaturating>0)NClusterSaturating++;
00244 }
00245
00246 sort(dedxHits.begin(),dedxHits.end(),less<DeDxHit>());
00247 std::pair<float,float> val_and_error = m_estimator->dedx(dedxHits);
00248
00249
00250
00251 val_and_error.second = NClusterSaturating;
00252
00253 dedxEstimate[j] = DeDxData(val_and_error.first, val_and_error.second, dedxHits.size() );
00254 }
00255 filler.insert(trackCollectionHandle, dedxEstimate.begin(), dedxEstimate.end());
00256
00257
00258 filler.fill();
00259
00260 iEvent.put(trackDeDxEstimateAssociation);
00261 }
00262
00263
00264
00265 void DeDxEstimatorProducer::MakeCalibrationMap()
00266 {
00267 if(!useCalibration)return;
00268
00269 TChain* t1 = new TChain("SiStripCalib/APVGain");
00270 t1->Add(m_calibrationPath.c_str());
00271
00272 unsigned int tree_DetId;
00273 unsigned char tree_APVId;
00274 double tree_Gain;
00275
00276 t1->SetBranchAddress("DetId" ,&tree_DetId );
00277 t1->SetBranchAddress("APVId" ,&tree_APVId );
00278 t1->SetBranchAddress("Gain" ,&tree_Gain );
00279
00280
00281
00282 for (unsigned int ientry = 0; ientry < t1->GetEntries(); ientry++) {
00283 t1->GetEntry(ientry);
00284 stModInfo* MOD = MODsColl[tree_DetId];
00285 MOD->Gain = tree_Gain;
00286 }
00287
00288 delete t1;
00289
00290 }
00291
00292
00293 int DeDxEstimatorProducer::getCharge(const SiStripCluster* Cluster, int& Saturating_Strips)
00294 {
00295 const vector<uint8_t>& Ampls = Cluster->amplitudes();
00296 uint32_t DetId = Cluster->geographicalId();
00297
00298
00299
00300 int toReturn = 0;
00301 Saturating_Strips = 0;
00302 for(unsigned int i=0;i<Ampls.size();i++){
00303 int CalibratedCharge = Ampls[i];
00304
00305 if(useCalibration){
00306 stModInfo* MOD = MODsColl[DetId];
00307
00308 CalibratedCharge = (int)(CalibratedCharge / MOD->Gain );
00309 if(CalibratedCharge>=1024){
00310 CalibratedCharge = 255;
00311 }else if(CalibratedCharge>=255){
00312 CalibratedCharge = 254;
00313 }
00314 }
00315
00316 toReturn+=CalibratedCharge;
00317 if(CalibratedCharge>=254)Saturating_Strips++;
00318 }
00319
00320
00321
00322
00323 return toReturn;
00324 }
00325
00326
00327
00328
00329
00330 DEFINE_FWK_MODULE(DeDxEstimatorProducer);