]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliMillePede2.cxx
Optionally the log term of Rossi parameterization for mult.scattering can be
[u/mrichter/AliRoot.git] / STEER / AliMillePede2.cxx
index 4963e0d17023c26a3c0c170899cbd6568e205888..43e9ee7c9a7a957c2125faca28b5d71ec379603b 100644 (file)
 #include "AliLog.h"
 #include <TStopwatch.h>
 #include <TFile.h>
+#include <TChain.h>
 #include <TMath.h>
 #include <TVectorD.h>
+#include <TArrayL.h>
+#include <TSystem.h>
 #include "AliMatrixSq.h"
 #include "AliSymMatrix.h"
 #include "AliRectMatrix.h"
 #include "AliMatrixSparse.h"
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <fstream>
 
 using namespace std;
 
@@ -89,7 +98,11 @@ AliMillePede2::AliMillePede2()
   fConsRecFile(0),
   fCurrRecDataID(0),
   fCurrRecConstrID(0),
-  fLocFitAdd(kTRUE)
+  fLocFitAdd(kTRUE),
+  fSelFirst(1),
+  fSelLast(-1),
+  fRejRunList(0),
+  fAccRunList(0)
 {}
 
 //_____________________________________________________________________________________________
@@ -103,7 +116,11 @@ AliMillePede2::AliMillePede2(const AliMillePede2& src) :
   fMatCLoc(0),fMatCGlo(0),fMatCGloLoc(0),fFillIndex(0),fFillValue(0),
   fDataRecFName(0),fRecord(0),fDataRecFile(0),
   fTreeData(0),fRecFileStatus(0),fConstrRecFName(0),fTreeConstr(0),fConsRecFile(0),fCurrRecDataID(0),
-  fCurrRecConstrID(0),fLocFitAdd(kTRUE)
+  fCurrRecConstrID(0),fLocFitAdd(kTRUE),
+  fSelFirst(1),
+  fSelLast(-1),
+  fRejRunList(0),
+  fAccRunList(0)
 {printf("Dummy\n");}
 
 //_____________________________________________________________________________________________
@@ -131,6 +148,8 @@ AliMillePede2::~AliMillePede2()
   delete fMatCLoc;
   delete fMatCGlo;
   delete fMatCGloLoc;
+  delete fRejRunList;
+  delete fAccRunList;
 } 
 
 //_____________________________________________________________________________________________
