CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoLocalMuon/DTSegment/src/DTCombinatorialPatternReco4D.cc

Go to the documentation of this file.
00001 
00008 #include "RecoLocalMuon/DTSegment/src/DTCombinatorialPatternReco4D.h"
00009 
00010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00011 #include "FWCore/Framework/interface/EventSetup.h"
00012 
00013 #include "RecoLocalMuon/DTSegment/src/DTSegmentUpdator.h"
00014 // For the 2D reco I use thei reconstructor!
00015 #include "RecoLocalMuon/DTSegment/src/DTCombinatorialPatternReco.h"
00016 #include "RecoLocalMuon/DTSegment/src/DTSegmentCand.h"
00017 
00018 #include "DataFormats/Common/interface/OwnVector.h"
00019 #include "DataFormats/DTRecHit/interface/DTRangeMapAccessor.h"
00020 #include "DataFormats/MuonDetId/interface/DTWireId.h"
00021 #include "DataFormats/DTRecHit/interface/DTRecHit1DPair.h"
00022 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
00023 #include "DataFormats/DTRecHit/interface/DTChamberRecSegment2D.h"
00024 
00025 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00026 
00027 using namespace std;
00028 using namespace edm;
00029 
00030 // TODO
00031 // Throw an exception if a theta segment container is requested and in the event
00032 // there isn't it. (Or launch a "lazy" reco on demand)
00033 
00034 DTCombinatorialPatternReco4D::DTCombinatorialPatternReco4D(const ParameterSet& pset):
00035   DTRecSegment4DBaseAlgo(pset), theAlgoName("DTCombinatorialPatternReco4D"){
00036 
00037     // debug parameter
00038     debug = pset.getUntrackedParameter<bool>("debug");
00039 
00040     //do you want the T0 correction?
00041     applyT0corr = pset.getParameter<bool>("performT0SegCorrection");
00042     computeT0corr = pset.getUntrackedParameter<bool>("computeT0Seg",true);
00043 
00044     // the updator
00045     theUpdator = new DTSegmentUpdator(pset);
00046 
00047     // the input type. 
00048     // If true the instructions in setDTRecSegment2DContainer will be schipped and the 
00049     // theta segment will be recomputed from the 1D rechits
00050     // If false the theta segment will be taken from the Event. Caveat: in this case the
00051     // event must contain the 2D segments!
00052     allDTRecHits = pset.getParameter<bool>("AllDTRecHits");
00053 
00054     // Get the concrete 2D-segments reconstruction algo from the factory
00055     // For the 2D reco I use this reconstructor!
00056     the2DAlgo = new DTCombinatorialPatternReco(pset.getParameter<ParameterSet>("Reco2DAlgoConfig"));
00057   }
00058 
00059 DTCombinatorialPatternReco4D::~DTCombinatorialPatternReco4D(){
00060   delete the2DAlgo;
00061   delete theUpdator;
00062 }
00063 
00064 void DTCombinatorialPatternReco4D::setES(const EventSetup& setup){
00065   setup.get<MuonGeometryRecord>().get(theDTGeometry);
00066   the2DAlgo->setES(setup);
00067   theUpdator->setES(setup);
00068 }
00069 
00070 void DTCombinatorialPatternReco4D::setChamber(const DTChamberId &chId){
00071   // Set the chamber
00072   theChamber = theDTGeometry->chamber(chId); 
00073 }
00074 
00075 void DTCombinatorialPatternReco4D::setDTRecHit1DContainer(Handle<DTRecHitCollection> all1DHits){
00076   theHitsFromPhi1.clear();
00077   theHitsFromPhi2.clear();
00078   theHitsFromTheta.clear();
00079 
00080   DTRecHitCollection::range rangeHitsFromPhi1 = 
00081     all1DHits->get(DTRangeMapAccessor::layersBySuperLayer( DTSuperLayerId(theChamber->id(),1) ) );
00082   DTRecHitCollection::range rangeHitsFromPhi2 = 
00083     all1DHits->get(DTRangeMapAccessor::layersBySuperLayer( DTSuperLayerId(theChamber->id(),3) ) );
00084 
00085   vector<DTRecHit1DPair> hitsFromPhi1(rangeHitsFromPhi1.first,rangeHitsFromPhi1.second);
00086   vector<DTRecHit1DPair> hitsFromPhi2(rangeHitsFromPhi2.first,rangeHitsFromPhi2.second);
00087   if(debug)
00088     cout<< "Number of DTRecHit1DPair in the SL 1 (Phi 1): " << hitsFromPhi1.size()<<endl
00089                                                                << "Number of DTRecHit1DPair in the SL 3 (Phi 2): " << hitsFromPhi2.size()<<endl;
00090 
00091   theHitsFromPhi1 = hitsFromPhi1;
00092   theHitsFromPhi2 = hitsFromPhi2;
00093 
00094   if(allDTRecHits){
00095     DTRecHitCollection::range rangeHitsFromTheta = 
00096       all1DHits->get(DTRangeMapAccessor::layersBySuperLayer( DTSuperLayerId(theChamber->id(),2) ) );
00097 
00098     vector<DTRecHit1DPair> hitsFromTheta(rangeHitsFromTheta.first,rangeHitsFromTheta.second);
00099     if(debug)
00100       cout<< "Number of DTRecHit1DPair in the SL 2 (Theta): " << hitsFromTheta.size()<<endl;
00101     theHitsFromTheta = hitsFromTheta;
00102   }
00103 
00104 }
00105 
00106 void DTCombinatorialPatternReco4D::setDTRecSegment2DContainer(Handle<DTRecSegment2DCollection> all2DSegments){
00107   theSegments2DTheta.clear();
00108 
00109   if(!allDTRecHits){
00110 
00111     //Extract the DTRecSegment2DCollection range for the theta SL
00112     DTRecSegment2DCollection::range rangeTheta = 
00113       all2DSegments->get(DTSuperLayerId(theChamber->id(),2));
00114 
00115     // Fill the DTRecSegment2D container for the theta SL
00116     vector<DTSLRecSegment2D> segments2DTheta(rangeTheta.first,rangeTheta.second);
00117 
00118     if(debug)
00119       cout << "Number of 2D-segments in the second SL (Theta): " << segments2DTheta.size() << endl;
00120     theSegments2DTheta = segments2DTheta;
00121   }
00122 
00123 }
00124 
00125 
00126 OwnVector<DTRecSegment4D>
00127 DTCombinatorialPatternReco4D::reconstruct() {
00128 
00129   OwnVector<DTRecSegment4D> result;
00130 
00131   if (debug){ 
00132     cout << "Segments in " << theChamber->id() << endl;
00133     cout << "Reconstructing of the Phi segments" << endl;
00134   }
00135 
00136   vector<DTHitPairForFit*> pairPhiOwned;
00137   vector<DTSegmentCand*> resultPhi = buildPhiSuperSegmentsCandidates(pairPhiOwned);
00138 
00139   if (debug) cout << "There are " << resultPhi.size() << " Phi cand" << endl;
00140 
00141   if (allDTRecHits){
00142     // take the theta SL of this chamber
00143     const DTSuperLayer* sl = theChamber->superLayer(2);
00144     // sl points to 0 if the theta SL was not found
00145     if(sl){
00146       // reconstruct the theta segments
00147       if(debug) cout<<"Reconstructing of the Theta segments"<<endl;
00148       OwnVector<DTSLRecSegment2D> thetaSegs = the2DAlgo->reconstruct(sl, theHitsFromTheta);
00149       vector<DTSLRecSegment2D> segments2DTheta(thetaSegs.begin(),thetaSegs.end());
00150       theSegments2DTheta = segments2DTheta;
00151     }
00152   }
00153 
00154   bool hasZed = false;
00155 
00156   // has this chamber the Z-superlayer?
00157   if (theSegments2DTheta.size()){
00158     hasZed = theSegments2DTheta.size() > 0;
00159     if (debug) cout << "There are " << theSegments2DTheta.size() << " Theta cand" << endl;
00160   } else {
00161     if (debug) cout << "No Theta SL" << endl;
00162   }
00163 
00164   // Now I want to build the concrete DTRecSegment4D.
00165   if(debug) cout<<"Building of the concrete DTRecSegment4D"<<endl;
00166   if (resultPhi.size()) {
00167     for (vector<DTSegmentCand*>::const_iterator phi=resultPhi.begin();
00168          phi!=resultPhi.end(); ++phi) {
00169 
00170       std::auto_ptr<DTChamberRecSegment2D> superPhi(**phi);
00171 
00172       theUpdator->update(superPhi.get());
00173       if(debug) cout << "superPhi: " << *superPhi << endl;
00174 
00175       if (hasZed) {
00176 
00177         // Create all the 4D-segment combining the Z view with the Phi one
00178         // loop over the Z segments
00179         for(vector<DTSLRecSegment2D>::const_iterator zed = theSegments2DTheta.begin();
00180             zed != theSegments2DTheta.end(); ++zed){
00181 
00182           if(debug) cout << "Theta: " << *zed << endl;
00183           // Important!!
00184           DTSuperLayerId ZedSegSLId(zed->geographicalId().rawId());
00185 
00186           // Put the theta segment poistion in its 3D place.
00187           // note: (superPhi is in the CHAMBER local frame)
00188           const DTSuperLayer* zSL = theChamber->superLayer(ZedSegSLId);
00189 
00190           // FIXME: should rather extrapolate for Y!
00191           LocalPoint zPos(zed->localPosition().x(), 
00192                          (zSL->toLocal(theChamber->toGlobal(superPhi->localPosition()))).y(),
00193                          0.);
00194 
00195           const LocalPoint posZInCh  = theChamber->toLocal( zSL->toGlobal(zPos));
00196           // FIXME: zed->localDirection() is in 2D. Should add the phi direction in the orthogonal plane as well!!
00197           const LocalVector dirZInCh = theChamber->toLocal( zSL->toGlobal(zed->localDirection()));
00198 
00199           DTRecSegment4D* newSeg = new DTRecSegment4D(*superPhi,*zed,posZInCh,dirZInCh);
00200 
00201           if (debug) cout << "Created a 4D seg " << *newSeg << endl;
00202 
00204           theUpdator->update(newSeg);
00205           if (debug) cout << "     seg updated " <<  *newSeg << endl;
00206 
00207 
00208           if(!applyT0corr && computeT0corr) theUpdator->calculateT0corr(newSeg);
00209           if(applyT0corr) theUpdator->update(newSeg,true);
00210 
00211           result.push_back(newSeg);
00212         }
00213       } else {
00214         // Only phi
00215 
00216         DTRecSegment4D* newSeg = new DTRecSegment4D(*superPhi);
00217 
00218         if (debug) cout << "Created a 4D segment using only the 2D Phi segment " << *newSeg << endl;
00219 
00220        //update the segment with the t0 and possibly vdrift correction
00221         if(!applyT0corr && computeT0corr) theUpdator->calculateT0corr(newSeg);
00222         if(applyT0corr) theUpdator->update(newSeg,true);
00223 
00224         result.push_back(newSeg);
00225       }
00226     }
00227   } else { 
00228     // DTRecSegment4D from zed projection only (unlikely, not so useful, but...)
00229     if (hasZed) {
00230       for(vector<DTSLRecSegment2D>::const_iterator zed = theSegments2DTheta.begin();
00231           zed != theSegments2DTheta.end(); ++zed){
00232         if(debug) cout << "Theta: " << *zed << endl;
00233 
00234         // Important!!
00235         DTSuperLayerId ZedSegSLId(zed->geographicalId().rawId());
00236 
00237         const LocalPoint posZInCh  = theChamber->toLocal( theChamber->superLayer(ZedSegSLId)->toGlobal(zed->localPosition() )) ;
00238         const LocalVector dirZInCh = theChamber->toLocal( theChamber->superLayer(ZedSegSLId)->toGlobal(zed->localDirection() )) ;
00239 
00240         DTRecSegment4D* newSeg = new DTRecSegment4D( *zed,posZInCh,dirZInCh);
00241 
00242         if (debug) cout << "Created a 4D segment using only the 2D Theta segment " << 
00243                      *newSeg << endl;
00244 
00245         if(!applyT0corr && computeT0corr) theUpdator->calculateT0corr(newSeg);
00246         if(applyT0corr) theUpdator->update(newSeg,true);
00247 
00248         result.push_back(newSeg);
00249       }
00250     }
00251   }
00252   // finally delete the candidates!
00253   for (vector<DTSegmentCand*>::iterator phi=resultPhi.begin();
00254        phi!=resultPhi.end(); ++phi) delete *phi;
00255   for (vector<DTHitPairForFit*>::iterator phiPair = pairPhiOwned.begin();
00256        phiPair!=pairPhiOwned.end(); ++phiPair) delete *phiPair;
00257 
00258   return result;
00259 }
00260 
00261 
00262 
00263 vector<DTSegmentCand*> DTCombinatorialPatternReco4D::buildPhiSuperSegmentsCandidates(vector<DTHitPairForFit*> &pairPhiOwned){
00264 
00265   DTSuperLayerId slId;
00266 
00267   if(theHitsFromPhi1.size())
00268     slId = theHitsFromPhi1.front().wireId().superlayerId();
00269   else
00270     if(theHitsFromPhi2.size())
00271       slId = theHitsFromPhi2.front().wireId().superlayerId();
00272     else{
00273       if(debug) cout<<"DTCombinatorialPatternReco4D::buildPhiSuperSegmentsCandidates: "
00274         <<"No Hits in the two Phi SL"<<endl;
00275       return vector<DTSegmentCand*>();
00276     }
00277 
00278   const DTSuperLayer *sl = theDTGeometry->superLayer(slId);
00279 
00280   vector<DTHitPairForFit*> pairPhi1 = the2DAlgo->initHits(sl,theHitsFromPhi1);
00281   // same sl!! Since the fit will be in the sl phi 1!
00282   vector<DTHitPairForFit*> pairPhi2 = the2DAlgo->initHits(sl,theHitsFromPhi2);
00283   // copy the pairPhi2 in the pairPhi1 vector 
00284   copy(pairPhi2.begin(),pairPhi2.end(),back_inserter(pairPhi1));
00285 
00286   pairPhiOwned.swap(pairPhi1);
00287   // Build the segment candidate
00288   return the2DAlgo->buildSegments(sl,pairPhiOwned);
00289 }
00290 
00292 DTRecSegment4D* DTCombinatorialPatternReco4D::segmentSpecialZed(const DTRecSegment4D* seg){
00293   // Get the zed projection
00294   //if (!seg->hasZed()) return seg;
00295   const DTSLRecSegment2D* zedSeg=seg->zSegment();
00296   std::vector<DTRecHit1D> hits = zedSeg->specificRecHits();
00297 
00298   // pick up a hit "in the middle", where the single hit will be put.
00299   int nHits=hits.size();
00300   DTRecHit1D middle=hits[static_cast<int>(nHits/2.)];
00301 
00302   // Need to extrapolate pos to the middle layer z
00303   LocalPoint posInSL = zedSeg->localPosition();
00304   LocalVector dirInSL = zedSeg->localDirection();
00305   LocalPoint posInMiddleLayer = posInSL+dirInSL*(-posInSL.z())/cos(dirInSL.theta());
00306 
00307   // create a hit with position and error as the Zed projection one's
00308   auto_ptr<DTRecHit1D> hit(new DTRecHit1D( middle.wireId(),
00309                                            middle.lrSide(),
00310                                            middle.digiTime(),
00311                                            posInMiddleLayer,
00312                                            zedSeg->localPositionError()));
00313 
00314   std::vector<DTRecHit1D> newHits(1,*hit);
00315 
00316   // create a new zed segment with that single hits, but same dir and pos
00317   LocalPoint pos(zedSeg->localPosition());
00318   LocalVector dir(zedSeg->localDirection());
00319   AlgebraicSymMatrix cov(zedSeg->covMatrix());
00320   double chi2(zedSeg->chi2());
00321   //cout << "zed " << *zedSeg << endl;
00322   auto_ptr<DTSLRecSegment2D> newZed(new DTSLRecSegment2D(zedSeg->superLayerId(),
00323                                                          pos,
00324                                                          dir,
00325                                                          cov,
00326                                                          chi2,
00327                                                          newHits));
00328   //cout << "newZed " << *newZed << endl;
00329 
00330   // create a 4d segment with the special zed
00331   DTRecSegment4D* result= new DTRecSegment4D(*seg->phiSegment(),
00332                                              *newZed,
00333                                              seg->localPosition(),
00334                                              seg->localDirection());
00335   // delete the input segment
00336   delete seg;
00337 
00338   // return it
00339   return result;
00340 }