#include "AliParamSolver.h" #include "AliSymMatrix.h" #include "AliLog.h" #include ClassImp(AliParamSolver) //______________________________________________________________________________________ AliParamSolver::AliParamSolver() : fMatrix(0),fSolGlo(0),fSolLoc(0),fMaxGlobal(0),fNGlobal(0),fNPoints(0),fMaxPoints(0), fRHSGlo(0),fRHSLoc(0),fMatGamma(0),fMatG(0),fCovDGl(0) { // default constructor } //______________________________________________________________________________________ AliParamSolver::AliParamSolver(Int_t maxglo,Int_t locbuff) : fMatrix(0),fSolGlo(0),fSolLoc(0),fMaxGlobal(maxglo),fNGlobal(maxglo),fNPoints(0),fMaxPoints(0), fRHSGlo(0),fRHSLoc(0),fMatGamma(0),fMatG(0),fCovDGl(0) { // constructor for nglo globals Init(locbuff); } //______________________________________________________________________________________ AliParamSolver::AliParamSolver(AliParamSolver& src) : TObject(src),fMatrix(0),fSolGlo(0),fSolLoc(0),fMaxGlobal(src.fMaxGlobal),fNGlobal(src.fNGlobal), fNPoints(0),fMaxPoints(0),fRHSGlo(0),fRHSLoc(0),fMatGamma(0),fMatG(0),fCovDGl(0) { // copy constructor if (src.fMatrix) { Init(src.fMaxPoints); (*this) = src; } } //______________________________________________________________________________________ AliParamSolver& AliParamSolver::operator=(const AliParamSolver& src) { // assignment operator if (this==&src) return *this; TObject::operator=(src); if (src.fMatrix && (fNGlobal!=src.fNGlobal || fMaxPointsSolveChol(fRHSGlo, fSolGlo, obtainCov)) { AliError("Solution Failed"); return kFALSE; } SetBit(kBitGloSol); if (obtainCov) SetBit(kBitCInv); } return kTRUE; } //______________________________________________________________________________________ Bool_t AliParamSolver::SolveLocals() { if (TestBit(kBitLocSol)) return kTRUE; if (!TestBit(kBitGloSol)) { AliError("Cannot solve for Locals before SolveGlobals is called"); return kFALSE; } for (int i=fNPoints;i--;) { double beta = fRHSLoc[i]; double *mtG = fMatG + i*fNGlobal; // G_i for (int j=fNGlobal;j--;) beta -= mtG[j]*fSolGlo[j]; fSolLoc[i] = beta/fMatGamma[i]; // Gamma^-1 * (beta - G_i * a) } SetBit(kBitLocSol); return kTRUE; } //______________________________________________________________________________________ AliSymMatrix* AliParamSolver::GetCovMatrix() { if (!TestBit(kBitGloSol)) { AliError("Cannot obtain Cov.Matrix before SolveGlobals is called"); return 0; } if (TestBit(kBitCInv)) return fMatrix; // if (fMatrix->InvertChol()) { SetBit(kBitCInv); return fMatrix; } return 0; } //______________________________________________________________________________________ Bool_t AliParamSolver::Solve(Bool_t obtainCov) { return (SolveGlobals(obtainCov) && SolveLocals()) ? kTRUE : kFALSE; } //______________________________________________________________________________________ void AliParamSolver::AddEquation(const Double_t* dGl,const Double_t *dLc,const Double_t *res, const Double_t *covI) { // add the measured point to chi2 normal equations // Input: // dGl : NGlo x 3 matrix of derivative for each of the 3 coordinates vs global params // dLc : 3-vector of derivative for each coordinate vs local param // res : residual of the point (extrapolated - measured) // covI: 3 x (3+1)/2 matrix of the (inverted) errors (symmetric) // // The contribution of the point to chi2 is V * covI * V // with component of the vector V(i) = dGl[i]*glob + dLc[i]*loc - res[i] // // Instead of the NGlo + NMeasPoints size matrix we create only NGlo size matrix using the // reduction a la millepede : http://www.desy.de/~blobel/millepede1.ps const double kTiny = 1e-16; // if (fNPoints+1 == fMaxPoints) ExpandStorage((fNPoints+1)*2); ResetBit(kBitGloSol|kBitLocSol); // if (TestBit(kBitCInv)) { // solution was obtained and the matrix was inverted for previous points fMatrix->InvertChol(); ResetBit(kBitCInv); } // double *mtG = fMatG + fNPoints*fNGlobal; // G_i double &beta = fRHSLoc[fNPoints]; double &gamma = fMatGamma[fNPoints]; double cDl[3]; // // cov * dR/dloc cDl[kX] = covI[kXX]*dLc[kX] + covI[kXY]*dLc[kY] + covI[kXZ]*dLc[kZ]; cDl[kY] = covI[kXY]*dLc[kX] + covI[kYY]*dLc[kY] + covI[kYZ]*dLc[kZ]; cDl[kZ] = covI[kXZ]*dLc[kX] + covI[kYZ]*dLc[kY] + covI[kZZ]*dLc[kZ]; // for (int i=fNGlobal;i--;) { const double *dGli = dGl+i*3; // derivatives of XYZ vs i-th global param double *cDgi = fCovDGl+i*3; // cov * dR/dGl_i cDgi[kX] = covI[kXX]*dGli[kX] + covI[kXY]*dGli[kY] + covI[kXZ]*dGli[kZ]; cDgi[kY] = covI[kXY]*dGli[kX] + covI[kYY]*dGli[kY] + covI[kYZ]*dGli[kZ]; cDgi[kZ] = covI[kXZ]*dGli[kX] + covI[kYZ]*dGli[kY] + covI[kZZ]*dGli[kZ]; // mtG[i] = cDl[kX]*dGli[kX] + cDl[kY]*dGli[kY] + cDl[kZ]*dGli[kZ]; // dR/dGl_i * cov * dR/dLoc } beta = res[kX]*cDl[kX] + res[kY]*cDl[kY] + res[kZ]*cDl[kZ]; //RHS: res*cov*dR/dloc gamma = dLc[kX]*cDl[kX] + dLc[kY]*cDl[kY] + dLc[kZ]*cDl[kZ]; //RHS: dR/dloc*cov*dR/dloc double locSol = TMath::Abs(gamma)=fNGlobal) { AliError(Form("Attempt to constraint non-existing parameter %d",parID)); return; } // (*fMatrix)(parID,parID) += err2inv; fRHSGlo[parID] += val*err2inv; // } //______________________________________________________________________________________ void AliParamSolver::Init(Int_t npini) { // create storage assuming maximum npini measured points fMatrix = new AliSymMatrix(fMaxGlobal); fSolGlo = new Double_t[fMaxGlobal]; fRHSGlo = new Double_t[fMaxGlobal]; // fCovDGl = new Double_t[3*fMaxGlobal]; ExpandStorage(npini); fMatrix->SetSizeUsed(fNGlobal); // } //______________________________________________________________________________________ void AliParamSolver::ExpandStorage(Int_t newSize) { // increase space to newSize measured points newSize = newSize>fMaxPoints ? newSize : fMaxPoints+1; double* tmp; tmp = new Double_t[newSize]; if (fSolLoc) delete[] fSolLoc; fSolLoc = tmp; // tmp = new Double_t[newSize]; if (fMatGamma) { memcpy(tmp,fMatGamma,fNPoints*sizeof(Double_t)); delete[] fMatGamma; } fMatGamma = tmp; // tmp = new Double_t[newSize]; if (fRHSLoc) { memcpy(tmp,fRHSLoc,fNPoints*sizeof(Double_t)); delete[] fRHSLoc; } fRHSLoc = tmp; // tmp = new Double_t[newSize*fMaxGlobal]; if (fMatG) { memcpy(tmp,fMatG,fNPoints*fMaxGlobal*sizeof(Double_t)); delete[] fMatG; } fMatG = tmp; // fMaxPoints = newSize; // } //______________________________________________________________________________________ void AliParamSolver::Clear(Option_t*) { fNPoints = 0; fMatrix->Reset(); for (int i=fNGlobal;i--;) fRHSGlo[i] = 0; ResetBit(kBitGloSol | kBitLocSol | kBitCInv); } //______________________________________________________________________________________ void AliParamSolver::Print(Option_t*) const { AliInfo(Form("Solver with %d globals for %d points",fNGlobal,fNPoints)); } //______________________________________________________________________________________ void AliParamSolver::SetNGlobal(Int_t n) { if (n>fMaxGlobal) { AliError(Form("Maximum number of globals was set to %n",fMaxGlobal)); return; } fNGlobal = n; fMatrix->SetSizeUsed(fNGlobal); } //______________________________________________________________________________________ void AliParamSolver::SetMaxGlobal(Int_t n) { if (n>0 && n==fMaxGlobal) return; fMaxGlobal = n; fNGlobal = n; if (fMatrix) delete fMatrix; if (fSolGlo) delete[] fSolGlo; if (fSolLoc) delete[] fSolLoc; if (fRHSGlo) delete[] fRHSGlo; if (fRHSLoc) delete[] fRHSLoc; if (fMatGamma) delete[] fMatGamma; if (fMatG) delete[] fMatG; if (fCovDGl) delete[] fCovDGl; n = TMath::Max(16,fMaxPoints); Init(n); // }