@@ -211,24 +230,49 @@ Bool_t AliMillePede2::InitDataRecStorage(Bool_t read)
 {
   // initialize the buffer for processed measurements records
   //
-  if (fDataRecFile) {AliInfo("Data Records File is already initialized"); return kFALSE;} 
+  if (fTreeData) {AliInfo("Data Records File is already initialized"); return kFALSE;} 
   //
   if (!fRecord) fRecord = new AliMillePedeRecord();
   //
-  fDataRecFile = TFile::Open(GetDataRecFName(),read ? "":"recreate");
-  if (!fDataRecFile) {AliFatal(Form("Failed to initialize data records file %s",GetDataRecFName())); return kFALSE;}
-  //
-  AliInfo(Form("File %s used for derivatives records",GetDataRecFName()));
-  if (read) {
-    fTreeData = (TTree*)fDataRecFile->Get("AliMillePedeRecords_Data");
-    if (!fTreeData) {AliFatal(Form("Did not find data records tree in %s",GetDataRecFName())); return kFALSE;}
-    fTreeData->SetBranchAddress("Record_Data",&fRecord);
-    AliInfo(Form("Found %d derivatives records",fTreeData->GetEntries()));
-  }
-  else {
+  if (!read) { // write mode: cannot use chain
+    fDataRecFile = TFile::Open(GetDataRecFName(),"recreate");
+    if (!fDataRecFile) {AliFatal(Form("Failed to initialize data records file %s",GetDataRecFName())); return kFALSE;}
+    AliInfo(Form("File %s used for derivatives records",GetDataRecFName()));
     fTreeData = new TTree("AliMillePedeRecords_Data","Data Records for AliMillePede2");
     fTreeData->Branch("Record_Data","AliMillePedeRecord",&fRecord,32000,99);
   }
+  else { // use chain
+    TChain* ch = new TChain("AliMillePedeRecords_Data");
+    //
+    if (fDataRecFName.EndsWith(".root")) ch->AddFile(fDataRecFName);
+    else { // assume text file with list of filenames
+      //
+      ifstream inpf(fDataRecFName.Data());
+      if (!inpf.good()) {AliInfo(Form("Failed on input records list %s\n",fDataRecFName.Data())); return kFALSE;}
+      //
+      TString recfName;
+      recfName.ReadLine(inpf);
+      while ( !(recfName.ReadLine(inpf)).eof() ) {
+       recfName = recfName.Strip(TString::kBoth,' ');
+       if (recfName.BeginsWith("//") || recfName.BeginsWith("#") || !recfName.EndsWith(".root")) {  // comment
+         AliInfo(Form("Skip %s\n",recfName.Data()));
+         continue;
+       }
+       //
+       recfName = recfName.Strip(TString::kBoth,',');
+       recfName = recfName.Strip(TString::kBoth,'"');
+       gSystem->ExpandPathName(recfName);
+       printf("Adding %s\n",recfName.Data());
+       ch->AddFile(recfName.Data());
+      }      
+    }
+    //
+    Long64_t nent = ch->GetEntries();
+    if (nent<1) { AliInfo("Obtained chain is empty"); return kFALSE;}
+    fTreeData = ch;
+    fTreeData->SetBranchAddress("Record_Data",&fRecord);
+    AliInfo(Form("Found %lld derivatives records",nent));
+  }
   fCurrRecDataID = -1;
   fRecFileStatus = read ? 1:2;
   //
@@ -252,7 +296,7 @@ Bool_t AliMillePede2::InitConsRecStorage(Bool_t read)
     fTreeConstr = (TTree*)fConsRecFile->Get("AliMillePedeRecords_Constraints");
     if (!fTreeConstr) {AliInfo(Form("Did not find constraints records tree in %s",GetConsRecFName())); return kFALSE;}
     fTreeConstr->SetBranchAddress("Record_Constraints",&fRecord);
-    AliInfo(Form("Found %d constraints records",fTreeConstr->GetEntries()));
+    AliInfo(Form("Found %lld constraints records",fTreeConstr->GetEntries()));
     //
   }
   else {
@@ -269,15 +313,17 @@ Bool_t AliMillePede2::InitConsRecStorage(Bool_t read)
 void AliMillePede2::CloseDataRecStorage()
 {
   if (fTreeData) {
-    if (fDataRecFile->IsWritable()) {
+    if (fDataRecFile && fDataRecFile->IsWritable()) {
       fDataRecFile->cd();
       fTreeData->Write();
     }
     delete fTreeData;  
     fTreeData = 0;
-    fDataRecFile->Close();
-    delete fDataRecFile;
-    fDataRecFile = 0;
+    if (fDataRecFile) {
+      fDataRecFile->Close();
+      delete fDataRecFile;
+      fDataRecFile = 0;
+    }
   }
   fRecFileStatus = 0;
   //
@@ -325,6 +371,13 @@ void AliMillePede2::SetRecordWeight(double wgh)
   fRecord->SetWeight(wgh);
 }
 
+//_____________________________________________________________________________________________
+void AliMillePede2::SetRecordRun(Int_t run)
+{
+  if (fRecFileStatus<2) InitDataRecStorage(); // create a buffer to store the data
+  fRecord->SetRunID(run);
+}
+
 //_____________________________________________________________________________________________
 void AliMillePede2::SetLocalEquation(double *dergb, double *derlc, double lMeas, double lSigma)
 {
@@ -489,6 +542,11 @@ Int_t AliMillePede2::LocalFit(double *localParams)
   //
   matCLoc.SetSizeUsed(++maxLocUsed);   // data with B=0 may use less than declared nLocals 
   //
+  /* //RRR
+  fRecord->Print("l");
+  printf("\nBefore\nLocalMatrix: "); matCLoc.Print("l");
+  printf("RHSLoc: "); for (int i=0;i<fNLocPar;i++) printf("%+e |",fVecBLoc[i]); printf("\n");
+  */
   // first try to solve by faster Cholesky decomposition, then by Gaussian elimination
   if (!matCLoc.SolveChol(fVecBLoc,kTRUE)) {
     AliInfo("Failed to solve locals by Cholesky, trying Gaussian Elimination");
@@ -500,7 +558,8 @@ Int_t AliMillePede2::LocalFit(double *localParams)
   }
   //
   // If requested, store the track params and errors
-  //  printf("locfit: "); for (int i=0;i<fNLocPar;i++) printf("%+e |",fVecBLoc[i]); printf("\n");
+  //RRR  printf("locfit: "); for (int i=0;i<fNLocPar;i++) printf("%+e |",fVecBLoc[i]); printf("\n");
+  
   if (localParams) for (int i=maxLocUsed; i--;) {
       localParams[2*i]   = fVecBLoc[i];
       localParams[2*i+1] = TMath::Sqrt(TMath::Abs(matCLoc.QueryDiag(i)));
@@ -613,6 +672,13 @@ Int_t AliMillePede2::LocalFit(double *localParams)
     }
   } // end of Update matrices
   //
+  /*//RRR
+  printf("After GLO\n");
+  printf("MatCLoc: "); fMatCLoc->Print("l");
+  printf("MatCGlo: "); fMatCGlo->Print("l");
+  printf("MatCGlLc:"); fMatCGloLoc->Print("l");
+  printf("BGlo: "); for (int i=0; i<fNGloPar; i++) printf("%+e |",fVecBGlo[i]); printf("\n");
+  */
   // calculate fMatCGlo -= fMatCGloLoc * fMatCLoc * fMatCGloLoc^T
   // and       fVecBGlo -= fMatCGloLoc * fVecBLoc
   //
@@ -652,6 +718,11 @@ Int_t AliMillePede2::LocalFit(double *localParams)
   //
   // reset compressed index array
   //
+  /*//RRR
+  printf("After GLOLoc\n");
+  printf("MatCGlo: "); fMatCGlo->Print("");
+  printf("BGlo: "); for (int i=0; i<fNGloPar; i++) printf("%+e |",fVecBGlo[i]); printf("\n");
+  */
   for (int i=nGloInFit;i--;) { 
     fGlo2CGlo[ fCGlo2Glo[i] ] = -1;
     fCGlo2Glo[i] = -1;
@@ -680,7 +751,7 @@ Int_t AliMillePede2::GlobalFit(Double_t *par, Double_t *error, Double_t *pull)
       fChi2CutFactor = TMath::Sqrt(fChi2CutFactor);
       if (fChi2CutFactor < 1.2*fChi2CutRef) {
        fChi2CutFactor = fChi2CutRef;
-       fIter = fMaxIter - 1;     // Last iteration
+       //RRR   fIter = fMaxIter - 1;     // Last iteration
       }
     }
     fIter++;
@@ -748,19 +819,29 @@ Int_t AliMillePede2::GlobalFitIteration()
   //
   //  Process data records and build the matrices
   Long_t ndr = fTreeData->GetEntries();
-  AliInfo(Form("Building the Global matrix from %d data records",ndr));
-  if (!ndr) return 0;
+  Long_t first = fSelFirst>0  ? fSelFirst : 0;
+  Long_t last  = fSelLast<1   ? ndr : (fSelLast>=ndr ? ndr : fSelLast+Long_t(1));
+  ndr = last - first;
+  //
+  AliInfo(Form("Building the Global matrix from data records %ld : %ld",first,last));
+  if (ndr<1) return 0;
   //
   TStopwatch swt; swt.Start();
   fLocFitAdd = kTRUE;  // add contributions of matching tracks
   for (Long_t i=0;i<ndr;i++) {
-    ReadRecordData(i);
+    Long_t iev = i+first;
+    ReadRecordData(iev);
+    if (!IsRecordAcceptable()) continue;
     LocalFit();
     if ( (i%int(0.2*ndr)) == 0) printf("%.1f%% of local fits done\n", double(100.*i)/ndr);
   }
   swt.Stop();
   printf("%ld local fits done: ", ndr);
+  /*
+  printf("MatCGlo: "); fMatCGlo->Print("l");
+  printf("BGlo: "); for (int i=0; i<fNGloPar; i++) printf("%+e |",fVecBGlo[i]); printf("\n");
   swt.Print();
+  */
   sw.Start(kFALSE);
   //
   //
@@ -821,7 +902,9 @@ Int_t AliMillePede2::GlobalFitIteration()
     fLocFitAdd = kFALSE;
     //
     for (Long_t i=0;i<ndr;i++) {
-      ReadRecordData(i);
+      Long_t iev = i+first;
+      ReadRecordData(iev);
+      if (!IsRecordAcceptable()) continue;
       Bool_t suppr = kFALSE;
       for (int ifx=nFixedGroups;ifx--;)if (fRecord->IsGroupPresent(fixGroups[ifx])) suppr = kTRUE;
       if (suppr) LocalFit();
@@ -845,6 +928,7 @@ Int_t AliMillePede2::GlobalFitIteration()
       fNGloFix++; 
       fVecBGlo[i] = 0.;
       matCGlo.DiagElem(i) = 1.;//float(fNLocEquations*fNLocEquations);
+      //      matCGlo.DiagElem(i) = float(fNLocEquations*fNLocEquations);
     }
     else matCGlo.DiagElem(i) += (fgWeightSigma ? fProcPnt[i] : 1.)/(fSigmaPar[i]*fSigmaPar[i]);
   }
@@ -918,6 +1002,12 @@ Int_t AliMillePede2::GlobalFitIteration()
 
   //
   sws.Start();
+
+  /*
+  printf("Solving:\n");
+  matCGlo.Print();
+  for (int i=0;i<fNGloSize;i++) printf("b%2d : %+e\n",i,fVecBGlo[i]);
+  */
   fGloSolveStatus = SolveGlobalMatEq();                     // obtain solution for this step
   sws.Stop();
   printf("Solve %d |",fIter); sws.Print();
@@ -953,7 +1043,7 @@ Int_t AliMillePede2::SolveGlobalMatEq()
     }
     //
     if (((AliSymMatrix*)fMatCGlo)->SolveSpmInv(fVecBGlo, kTRUE)) return gkInvert;
-    else AliInfo("Solution of Global Dense System by Gaussian Elimiation failed, trying iterative methods");
+    else AliInfo("Solution of Global Dense System by Gaussian Elimination failed, trying iterative methods");
   }
   // try to solve by minres
   TVectorD sol(fNGloSize);
