00001
00012
00013 #include "RecoLocalMuon/DTSegment/src/DTSegmentUpdator.h"
00014
00015
00016
00017
00018 #include "DataFormats/DTRecHit/interface/DTChamberRecSegment2D.h"
00019
00020 #include "DataFormats/DTRecHit/interface/DTRecSegment2D.h"
00021 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
00022 #include "DataFormats/DTRecHit/interface/DTChamberRecSegment2D.h"
00023 #include "DataFormats/DTRecHit/interface/DTRecSegment4D.h"
00024 #include "DataFormats/DTRecHit/interface/DTRecHit1D.h"
00025 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
00026
00027 #include "RecoLocalMuon/DTSegment/src/DTSegmentCand.h"
00028 #include "RecoLocalMuon/DTRecHit/interface/DTRecHitAlgoFactory.h"
00029 #include "RecoLocalMuon/DTSegment/src/DTLinearFit.h"
00030
00031 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00032 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00033 #include "Geometry/DTGeometry/interface/DTLayer.h"
00034
00035 #include "FWCore/Utilities/interface/Exception.h"
00036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00037 #include "FWCore/Framework/interface/EventSetup.h"
00038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00039
00040
00041 #include <string>
00042
00043 using namespace std;
00044 using namespace edm;
00045
00046
00047
00049 DTSegmentUpdator::DTSegmentUpdator(const ParameterSet& config) :
00050 theFitter(new DTLinearFit()) ,
00051 vdrift_4parfit(config.getParameter<bool>("performT0_vdriftSegCorrection")),
00052 T0_hit_resolution(config.getParameter<double>("hit_afterT0_resolution")),
00053 perform_delta_rejecting(config.getParameter<bool>("perform_delta_rejecting")),
00054 debug(config.getUntrackedParameter<bool>("debug",false))
00055 {
00056 string theAlgoName = config.getParameter<string>("recAlgo");
00057 theAlgo = DTRecHitAlgoFactory::get()->create(theAlgoName,
00058 config.getParameter<ParameterSet>("recAlgoConfig"));
00059
00060 if(debug)
00061 cout << "[DTSegmentUpdator] Constructor called" << endl;
00062 }
00063
00065 DTSegmentUpdator::~DTSegmentUpdator() {
00066 delete theFitter;
00067 }
00068
00069
00070
00071 void DTSegmentUpdator::setES(const EventSetup& setup){
00072 setup.get<MuonGeometryRecord>().get(theGeom);
00073 theAlgo->setES(setup);
00074 }
00075
00076 void DTSegmentUpdator::update(DTRecSegment4D* seg, const bool calcT0) const {
00077
00078 if(debug) cout << "[DTSegmentUpdator] Starting to update the segment" << endl;
00079
00080 const bool hasPhi = seg->hasPhi();
00081 const bool hasZed = seg->hasZed();
00082
00083
00084 if(perform_delta_rejecting && hasPhi) rejectBadHits(seg->phiSegment());
00085
00086 int step = (hasPhi && hasZed) ? 3 : 2;
00087 if(calcT0) step = 4;
00088
00089 if(debug) cout << "Step of update is " << step << endl;
00090
00091 GlobalPoint pos = theGeom->idToDet(seg->geographicalId())->toGlobal(seg->localPosition());
00092 GlobalVector dir = theGeom->idToDet(seg->geographicalId())->toGlobal(seg->localDirection());
00093
00094 if(calcT0) calculateT0corr(seg);
00095
00096 if(hasPhi) updateHits(seg->phiSegment(),pos,dir,step);
00097 if(hasZed) updateHits(seg->zSegment() ,pos,dir,step);
00098
00099 fit(seg);
00100 }
00101
00102 void DTSegmentUpdator::update(DTRecSegment2D* seg) const {
00103 GlobalPoint pos = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localPosition());
00104 GlobalVector dir = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localDirection());
00105
00106 updateHits(seg,pos,dir);
00107 fit(seg);
00108 }
00109
00110 void DTSegmentUpdator::fit(DTRecSegment4D* seg) const {
00111
00112 if(seg->hasPhi()) fit(seg->phiSegment());
00113 if(seg->hasZed()) fit(seg->zSegment());
00114
00115 const DTChamber* theChamber = theGeom->chamber(seg->chamberId());
00116
00117 if(seg->hasPhi() && seg->hasZed() ) {
00118
00119 DTChamberRecSegment2D *segPhi=seg->phiSegment();
00120 DTSLRecSegment2D *segZed=seg->zSegment();
00121
00122
00123 LocalPoint posPhiInCh = segPhi->localPosition();
00124 LocalVector dirPhiInCh= segPhi->localDirection();
00125
00126
00127 const DTSuperLayer* zSL = theChamber->superLayer(segZed->superLayerId());
00128 LocalPoint zPos(segZed->localPosition().x(),
00129 (zSL->toLocal(theChamber->toGlobal(segPhi->localPosition()))).y(),
00130 0.);
00131
00132 LocalPoint posZInCh = theChamber->toLocal(zSL->toGlobal(zPos));
00133
00134 LocalVector dirZInCh = theChamber->toLocal(zSL->toGlobal(segZed->localDirection()));
00135
00136 LocalPoint posZAt0 = posZInCh + dirZInCh*(-posZInCh.z())/cos(dirZInCh.theta());
00137
00138
00139
00140 LocalVector dir=LocalVector(dirPhiInCh.x()/fabs(dirPhiInCh.z()),dirZInCh.y()/fabs(dirZInCh.z()),-1.);
00141
00142 seg->setPosition(LocalPoint(posPhiInCh.x(),posZAt0.y(),0.));
00143 seg->setDirection(dir.unit());
00144
00145 AlgebraicSymMatrix mat(4);
00146
00147
00148 mat[0][0] = segPhi->parametersError()[0][0];
00149 mat[0][2] = segPhi->parametersError()[0][1];
00150 mat[2][2] = segPhi->parametersError()[1][1];
00151
00152 seg->setCovMatrix(mat);
00153 seg->setCovMatrixForZed(posZInCh);
00154
00155 }
00156
00157 else if (seg->hasPhi()) {
00158 DTChamberRecSegment2D *segPhi=seg->phiSegment();
00159
00160 seg->setPosition(segPhi->localPosition());
00161 seg->setDirection(segPhi->localDirection());
00162
00163 AlgebraicSymMatrix mat(4);
00164
00165 mat[0][0] = segPhi->parametersError()[0][0];
00166 mat[0][2] = segPhi->parametersError()[0][1];
00167 mat[2][2] = segPhi->parametersError()[1][1];
00168
00169 seg->setCovMatrix(mat);
00170 }
00171
00172 else if (seg->hasZed()) {
00173 DTSLRecSegment2D *segZed = seg->zSegment();
00174
00175
00176 GlobalPoint glbPosZ = ( theGeom->superLayer(segZed->superLayerId()) )->toGlobal(segZed->localPosition());
00177 LocalPoint posZInCh = ( theGeom->chamber(segZed->superLayerId().chamberId()) )->toLocal(glbPosZ);
00178
00179 GlobalVector glbDirZ = (theGeom->superLayer(segZed->superLayerId()) )->toGlobal(segZed->localDirection());
00180 LocalVector dirZInCh = (theGeom->chamber(segZed->superLayerId().chamberId()) )->toLocal(glbDirZ);
00181
00182 LocalPoint posZAt0 = posZInCh+
00183 dirZInCh*(-posZInCh.z())/cos(dirZInCh.theta());
00184
00185 seg->setPosition(posZAt0);
00186 seg->setDirection(dirZInCh);
00187
00188 AlgebraicSymMatrix mat(4);
00189
00190 seg->setCovMatrix(mat);
00191 seg->setCovMatrixForZed(posZInCh);
00192 }
00193 }
00194
00195 bool DTSegmentUpdator::fit(DTSegmentCand* seg) const {
00196 if (!seg->good()) return false;
00197
00198 vector<float> x;
00199 vector<float> y;
00200 vector<float> sigy;
00201
00202 DTSegmentCand::AssPointCont hits=seg->hits();
00203 for (DTSegmentCand::AssPointCont::const_iterator iter=hits.begin();
00204 iter!=hits.end(); ++iter) {
00205 LocalPoint pos = (*iter).first->localPosition((*iter).second);
00206 x.push_back(pos.z());
00207 y.push_back(pos.x());
00208 sigy.push_back(sqrt((*iter).first->localPositionError().xx()));
00209 }
00210
00211 LocalPoint pos;
00212 LocalVector dir;
00213 AlgebraicSymMatrix covMat(2);
00214
00215 double chi2 = 0.;
00216 fit(x,y,sigy,pos,dir,covMat,chi2);
00217
00218 seg->setPosition(pos);
00219 seg->setDirection(dir);
00220
00221
00222
00223
00224 seg->setCovMatrix(covMat);
00225
00226
00227 seg->setChi2(chi2);
00228 return true;
00229 }
00230
00231 void DTSegmentUpdator::fit(DTRecSegment2D* seg) const {
00232
00233
00234
00235 vector<float> x;
00236 vector<float> y;
00237 vector<float> sigy;
00238
00239 vector<DTRecHit1D> hits=seg->specificRecHits();
00240 for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00241 hit!=hits.end(); ++hit) {
00242
00243
00244 GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00245 LocalPoint pos = ( theGeom->idToDet(seg->geographicalId()) )->toLocal(glbPos);
00246
00247 x.push_back(pos.z());
00248 y.push_back(pos.x());
00249
00250
00251
00252 ErrorFrameTransformer tran;
00253 GlobalError glbErr =
00254 tran.transform( hit->localPositionError(),(theGeom->layer( hit->wireId().layerId() ))->surface());
00255 LocalError slErr =
00256 tran.transform( glbErr, (theGeom->idToDet(seg->geographicalId()))->surface());
00257
00258 sigy.push_back(sqrt(slErr.xx()));
00259 }
00260
00261 LocalPoint pos;
00262 LocalVector dir;
00263 AlgebraicSymMatrix covMat(2);
00264 double chi2 = 0.;
00265
00266 fit(x,y,sigy,pos,dir,covMat,chi2);
00267
00268 seg->setPosition(pos);
00269 seg->setDirection(dir);
00270
00271
00272
00273
00274 seg->setCovMatrix(covMat);
00275
00276
00277 seg->setChi2(chi2);
00278 }
00279
00280 void DTSegmentUpdator::fit(const vector<float>& x,
00281 const vector<float>& y,
00282 const vector<float>& sigy,
00283 LocalPoint& pos,
00284 LocalVector& dir,
00285 AlgebraicSymMatrix& covMatrix,
00286 double& chi2) const {
00287
00288 float slope = 0.;
00289 float intercept = 0.;
00290 float covss = 0.;
00291 float covii = 0.;
00292 float covsi = 0.;
00293
00294
00295 theFitter->fit(x,y,x.size(),sigy,slope,intercept,covss,covii,covsi);
00296
00297
00298
00299
00300
00301
00302 pos = LocalPoint(intercept,0.,0.);
00303
00304
00305
00306 dir = LocalVector(-slope,0.,-1.).unit();
00307
00308 covMatrix = AlgebraicSymMatrix(2);
00309 covMatrix[0][0] = covss;
00310 covMatrix[1][1] = covii;
00311 covMatrix[1][0] = covsi;
00312
00313
00314 chi2 = 0.;
00315 for(unsigned int i=0; i<x.size() ; ++i) {
00316 double resid= y[i] - (intercept + slope*x[i]);
00317 chi2 += (resid/sigy[i])*(resid/sigy[i]);
00318 }
00319 }
00320
00321
00322
00323 void DTSegmentUpdator::updateHits(DTRecSegment2D* seg, GlobalPoint &gpos,
00324 GlobalVector &gdir, const int step) const{
00325
00326
00327
00328
00329 vector<DTRecHit1D> toBeUpdatedRecHits = seg->specificRecHits();
00330 vector<DTRecHit1D> updatedRecHits;
00331
00332 for (vector<DTRecHit1D>::iterator hit= toBeUpdatedRecHits.begin();
00333 hit!=toBeUpdatedRecHits.end(); ++hit) {
00334
00335 const DTLayer* layer = theGeom->layer( hit->wireId().layerId() );
00336
00337 LocalPoint segPos=layer->toLocal(gpos);
00338 LocalVector segDir=layer->toLocal(gdir);
00339
00340
00341 const float angle = atan(segDir.x()/-segDir.z());
00342
00343
00344 LocalPoint segPosAtLayer=segPos+segDir*(-segPos.z())/cos(segDir.theta());
00345
00346 DTRecHit1D newHit1D = (*hit);
00347
00348 bool ok = true;
00349
00350 if (step == 2) {
00351 ok = theAlgo->compute(layer,*hit,angle,newHit1D);
00352
00353 } else if (step == 3) {
00354
00355 LocalPoint hitPos(hit->localPosition().x(),+segPosAtLayer.y(),0.);
00356
00357 GlobalPoint glbpos= theGeom->layer( hit->wireId().layerId() )->toGlobal(hitPos);
00358
00359 newHit1D.setPosition(hitPos);
00360
00361 ok = theAlgo->compute(layer,*hit,angle,glbpos,newHit1D);
00362
00363 } else if (step == 4) {
00364
00365
00366 double vminf =0.;
00367 if(vdrift_4parfit) vminf = seg->vDrift();
00368
00369 double cminf = 0.;
00370 if(seg->ist0Valid()) cminf = - seg->t0()*0.00543;
00371
00372
00373
00374
00375
00376 const float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
00377 const float distance = fabs(hit->localPosition().x() - xwire);
00378
00379 const int ilc = ( hit->lrSide() == DTEnums::Left ) ? 1 : -1;
00380
00381 const double dy_corr = (vminf*ilc*distance-cminf*ilc );
00382
00383 LocalPoint point(hit->localPosition().x() + dy_corr, +segPosAtLayer.y(), 0.);
00384
00385
00386
00387
00388
00389 LocalError error(T0_hit_resolution*T0_hit_resolution,0.,0.);
00390
00391 newHit1D.setPositionAndError(point, error);
00392
00393
00394 ok = true;
00395
00396 } else throw cms::Exception("DTSegmentUpdator")<<" updateHits called with wrong step " << endl;
00397
00398 if (ok) updatedRecHits.push_back(newHit1D);
00399 else {
00400 LogError("DTSegmentUpdator")<<"DTSegmentUpdator::updateHits failed update" << endl;
00401 throw cms::Exception("DTSegmentUpdator")<<"updateHits failed update"<<endl;
00402 }
00403
00404 }
00405 seg->update(updatedRecHits);
00406 }
00407
00408 void DTSegmentUpdator::rejectBadHits(DTChamberRecSegment2D* phiSeg) const {
00409
00410 vector<float> x;
00411 vector<float> y;
00412
00413 if(debug) cout << " Inside the segment updator, now loop on hits: ( x == z_loc , y == x_loc) " << endl;
00414
00415 vector<DTRecHit1D> hits = phiSeg->specificRecHits();
00416 for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00417 hit!=hits.end(); ++hit) {
00418
00419
00420 GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00421 LocalPoint pos = ( theGeom->idToDet(phiSeg->geographicalId()) )->toLocal(glbPos);
00422
00423 x.push_back(pos.z());
00424 y.push_back(pos.x());
00425 }
00426
00427 if(debug){
00428 cout << " end of segment! " << endl;
00429 cout << " size = Number of Hits: " << x.size() << " " << y.size() << endl;
00430 }
00431
00432
00433 float par[2]={0.,0.};
00434
00435
00436 float Sx = 0.;
00437 float Sy = 0.;
00438 float Sx2 = 0.;
00439 float Sy2 = 0.;
00440 float Sxy = 0.;
00441
00442 size_t N = x.size();
00443
00444 for(size_t i = 0; i < N;++i){
00445 Sx += x.at(i);
00446 Sy += y.at(i);
00447 Sx2 += x.at(i)*x.at(i);
00448 Sy2 += y.at(i)*y.at(i);
00449 Sxy += x.at(i)*y.at(i);
00450
00451 }
00452
00453 const float delta = N*Sx2 - Sx*Sx;
00454 par[0] = ( Sx2*Sy - Sx*Sxy )/delta;
00455 par[1] = ( N*Sxy - Sx*Sy )/delta;
00456
00457 if(debug) cout << "fit 2 parameters done ----> par0: "<< par[0] << " par1: "<< par[1] << endl;
00458
00459
00460 float residuals[N];
00461
00462 for(size_t i = 0; i < N;++i)
00463 residuals[i] = 0;
00464
00465 for(size_t i = 0; i < N;++i){
00466 residuals[i] = y.at(i) - par[1]*x.at(i) - par[0];
00467 if(debug){
00468 cout<<" i: "<<i<<" y_i "<<y.at(i)<<" x_i "<<x.at(i)<<" res_i "<<residuals[i];
00469 if (i==N-1) cout<<endl;
00470 }
00471 }
00472
00473 if(debug) cout << " Residuals computed! "<< endl;
00474
00475
00476
00477 vector<DTRecHit1D> updatedRecHits;
00478
00479 float mean_residual = 0.;
00480
00481 for (size_t i = 0; i < N; ++i)
00482 mean_residual += fabs(residuals[i]);
00483
00484 mean_residual = mean_residual/(N - 2);
00485
00486 if(debug) cout << " mean_residual: "<< mean_residual << endl;
00487
00488 int i = 0;
00489
00490 for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00491 hit!=hits.end(); ++hit) {
00492
00493 DTRecHit1D newHit1D = (*hit);
00494
00495 float normResidual = mean_residual > 0 ? fabs(residuals[i])/mean_residual : 0;
00496 if(normResidual < 1.5){
00497
00498 updatedRecHits.push_back(newHit1D);
00499 if(debug) cout << " accepted "<< i+1 << "th hit" <<" Irej: " << normResidual << endl;
00500 ++i;
00501 }
00502 else {
00503 if(debug) cout << " rejected "<< i+1 << "th hit" <<" Irej: " << normResidual << endl;
00504 ++i;
00505 continue;
00506 }
00507 }
00508
00509 phiSeg->update(updatedRecHits);
00510
00511
00512 if(debug){
00513
00514 vector<float> x_upd;
00515 vector<float> y_upd;
00516
00517 cout << " Check the update action: " << endl;
00518
00519 vector<DTRecHit1D> hits_upd = phiSeg->specificRecHits();
00520 for (vector<DTRecHit1D>::const_iterator hit=hits_upd.begin();
00521 hit!=hits_upd.end(); ++hit) {
00522
00523
00524 GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00525 LocalPoint pos = ( theGeom->idToDet(phiSeg->geographicalId()) )->toLocal(glbPos);
00526
00527 x_upd.push_back(pos.z());
00528 y_upd.push_back(pos.x());
00529
00530 cout << " x_upd: "<< pos.z() << " y_upd: "<< pos.x() << endl;
00531
00532
00533 }
00534
00535 cout << " end of segment! " << endl;
00536 cout << " size = Number of Hits: " << x_upd.size() << " " << y_upd.size() << endl;
00537
00538 }
00539
00540 return;
00541 }
00542
00543 void DTSegmentUpdator::calculateT0corr(DTRecSegment4D* seg) const {
00544 if(seg->hasPhi()) calculateT0corr(seg->phiSegment());
00545 if(seg->hasZed()) calculateT0corr(seg->zSegment());
00546 }
00547
00548 void DTSegmentUpdator::calculateT0corr(DTRecSegment2D* seg) const {
00549
00550
00551
00552 vector<double> d_drift;
00553 vector<float> x;
00554 vector<float> y;
00555 vector<int> lc;
00556
00557 vector<DTRecHit1D> hits=seg->specificRecHits();
00558
00559 DTWireId wireId;
00560 int nptfit = 0;
00561
00562 for (vector<DTRecHit1D>::const_iterator hit=hits.begin();
00563 hit!=hits.end(); ++hit) {
00564
00565
00566 GlobalPoint glbPos = ( theGeom->layer( hit->wireId().layerId() ) )->toGlobal(hit->localPosition());
00567 LocalPoint pos = ( theGeom->idToDet(seg->geographicalId()) )->toLocal(glbPos);
00568
00569 const DTLayer* layer = theGeom->layer( hit->wireId().layerId() );
00570 float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
00571 float distance = fabs(hit->localPosition().x() - xwire);
00572
00573 int ilc = ( hit->lrSide() == DTEnums::Left ) ? 1 : -1;
00574
00575 nptfit++;
00576 x.push_back(pos.z());
00577 y.push_back(pos.x());
00578 lc.push_back(ilc);
00579 d_drift.push_back(distance);
00580
00581
00582 }
00583
00584 double chi2fit = 0.;
00585 float cminf = 0.;
00586 double vminf = 0.;
00587
00588 if ( nptfit > 2 ) {
00589
00590 Fit4Var(x,y,lc,d_drift,nptfit,cminf,vminf,chi2fit);
00591
00592 double t0cor = -999.;
00593 if(cminf > -998.) t0cor = - cminf/0.00543 ;
00594
00595
00596
00597
00598
00599
00600 seg->setT0(t0cor);
00601 seg->setVdrift(vminf);
00602 }
00603 }
00604
00605
00606 void DTSegmentUpdator::Fit4Var(const vector<float>& xfit,
00607 const vector<float>& yfit,
00608 const vector<int>& lfit,
00609 const vector<double>& tfit,
00610 const int nptfit,
00611 float& cminf,
00612 double& vminf,
00613 double& chi2fit) const {
00614
00615 const double sigma = 0.0295;
00616 double aminf = 0.;
00617 double bminf = 0.;
00618 int nppar = 0;
00619 double sx = 0.;
00620 double sx2 = 0.;
00621 double sy = 0.;
00622 double sxy = 0.;
00623 double sl = 0.;
00624 double sl2 = 0.;
00625 double sly = 0.;
00626 double slx = 0.;
00627 double st = 0.;
00628 double st2 = 0.;
00629 double slt = 0.;
00630 double sltx = 0.;
00631 double slty = 0.;
00632 double chi2fitN2 = -1. ;
00633 double chi2fit3 = -1.;
00634 double chi2fitN3 = -1. ;
00635 double chi2fitN4 = -1.;
00636 float bminf3 = bminf;
00637 float aminf3 = aminf;
00638 float cminf3 = cminf;
00639 int nppar2 = 0;
00640 int nppar3 = 0;
00641 int nppar4 = 0;
00642
00643 cminf = -999.;
00644 vminf = 0.;
00645
00646 for (int j=0; j<nptfit; j++){
00647 sx = sx + xfit[j];
00648 sy = sy + yfit[j];
00649 sx2 = sx2 + xfit[j]*xfit[j];
00650 sxy = sxy + xfit[j]*yfit[j];
00651 sl = sl + lfit[j];
00652 sl2 = sl2 + lfit[j]*lfit[j];
00653 sly = sly + lfit[j]*yfit[j];
00654 slx = slx + lfit[j]*xfit[j];
00655 st = st + tfit[j];
00656 st2 = st2 + tfit[j] * tfit[j];
00657 slt = slt + lfit[j] * tfit[j];
00658 sltx = sltx + lfit[j] * tfit[j]*xfit[j];
00659 slty = slty + lfit[j] * tfit[j]*yfit[j];
00660
00661 }
00662
00663 const double delta = nptfit*sx2 - sx*sx;
00664
00665 double a = 0.;
00666 double b = 0.;
00667
00668 if (delta!=0){
00669 a = (sx2*sy - sx*sxy)/delta;
00670 b = (nptfit*sxy - sx*sy)/delta;
00671
00672
00673 for (int j=0; j<nptfit; j++){
00674 const double ypred = a + b*xfit[j];
00675 const double dy = (yfit[j] - ypred)/sigma;
00676 chi2fit = chi2fit + dy*dy;
00677 }
00678 }
00679
00680 bminf = b;
00681 aminf = a;
00682
00683 nppar = 2;
00684 nppar2 = nppar;
00685
00686 chi2fitN2 = chi2fit/(nptfit-2);
00687
00688
00689
00690 if (nptfit >= 3) {
00691
00692 const double d1 = sy;
00693 const double d2 = sxy;
00694 const double d3 = sly;
00695 const double c1 = sl;
00696 const double c2 = slx;
00697 const double c3 = sl2;
00698 const double b1 = sx;
00699 const double b2 = sx2;
00700 const double b3 = slx;
00701 const double a1 = nptfit;
00702 const double a2 = sx;
00703 const double a3 = sl;
00704
00705
00706 const double b4 = b2*a1-b1*a2;
00707 const double c4 = c2*a1-c1*a2;
00708 const double d4 = d2*a1-d1*a2;
00709 const double b5 = a1*b3-a3*b1;
00710 const double c5 = a1*c3-a3*c1;
00711 const double d5 = a1*d3-d1*a3;
00712 const double a6 = slt;
00713 const double b6 = sltx;
00714 const double c6 = st;
00715 const double v6 = st2;
00716 const double d6 = slty;
00717
00718 if (((c5*b4-c4*b5)*b4*a1)!=0) {
00719 nppar = 3;
00720 chi2fit = 0.;
00721 cminf = (d5*b4-d4*b5)/(c5*b4-c4*b5);
00722 bminf = d4/b4 -cminf *c4/b4;
00723 aminf = (d1/a1 -cminf*c1/a1 -bminf*b1/a1);
00724
00725 for (int j=0; j<nptfit; j++){
00726 const double ypred = aminf + bminf*xfit[j];
00727 const double dy = (yfit[j]-cminf*lfit[j] - ypred)/sigma;
00728 chi2fit = chi2fit + dy*dy;
00729
00730 }
00731 chi2fit3 = chi2fit;
00732 if (nptfit>3)
00733 chi2fitN3 = chi2fit /(nptfit-3);
00734
00735 }
00736 else {
00737 cminf = -999.;
00738 bminf = b;
00739 aminf = a;
00740 chi2fit3 = chi2fit;
00741 chi2fitN3 = chi2fit /(nptfit-2);
00742 }
00743
00744 bminf3 = bminf;
00745 aminf3 = aminf;
00746 cminf3 = cminf;
00747 nppar3 = nppar;
00748
00749 if (debug) {
00750 cout << "dt0= 0 : slope 2 = " << b << " pos in = " << a << " chi2fitN2 = " << chi2fitN2
00751 << " nppar = " << nppar2 << " nptfit = " << nptfit << endl;
00752 cout << "dt0 = 0 : slope 3 = " << bminf << " pos out = " << aminf << " chi2fitN3 = "
00753 << chi2fitN3 << " nppar = " << nppar3 << " T0_ev ns = " << cminf/0.00543 << endl;
00754 }
00755
00756
00757
00758 if( nptfit>=5) {
00759 const 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))
00760 + a2*a2*c6*c6 + 2*a2*(a3*(b3*v6 - b6*c6) - a6*b3*c6) + a3*a3*(b6*b6 - b2*v6)
00761 + a6*(2*a3*(b2*c6 - b3*b6) + a6*b3*b3));
00762
00763
00764 if (det != 0) {
00765 nppar = 4;
00766 chi2fit = 0.;
00767
00768 aminf = (a1*(a2*(b6*d6 - v6*d2) + a6*(b6*d2 - b2*d6) + d1*(b2*v6 - b6*b6)) - a2*(b3*(c6*d6 - v6*d3)
00769 + c6*(b6*d3 - c6*d2)) + a3*(b2*(c6*d6 - v6*d3) + b3*(v6*d2 - b6*d6) + b6*(b6*d3 - c6*d2))
00770 + a6*(b2*c6*d3 + b3*(b3*d6 - b6*d3 - c6*d2)) - d1*(b2*c6*c6 + b3*(b3*v6 - 2*b6*c6)))/det;
00771 bminf = - (a1*a1*(b6*d6 - v6*d2) - a1*(a2*(a6*d6 - v6*d1) - a6*a6*d2 + a6*b6*d1 + b3*(c6*d6 - v6*d3)
00772 + c6*(b6*d3 - c6*d2)) + a2*(a3*(c6*d6 - v6*d3) + c6*(a6*d3 - c6*d1)) + a3*a3*(v6*d2 - b6*d6)
00773 + a3*(a6*(b3*d6 + b6*d3 - 2*c6*d2) - d1*(b3*v6 - b6*c6)) - a6*b3*(a6*d3 - c6*d1))/det;
00774 cminf = -(a1*(b2*(c6*d6 - v6*d3) + b3*(v6*d2 - b6*d6) + b6*(b6*d3 - c6*d2)) + a2*a2*(v6*d3 - c6*d6)
00775 + a2*(a3*(b6*d6 - v6*d2) + a6*(b3*d6 - 2*b6*d3 + c6*d2) - d1*(b3*v6 - b6*c6))
00776 + a3*(d1*(b2*v6 - b6*b6) - a6*(b2*d6 - b6*d2)) + a6*(a6*(b2*d3 - b3*d2) - d1*(b2*c6 - b3*b6)))/det;
00777 vminf = - (a1*a1*(b2*d6 - b6*d2) - a1*(a2*a2*d6 - a2*(a6*d2 + b6*d1) + a6*b2*d1 + b2*c6*d3
00778 + 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))
00779 + a3*a3*(b6*d2 - b2*d6) + a3*(a6*(b2*d3 - b3*d2) + d1*(b2*c6 - b3*b6)) + a6*b3*b3*d1)/det;
00780
00781
00782 for (int j=0; j<nptfit; j++) {
00783 const double ypred = aminf + bminf*xfit[j];
00784 const double dy = (yfit[j]+vminf*lfit[j]*tfit[j]-cminf*lfit[j] -ypred)/sigma;
00785 chi2fit = chi2fit + dy*dy;
00786
00787 }
00788 if (nptfit<=nppar){
00789 chi2fitN4=-1;
00790
00791 }
00792 else{
00793 chi2fitN4= chi2fit / (nptfit-nppar);
00794 }
00795 }
00796 else {
00797 vminf = 0.;
00798
00799 if (nptfit <= nppar) chi2fitN4=-1;
00800 else chi2fitN4 = chi2fit / (nptfit-nppar);
00801 }
00802
00803 if (fabs(vminf) >= 0.29) {
00804
00805 vminf = 0.;
00806 cminf = cminf3;
00807 aminf = aminf3;
00808 bminf = bminf3;
00809 nppar = 3;
00810 chi2fit = chi2fit3;
00811 }
00812
00813 }
00814
00815 if(!vdrift_4parfit){
00816
00817 cminf = cminf3;
00818 aminf = aminf3;
00819 bminf = bminf3;
00820 nppar = 3;
00821 chi2fit = chi2fit3;
00822 }
00823
00824 nppar4 = nppar;
00825
00826 }
00827
00828 if (debug) {
00829 cout << " dt0= 0 : slope 4 = " << bminf << " pos out = " << aminf <<" chi2fitN4 = " << chi2fitN4
00830 << " nppar= " << nppar4 << " T0_ev ns= " << cminf/0.00543 <<" delta v = " << vminf <<endl;
00831 cout << nptfit << " nptfit " << " end chi2fit = " << chi2fit/ (nptfit-nppar ) << " T0_ev ns= " << cminf/0.00543 << " delta v = " << vminf <<endl;
00832 }
00833
00834 if ( fabs(vminf) >= 0.09 && debug ) {
00835 cout << "vminf gt 0.09 det= " << endl;
00836 cout << "dt0= 0 : slope 4 = "<< bminf << " pos out = " << aminf << " chi2fitN4 = " << chi2fitN4
00837 << " T0_ev ns = " << cminf/0.00543 << " delta v = "<< vminf << endl;
00838 cout << "dt0 = 0 : slope 2 = "<< b << " pos in = " << a <<" chi2fitN2 = " << chi2fitN2
00839 << " nppar = " << nppar-1 << " nptfit = " << nptfit <<endl;
00840 cout << "dt0 = 0 : slope 3 = " << bminf << " pos out = " << aminf << " chi2fitN3 = "
00841 << chi2fitN3 << " T0_ev ns = " << cminf/0.00543 << endl;
00842 cout << nptfit <<" nptfit "<< " end chi2fit = " << chi2fit << "T0_ev ns= " << cminf/0.00543 << "delta v = "<< vminf <<endl;
00843 }
00844
00845 if (nptfit != nppar) chi2fit = chi2fit / (nptfit-nppar);
00846 }