CMS 3D CMS Logo

DTSegmentUpdator.cc

Go to the documentation of this file.
00001 
00010 /* This Class Header */
00011 #include "RecoLocalMuon/DTSegment/src/DTSegmentUpdator.h"
00012 
00013 /* Collaborating Class Header */
00014 
00015 #include "DataFormats/DTRecHit/interface/DTRecSegment2D.h"
00016 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
00017 #include "DataFormats/DTRecHit/interface/DTChamberRecSegment2D.h"
00018 #include "DataFormats/DTRecHit/interface/DTRecSegment4D.h"
00019 #include "DataFormats/DTRecHit/interface/DTRecHit1D.h"
00020 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
00021 
00022 #include "RecoLocalMuon/DTSegment/src/DTSegmentCand.h"
00023 #include "RecoLocalMuon/DTRecHit/interface/DTRecHitAlgoFactory.h"
00024 #include "RecoLocalMuon/DTSegment/src/DTLinearFit.h"
00025 
00026 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00027 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00028 #include "Geometry/DTGeometry/interface/DTLayer.h"
00029 
00030 #include "FWCore/Utilities/interface/Exception.h"
00031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00032 #include "FWCore/Framework/interface/EventSetup.h"
00033 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00034 
00035 /* C++ Headers */
00036 #include <string>
00037 using namespace std;
00038 using namespace edm;
00039 
00040 /* ====================================================================== */
00041 
00043 DTSegmentUpdator::DTSegmentUpdator(const ParameterSet& config) :
00044   theFitter(new DTLinearFit()) ,
00045   T0_fit_flag(config.getParameter<bool>("performT0SegCorrection")), 
00046   vdrift_4parfit(config.getParameter<bool>("performT0_vdriftSegCorrection")),
00047   T0_hit_resolution(config.getParameter<double>("hit_afterT0_resolution")),
00048   T0_seg_debug(config.getUntrackedParameter<bool>("T0SegCorrectionDebug",false)) 
00049 {  
00050   string theAlgoName = config.getParameter<string>("recAlgo");
00051   theAlgo = DTRecHitAlgoFactory::get()->create(theAlgoName, 
00052                                                config.getParameter<ParameterSet>("recAlgoConfig"));
00053 }
00054 
00056 DTSegmentUpdator::~DTSegmentUpdator() {
00057   delete theFitter;
00058 }
00059 
00060 /* Operations */ 
00061 
00062 void DTSegmentUpdator::setES(const edm::EventSetup& setup){
00063   setup.get<MuonGeometryRecord>().get(theGeom);
00064   theAlgo->setES(setup);
00065 }
00066 
00067 void DTSegmentUpdator::update(DTRecSegment4D* seg)  {
00068 
00069   bool hasPhi=seg->hasPhi();
00070   bool hasZed=seg->hasZed();
00071   int step;
00072 
00073   if (hasPhi && hasZed) step=3;
00074   else step=2;
00075 
00076   GlobalPoint pos =  (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localPosition());
00077   GlobalVector dir = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localDirection());
00078   if (hasPhi) {
00079     DTChamberRecSegment2D *segPhi=seg->phiSegment();
00080 
00081     if (T0_fit_flag) {
00082       float t0cor_seg = segPhi->theT0;  // get the current value of the t0seg
00083 
00084       if (T0_seg_debug){
00085         cout << "  before  fitT0_seg(seg) in Update 4D, t0cor_seg in phi = " << t0cor_seg << endl;
00086       }
00087 
00088       float  t0cor=0.;//value wich will be computed in the fit 
00089       double vminf=0.;// % of vdrift change  
00090       float  cminf=0.;// shift on space 
00091 
00092       if (t0cor_seg == 0 ) {                                    // if t0cor_seg already computed keep its value
00093 
00094         fitT0_seg(seg->phiSegment(),t0cor,vminf,cminf);          // find t0 and vdrift corrections to the segment hits
00095 
00096         updateHitsN(seg->phiSegment(), vminf, cminf ,pos,dir,2);         // apply found corrections to hits
00097 
00098         if(segPhi->theT0 != t0cor )     
00099           cout << " Attention: in Update 4D the phi time segment has not been updated properly! segPhi " <<segPhi->theT0 <<" t0cor" << t0cor <<endl;
00100       }
00101       else {  
00102         updateHitsN(seg->phiSegment(),vminf,cminf,pos,dir,step);
00103       }
00104       // nothing to do here the hits have been already corrected for position and direction in the fitT0_seg
00105       if(T0_seg_debug)  
00106         cout << " After  fitT0_seg(seg) in Update 4D : Phi seg !!t0corphi = " << segPhi->theT0 << endl;
00107     }                    // end if T0_seg_flag      
00108     else 
00109 
00110       updateHits(seg->phiSegment(),pos,dir,step);
00111 
00112   }
00113 
00114   if (hasZed) {
00115 
00116     if (T0_fit_flag) {
00117 
00118       DTSLRecSegment2D *segZed=seg->zSegment();
00119 
00120       float t0cor_seg = segZed->theT0;  // get the current value of the t0seg
00121       float t0cor=0.;//value wich will be computed in the fit 
00122       double  vminf=0.;//value wich will be computed in the fit 
00123       float  cminf=0.;
00124 
00125       if (T0_seg_debug){
00126         cout << "  before  fitT0_seg(seg) in Update 4D, t0cor_seg in Zed = " << t0cor_seg << endl;
00127       }
00128 
00129       if (t0cor_seg == 0 ) {                                    // if t0cor_seg already computed keep its value and dont update hits for that
00130 
00131         fitT0_seg(seg->zSegment(),t0cor, vminf, cminf);          // find t0 and vdrift corrections to the segment hits
00132 
00133 
00134         updateHitsN(seg->zSegment(),vminf, cminf,pos,dir,2);             // apply found corrections to hits
00135 
00136         if(segZed->theT0 != t0cor)  //just a check that the computed value is correctly stored in the segment   
00137           cout << " Attention: in Update 4D the theta time segment has not been updated properly! segZed " 
00138             <<segZed->theT0 <<" t0cor" << t0cor  << endl;
00139 
00140       } 
00141       else{ 
00142         updateHitsN(seg->zSegment(), vminf ,cminf ,pos,dir,step);
00143       }
00144       if(T0_seg_debug)  cout << " After  fitT0_seg(seg) in Update 4D : Zed seg !! t0corzed = " << segZed->theT0 << endl;
00145 
00146     }                    // end if T0_seg_flag      
00147     else 
00148 
00149       updateHits(seg->zSegment(),pos,dir,step);
00150   }   
00151 
00152   fit(seg);
00153 }
00154 
00155 void DTSegmentUpdator::update(DTRecSegment2D* seg)  {
00156   if (T0_fit_flag ) {
00157     double  vminf=0.;//value wich will be computed in the fit 
00158     float  cminf=0.;
00159 
00160     float t0cor_seg = seg->theT0;
00161     float t0cor ;
00162     if (T0_seg_debug)   
00163       cout << "  entered in update(DTRecSegment2D* seg)  !! t0cor = "<< t0cor  << endl;
00164 
00165     if (t0cor_seg == 0. ) fitT0_seg(seg,t0cor, vminf,cminf);//for correction on only PHI+theta 4D segments) comment this line
00166 
00167     updateHitsN(seg,vminf,cminf);  // updates of 2d segment
00168 
00169     if (T0_seg_debug) cout << " After  fitT0_seg(seg) in update(DTRecSegment2D* seg)!! t0cor =  " << t0cor << endl;
00170     // 
00171   } 
00172 
00173   else {                        //original routine
00174     updateHits(seg);
00175   }
00176   fit(seg);
00177 }
00178 
00179 void DTSegmentUpdator::fit(DTRecSegment4D* seg) {
00180   // after the update must refit the segments
00181   if(seg->hasPhi()) fit(seg->phiSegment());
00182   if(seg->hasZed()) fit(seg->zSegment());
00183 
00184   if(seg->hasPhi() && seg->hasZed() ) {
00185 
00186     DTChamberRecSegment2D *segPhi=seg->phiSegment();
00187     DTSLRecSegment2D *segZed=seg->zSegment();
00188 
00189     // NB Phi seg is already in chamber ref
00190     LocalPoint posPhiInCh = segPhi->localPosition();
00191     LocalVector dirPhiInCh= segPhi->localDirection();
00192 
00193     // Zed seg is in SL one
00194     GlobalPoint glbPosZ = ( theGeom->superLayer(segZed->superLayerId()) )->toGlobal(segZed->localPosition());
00195     LocalPoint posZInCh = ( theGeom->chamber(segZed->superLayerId().chamberId()) )->toLocal(glbPosZ);
00196 
00197     GlobalVector glbDirZ = (theGeom->superLayer(segZed->superLayerId()) )->toGlobal(segZed->localDirection());
00198     LocalVector dirZInCh = (theGeom->chamber(segZed->superLayerId().chamberId()) )->toLocal(glbDirZ);
00199 
00200     LocalPoint posZAt0 = posZInCh+
00201       dirZInCh*(-posZInCh.z())/cos(dirZInCh.theta());
00202 
00203     // given the actual definition of chamber refFrame, (with z poiniting to IP),
00204     // the zed component of direction is negative.
00205     LocalVector dir=LocalVector(dirPhiInCh.x()/fabs(dirPhiInCh.z()),
00206                                 dirZInCh.y()/fabs(dirZInCh.z()),
00207                                 -1.);
00208 
00209     seg->setPosition(LocalPoint(posPhiInCh.x(),posZAt0.y(),0.));
00210     seg->setDirection(dir.unit());
00211 
00212     AlgebraicSymMatrix mat(4);
00213 
00214     // set cov matrix
00215     mat[0][0]=segPhi->parametersError()[0][0]; //sigma (dx/dz)
00216     mat[0][2]=segPhi->parametersError()[0][1]; //cov(dx/dz,x)
00217     mat[2][2]=segPhi->parametersError()[1][1]; //sigma (x)
00218 
00219     seg->setCovMatrix(mat);
00220     seg->setCovMatrixForZed(posZInCh);
00221 
00222   }
00223   else if (seg->hasPhi()) {
00224     DTChamberRecSegment2D *segPhi=seg->phiSegment();
00225 
00226     seg->setPosition(segPhi->localPosition());
00227     seg->setDirection(segPhi->localDirection());
00228 
00229     AlgebraicSymMatrix mat(4);
00230     // set cov matrix
00231     mat[0][0]=segPhi->parametersError()[0][0]; //sigma (dx/dz)
00232     mat[0][2]=segPhi->parametersError()[0][1]; //cov(dx/dz,x)
00233     mat[2][2]=segPhi->parametersError()[1][1]; //sigma (x)
00234 
00235     seg->setCovMatrix(mat);
00236   }
00237   else if (seg->hasZed()) {
00238     DTSLRecSegment2D *segZed=seg->zSegment();
00239 
00240     // Zed seg is in SL one
00241     GlobalPoint glbPosZ = ( theGeom->superLayer(segZed->superLayerId()) )->toGlobal(segZed->localPosition());
00242     LocalPoint posZInCh = ( theGeom->chamber(segZed->superLayerId().chamberId()) )->toLocal(glbPosZ);
00243 
00244     GlobalVector glbDirZ = (theGeom->superLayer(segZed->superLayerId()) )->toGlobal(segZed->localDirection());
00245     LocalVector dirZInCh = (theGeom->chamber(segZed->superLayerId().chamberId()) )->toLocal(glbDirZ);
00246 
00247     LocalPoint posZAt0 = posZInCh+
00248       dirZInCh*(-posZInCh.z())/cos(dirZInCh.theta());
00249 
00250     seg->setPosition(posZAt0);
00251     seg->setDirection(dirZInCh);
00252 
00253     AlgebraicSymMatrix mat(4);
00254     // set cov matrix
00255     seg->setCovMatrix(mat);
00256     seg->setCovMatrixForZed(posZInCh);
00257   }
00258 }
00259 
00260 
00261 bool DTSegmentUpdator::fit(DTSegmentCand* seg) {
00262   if (!seg->good()) return false;
00263 
00264   vector<float> x;
00265   vector<float> y;
00266   vector<float> sigy;
00267 
00268   DTSegmentCand::AssPointCont hits=seg->hits();
00269   for (DTSegmentCand::AssPointCont::const_iterator iter=hits.begin();
00270        iter!=hits.end(); ++iter) {
00271     LocalPoint pos = (*iter).first->localPosition((*iter).second);
00272     x.push_back(pos.z()); 
00273     y.push_back(pos.x());
00274     sigy.push_back(sqrt((*iter).first->localPositionError().xx()));
00275   }
00276 
00277   LocalPoint pos;
00278   LocalVector dir;
00279   AlgebraicSymMatrix covMat(2);
00280   double chi2=0;
00281   fit(x,y,sigy,pos,dir,covMat,chi2);
00282 
00283   seg->setPosition(pos);
00284   seg->setDirection(dir);
00285 
00286   //cout << "pos " << segPosition<< endl;
00287   //cout << "dir " << segDirection<< endl;
00288 
00289   seg->setCovMatrix(covMat);
00290   // cout << "Mat " << covMat << endl;
00291 
00292   seg->setChi2(chi2);
00293   return true;
00294 }
00295 
00296 void DTSegmentUpdator::fit(DTRecSegment2D* seg) {
00297   // WARNING: since this method is called both with a 2D and a 2DPhi as argument
00298   // seg->geographicalId() can be a superLayerId or a chamberId 
00299 
00300   vector<float> x;
00301   vector<float> y;
00302   vector<float> sigy;
00303 
00304   vector<DTRecHit1D> hits=seg->specificRecHits();
00305   for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00306        hit!=hits.end(); ++hit) {
00307 
00308     // I have to get the hits position (the hit is in the layer rf) in SL frame...
00309     GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00310     LocalPoint pos = ( theGeom->idToDet(seg->geographicalId()) )->toLocal(glbPos);
00311 
00312     x.push_back(pos.z()); 
00313     y.push_back(pos.x());
00314 
00315     // Get local error in SL frame
00316     //RB: is it right in this way? 
00317     ErrorFrameTransformer tran;
00318     GlobalError glbErr =
00319       tran.transform( hit->localPositionError(),(theGeom->layer( hit->wireId().layerId() ))->surface());
00320     LocalError slErr =
00321       tran.transform( glbErr, (theGeom->idToDet(seg->geographicalId()))->surface());
00322 
00323     sigy.push_back(sqrt(slErr.xx()));
00324   }
00325 
00326   LocalPoint pos;
00327   LocalVector dir;
00328   AlgebraicSymMatrix covMat(2);
00329   double chi2=0;
00330   fit(x,y,sigy,pos,dir,covMat,chi2);
00331 
00332   seg->setPosition(pos);
00333 
00334   seg->setDirection(dir);
00335 
00336   //cout << "pos " << segPosition<< endl;
00337   //cout << "dir " << segDirection<< endl;
00338 
00339   seg->setCovMatrix(covMat);
00340   // cout << "Mat " << mat << endl;
00341 
00342   seg->setChi2(chi2);
00343 }
00344 
00345 
00346 void DTSegmentUpdator::fitT0(DTRecSegment2D* seg) {
00347   // WARNING: since this method is called both with a 2D and a 2DPhi as argument
00348   // seg->geographicalId() can be a superLayerId or a chamberId 
00349 
00350   double x,y;
00351   double sx=0,sy=0,sxy=0,sxx=0,ssx=0,ssy=0,s=0,ss=0;
00352   int leftHits=0,rightHits=0;
00353 
00354   vector<DTRecHit1D> hits=seg->specificRecHits();
00355 
00356   for (vector<DTRecHit1D>::const_iterator hit=hits.begin(); hit!=hits.end(); ++hit) {
00357 
00358     // I have to get the hits position (the hit is in the layer rf) in SL frame...
00359     GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00360     LocalPoint pos = ( theGeom->idToDet(seg->geographicalId()) )->toLocal(glbPos);
00361 
00362     x=pos.z();
00363     y=pos.x();
00364 
00365     sx+=x;
00366     sy+=y;
00367     sxy+=x*y;
00368     sxx+=x*x;
00369     s++;
00370 
00371     if (hit->lrSide()==DTEnums::Left) {
00372       leftHits++;
00373       ssx+=x;
00374       ssy+=y;
00375       ss++;
00376     } else {
00377       rightHits++;
00378       ssx-=x;
00379       ssy-=y;
00380       ss--;
00381     }  
00382   }      
00383 
00384   double t0_corr=0.;
00385 
00386   if (leftHits && rightHits) {
00387     double delta = ss*ss*sxx+s*sx*sx+s*ssx*ssx-s*s*sxx-2*ss*sx*ssx;
00388     if (delta) {
00389       //      a=(ssy*s*ssx+sxy*ss*ss+sy*sx*s-sy*ss*ssx-ssy*sx*ss-sxy*s*s)/delta;
00390       //      b=(ssx*sy*ssx+sxx*ssy*ss+sx*sxy*s-sxx*sy*s-ssx*sxy*ss-sx*ssy*ssx)/delta;
00391       t0_corr=(ssx*s*sxy+sxx*ss*sy+sx*sx*ssy-sxx*s*ssy-sx*ss*sxy-ssx*sx*sy)/delta;
00392     }
00393   }
00394 
00395   t0_corr/=-0.00543; // convert drift distance to time
00396 
00397   seg->setT0(t0_corr);  
00398 }
00399 
00400 void DTSegmentUpdator::fit(const vector<float>& x,
00401                            const vector<float>& y, 
00402                            const vector<float>& sigy,
00403                            LocalPoint& pos,
00404                            LocalVector& dir,
00405                            AlgebraicSymMatrix& covMatrix,
00406                            double& chi2) {
00407   float slope,intercept,covss,covii,covsi;
00408   // do the fit
00409   theFitter->fit(x,y,x.size(),sigy,slope,intercept,covss,covii,covsi);
00410   // cout << "slope " << slope << endl;
00411   // cout << "intercept " << intercept << endl;
00412 
00413   // intercept is the x() in chamber frame when the segment cross the chamber
00414   // plane (at z()=0), the y() is not measured, so let's put the center of the
00415   // chamber.
00416   pos = LocalPoint(intercept,0.,0.);
00417 
00418   //  slope is dx()/dz(), while dy()/dz() is by definition 0, finally I want the
00419   //  segment to point outward, so opposite to local z
00420   dir = LocalVector(-slope,0.,-1.).unit();
00421 
00422   covMatrix = AlgebraicSymMatrix(2);
00423   covMatrix[0][0] = covss; // this is var(dy/dz)
00424   covMatrix[1][1] = covii; // this is var(y)
00425   covMatrix[1][0] = covsi; // this is cov(dy/dz,y)
00426 
00427   /* Calculate chi2. */
00428   chi2 = 0.;
00429   for(unsigned int i=0; i<x.size() ; ++i) {
00430     double resid= y[i] - (intercept + slope*x[i]);
00431     chi2 += (resid/sigy[i])*(resid/sigy[i]);
00432   }
00433 }
00434 
00435 void DTSegmentUpdator::updateHits(DTRecSegment2D* seg) {
00436   GlobalPoint pos = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localPosition());
00437   GlobalVector dir = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localDirection());
00438   updateHits(seg, pos, dir);
00439 }
00440 
00441 // The GlobalPoint and the GlobalVector can be either the glb position and the direction
00442 // of the 2D-segment itself or the glb position and direction of the 4D segment
00443 void DTSegmentUpdator::updateHits(DTRecSegment2D* seg,
00444                                   GlobalPoint &gpos,
00445                                   GlobalVector &gdir,
00446                                   int step) {
00447 
00448   // it is not necessary to have DTRecHit1D* to modify the obj in the container
00449   // but I have to be carefully, since I cannot make a copy before the iteration!
00450 
00451   vector<DTRecHit1D> toBeUpdatedRecHits = seg->specificRecHits();
00452   vector<DTRecHit1D> updatedRecHits;
00453 
00454   for (vector<DTRecHit1D>::iterator hit= toBeUpdatedRecHits.begin(); 
00455        hit!=toBeUpdatedRecHits.end(); ++hit) {
00456 
00457     const DTLayer* layer = theGeom->layer( hit->wireId().layerId() );
00458 
00459     LocalPoint segPos=layer->toLocal(gpos);
00460     LocalVector segDir=layer->toLocal(gdir);
00461     // define impact angle needed by the step 2
00462     const float angle = atan(segDir.x()/-segDir.z());
00463     // define the local position (extr.) of the segment. Needed by the third step 
00464     LocalPoint segPosAtLayer=segPos+segDir*(-segPos.z())/cos(segDir.theta());
00465 
00466     DTRecHit1D newHit1D=(*hit);
00467 
00468     bool ok=true;
00469 
00470     if (step==2) {
00471       ok = theAlgo->compute(layer,
00472                             (*hit),
00473                             angle,
00474                             newHit1D);
00475     } else if (step==3) {
00476 
00477       LocalPoint hitPos(hit->localPosition().x(),+segPosAtLayer.y(),0.);
00478 
00479       GlobalPoint glbpos= theGeom->layer( hit->wireId().layerId() )->toGlobal(hitPos);
00480 
00481       newHit1D.setPosition(hitPos);
00482 
00483       ok = theAlgo->compute(layer,
00484                             (*hit),
00485                             angle,glbpos,
00486                             newHit1D);
00487     } else {
00488       throw cms::Exception("DTSegmentUpdator")<<" updateHits called with wrong step"<<endl;
00489     }
00490 
00491     if (ok) {
00492       updatedRecHits.push_back(newHit1D);
00493     } else {
00494       LogError("DTSegmentUpdator")<<"DTSegmentUpdator::updateHits failed update" << endl;
00495       throw cms::Exception("DTSegmentUpdator")<<"updateHits failed update"<<endl;
00496     }
00497   }
00498   seg->update(updatedRecHits);
00499   if ( ! T0_fit_flag) fitT0(seg);
00500 }
00501 
00502 
00503 void DTSegmentUpdator::fitT0_seg(DTRecSegment2D* seg, float& t0cor ,double& vminf,float& cminf) {
00504   // WARNING: since this method is called both with a 2D and a 2DPhi as argument
00505   // seg->geographicalId() can be a superLayerId or a chamberId 
00506 
00507   vector<double> d_drift;
00508   //vector<float> t;
00509   vector<float> x;
00510   vector<float> y;
00511   vector<float> sigy;
00512   vector<int> lc;
00513 
00514   vector<DTRecHit1D> hits=seg->specificRecHits();
00515 
00516   DTWireId wireId;
00517   //  int npt=0;
00518   //  for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00519   //       hit!=hits.end(); ++hit) {
00520   //       wireId = hit->wireId();
00522   //       npt++;
00523   //  }
00524   int npt=0;
00525   for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00526        hit!=hits.end(); ++hit) {
00527     // I have to get the hits position (the hit is in the layer rf) in SL frame...
00528     GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00529     LocalPoint pos = ( theGeom->idToDet(seg->geographicalId()) )->toLocal(glbPos);
00530     //int wireId=(hit->wireId().wire());
00531     const DTLayer* layer = theGeom->layer( hit->wireId().layerId() );
00532     float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
00533     float distance = fabs(hit->localPosition().x() - xwire);
00534     //  float time=0;
00535     //  time    =hit->digiTime();
00536 
00537 
00538     //  cout << " Drift space  d_drift "<<distance  <<endl;
00539 
00540 
00541     int ilc=0;
00542     if ( hit->lrSide() == DTEnums::Left ) ilc= 1;
00543     else                                  ilc=-1;    
00544 
00545     npt++;
00546     x.push_back(pos.z()); 
00547     y.push_back(pos.x());
00548     lc.push_back(ilc);
00549     d_drift.push_back(distance);
00550 
00551     //   t.push_back(time);
00552     // cout << "fitT0_seg time "<< time<< " d_drift "<<distance  <<" npt= " <<npt<<endl;
00553   }
00554 
00555   double chi2fit=0;
00556   double chi20=0;
00557   int nptfit=npt;
00558   int nppar=0;
00559   float aminf;
00560   float bminf;
00561   // float 
00562   cminf=0.; 
00563   // double 
00564   vminf=0.;
00565   double vminf0=0;
00566   /*  cout << "dimensione vettori: " << x.size() << " "
00567       << y.size() << " "
00568       << lc.size() << " "
00569       << endl;*/
00570   chi20 =seg->chi2(); //previous chi2
00571 
00572 
00573   //NB chi2fit is normalized
00574   if (nptfit>2) Fit4Var(x,y,sigy,lc,d_drift,nptfit,nppar,aminf,bminf,cminf,vminf0,chi2fit,false);
00575   vminf=vminf0;
00576 
00577   seg->setT0(0.1000); //just for setting a dummy unused value to tell that T0 has been already applyed;
00578 
00579   float dvDrift0 = -0.000001;
00580   float t0cor_dvDrift=0.;
00581 
00582   if ( nptfit>2            )  {
00583     t0cor = - cminf/0.00543 ; // in ns ;
00584     if ( (abs(vminf))< 0.09 )  dvDrift0 = vminf/10.;
00585     // Per Nicola ... si potrebbe sostituire il valore della vdrift costante  usata nell'algo per creare le hits...
00586 
00587     float   t0cor_10 = int(t0cor *10)/10.; //in 0.1 ns;
00588 
00589     t0cor_dvDrift=t0cor_10;
00590 
00591 
00592     if (vdrift_4parfit) {
00593       float dvDrift  = dvDrift0;
00594       if ( dvDrift0 < 0. )  {   dvDrift=  - dvDrift0 +.01;  }
00595 
00596       t0cor_dvDrift =   dvDrift + t0cor_10 ;
00597       if ( t0cor_10 < 0. )    t0cor_dvDrift = - dvDrift + t0cor_10 ;
00598 
00599 
00600       //NPT if (t0cor_dvDrift!= 0) cout <<  "NPT " << npt <<  "   " <<  wireId.wheel() << "   " << wireId.station() << "   " <<  wireId.sector() <<" " << t0cor << " vdrift= " << dvDrift0 <<endl;
00601       //if (t0cor != 0) cout <<  "NPT " <<"t0cor " << t0cor_dvDrift << endl;
00602       //if (t0cor != 0) cout <<  "NPT t0cor _10= " << t0cor_10 << " vdrift= " << dvDrift << "t0_seg= " << t0cor_dvDrift <<endl;
00603       //NPT if (t0cor_dvDrift != 0) {
00604       //NPT     for (int jnpt=0; jnpt<npt; jnpt++){
00605       //NPT      cout <<  "NPT " <<jnpt+1 << "  " <<x[jnpt] << " " <<y[jnpt] <<"    " <<lc[jnpt]<< " " << d_drift[jnpt] << endl;
00606       //NPT     }
00607       //NPT }
00608 
00609     }
00610 
00611     //    updateHitsN ( seg,vminf,cminf);  // here the rehits are updated
00612     t0cor= t0cor_dvDrift;
00613     seg->setT0(t0cor_dvDrift);        // here the applied time + vdrift corrections are recorded in the segment
00614   }
00615 }
00616 
00617 
00618 void DTSegmentUpdator::updateHitsN(DTRecSegment2D* seg,
00619                                    double &vminf, float &cminf ) {
00620   GlobalPoint pos = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localPosition());
00621   GlobalVector dir = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localDirection());
00622 
00623   updateHitsN(seg, vminf, cminf, pos, dir,2);
00624 }
00625 
00626 // The GlobalPoint and the GlobalVector can be either the glb position and the direction
00627 // of the 2D-segment itself or the glb position and direction of the 4D segment
00628 
00629 
00630 
00631 // The GlobalPoint and the GlobalVector can be either the glb position and the direction
00632 // of the 2D-segment itself or the glb position and direction of the 4D segment
00633 void DTSegmentUpdator::updateHitsN(DTRecSegment2D* seg,
00634                                    double &vminf, float &cminf,
00635                                    GlobalPoint &gpos,
00636                                    GlobalVector &gdir,
00637                                    int step) {
00638 
00639   // it is not necessary to have DTRecHit1D* to modify the obj in the container
00640   // but I have to be carefully, since I cannot make a copy before the iteration!
00641 
00642   vector<DTRecHit1D> toBeUpdatedRecHits = seg->specificRecHits();
00643   vector<DTRecHit1D> updatedRecHits;
00644 
00645   for (vector<DTRecHit1D>::iterator hit= toBeUpdatedRecHits.begin(); 
00646        hit!=toBeUpdatedRecHits.end(); ++hit) {
00647     //*******************
00648     GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00649     LocalPoint pos = ( theGeom->idToDet(seg->geographicalId()) )->toLocal(glbPos);
00650     float time=0;
00651     //int wireId=(hit->wireId().wire());
00652     const DTLayer* layer = theGeom->layer( hit->wireId().layerId() );
00653     float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
00654     float distance = fabs(hit->localPosition().x() - xwire);
00655     time        =hit->digiTime();
00656     //    float y=hit->localPosition().x();
00657     //  distance from the wire: hit in local coordinate - wire posizion 
00658     //  cout << " Drift space  d_drift "<<distance  <<endl;
00659 
00660     int ilc=0;
00661     if ( hit->lrSide() == DTEnums::Left ) ilc= 1;
00662 
00663     else                                  ilc=-1;    
00664 
00665     //*********************************************    
00666     bool   ok=true;
00667     double dy_corr = (vminf*ilc*distance-cminf*ilc ); 
00668     //*********************************************    
00669     LocalPoint segPos=layer->toLocal(gpos);
00670     LocalVector segDir=layer->toLocal(gdir);
00671     // define impact angle needed by the step 2
00672     //  not used here   const float angle = atan(segDir.x()/-segDir.z());
00673     // define the local position (extr.) of the segment. Needed by the third step 
00674     LocalPoint segPosAtLayer=segPos+segDir*(-segPos.z())/cos(segDir.theta());
00675 
00676     DTRecHit1D newHit1D=(*hit);
00677     LocalPoint leftPoint(hit->localPosition().x() +dy_corr,+segPosAtLayer.y(),0.);;
00678     LocalPoint rightPoint(hit->localPosition().x()+dy_corr,+segPosAtLayer.y(),0.);;
00679     //T0_hit_resolution=0.03;       //to be removed once inserted as cfi changeable parameter
00680     float  hitresol=T0_hit_resolution;   //local resolution in use      
00681     LocalError error(hitresol*hitresol,0.,0.);
00682     switch(newHit1D.lrSide()) {
00683 
00684       case DTEnums::Left:
00685         newHit1D.setPositionAndError(leftPoint, error);
00686         break;
00687 
00688       case DTEnums::Right:
00689         newHit1D.setPositionAndError(rightPoint, error);
00690         break;
00691 
00692       default:
00693         throw cms::Exception("InvalidDTCellSide") << "[DTLinearDriftAlgo] Compute at Step "
00694           << step << ", Hit side "
00695           << newHit1D.lrSide()
00696           << " is invalid!" << endl;
00697         break;
00698         // return false;
00699     }
00700 
00701 
00702     if (ok) {
00703       updatedRecHits.push_back(newHit1D);
00704     } else {
00705       LogError("DTSegmentUpdator")<<"DTSegmentUpdator::updateHits failed update" << endl;
00706       throw cms::Exception("DTSegmentUpdator")<<"updateHits failed update"<<endl;
00707     }
00708   }
00709   seg->update(updatedRecHits);
00710 } 
00711 
00712 void DTSegmentUpdator::Fit4Var(
00713                                const vector<float>& xfit,
00714                                const vector<float>& yfit,
00715                                const vector<float>& sigy,
00716                                const vector<int>& lfit,
00717                                const vector<double>& tfit,
00718                                int& nptfit,
00719                                int& nppar,
00720                                //            LocalPoint& pos,
00721                                //            LocalVector& dir,
00722                                float& aminf,
00723                                float& bminf,
00724                                float& cminf,
00725                                double& vminf,
00726                                double& chi2fit,
00727                                bool debug0){ 
00728   //**a bool vdrift_4parfit =false;
00729   //  bool vdrift_4parfit =true;
00730   // debug=true;
00731   bool debug=false;     
00732   double sigma = 0.0295;// errors can be inserted .just load them/that is the usual TB resolution value for DT chambers 
00733   double delta = 0;
00734   double sx = 0;
00735   double  sx2 = 0;
00736   double sy = 0;
00737   double sxy = 0;
00738   double sl = 0;
00739   double sl2 = 0;
00740   double sly = 0;
00741   double slx = 0;
00742   double st = 0;
00743   double st2 = 0;
00744   double slt = 0;
00745   double sltx = 0;
00746   double slty = 0;
00747   double  chi2fit2=-1;
00748   double  chi2fitN2=-1 ;
00749   double  chi2fit3=-1;
00750   double  chi2fitN3=-1 ;
00751   double  chi2fit4=-1;
00752   double  chi2fitN4=-1 ;
00753   float bminf3=bminf;
00754   float aminf3=aminf;
00755   float cminf3=cminf;
00756   int nppar2=0;
00757   int nppar3=0;
00758   int nppar4=0;
00759   cminf=0.;
00760   vminf=0.;
00761   if ( T0_seg_debug)  debug=true;
00762   //cout << "sigma = "<<sigma;
00763   for (int j=0; j<nptfit; j++){
00764     sx  = sx + xfit[j];       
00765     sy  = sy + yfit[j];
00766     sx2 = sx2 + xfit[j]*xfit[j];
00767     sxy = sxy + xfit[j]*yfit[j];
00768     sl  = sl + lfit[j];       
00769     sl2 = sl2 + lfit[j]*lfit[j];
00770     sly = sly + lfit[j]*yfit[j];
00771     slx = slx + lfit[j]*xfit[j];
00772     st = st + tfit[j];
00773     st2 = st2 + tfit[j] * tfit[j];
00774     slt = slt + lfit[j] * tfit[j];
00775     sltx = sltx + lfit[j] * tfit[j]*xfit[j];
00776     slty = slty + lfit[j] * tfit[j]*yfit[j];
00777 
00778   } //end loop
00779   delta = nptfit*sx2 - sx*sx;
00780   // cout << delta << " " << nptfit << " " << sigma << endl;
00781   //cout << "npfit"<< nptfit<< "delta"<< delta<<endl;
00782   //cout << <<endl;
00783   double a = 0;
00784   double b = 0;        
00785   if (delta!=0  ){   //
00786     a = (sx2*sy - sx*sxy)/delta;
00787     b = (nptfit*sxy - sx*sy)/delta;
00788 
00789     //  cout << " NPAR=2 : slope = "<<b<< "    intercept = "<<a <<endl;
00790     for (int j=0; j<nptfit; j++){
00791       double ypred = a + b*xfit[j];
00792       double dy = (yfit[j] - ypred)/sigma;
00793       chi2fit = chi2fit + dy*dy;
00794     } //end loop chi2
00795   }
00796 
00797   bminf=b;
00798   aminf=a;
00799 
00800   nppar=2; 
00801   nppar2=nppar; 
00802 
00803   chi2fit2 = chi2fit;
00804   chi2fitN2 = chi2fit/(nptfit-2);
00805   // cout << "dt0 = 0chi2fit = " << chi2fit << "  slope = "<<b<<endl;
00806   // cout << chi2fit;
00807 
00808   if (nptfit>=3) {
00809 
00810     double d1=  sy;
00811     double d2=  sxy;
00812     double d3=  sly;
00813     double c1=  sl;
00814     double c2=  slx;
00815     double c3=  sl2;
00816     double b1=  sx;
00817     double b2=  sx2;
00818     double b3=  slx;
00819     double a1= nptfit;
00820     double a2=  sx;
00821     double a3=  sl;
00822     double b4= b2*a1-b1*a2; // questo e i seguenti sono inutilizzati nel fit a 4 variabili
00823     double c4= c2*a1-c1*a2;
00824     double d4= d2*a1-d1*a2;
00825     double b5= a1*b3-a3*b1;
00826     double c5= a1*c3-a3*c1;
00827     double d5= a1*d3-d1*a3;
00828     double a6 = slt;
00829     double b6 = sltx;
00830     double c6 = st;
00831     double v6 = st2;    
00832     double d6 = slty;
00833     if (((c5*b4-c4*b5)*b4*a1)!=0) {
00834       nppar=3;
00835       chi2fit = 0.;
00836       cminf=(d5*b4-d4*b5)/(c5*b4-c4*b5);
00837       bminf=d4/b4 -cminf *c4/b4;
00838       aminf=(d1/a1 -cminf*c1/a1 -bminf*b1/a1);
00839 
00840       for (int j=0; j<nptfit; j++){
00841         double ypred = aminf + bminf*xfit[j];
00842         double dy = (yfit[j]-cminf*lfit[j] - ypred)/sigma;
00843         chi2fit = chi2fit + dy*dy;
00844 
00845       } //end loop chi2
00846       chi2fit3 = chi2fit;
00847       if (nptfit>3)
00848         chi2fitN3 = chi2fit /(nptfit-3);
00849 
00850     }
00851     else {
00852       cminf=0;
00853       bminf=b;
00854       aminf=a;
00855       chi2fit3 = chi2fit;
00856       chi2fitN3 = chi2fit /(nptfit-2);
00857     }
00858 
00859     bminf3=bminf;
00860     aminf3=aminf;
00861     cminf3=cminf;
00862     //          }  
00863     nppar3=nppar;
00864     if (debug)   cout << "   dt0= 0 : slope 2  = "<<b     << "  pos in  = " << a     <<" chi2fitN2 = " << chi2fitN2 <<"  nppar= " << nppar2 << " nptfit= " << nptfit <<endl;
00865     if (debug)  
00866       cout << "   dt0= 0 : slope 3  = "<<bminf << "  pos out = " << aminf <<" chi2fitN3 = " << chi2fitN3 <<"  nppar= " << nppar3 << " T0_ev ns= " << cminf/0.00543 <<endl;
00867     //***********************************
00868     //     cout << " vdrift_4parfit "<< vdrift_4parfit<<endl;
00869     if( (nptfit>=5) && vdrift_4parfit) { 
00870       double det = (a1*a1*(b2*v6 - b6*b6) - a1*(a2*a2*v6 - 2*a2*a6*b6 + a6*a6*b2 + b2*c6*c6 + b3*(b3*v6 - 2*b6*c6))
00871                     + a2*a2*c6*c6 + 2*a2*(a3*(b3*v6 - b6*c6) - a6*b3*c6) + a3*a3*(b6*b6 - b2*v6)
00872                     + a6*(2*a3*(b2*c6 - b3*b6) + a6*b3*b3)); 
00873 
00874       // the dv/vdrift correction may be computed  under vdrift_4parfit request;
00875       if (det != 0) { 
00876         nppar = 4;
00877         chi2fit =0;
00878         // computation of   a, b, c e v
00879         aminf = (a1*(a2*(b6*d6 - v6*d2) + a6*(b6*d2 - b2*d6) + d1*(b2*v6 - b6*b6)) - a2*(b3*(c6*d6 - v6*d3)
00880                                                                                          + c6*(b6*d3 - c6*d2)) + a3*(b2*(c6*d6 - v6*d3) + b3*(v6*d2 - b6*d6) + b6*(b6*d3 - c6*d2))
00881                  + a6*(b2*c6*d3 + b3*(b3*d6 - b6*d3 - c6*d2)) - d1*(b2*c6*c6 + b3*(b3*v6 - 2*b6*c6)))/det;
00882         bminf = - (a1*a1*(b6*d6 - v6*d2) - a1*(a2*(a6*d6 - v6*d1) - a6*a6*d2 + a6*b6*d1 + b3*(c6*d6 - v6*d3)
00883                                                + c6*(b6*d3 - c6*d2)) + a2*(a3*(c6*d6 - v6*d3) + c6*(a6*d3 - c6*d1)) + a3*a3*(v6*d2 - b6*d6)
00884                    + a3*(a6*(b3*d6 + b6*d3 - 2*c6*d2) - d1*(b3*v6 - b6*c6)) - a6*b3*(a6*d3 - c6*d1))/det;
00885         cminf = -(a1*(b2*(c6*d6 - v6*d3) + b3*(v6*d2 - b6*d6) + b6*(b6*d3 - c6*d2)) + a2*a2*(v6*d3 - c6*d6)
00886                   + a2*(a3*(b6*d6 - v6*d2) + a6*(b3*d6 - 2*b6*d3 + c6*d2) - d1*(b3*v6 - b6*c6))
00887                   + a3*(d1*(b2*v6 - b6*b6) - a6*(b2*d6 - b6*d2)) + a6*(a6*(b2*d3 - b3*d2) - d1*(b2*c6 - b3*b6)))/det;
00888         vminf = - (a1*a1*(b2*d6 - b6*d2) - a1*(a2*a2*d6 - a2*(a6*d2 + b6*d1) + a6*b2*d1 + b2*c6*d3
00889                                                + b3*(b3*d6 - b6*d3 - c6*d2)) + a2*a2*c6*d3 + a2*(a3*(2*b3*d6 - b6*d3 - c6*d2) - b3*(a6*d3 + c6*d1))
00890                    + a3*a3*(b6*d2 - b2*d6) + a3*(a6*(b2*d3 - b3*d2) + d1*(b2*c6 - b3*b6)) + a6*b3*b3*d1)/det;
00891 
00892         //  chi 2
00893         for (int j=0; j<nptfit; j++) {
00894           //                    cout << "sigma " << sigma << endl;
00895           double ypred = aminf + bminf*xfit[j];
00896           double dy = (yfit[j]+vminf*lfit[j]*tfit[j]-cminf*lfit[j] -ypred)/sigma; 
00897           chi2fit = chi2fit + dy*dy;
00898 
00899         } //end loop chi2
00900         if (nptfit<=nppar){ 
00901           chi2fit4=chi2fit;  //set negative Chi2 if not a fit...;
00902           chi2fitN4=-1;
00903           //            cout << "nptfit " << nptfit << " nppar " << nppar << endl;
00904         }
00905         else{
00906           chi2fit4 = chi2fit ;
00907           chi2fitN4= chi2fit / (nptfit-nppar); 
00908         }
00909       }
00910       else {
00911         chi2fit4 = chi2fit;
00912         vminf=0.;
00913         if (nptfit <= nppar) {
00914           chi2fitN4=-1;
00915 
00916         }
00917         else{
00918           chi2fitN4     = chi2fit / (nptfit-nppar); 
00919 
00920         }
00921       }
00922       if (abs(vminf) >= 0.09) {
00923         // for safety and for code construction..dont accept correction on dv/vdrift greater then 0.09
00924         vminf=0;
00925         cminf=cminf3;
00926         aminf=aminf3;
00927         bminf=bminf3;
00928         nppar=3;
00929         chi2fit = chi2fit3;
00930       }
00931 
00932     }  //end if vdrift
00933     nppar4=nppar;
00934     //
00935 }  //end nptfit >=3
00936 
00937 if (debug)    cout << "   dt0= 0 : slope 4  = "<<bminf << "  pos out = " << aminf <<" chi2fitN4 = " << chi2fitN4 <<"  nppar= " <<nppar4<< " T0_ev ns= " << cminf/0.00543 <<" delta v = "<< vminf <<endl;
00938 if ((abs(vminf)>=0.09)&&debug ) {  //checks only vdrift less then 10 % accepted
00939   cout << "  vminf gt 0.09 det=  " <<  endl;
00940   cout << "   dt0= 0 : slope 4  = "<<bminf << "  pos out = " << aminf <<" chi2fitN4 = " << chi2fitN4 << " T0_ev ns= " << cminf/0.00543 <<" delta v = "<< vminf <<endl;
00941   cout << "   dt0= 0 : slope 2  = "<<b     << "  pos in  = " << a     <<" chi2fitN2 = " << chi2fitN2 <<"  nppar= " <<nppar-1<< " nptfit= " << nptfit <<endl;
00942   cout << "   dt0= 0 : slope 3  = "<<bminf << "  pos out = " << aminf <<" chi2fitN3 = " << chi2fitN3 << " T0_ev ns= " << cminf/0.00543 <<endl;
00943   cout << nptfit   <<" nptfit "<< "   end  chi2fit = " << chi2fit << "T0_ev ns= " << cminf/0.00543 << "delta v = "<< vminf <<endl;        
00944 }
00945 //   if (debug) cout << " 4-parameters fit:  " << " nppar= " <<nppar<< " nptfit= " <<nptfit<< endl;
00946 //   if (debug) cout << "   dt0= 0 : slope in = "<<b<< "  pos in = " << a <<endl;
00947 //   if (debug) cout << "   dt0= 0 : slope out = "<<bminf<< "  pos out = " << aminf <<endl;
00948 //   if (debug)  cout << nptfit   <<" nptfit "<< "   end  chi2fit = " << chi2fit << "T0_ev ns= " << cminf/0.00543 << "delta v = "<< vminf <<endl;
00949 //   chi2fit=-1000.; // chi2fit is the nomalized chi2 at the output end ;
00950 if (debug)  cout << nptfit   <<" nptfit "<< "   end  chi2fit = " << chi2fit/ (nptfit-nppar )<< "T0_ev ns= " << cminf/0.00543 << "delta v = "<< vminf <<endl;
00951 if (nptfit!= nppar) chi2fit     = chi2fit / (nptfit-nppar);
00952 
00953 
00954 }
00955 

Generated on Tue Jun 9 17:43:54 2009 for CMSSW by  doxygen 1.5.4