@@ -969,7 +1059,32 @@ Int_t AliMillePede2::SolveGlobalMatEq()
   else 
     AliInfo(Form("Undefined Iteritive Solver ID=%d, only %d are defined",fgIterSol,AliMinResSolve::kNSolvers));
   //
-  if (!res) return gkFailed;
+  if (!res) {
+    const char* faildump = "fgmr_failed.dat";
+    int defout = dup(1);
+    if (defout<0) {
+      AliInfo("Failed on dup");
+      return gkFailed;
+    }
+    int slvDump = open(faildump, O_RDWR|O_CREAT, 0666);
+    if (slvDump>=0) {
+      dup2(slvDump,1);
+      //
+      printf("#Failed to solve using solver %d with PreCond: %d MaxIter: %d Tol: %e NKrylov: %d\n",
+            fgIterSol,fgMinResCondType,fgMinResMaxIter,fgMinResTol,fgNKrylovV);
+      printf("#Dump of matrix:\n");
+      fMatCGlo->Print("10");
+      printf("#Dump of RHS:\n");
+      for (int i=0;i<fNGloSize;i++) printf("%d %+.10f\n",i,fVecBGlo[i]);
+      //
+      dup2(defout,1);
+      close(slvDump);
+      close(defout);
+      printf("#Dumped failed matrix and RHS to %s\n",faildump);
+    }
+    else AliInfo("Failed on file open for matrix dumping");
+    return gkFailed;
+  }
   for (int i=fNGloSize;i--;) fVecBGlo[i] = sol[i];
   return gkNoInversion;
   //
