14 #include <TStopwatch.h> 29 #include <sys/types.h> 64 fNLagrangeConstraints(0),
68 fGloSolveStatus(kFailed),
98 fRecDataTreeName("AliMillePedeRecords_Data"),
99 fRecConsTreeName("AliMillePedeRecords_Consaints"),
100 fRecDataBranchName("Record_Data"),
101 fRecConsBranchName("Record_Consaints"),
103 fDataRecFName("/tmp/mp2_data_records.root"),
109 fConstrRecFName("/tmp/mp2_constraints_records.root"),
115 fUseRecordWeight(kTRUE),
125 fWghScl[0] = fWghScl[1] = -1;
130 TObject(src),fNLocPar(0),fNGloPar(0),fNGloParIni(0),fNGloSize(0),fNLocEquations(0),fIter(0),
131 fMaxIter(10),fNStdDev(3),fNGloConstraints(0),fNLagrangeConstraints(0),
132 fNLocFits(0),fNLocFitsRejected(0),
133 fNGloFix(0),fGloSolveStatus(0),fChi2CutFactor(0),fChi2CutRef(0),fResCutInit(0),
134 fResCut(0),fMinPntValid(1),fNGroupsSet(0),fParamGrID(0),fProcPnt(0),fVecBLoc(0),fDiagCGlo(0),fVecBGlo(0),
135 fInitPar(0),fDeltaPar(0),fSigmaPar(0),fIsLinear(0),fConstrUsed(0),fGlo2CGlo(0),fCGlo2Glo(0),
136 fMatCLoc(0),fMatCGlo(0),fMatCGloLoc(0),fFillIndex(0),fFillValue(0),
137 fRecDataTreeName(0),fRecConsTreeName(0),fRecDataBranchName(0),fRecConsBranchName(0),
138 fDataRecFName(0),fRecord(0),fDataRecFile(0),
139 fTreeData(0),fRecFileStatus(0),fConstrRecFName(0),fTreeConstr(0),fConsRecFile(0),fCurrRecDataID(0),
140 fCurrRecConstrID(0),fLocFitAdd(kTRUE),
141 fUseRecordWeight(kTRUE),
197 for (
int i=0;i<nGlo;i++) if (regroup[i]>=0) {ng++;
if (regroup[i]>maxPID) maxPID = regroup[i];}
199 AliInfo(Form(
"Regrouping is requested: from %d raw to %d formal globals grouped to %d real globals",nGlo,ng,maxPID));
205 if (lResCut>0)
fResCut = lResCut;
206 if (lNStdDev>0)
fNStdDev = lNStdDev;
275 if (
fTreeData) {
AliInfo(
"Data Records File is already initialized");
return kFALSE;}
293 if (!inpf.good()) {
AliInfo(Form(
"Failed on input records list %s\n",
fDataRecFName.Data()));
return kFALSE;}
296 while ( !(recfName.ReadLine(inpf)).eof() ) {
297 recfName = recfName.Strip(TString::kBoth,
' ');
298 if (recfName.BeginsWith(
"//") || recfName.BeginsWith(
"#") || !recfName.EndsWith(
".root")) {
299 AliInfo(Form(
"Skip %s\n",recfName.Data()));
303 recfName = recfName.Strip(TString::kBoth,
',');
304 recfName = recfName.Strip(TString::kBoth,
'"');
305 gSystem->ExpandPathName(recfName);
306 printf(
"Adding %s\n",recfName.Data());
307 ch->AddFile(recfName.Data());
311 Long64_t nent = ch->GetEntries();
312 if (nent<1) {
AliInfo(
"Obtained chain is empty");
return kFALSE;}
315 AliInfo(Form(
"Found %lld derivatives records",nent));
328 if (
fConsRecFile) {
AliInfo(
"Constraints Records File is already initialized");
return kFALSE;}
434 for (
int i=
fNLocPar; i--;) derlc[i] = 0.0;
458 double *derlc,
int nlc,
double lMeas,
double lSigma)
462 for (
int i=nlc;i--;) derlc[i] = 0.0;
463 for (
int i=ngb;i--;) dergb[i] = 0.0;
523 static int nrefSize = 0;
525 static Int_t *refLoc=0,*refGlo=0,*nrefLoc=0,*nrefGlo=0;
541 if (nrefSize<=nPoints) {
543 nrefSize = 2*(nPoints+1);
544 tmpA = refLoc; refLoc =
new Int_t[nrefSize];
if (tmpA) memcpy(refLoc,tmpA,nPoints*
sizeof(
int));
545 tmpA = refGlo; refGlo =
new Int_t[nrefSize];
if (tmpA) memcpy(refGlo,tmpA,nPoints*
sizeof(
int));
546 tmpA = nrefLoc; nrefLoc =
new Int_t[nrefSize];
if (tmpA) memcpy(nrefLoc,tmpA,nPoints*
sizeof(
int));
547 tmpA = nrefGlo; nrefGlo =
new Int_t[nrefSize];
if (tmpA) memcpy(nrefGlo,tmpA,nPoints*
sizeof(
int));
550 refLoc[nPoints] = ++cnt;
553 nrefLoc[nPoints] = nLoc;
555 refGlo[nPoints] = ++cnt;
558 nrefGlo[nPoints] = nGlo;
568 Int_t maxLocUsed = 0;
570 for (
int ip=nPoints;ip--;) {
580 for (
int i=nrefGlo[ip];i--;) {
586 else indGlo[i] = idtmp;
590 if (iID<0 ||
fSigmaPar[iID]<=0.)
continue;
596 for (
int i=nrefLoc[ip];i--;) {
597 fVecBLoc[ indLoc[i] ] += weight*resid*derLoc[i];
598 if (indLoc[i]>maxLocUsed) maxLocUsed = indLoc[i];
599 for (
int j=i+1;j--;) matCLoc(indLoc[i] ,indLoc[j]) += weight*derLoc[i]*derLoc[j];
613 AliInfo(
"Failed to solve locals by Cholesky, trying Gaussian Elimination");
615 AliInfo(
"Failed to solve locals by Gaussian Elimination, skip...");
624 if (localParams)
for (
int i=maxLocUsed; i--;) {
626 localParams[2*i+1] = TMath::Sqrt(TMath::Abs(matCLoc.
QueryDiag(i)));
632 for (
int ip=nPoints;ip--;) {
643 for (
int i=nrefLoc[ip];i--;) resid -= derLoc[i]*
fVecBLoc[ indLoc[i] ];
645 for (
int i=nrefGlo[ip];i--;) {
647 if ( iID<0 ||
fSigmaPar[iID] <= 0.)
continue;
653 double absres = TMath::Abs(resid);
661 lChi2 += weight*resid*resid ;
666 int nDoF = nEq-maxLocUsed;
667 lChi2 = (nDoF>0) ? lChi2/nDoF : 0;
689 for (
int ip=nPoints;ip--;) {
699 for (
int i=nrefGlo[ip];i--;) {
701 if ( iID<0 ||
fSigmaPar[iID] <= 0.)
continue;
706 for (
int ig=nrefGlo[ip];ig--;) {
707 int iIDg = indGlo[ig];
708 if ( iIDg<0 ||
fSigmaPar[iIDg] <= 0.)
continue;
710 else fVecBGlo[ iIDg ] -= weight*resid*derGlo[ig];
714 for (
int jg=ig+1;jg--;) {
715 int jIDg = indGlo[jg];
716 if ( jIDg<0 ||
fSigmaPar[jIDg] <= 0.)
continue;
717 if ( !
IsZero(vl = weight*derGlo[ig]*derGlo[jg]) ) {
727 Double_t *rowGL = matCGloLoc(nGloInFit);
728 for (
int k=maxLocUsed;k--;) rowGL[k] = 0.0;
733 Double_t *rowGLIDg = matCGloLoc(iCIDg);
734 for (
int il=nrefLoc[ip];il--;) rowGLIDg[ indLoc[il] ] += weight*derGlo[ig]*derLoc[il];
752 for (
int iCIDg=0; iCIDg<nGloInFit; iCIDg++) {
756 Double_t *rowGLIDg = matCGloLoc(iCIDg);
757 for (
int kl=0;kl<maxLocUsed;kl++)
if (rowGLIDg[kl]) vl += rowGLIDg[kl]*
fVecBLoc[kl];
761 for (
int jCIDg=0;jCIDg<=iCIDg; jCIDg++) {
765 Double_t *rowGLJDg = matCGloLoc(jCIDg);
766 for (
int kl=0;kl<maxLocUsed;kl++) {
768 if ( (!
IsZero(vll=rowGLIDg[kl]*rowGLJDg[kl])) ) vl += matCLoc.
QueryDiag(kl)*vll;
771 for (
int ll=0;ll<kl;ll++) {
772 if ( !
IsZero(vll=rowGLIDg[kl]*rowGLJDg[ll]) ) vl += matCLoc(kl,ll)*vll;
773 if ( !
IsZero(vll=rowGLIDg[ll]*rowGLJDg[kl]) ) vl += matCLoc(kl,ll)*vll;
791 for (
int i=nGloInFit;i--;) {
806 TStopwatch sw; sw.Start();
809 AliInfo(
"Starting Global fit.");
826 AliInfo(Form(
"Global fit %s, CPU time: %.1f",res ?
"Converged":
"Failed",sw.CpuTime()));
847 AliInfo(
"No data was stored, stopping iteration");
887 Long_t last = fSelLast<1 ? ndr : (fSelLast>=ndr ? ndr :
fSelLast+Long_t(1));
890 AliInfo(Form(
"Building the Global matrix from data records %ld : %ld",first,last));
893 TStopwatch swt; swt.Start();
895 for (Long_t i=0;i<ndr;i++) {
896 Long_t iev = i+first;
900 if ( (i%
int(0.2*ndr)) == 0)
printf(
"%.1f%% of local fits done\n",
double(100.*i)/ndr);
903 printf(
"%ld local fits done: ", ndr);
920 Int_t fixArrSize = 10;
921 Int_t nFixedGroups = 0;
922 TArrayI fixGroups(fixArrSize);
926 double oldMin = 1.e20;
927 double oldMax =-1.e20;
931 if (grID<0)
continue;
936 for (
int iold=oldStart;iold>i;iold--)
fProcPnt[iold] = 0;
938 for (
int j=nFixedGroups;j--;)
if (fixGroups[j]==grIDold) {fnd=kTRUE;
break;}
940 if (nFixedGroups>=fixArrSize) {fixArrSize*=2; fixGroups.Set(fixArrSize);}
941 fixGroups[nFixedGroups++] = grIDold;
956 for (
int iold=oldStart;iold--;)
fProcPnt[iold] = 0;
958 for (
int j=nFixedGroups;j--;)
if (fixGroups[j]==grIDold) {fnd=kTRUE;
break;}
960 if (nFixedGroups>=fixArrSize) {fixArrSize*=2; fixGroups.Set(fixArrSize);}
961 fixGroups[nFixedGroups++] = grIDold;
968 for (Long_t i=0;i<ndr;i++) {
969 Long_t iev = i+first;
972 Bool_t suppr = kFALSE;
980 for (
int i=0;i<nFixedGroups;i++)
printf(
"%d ",fixGroups[i]);
printf(
"\n");
1013 for (
int jp=csize;jp--;) {
1015 if (
fkReGroup[idp]<0)
AliFatal(Form(
"Constain is requested for suppressed parameter #%d",indV[jp]));
1021 int nSuppressed = 0;
1023 for (
int j=csize;j--;) {
1024 if (
fProcPnt[indV[j]]<1) nSuppressed++;
1026 maxStat = TMath::Max(maxStat,
fProcPnt[indV[j]]);
1030 if (nSuppressed==csize) {
1043 for (
int j=csize; j--;) val -= der[j]*(
fInitPar[ indV[j] ]+
fDeltaPar[ indV[j] ]);
1047 double sig2i = (
fgWeightSigma ? TMath::Sqrt(maxStat) : 1.)/sig/sig;
1048 for (
int ir=0;ir<csize;ir++) {
1050 for (
int ic=0;ic<=ir;ic++) {
1052 double vl = der[ir]*der[ic]*sig2i;
1053 if (!
IsZero(vl)) matCGlo(iID,jID) += vl;
1055 fVecBGlo[iID] += val*der[ir]*sig2i;
1059 for (
int j=csize; j--;) {
1071 AliInfo(Form(
"Obtained %-7ld equations from %-7ld records (%-7ld rejected). Fixed %-4d globals",
1077 #ifdef _DUMP_EQ_BEFORE_ 1078 const char* faildumpB = Form(
"mp2eq_before%d.dat",
fIter);
1079 int defoutB = dup(1);
1080 if (defoutB<0) {
AliFatal(
"Failed on dup"); exit(1);}
1081 int slvDumpB = open(faildumpB, O_RDWR|O_CREAT, 0666);
1085 matCGlo.
Print(
"10");
1098 #ifdef _DUMPEQ_BEFORE_ 1099 const char* faildumpB = Form(
"mp2eq_before%d.dat",
fIter);
1100 int defoutB = dup(1);
1101 int slvDumpB = open(faildumpB, O_RDWR|O_CREAT, 0666);
1115 #ifdef _DUMPEQ_AFTER_ 1116 const char* faildumpA = Form(
"mp2eq_after%d.dat",
fIter);
1117 int defoutA = dup(1);
1118 int slvDumpA = open(faildumpA, O_RDWR|O_CREAT, 0666);
1140 #ifdef _DUMP_EQ_AFTER_ 1141 const char* faildumpA = Form(
"mp2eq_after%d.dat",
fIter);
1142 int defoutA = dup(1);
1143 if (defoutA<0) {
AliFatal(
"Failed on dup"); exit(1);}
1144 int slvDumpA = open(faildumpA, O_RDWR|O_CREAT, 0666);
1147 printf(
"Solving%d for %d params\n",
fIter,fNGloSize);
1148 matCGlo.
Print(
"10");
1183 else AliInfo(
"Solution of Global Dense System by Cholesky failed, trying Gaussian Elimiation");
1187 else AliInfo(
"Solution of Global Dense System by Gaussian Elimination failed, trying iterative methods");
1195 Bool_t
res = kFALSE;
1204 const char* faildump =
"fgmr_failed.dat";
1205 int defout = dup(1);
1210 int slvDump = open(faildump, O_RDWR|O_CREAT, 0666);
1214 printf(
"#Failed to solve using solver %d with PreCond: %d MaxIter: %d Tol: %e NKrylov: %d\n",
1216 printf(
"#Dump of matrix:\n");
1218 printf(
"#Dump of RHS:\n");
1224 printf(
"#Dumped failed matrix and RHS to %s\n",faildump);
1226 else AliInfo(
"Failed on file open for matrix dumping");
1242 float sn[3] = {0.47523, 1.690140, 2.782170};
1243 float table[3][30] = {{1.0000, 1.1479, 1.1753, 1.1798, 1.1775, 1.1730, 1.1680, 1.1630,
1244 1.1581, 1.1536, 1.1493, 1.1454, 1.1417, 1.1383, 1.1351, 1.1321,
1245 1.1293, 1.1266, 1.1242, 1.1218, 1.1196, 1.1175, 1.1155, 1.1136,
1246 1.1119, 1.1101, 1.1085, 1.1070, 1.1055, 1.1040},
1247 {4.0000, 3.0900, 2.6750, 2.4290, 2.2628, 2.1415, 2.0481, 1.9736,
1248 1.9124, 1.8610, 1.8171, 1.7791, 1.7457, 1.7161, 1.6897, 1.6658,
1249 1.6442, 1.6246, 1.6065, 1.5899, 1.5745, 1.5603, 1.5470, 1.5346,
1250 1.5230, 1.5120, 1.5017, 1.4920, 1.4829, 1.4742},
1251 {9.0000, 5.9146, 4.7184, 4.0628, 3.6410, 3.3436, 3.1209, 2.9468,
1252 2.8063, 2.6902, 2.5922, 2.5082, 2.4352, 2.3711, 2.3143, 2.2635,
1253 2.2178, 2.1764, 2.1386, 2.1040, 2.0722, 2.0428, 2.0155, 1.9901,
1254 1.9665, 1.9443, 1.9235, 1.9040, 1.8855, 1.8681}};
1260 lNSig = TMath::Max(1,TMath::Min(nSig,3));
1263 return table[lNSig-1][nDoF-1];
1266 return ((sn[lNSig-1]+TMath::Sqrt(
float(2*nDoF-3)))*
1267 (sn[lNSig-1]+TMath::Sqrt(
float(2*nDoF-3))))/float(2*nDoF-2);
1294 if (res>=0)
return TMath::Sqrt(res);
1322 double lGlobalCor =0.;
1324 printf(
"\nMillePede2 output\n");
1325 printf(
" Result of fit for global parameters\n");
1326 printf(
" ===================================\n");
1327 printf(
" I initial final differ lastcor error gcor Npnt\n");
1328 printf(
"----------------------------------------------------------------------------------------------\n");
1330 int lastPrintedId = -1;
1332 int i =
GetRGId(i0);
if (i<0)
continue;
1333 if (i!=i0 && lastPrintedId>=0 && i<=lastPrintedId)
continue;
1340 lGlobalCor = TMath::Sqrt(TMath::Abs(1.0-1.0/(dg*
fDiagCGlo[i])));
1341 printf(
"%4d(%4d)\t %+.6f\t %+.6f\t %+.6f\t %.6f\t %.6f\t %.6f\t %6d\n",
1356 static Long_t prevRunID = kMaxInt;
1357 static Bool_t prevAns = kTRUE;
1359 if (runID!=prevRunID) {
1366 for (
int i=n;i--;)
if (runID == (*
fRejRunList)[i]) {
1368 AliInfo(Form(
"New Run to reject: %ld",runID));
1374 for (
int i=n;i--;)
if (runID == (*
fAccRunList)[i]) {
1377 AliInfo(Form(
"New Run to accept explicitly: %ld, weight=%f",runID,
fRunWgh));
1380 if (!prevAns)
AliInfo(Form(
"New Run is not in the list to accept: %ld",runID));
1394 if (nruns<1 || !runs)
return;
1396 for (
int i=0;i<nruns;i++) (*
fRejRunList)[i] = runs[i];
1406 if (nruns<1 || !runs)
return;
1409 for (
int i=0;i<nruns;i++) {
1410 (*fAccRunList)[i] = runs[i];
1411 (*fAccRunListWgh)[i] =wghList ? wghList[i] : 1.0;
1420 int id =
GetRGId(i);
if (
id<0)
continue;
1430 int id =
GetRGId(i);
if (
id<0)
continue;
1439 int id =
GetRGId(i);
if (
id<0)
return;
1447 int id =
GetRGId(i);
if (
id<0)
return;
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
TFile * Open(const char *filename, Long64_t &nevents)
int SolveSpmInv(double *vecB, Bool_t stabilize=kTRUE)
Bool_t IsZero(Double_t v, Double_t eps=1e-16) const
Bool_t InitConsRecStorage(Bool_t read=kFALSE)
virtual Double_t DiagElem(Int_t r) const =0
static Bool_t fgWeightSigma
void SetWeight(Double_t w=1)
AliRectMatrix * fMatCGloLoc
const char * GetRecDataBranchName() const
static Int_t fgMinResMaxIter
static Bool_t fgIsMatGloSparse
void SetRecordRun(Int_t run)
Double_t GetFinalError(int i) const
Int_t fNLagrangeConstraints
Double_t GetWeight() const
Double_t * GetValue() const
void SetGlobalConstraint(const double *dergb, double val, double sigma=0)
Bool_t InitDataRecStorage(Bool_t read=kFALSE)
void AddResidual(Double_t val)
const char * GetRecConsTreeName() const
virtual Double_t QueryDiag(Int_t rc) const
virtual void AddToRow(Int_t r, Double_t *valc, Int_t *indc, Int_t n)=0
Bool_t IsWeight(Int_t i) const
void SetRecordWeight(double wgh)
void Print(const Option_t *option="") const
Bool_t IsResidual(Int_t i) const
Bool_t SolveChol(Double_t *brhs, Bool_t invert=kFALSE)
void SetAccRunList(const UInt_t *runs, Int_t nruns, const Float_t *wghList=0)
Bool_t ImposeDataRecFile(const char *fname)
Double_t GetPull(int i) const
Bool_t SolveMinRes(Double_t *VecSol, Int_t precon=0, int itnlim=2000, double rtol=1e-12)
void SetConsRecFName(const char *flname)
void SetSigmaPars(const Double_t *par)
void AddIndexValue(Int_t ind, Double_t val)
Double_t GetParError(int iPar) const
Bool_t IsRecordAcceptable()
void ReadRecordData(Long_t recID)
static Double_t fgMinResTol
std::vector< RunInfo > runs
Double_t GetFinalParam(int i) const
Int_t InitMille(int nGlo, int nLoc, Int_t lNStdDev=-1, double lResCut=-1., double lResCutInit=-1., const Int_t *regroup=0)
const Char_t * GetConsRecFName() const
Long_t fCurrRecDataID
File of processed constraints records.
Bool_t ReadNextRecordConstraint()
void SetInitPars(const Double_t *par)
void ReadRecordConstraint(Long_t recID)
TFile * fConsRecFile
Tree of constraint records.
Bool_t IsGroupPresent(Int_t id) const
void SetDataRecFName(const char *flname)
Bool_t SolveFGMRES(Double_t *VecSol, Int_t precon=0, int itnlim=2000, double rtol=1e-12, int nkrylov=60)
#define AliFatal(message)
void SetSymmetric(Bool_t v=kTRUE)
Int_t LocalFit(double *localParams=0)
Int_t GlobalFitIteration()
void SaveRecordConstraint()
AliMillePedeRecord * fRecord
void SetInitPar(Int_t i, Double_t par)
Int_t GetRGId(Int_t i) const
void SetSigmaPar(Int_t i, Double_t par)
Float_t Chi2DoFLim(int nSig, int nDoF) const
void SetRunID(UInt_t run)
static Int_t fgMinResCondType
void CloseConsRecStorage()
void SetLocalEquation(double *dergb, double *derlc, double lMeas, double lSigma)
Bool_t ImposeConsRecFile(const char *fname)
Int_t * fGlo2CGlo
Flag for used constraints.
Int_t SetIterations(double lChi2CutFac)
void AddWeight(Double_t val)
const Char_t * GetDataRecFName() const
Int_t GlobalFit(Double_t *par=0, Double_t *error=0, Double_t *pull=0)
const char * GetRecDataTreeName() const
void CloseDataRecStorage()
Bool_t ReadNextRecordData()
virtual void Print(Option_t *option="") const =0
Double_t * fInitPar
Vector B global (parameters)
const char * GetRecConsBranchName() const
void SetRejRunList(const UInt_t *runs, Int_t nruns)
Int_t PrintGlobalParameters() const
void SetSizeUsed(Int_t sz)