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