@@ -1064,3 +1179,54 @@ Int_t AliMillePede2::PrintGlobalParameters() const
   }
   return 1;
 }
+
+//_____________________________________________________________________________________________
+Bool_t AliMillePede2::IsRecordAcceptable() const
+{
+  // validate record according run lists set by the user
+  static Long_t prevRunID = kMaxInt;
+  static Bool_t prevAns   = kTRUE;
+  Long_t runID = fRecord->GetRunID();
+  if (runID!=prevRunID) {
+    int n = 0;
+    prevRunID = runID;
+    // is run to be rejected?
+    if (fRejRunList && (n=fRejRunList->GetSize())) {
+      prevAns = kTRUE;
+      for (int i=n;i--;) if (runID == (*fRejRunList)[i]) {
+         prevAns = kFALSE; 
+         printf("New Run to reject: %ld -> %d\n",runID,prevAns);
+         break;
+       }
+    }
+    else if (fAccRunList && (n=fAccRunList->GetSize())) {     // is run specifically selected
+      prevAns = kFALSE;
+      for (int i=n;i--;) if (runID == (*fAccRunList)[i]) {prevAns = kTRUE; break;}
+    }
+  }
+  //
+  return prevAns;
+  //
+}
+
+//_____________________________________________________________________________________________
+void AliMillePede2::SetRejRunList(const UInt_t *runs, Int_t nruns)
+{
+  // set the list of runs to be rejected
+  if (fRejRunList) delete fRejRunList; 
+  fRejRunList = 0;
+  if (nruns<1 || !runs) return;
+  fRejRunList = new TArrayL(nruns);
+  for (int i=0;i<nruns;i++) (*fRejRunList)[i] = runs[i];
+}
+
+//_____________________________________________________________________________________________
+void AliMillePede2::SetAccRunList(const UInt_t *runs, Int_t nruns)
+{
+  // set the list of runs to be selected
+  if (fAccRunList) delete fAccRunList;
+  fAccRunList = 0;
+  if (nruns<1 || !runs) return;
+  fAccRunList = new TArrayL(nruns);
+  for (int i=0;i<nruns;i++) (*fAccRunList)[i] = runs[i];
+}