#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 <stdlib.h>
#include "TMatrixD.h"
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);
Bool_t doTargScan=fitInOut->getDoTargScanFlag();
Bool_t noWightsFor3Iter=kFALSE;
Bool_t useTukeyInScan=kFALSE;
Bool_t useNewErrorsForFirstIter=kFALSE;
if(!fitInOut->getCalcInitValueFlag() && doTargScan) targetScan(useTukeyInScan);
stepFit=initStepFit;
return2to1 = 0;
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);
return doMinimization();
}
Int_t HMdcTrackFitterB::doMinimization(void) {
Int_t minimizationMethod = 1;
for (iteration = 0; iteration < maxIteration; iteration++ ) {
if(minimizationMethod==1) {
minimizationMethod=firstMethod();
if(minimizationMethod<1) break;
} else if(minimizationMethod==2) {
minimizationMethod=secondMethod();
if(minimizationMethod<1) break;
}
}
exitFlag=(minimizationMethod<0) ? -minimizationMethod : 4;
if(fprint) printResult();
wires.valueOfFunctional(finalParam,2);
if(!wires.calcNGoodWiresAndChi2(finalParam)) return 0;
if(testChi2Cut() && exitFlag <= 3) {
if(wires.calcErrorsAnalyt(finalParam)) {
if(fprint) printf(" !!! GOOD EXIT !!!\n");
return 1;
}
exitFlag=5;
}
return 0;
}
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;nTg<nTargets;nTg++) {
HGeomVector* targ=fSCSec.getTarget(nTg);
parMin.setParam( targ->getX(), 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()<finalParam.getChi2()) {
finalParam.copyNewParam(parMin);
if(fClst) fClst->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()<finalParam.getChi2()) {
zMin=z;
finalParam.copyNewParam(parMin);
if(fClst) fClst->setTarg(xTg,yTg,z);
}
wires.setUnitWeights();
}
}
finalParam.setIterNumb(0);
}
Int_t HMdcTrackFitterB::firstMethod(void) {
Double_t funct1beforeFilter=finalParam.functional();
wires.calcAnalyticDerivatives1(finalParam);
for(; iteration<maxIteration; iteration++) {
downhillOnGradient(finalParam);
if(fprint) finalParam.printParam("out1");
iterAfterFilter++;
if(return2to1 > 0 && iterAfterFilter < 2) {
wires.calcAnalyticDerivatives1(finalParam);
continue;
}
if((iterAfterFilter>=2 && ((finalParam>funct1beforeFilter && iteration>2) ||
finalParam.isFunctRelChangLess(limDeltaF1to2))) ||
finalParam<limFunct1to2) {
wires.calcTdcErrorsAndFunct(finalParam,1);
return 2;
}
if(iterAfterFilter == limIter1forFilter) {
funct1beforeFilter = finalParam.functional();
if(fitInOut->useTukey() && wires.filterOfHitsV2(finalParam))
iterAfterFilter=0;
wires.calcTdcErrorsAndFunct(finalParam);
}
wires.calcAnalyticDerivatives1(finalParam);
if(calcScaledAGrad(finalParam)<limGrad1to2) {
if(fitInOut->useTukey() && wires.filterOfHitsV2(finalParam)) iterAfterFilter=0;
wires.calcTdcErrorsAndFunct(finalParam,1);
return 2;
}
}
return -4;
}
Int_t HMdcTrackFitterB::secondMethod(void) {
Int_t iteration2=0;
Int_t nTestTukey=0;
Int_t nFinalNeg=0;
Bool_t final = kFALSE;
parMin.copyAllParam(finalParam);
for(; iteration<maxIteration; iteration++) {
wires.calcAnalyticDerivatives2(parMin);
parMin.saveFunct();
pari.copyParam(parMin);
solutionOfLinearEquationsSystem(parMin);
if(fprint) parMin.printParam((final) ? "outF":"out2");
Bool_t parMinEqFinalParam = (parMin > 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++;
if(!final) {
if(!pari.compare(parMin,limStep2,1.5) ||
(return2to1>0 && iteration2>=limIter2)) {
if(!parMinEqFinalParam) wires.valueOfFunctional(finalParam);
if(fitInOut->useTukey()) wires.filterOfHitsV2(finalParam);
wires.valueOfFunctAndErr(finalParam);
wires.setWeightsTo1or0(finalParam);
iterAfterFilter = -1000000;
if(finalParam > 100000.0) return -5;
parMin.copyAllParam(finalParam);
final = kTRUE;
iteration2 = 0;
} else if(iteration2 >= limIter2) {
if(!parMinEqFinalParam) wires.valueOfFunctional(finalParam);
if(fitInOut->useTukey() && wires.filterOfHitsV2(finalParam))
iterAfterFilter=0;
wires.calcTdcErrorsAndFunct(finalParam);
iteration2 = 0;
return2to1++;
return 1;
}
} else {
if(parMinEqFinalParam) {
wires.valueOfFunctAndErr(finalParam);
if(iteration2>=2 && nTestTukey++<2 && wires.testTukeyWeights(finalParam))
iteration2=0;
finalParam.saveFunct();
parMin.copyAllParam(finalParam);
if(wires.calcAGradAnalyt(finalParam) < limGrad2) return -1;
if(iteration2 < 2) continue;
if(!pari.compare(finalParam,limStep2)) return -2;
if(iteration2 >= limIter2) return -3;
nFinalNeg=0;
} else {
nFinalNeg++;
if(nFinalNeg<3) iteration2--;
else if(nFinalNeg<6) {
wires.valueOfFunctAndErr(finalParam);
if(wires.testTukeyWeights(finalParam)) iteration2=0;
finalParam.saveFunct();
if(wires.calcAGradAnalyt(finalParam) < limGrad2) return -1;
if(nFinalNeg>3 && !finalParam.compare(parMin,limStep2)) return -2;
parMin.copyAllParam(finalParam);
iteration2--;
} else {
if(wires.calcAGradAnalyt(finalParam) < limGrad2) return -1;
if(iteration2 < 2) continue;
if(!finalParam.compare(parMin,limStep2)) return -2;
if(iteration2 >= limIter2) return -3;
}
}
}
}
return -4;
}
void HMdcTrackFitterB::solutionOfLinearEquationsSystem(HMdcTrackParam& par) {
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_t i = 0; i < nmOfPar; i++) {
for(Int_t 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_t l = 0; l < nmOfPar; l++) {
Double_t maxA = 0.0 ;
for(Int_t i = 0; i < nmOfPar; i++) {
if(ieq[i] != -1) continue;
for(Int_t 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_t j = 0; j <= nmOfPar; j++) a[iMax][j] /= corr;
for(Int_t i = 0; i < nmOfPar; i++) {
if(i == iMax) continue;
corr = a[i][jMax];
for(Int_t j = 0; j <= nmOfPar; j++) a[i][j] -= a[iMax][j]*corr;
}
}
for(Int_t i = 0; i < nmOfPar; i++) {
Int_t iout = ieq[i];
if(iout>=0) par.addToParam(iout,a[i][nmOfPar]);
}
wires.valueOfFunctional(par);
par.incIterNumb();
}
Last change: Sat May 22 13:04:02 2010
Last generated: 2010-05-22 13:04
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.