//*--- Author : V.Pechenov //*--- Modified: 23.01.07 V.Pechenov //*--- Modified: 16.06.2005 by V.Pechenov #include "hmdctrackfitterb.h" #include "hmdctrackfitpar.h" #include "hmdcsizescells.h" #include "hmdccal2parsim.h" #include "hsymmat.h" #include "hmdccal1sim.h" #include "hcategory.h" #include "hmdcclus.h" #include #include //_HADES_CLASS_DESCRIPTION ////////////////////////////////////////////////////////////////////////////// // // HMdcTrackFitterB // // Dubna track straight piece fitter. Version B. // It is tuned version of HMdcTrackFitterA. // ////////////////////////////////////////////////////////////////////////////// ClassImp(HMdcTrackFitterB) HMdcTrackFitterB::HMdcTrackFitterB(HMdcTrackFitInOut* fIO) : HMdcTrackFitterA(fIO) { } HMdcTrackFitterB::~HMdcTrackFitterB(void) { } //----------------------------------------------------- Int_t HMdcTrackFitterB::minimize(Int_t iter) { if(fprint) { printf("\n ********************************\n"); printf(" *** PROGRAM OF TRACK FITTING ***\n"); printf(" ********************************\n"); } wires.setSizeGrad2Matr(initParam); finalParam.copyLine(initParam); finalParam.setIterNumb(0); parMin.copyPlanes(initParam); pari.copyPlanes(initParam); tmpPar.copyPlanes(initParam); // Target scanning: Bool_t doTargScan=fitInOut->doTargScan; Bool_t noWightsFor3Iter=kFALSE; //kTRUE; Bool_t useTukeyInScan=kFALSE; Bool_t useNewErrorsForFirstIter=kFALSE; if(doTargScan) targetScan(useTukeyInScan); //********* Initialisation of fit ************************ stepFit=initStepFit; // init value of step return2to1 = 0; // counter wires.setInitWeghts(finalParam); if(useNewErrorsForFirstIter) wires.valueOfFunctAndErr(finalParam); else { wires.valueOfFunctional(finalParam); //??? wires.calcTdcErrorsAndFunct(finalParam); } iterAfterFilter=0; if(!noWightsFor3Iter && fitInOut->useTukey()) wires.filterOfHitsV2(finalParam,1); //!!!!!!!!!!!!!!??? //iterAfterFilter=-9; //!!!!!!!!!!!!!!!!!!! return doMinimization(); } void HMdcTrackFitterB::targetScan(Bool_t useTukeyInScan) { if(wires.getSegment()==1) return; HMdcSizesCellsSec& fSCSec=(*fitInOut->getMdcSizesCells())[wires.getSector()]; Int_t nTargets=fSCSec.getNumOfTargets(); HMdcClus* fClst=wires.getClust1(); if(nTargets>1) { for(Int_t nTg=0;nTggetX(), targ->getY(), targ->getZ(), wires.getXClst(),wires.getYClst(),wires.getZClst()); wires.valueOfFunctAndErr(parMin); if(useTukeyInScan) wires.filterOfHitsV2(parMin,1); wires.calcNGoodWiresAndChi2(parMin); if(fprint)printf("Scan: %i target. chi2/NDF=%g\n",nTg,parMin.getChi2()); if(nTg==0 || parMin.getChi2()setTarg(targ->getX(), targ->getY(), targ->getZ()); } wires.setUnitWeights(); } } else { const HGeomVector& firstTargPoint=fSCSec.getTargetFirstPoint(); const HGeomVector& lastTargPoint=fSCSec.getTargetLastPoint(); Double_t z1=firstTargPoint.getZ(); Double_t z2=lastTargPoint.getZ(); if(z2-z1 < 5.) return; Double_t xPl=wires.getXClst(); Double_t yPl=wires.getYClst(); Double_t zPl=wires.getZClst(); const HGeomVector& targ=fSCSec.getTargetMiddlePoint(); Double_t xTg=targ.getX(); Double_t yTg=targ.getY(); Double_t zMin=-5000.; for(Double_t z=z1;z<=z2;z+=2.5) { //!!!!!!!!!!!!!!!!!!!! parMin.setParam(xTg,yTg,z, xPl,yPl,zPl); //!!!!!!!!!!!!!!!!!!!! wires.valueOfFunctAndErr(parMin); if(useTukeyInScan) wires.filterOfHitsV2(parMin,1); wires.calcNGoodWiresAndChi2(parMin); if(fprint)printf("Scan: Ztarget=%5.1f chi2/NDF=%g\n",z,parMin.getChi2()); if(zMin<-4000. || parMin.getChi2()setTarg(xTg,yTg,z); } wires.setUnitWeights(); } } finalParam.setIterNumb(0); } Int_t HMdcTrackFitterB::firstMethod(void) { //*** 1-st method // function return minimizationMethod flag Double_t funct1beforeFilter=finalParam.functional(); // wires.calcDerivatives(finalParam,1); wires.calcAnalyticDerivatives1(finalParam); for(; iteration 0 && iterAfterFilter < 2) { // wires.calcDerivatives(finalParam,1); wires.calcAnalyticDerivatives1(finalParam); continue; } if((iterAfterFilter>=2 && ((finalParam>funct1beforeFilter && iteration>2) || finalParam.isFunctRelChangLess(limDeltaF1to2))) || finalParamuseTukey() && wires.filterOfHitsV2(finalParam)) iterAfterFilter=0; wires.calcTdcErrorsAndFunct(finalParam,1); return 2; // mini. method } if(iterAfterFilter == limIter1forFilter) { // ??? == Pochemu??? funct1beforeFilter = finalParam.functional(); if(fitInOut->useTukey() && wires.filterOfHitsV2(finalParam)) iterAfterFilter=0; wires.calcTdcErrorsAndFunct(finalParam); } // wires.calcDerivatives(finalParam,1); wires.calcAnalyticDerivatives1(finalParam); // Scaled gradiend calculation // ??? Pochemu proveryaetsya sc.gr.??? if(calcScaledAGrad(finalParam) finalParam) ? kFALSE:kTRUE; if(parMinEqFinalParam) { wires.valueOfFunctAndErr(parMin); finalParam.copyAllParam(parMin); if(!final && fitInOut->useTukey() && iterAfterFilter>=3) { wires.filterOfHitsV2(parMin); finalParam.copyAllParam(parMin); iterAfterFilter=0; continue; } } iteration2++; //*** Test for exit from minimization if(!final) { if(!pari.compare(parMin,limStep2,1.5) || (return2to1>0 && iteration2>=limIter2)) { // For filtering take the best parameters: if(!parMinEqFinalParam) wires.valueOfFunctional(finalParam); if(fitInOut->useTukey()) wires.filterOfHitsV2(finalParam); wires.valueOfFunctAndErr(finalParam); wires.setWeightsTo1or0(finalParam); // for finalParam! iterAfterFilter = -1000000; if(finalParam > 100000.0) return -5; // Too large functional ! parMin.copyAllParam(finalParam); final = kTRUE; iteration2 = 0; } else if(iteration2 >= limIter2) { // For filtering take the best parameters: if(!parMinEqFinalParam) wires.valueOfFunctional(finalParam); if(fitInOut->useTukey() && wires.filterOfHitsV2(finalParam)) iterAfterFilter=0; wires.calcTdcErrorsAndFunct(finalParam); iteration2 = 0; return2to1++; return 1; // go back to the first method } } else { if(parMinEqFinalParam) { wires.valueOfFunctAndErr(finalParam); if(iteration2>=2 && nTestTukey++<2 && wires.testTukeyWeights(finalParam)) iteration2=0; finalParam.saveFunct(); parMin.copyAllParam(finalParam); // wires.calcDerivatives(finalParam,2); // if(wires.getAGrad() < limGrad2) return -1; // return exit flag 1 if(wires.calcAGradAnalyt(finalParam) < limGrad2) return -1; // return exit flag 1 if(iteration2 < 2) continue; if(!pari.compare(finalParam,limStep2)) return -2; // return exit flag 2 if(iteration2 >= limIter2) return -3; // return exit flag 3 nFinalNeg=0; } else { nFinalNeg++; if(nFinalNeg<3) iteration2--; // Try three times else if(nFinalNeg<6) { // Try three times wires.valueOfFunctAndErr(finalParam); if(wires.testTukeyWeights(finalParam)) iteration2=0; finalParam.saveFunct(); if(wires.calcAGradAnalyt(finalParam) < limGrad2) return -1; // return exit flag 1 if(nFinalNeg>3 && !finalParam.compare(parMin,limStep2)) return -2; // return exit flag 2 parMin.copyAllParam(finalParam); iteration2--; } else { if(wires.calcAGradAnalyt(finalParam) < limGrad2) return -1; // return exit flag 1 if(iteration2 < 2) continue; if(!finalParam.compare(parMin,limStep2)) return -2; // return exit flag 2 if(iteration2 >= limIter2) return -3; // return exit flag 3 } } } } return -4; } void HMdcTrackFitterB::solutionOfLinearEquationsSystem(HMdcTrackParam& par) { // input : matrix grad2[i][j] (i-string, j-column), vector grad[i] // output: new param. in vector par[i] Double_t a[10][11]; Int_t ieq[10]; TMatrixD& grad2m=wires.getGrad2Matr(); Double_t* grad=wires.getGrad(); Int_t nmOfPar=par.getNumParam(); for(int i = 0; i < nmOfPar; i++) { for(int j = 0; j < nmOfPar; j++) a[i][j] = grad2m(i,j); a[i][nmOfPar] = -grad[i]; ieq[i] = -1; } Int_t iMax = 0; Int_t jMax = 0; for(int l = 0; l < nmOfPar; l++) { Double_t maxA = 0.0 ; for(int i = 0; i < nmOfPar; i++) { if(ieq[i] != -1) continue; for(int j = 0; j < nmOfPar; j++) { if(fabs(a[i][j]) <= maxA) continue; maxA = fabs(a[i][j]); iMax = i; jMax = j; } } ieq[iMax] = jMax; Double_t corr = a[iMax][jMax]; for(int j = 0; j <= nmOfPar; j++) a[iMax][j] /= corr; for(int i = 0; i < nmOfPar; i++) { if(i == iMax) continue; corr = a[i][jMax]; for(int j = 0; j <= nmOfPar; j++) a[i][j] -= a[iMax][j]*corr; } } //printf("slI: "); par.printParam(); //Bool_t jump=kFALSE; for(int i = 0; i < nmOfPar; i++) { Int_t iout = ieq[i]; //if(iout>=0 && fabs(a[i][nmOfPar])>100.) { // printf("jump for par.%i on %f\n",iout,a[i][nmOfPar]); // jump=kTRUE; //} if(iout>=0) par.addToParam(iout,a[i][nmOfPar]); //!!! } //if(jump) grad2m.Print(); //printf("slO: "); par.printParam(); wires.valueOfFunctional(par); par.incIterNumb(); }