// - OCDB-like root file //
// - geometry file (like misaligned_geometry.root) //
// //
+// Some examples of usage (in an aliroot session): //
+// AliTRDalignment a,b,c,d,e; //
+// double xsm[]={0,0,0,-70,0,0}; //
+// double xch[]={0,0,-50,0,0,0}; //
+// a.SetSm(4,xsm); //
+// a.SetCh(120,xch); //
+// a.WriteAscii("kuku.dat"); //
+// TGeoManager::Import("geometry.root"); a.WriteRoot("kuku.root"); //
+// TGeoManager::Import("geometry.root"); a.WriteDB("kukudb.root",0,0); //
+// TGeoManager::Import("geometry.root"); //
+// a.WriteDB("local://$ALICE_ROOT/OCDB", "TRD/Align/Data", 0,0); //
+// TGeoManager::Import("geometry.root"); a.WriteGeo("kukugeometry.root"); //
+// //
+// b.ReadAscii("kuku.dat"); //
+// TGeoManager::Import("geometry.root"); c.ReadRoot("kuku.root"); //
+// TGeoManager::Import("geometry.root"); d.ReadDB("kukudb.root"); //
+// TGeoManager::Import("kukugeometry.root"); e.ReadCurrentGeo(); //
+// //
+// e.PrintSm(4); //
+// e.PrintCh(120); //
+// a.PrintRMS(); //
+// b.PrintRMS(); //
+// e.PrintRMS(); //
+// //
+// //
// D.Miskowiec, November 2006 //
// //
///////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
-#include <string>
+//#include <string>
#include "TMath.h"
#include "TFile.h"
#include "AliLog.h"
#include "AliAlignObj.h"
-#include "AliAlignObjAngles.h"
+#include "AliAlignObjParams.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBMetaData.h"
#include "AliCDBEntry.h"
#include "AliCDBId.h"
+#include "AliSurveyObj.h"
+#include "AliSurveyPoint.h"
#include "AliTRDalignment.h"
-void TRDalignmentFcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *x, Int_t iflag);
+void trdAlignmentFcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *x, Int_t iflag);
ClassImp(AliTRDalignment)
fSurveyX[i][j][k][l] = 0.0;
fSurveyY[i][j][k][l] = 0.0;
fSurveyZ[i][j][k][l] = 0.0;
- fSurveyE[i][j][k][l] = 0.0;
+ fSurveyEX[i][j][k][l] = 0.0;
+ fSurveyEY[i][j][k][l] = 0.0;
+ fSurveyEZ[i][j][k][l] = 0.0;
}
// Initialize the nominal positions of the survey points
fSurveyX[i][j][k][l] = source.fSurveyX[i][j][k][l];
fSurveyY[i][j][k][l] = source.fSurveyY[i][j][k][l];
fSurveyZ[i][j][k][l] = source.fSurveyZ[i][j][k][l];
- fSurveyE[i][j][k][l] = source.fSurveyE[i][j][k][l];
+ fSurveyEX[i][j][k][l] = source.fSurveyEX[i][j][k][l];
+ fSurveyEY[i][j][k][l] = source.fSurveyEY[i][j][k][l];
+ fSurveyEZ[i][j][k][l] = source.fSurveyEZ[i][j][k][l];
}
for (int j=0; j<2; j++) for (int k=0; k<2; k++) for (int l=0; l<2; l++) {
fSurveyX0[j][k][l] = source.fSurveyX0[j][k][l];
fSurveyX[i][j][k][l] = source.fSurveyX[i][j][k][l];
fSurveyY[i][j][k][l] = source.fSurveyY[i][j][k][l];
fSurveyZ[i][j][k][l] = source.fSurveyZ[i][j][k][l];
- fSurveyE[i][j][k][l] = source.fSurveyE[i][j][k][l];
+ fSurveyEX[i][j][k][l] = source.fSurveyEX[i][j][k][l];
+ fSurveyEY[i][j][k][l] = source.fSurveyEY[i][j][k][l];
+ fSurveyEZ[i][j][k][l] = source.fSurveyEZ[i][j][k][l];
}
for (int j=0; j<2; j++) for (int k=0; k<2; k++) for (int l=0; l<2; l++) {
fSurveyX0[j][k][l] = source.fSurveyX0[j][k][l];
//
double x[6];
+ double xmax[6]={999, 0.6, 999, 999, 999, 999};
for (int i = 0; i < 18; i++) {
- fRan.Rannor(x[0],x[1]);
- fRan.Rannor(x[2],x[3]);
- fRan.Rannor(x[4],x[5]);
- for (int j = 0; j < 6; j++) x[j] *= a[j];
+ for (int j = 0; j < 6; j++) {
+ do {x[j] = fRan.Gaus(0,a[j]);} while (TMath::Abs(x[j]) > xmax[j]);
+ }
SetSm(i,x);
//PrintSm(i);
}
}
+//_____________________________________________________________________________
+void AliTRDalignment::ReadCurrentGeo()
+{
+ //
+ // use currently loaded geometry to determine misalignment by comparing
+ // original and misaligned matrix of the last node
+ // Now, original, does not mean "ideal". It is the matrix before the alignment.
+ // So, if alignment was applied more than once, the numbers extracted will
+ // represent just the last alignment. -- check this!
+ //
+
+ TGeoPNEntry *pne;
+ TGeoHMatrix *ideSm[18]; // ideal
+ TGeoHMatrix *misSm[18]; // misaligned
+ for (int i = 0; i < 18; i++) if ((pne = gGeoManager->GetAlignableEntry(GetSmName(i)))) {
+
+ // read misaligned and original matrices
+
+ TGeoPhysicalNode *node = pne->GetPhysicalNode();
+ if (!node) AliError(Form("physical node entry %s has no physical node",GetSmName(i)));
+ if (!node) continue;
+ misSm[i] = new TGeoHMatrix(*node->GetNode(node->GetLevel())->GetMatrix());
+ ideSm[i] = new TGeoHMatrix(*node->GetOriginalMatrix());
+
+ // calculate the local misalignment matrices as inverse misaligned times ideal
+
+ TGeoHMatrix mat(ideSm[i]->Inverse());
+ mat.Multiply(misSm[i]);
+ double *tra = mat.GetTranslation();
+ double *rot = mat.GetRotationMatrix();
+ double pars[6];
+ pars[0] = tra[0];
+ pars[1] = tra[1];
+ pars[2] = tra[2];
+ if (TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) AliError("Failed to extract roll-pitch-yall angles!");
+ double raddeg = TMath::RadToDeg();
+ pars[3] = raddeg * TMath::ATan2(-rot[5],rot[8]);
+ pars[4] = raddeg * TMath::ASin(rot[2]);
+ pars[5] = raddeg * TMath::ATan2(-rot[1],rot[0]);
+ SetSm(i,pars);
+
+ // cleanup
+
+ delete ideSm[i];
+ delete misSm[i];
+ }
+
+ TGeoHMatrix *ideCh[540]; // ideal
+ TGeoHMatrix *misCh[540]; // misaligned
+ for (int i = 0; i < 540; i++) if ((pne = gGeoManager->GetAlignableEntry(GetChName(i)))) {
+
+ // read misaligned and original matrices
+
+ TGeoPhysicalNode *node = pne->GetPhysicalNode();
+ if (!node) AliError(Form("physical node entry %s has no physical node",GetChName(i)));
+ if (!node) continue;
+ misCh[i] = new TGeoHMatrix(*node->GetNode(node->GetLevel())->GetMatrix());
+ ideCh[i] = new TGeoHMatrix(*node->GetOriginalMatrix());
+
+ // calculate the local misalignment matrices as inverse misaligned times ideal
+
+ TGeoHMatrix mat(ideCh[i]->Inverse());
+ mat.Multiply(misCh[i]);
+ double *tra = mat.GetTranslation();
+ double *rot = mat.GetRotationMatrix();
+ double pars[6];
+ pars[0] = tra[0];
+ pars[1] = tra[1];
+ pars[2] = tra[2];
+ if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) {
+ AliError("Failed to extract roll-pitch-yall angles!");
+ return;
+ }
+ double raddeg = TMath::RadToDeg();
+ pars[3] = raddeg * TMath::ATan2(-rot[5],rot[8]);
+ pars[4] = raddeg * TMath::ASin(rot[2]);
+ pars[5] = raddeg * TMath::ATan2(-rot[1],rot[0]);
+ SetCh(i,pars);
+
+ // cleanup
+ delete ideCh[i];
+ delete misCh[i];
+ }
+
+ return;
+
+}
+
//_____________________________________________________________________________
void AliTRDalignment::ReadRoot(char *filename)
{
//
// read the alignment data from root file
- // here I expect a fixed order and number of elements
- // it would be much better to identify the alignment objects
- // one by one and set the parameters of the corresponding sm or ch
//
TFile fi(filename,"READ");
AliCDBManager *cdb = AliCDBManager::Instance();
AliCDBStorage *storLoc = cdb->GetStorage(db);
AliCDBEntry *e = storLoc->Get(path,run,version,subversion);
- e->PrintMetaData();
- fComment.SetString(e->GetMetaData()->GetComment());
- TClonesArray *ar = (TClonesArray *) e->GetObject();
- ArToNumbers(ar);
-
+ if (e) {
+ e->PrintMetaData();
+ fComment.SetString(e->GetMetaData()->GetComment());
+ TClonesArray *ar = (TClonesArray *) e->GetObject();
+ ArToNumbers(ar);
+ }
}
//_____________________________________________________________________________
-void AliTRDalignment::ReadGeo(char *misaligned)
-{
- //
- // determine misalignment by comparing original and misaligned matrix
- // of the last node on the misaligned_geometry file
- // an alternative longer way is in attic.C
- //
-
- TGeoHMatrix *ideSm[18]; // ideal
- TGeoHMatrix *ideCh[540];
- TGeoHMatrix *misSm[18]; // misaligned
- TGeoHMatrix *misCh[540];
-
- // read misaligned and original matrices
-
- TGeoManager::Import(misaligned);
- for (int i = 0; i < 18; i++) {
- TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(GetSmName(i));
- if (!pne) AliError(Form("no such physical node entry: %s",GetSmName(i)));
- TGeoPhysicalNode *node = pne->GetPhysicalNode();
- if (!node) AliError(Form("physical node entry %s has no physical node",GetSmName(i)));
- misSm[i] = new TGeoHMatrix(*node->GetNode(node->GetLevel())->GetMatrix());
- ideSm[i] = new TGeoHMatrix(*node->GetOriginalMatrix());
- }
- for (int i = 0; i < 540; i++) {
- TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(GetChName(i));
- if (!pne) AliError(Form("no such physical node entry: %s",GetChName(i)));
- TGeoPhysicalNode *node = pne->GetPhysicalNode();
- if (!node) AliError(Form("physical node entry %s has no physical node",GetChName(i)));
- misCh[i] = new TGeoHMatrix(*node->GetNode(node->GetLevel())->GetMatrix());
- ideCh[i] = new TGeoHMatrix(*node->GetOriginalMatrix());
- }
-
- // calculate the local misalignment matrices as inverse misaligned times ideal
-
- for (int i = 0; i < 18; i++) {
- TGeoHMatrix mat(ideSm[i]->Inverse());
- mat.Multiply(misSm[i]);
- double *tra = mat.GetTranslation();
- double *rot = mat.GetRotationMatrix();
- double pars[6];
- pars[0] = tra[0];
- pars[1] = tra[1];
- pars[2] = tra[2];
- if (TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) AliError("Failed to extract roll-pitch-yall angles!");
- double raddeg = TMath::RadToDeg();
- pars[3] = raddeg * TMath::ATan2(-rot[5],rot[8]);
- pars[4] = raddeg * TMath::ASin(rot[2]);
- pars[5] = raddeg * TMath::ATan2(-rot[1],rot[0]);
- SetSm(i,pars);
- }
-
- for (int i = 0; i < 540; i++) {
- TGeoHMatrix mat(ideCh[i]->Inverse());
- mat.Multiply(misCh[i]);
- double *tra = mat.GetTranslation();
- double *rot = mat.GetRotationMatrix();
- double pars[6];
- pars[0] = tra[0];
- pars[1] = tra[1];
- pars[2] = tra[2];
- if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) {
- AliError("Failed to extract roll-pitch-yall angles!");
- return;
- }
- double raddeg = TMath::RadToDeg();
- pars[3] = raddeg * TMath::ATan2(-rot[5],rot[8]);
- pars[4] = raddeg * TMath::ASin(rot[2]);
- pars[5] = raddeg * TMath::ATan2(-rot[1],rot[0]);
- SetCh(i,pars);
+Bool_t AliTRDalignment::DecodeSurveyPointName(TString pna, Int_t &sm, Int_t &iz,
+ Int_t &ir, Int_t &iphi) {
+ // decode the survey point name and extract the sm, z, r and phi indices
+
+ if (pna(0,6)!="TRD_sm") {
+ AliError(Form("unexpected point name: %s",pna.Data()));
+ return kFALSE;
}
-
- // cleanup
- for (int i = 0; i < 18; i++) delete ideSm[i];
- for (int i = 0; i < 18; i++) delete misSm[i];
- for (int i = 0; i < 540; i++) delete ideCh[i];
- for (int i = 0; i < 540; i++) delete misCh[i];
-
- return;
-
+ sm = atoi(pna(6,2).Data()); // supermodule number
+ iz = -1;
+ if (pna(8) == 'a') iz=0; // anticlockwise, positive z
+ if (pna(8) == 'c') iz=1; // clockwise, negative z
+ ir = -1;
+ if (pna(9) == 'l') ir=0; // low radius
+ if (pna(9) == 'h') ir=1; // high radius
+ iphi = -1;
+ if (pna(10) == '0') iphi = 0; // low phi within supermodule
+ if (pna(10) == '1') iphi = 1; // high phi within supermodule
+ if (sm>=0 && sm<18 && iz>=0 && iz<2 && ir>=0 && ir<2 && iphi>=0 && iphi<2) return kTRUE;
+ AliError(Form("cannot decode point name: %s",pna.Data()));
+ return kFALSE;
}
//_____________________________________________________________________________
while (1) {
TString pna; // point name
- char type;
+ char type, target;
double x,y,z,precision;
- in >> pna >> x >> y >> z >> type >> precision;
+
+ in >> pna >> x >> y >> z >> type >> target >> precision;
if (in.fail()) break;
- if (pna(0,6)!="TRD_sm") {
- AliError(Form("unexpected point name: %s",pna.Data()));
- break;
- }
- int i = atoi(pna(6,0).Data()); // supermodule number
- int j = -1;
- if (pna(8) == 'a') j=0; // anticlockwise, positive z
- if (pna(8) == 'c') j=1; // clockwise, negative z
- int k = -1;
- if (pna(9) == 'l') k=0; // low radius
- if (pna(9) == 'h') k=1; // high radius
- int l = atoi(pna(10,0).Data()); // phi within supermodule
- if (i>=0 && i<18 && j>=0 && j<2 && k>=0 && k<2 && l>=0 && l<2) {
+ Int_t i,j,k,l;
+ if (DecodeSurveyPointName(pna,i,j,k,l)) {
fSurveyX[i][j][k][l] = tocm*x;
fSurveyY[i][j][k][l] = tocm*y;
fSurveyZ[i][j][k][l] = tocm*z;
- fSurveyE[i][j][k][l] = precision/10; // "precision" is supposed to be in mm
- std::cout << "decoded "<<pna<<" "
- <<fSurveyX[i][j][k][l]<<" "
- <<fSurveyY[i][j][k][l]<<" "
- <<fSurveyZ[i][j][k][l]<<" "
- <<fSurveyE[i][j][k][l]<<std::endl;
+ fSurveyEX[i][j][k][l] = precision/10; // "precision" is supposed to be in mm
+ fSurveyEY[i][j][k][l] = precision/10; // "precision" is supposed to be in mm
+ fSurveyEZ[i][j][k][l] = precision/10; // "precision" is supposed to be in mm
+ // if, at some point, separate precision numbers for x,y,z show up in the
+ // survey reports the function will fail here
+ printf("decoded %s %02d %d %d %d %8.2f %8.2f %8.2f %6.2f %6.2f %6.2f\n",
+ pna.Data(), i, j, k, l,
+ fSurveyX[i][j][k][l], fSurveyY[i][j][k][l], fSurveyZ[i][j][k][l],
+ fSurveyEX[i][j][k][l], fSurveyEY[i][j][k][l], fSurveyEZ[i][j][k][l]);
} else AliError(Form("cannot decode point name: %s",pna.Data()));
}
in.close();
TString info = "Survey "+title+" "+date+" "+url+" "+version+" "+observations;
info.ReplaceAll("\r","");
fComment.SetString(info.Data());
-
+
+}
+
+//_____________________________________________________________________________
+void AliTRDalignment::ReadSurveyReport(AliSurveyObj *so)
+{
+ //
+ // Read survey report and store the numbers in fSurveyX, fSurveyY, fSurveyZ,
+ // and fSurveyE. Store the survey info in the fComment.
+ // Each supermodule has 8 survey points. The point names look like
+ // TRD_sm08ah0 and have the following meaning.
+ //
+ // sm00..17 mean supermodule 0 through 17, following the phi.
+ // Supermodule 00 is between phi=0 and phi=20 degrees.
+ //
+ // a or c denotes the anticlockwise and clockwise end of the supermodule
+ // in z. Clockwise end is where z is negative and where the muon arm sits.
+ //
+ // l or h denote low radius and high radius holes
+ //
+ // 0 or 1 denote the hole at smaller and at larger phi, respectively.
+ //
+
+ // read and process the data from the survey object
+
+ Int_t size = so->GetEntries();
+ printf("-> %d\n", size);
+
+ TString title = so->GetReportTitle();
+ TString date = so->GetReportDate();
+ TString subdetector = so->GetDetector();
+ TString url = so->GetURL();
+ TString report = so->GetReportNumber();
+ TString version = so->GetReportVersion();
+ TString observations = so->GetObservations();
+ TString system = so->GetCoordSys();
+ TString units = so->GetUnits();
+
+ // check what we found so far (watch out, they have \r at the end)
+
+ std::cout<<"title .........."<<title<<std::endl;
+ std::cout<<"date ..........."<<date<<std::endl;
+ std::cout<<"subdetector ...."<<subdetector<<std::endl;
+ std::cout<<"url ............"<<url<<std::endl;
+ std::cout<<"version ........"<<version<<std::endl;
+ std::cout<<"observations ..."<<observations<<std::endl;
+ std::cout<<"system ........."<<system<<std::endl;
+ std::cout<<"units .........."<<units<<std::endl;
+
+ if (!subdetector.Contains("TRD")) {
+ AliWarning(Form("Not a TRD survey file, subdetector = %s",subdetector.Data()));
+ return;
+ }
+ double tocm = 0; // we want to have it in cm
+ if (units.Contains("mm")) tocm = 0.1;
+ else if (units.Contains("cm")) tocm = 1.0;
+ else if (units.Contains("m")) tocm = 100.0;
+ else if (units.Contains("pc")) tocm = 3.24078e-15;
+ else {
+ AliError(Form("unexpected units: %s",units.Data()));
+ return;
+ }
+ if (!system.Contains("ALICEPH")) {
+ AliError(Form("wrong system: %s, should be ALICEPH",system.Data()));
+ return;
+ }
+
+ // for every survey point, decode the point name and store the numbers in
+ // the right place in the arrays fSurveyX etc.
+
+ TObjArray *points = so->GetData();
+ for (int ip = 0; ip<points->GetEntries(); ++ip) {
+ AliSurveyPoint *po = (AliSurveyPoint *) points->At(ip);
+ TString pna = po->GetPointName();
+ Int_t i,j,k,l;
+ if (DecodeSurveyPointName(pna,i,j,k,l)) {
+ fSurveyX[i][j][k][l] = tocm*po->GetX();
+ fSurveyY[i][j][k][l] = tocm*po->GetY();
+ fSurveyZ[i][j][k][l] = tocm*po->GetZ();
+ fSurveyEX[i][j][k][l] = po->GetPrecisionX()/10; // "precision" is supposed to be in mm
+ fSurveyEY[i][j][k][l] = po->GetPrecisionY()/10;
+ fSurveyEZ[i][j][k][l] = po->GetPrecisionZ()/10;
+ printf("decoded %s %02d %d %d %d %8.2f %8.2f %8.2f %6.2f %6.2f %6.2f\n",
+ pna.Data(), i, j, k, l,
+ fSurveyX[i][j][k][l], fSurveyY[i][j][k][l], fSurveyZ[i][j][k][l],
+ fSurveyEX[i][j][k][l], fSurveyEY[i][j][k][l], fSurveyEZ[i][j][k][l]);
+ } else AliError(Form("cannot decode point name: %s",pna.Data()));
+ }
+
+ TString info = "Survey "+title+" "+date+" "+url+" "+report+" "+version+" "+observations;
+ info.ReplaceAll("\r","");
+ fComment.SetString(info.Data());
}
//_____________________________________________________________________________
// parameters a[6]. Return chi-squared.
//
- if (!gGeoManager) LoadIdealGeometry();
+ if (!IsGeoLoaded()) return 0;
printf("Survey of supermodule %d\n",i);
- AliAlignObjAngles al(GetSmName(i),0,a[0],a[1],a[2],a[3],a[4],a[5],0);
+ AliAlignObjParams al(GetSmName(i),0,a[0],a[1],a[2],a[3],a[4],a[5],0);
TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(GetSmName(i));
if (!pne) AliError(Form("no such physical node entry: %s",GetSmName(i)));
TGeoPhysicalNode *node = pne->GetPhysicalNode();
double chi2=0;
printf(" sm z r phi x (lab phi) y (lab z) z (lab r) all in cm\n");
for (int j=0; j<2; j++) for (int k=0; k<2; k++) for (int l=0; l<2; l++) {
- if (fSurveyE[i][j][k][l] == 0.0) continue; // no data for this survey point
+ if (fSurveyEX[i][j][k][l] == 0.0
+ && fSurveyEY[i][j][k][l] == 0.0
+ && fSurveyEZ[i][j][k][l] == 0.0) continue; // no data for this survey point
double master[3] = {fSurveyX[i][j][k][l],fSurveyY[i][j][k][l],fSurveyZ[i][j][k][l]};
double local[3];
ma->MasterToLocal(master,local);
double dx = local[0]-fSurveyX0[j][k][l];
double dy = local[1]-fSurveyY0[j][k][l];
double dz = local[2]-fSurveyZ0[j][k][l];
- chi2 += (dx*dx+dy*dy+dz*dz)/fSurveyE[i][j][k][l]/fSurveyE[i][j][k][l];
+ chi2 += dx*dx/fSurveyEX[i][j][k][l]/fSurveyEX[i][j][k][l];
+ chi2 += dy*dy/fSurveyEY[i][j][k][l]/fSurveyEY[i][j][k][l];
+ chi2 += dz*dz/fSurveyEZ[i][j][k][l]/fSurveyEZ[i][j][k][l];
printf("local survey %3d %3d %3d %3d %12.3f %12.3f %12.3f\n",i,j,k,l,local[0],local[1],local[2]);
printf("local ideal %12.3f %12.3f %12.3f\n",fSurveyX0[j][k][l],
fSurveyY0[j][k][l],fSurveyZ0[j][k][l]);
}
//_____________________________________________________________________________
-void TRDalignmentFcn(int &npar, double *g, double &f, double *par, int iflag) {
+void trdAlignmentFcn(int &npar, double *g, double &f, double *par, int iflag) {
//
// Standard function as needed by Minuit-like minimization procedures.
AliTRDalignment *alignment = (AliTRDalignment*) gMinuit->GetObjectFit();
f = alignment->SurveyChi2(par);
- if (iflag==3);
- if (npar);
- if (g); // no warnings about unused stuff...
+ if (iflag==3) {}
+ if (npar) {}
+ if (g) {} // no warnings about unused stuff...
}
TFitter fitter(100);
gMinuit->SetObjectFit(this);
- fitter.SetFCN(TRDalignmentFcn);
+ fitter.SetFCN(trdAlignmentFcn);
fitter.SetParameter(0,"dx",0,0.5,0,0);
fitter.SetParameter(1,"dy",0,0.5,0,0);
fitter.SetParameter(2,"dz",0,0.5,0,0);
// store the alignment data on root file
//
- TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
+ TClonesArray *ar = new TClonesArray("AliAlignObjParams",10000);
NumbersToAr(ar);
TFile fo(filename,"RECREATE");
if (fo.IsOpen()) {
// dumping on a DB-like file
//
- TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
+ TClonesArray *ar = new TClonesArray("AliAlignObjParams",10000);
NumbersToAr(ar);
- char *path = "di1/di2/di3";
+ const Char_t *path = "TRD/Align/Data";
AliCDBId id(path,run0,run1);
AliCDBMetaData *md = new AliCDBMetaData();
md->SetResponsible("Dariusz Miskowiec");
// store the alignment data in database
//
- TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
+ TClonesArray *ar = new TClonesArray("AliAlignObjParams",10000);
NumbersToAr(ar);
AliCDBManager *cdb = AliCDBManager::Instance();
AliCDBStorage *storLoc = cdb->GetStorage(db);
void AliTRDalignment::WriteGeo(char *filename)
{
//
- // apply misalignment to (currently loaded ideal) geometry and store the
+ // apply misalignment to current geometry and store the
// resulting geometry on a root file
//
- TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
+ TClonesArray *ar = new TClonesArray("AliAlignObjParams",10000);
NumbersToAr(ar);
- for (int i = 0; i < ar->GetEntriesFast(); i++) {
- AliAlignObj *alobj = (AliAlignObj *) ar->UncheckedAt(i);
- alobj->ApplyToGeometry();
- }
delete ar;
gGeoManager->Export(filename);
void AliTRDalignment::ArToNumbers(TClonesArray *ar)
{
//
- // read numbers from the array of AliAlignObj objects and fill fSm and fCh
+ // for each of the alignment objects in array ar extract the six local
+ // alignment parameters; recognize by name to which supermodule or chamber
+ // the alignment object pertains; set the respective fSm or fCh
//
- LoadIdealGeometry();
- SetZero();
- double pa[6];
- for (int i = 0; i < 18; i++) {
+ ar->Sort();
+ if (!IsGeoLoaded()) return;
+ for (int i = 0; i < ar->GetEntries(); i++) {
AliAlignObj *aao = (AliAlignObj *) ar->At(i);
- aao->GetLocalPars(pa,pa+3);
- SetSm(i,pa);
- }
- for (int i = 0; i < 540; i++) {
- AliAlignObj *aao = (AliAlignObj *) ar->At(18+i);
- aao->GetLocalPars(pa,pa+3);
- SetCh(i,pa);
+ aao->ApplyToGeometry();
}
+ SetZero();
+ ReadCurrentGeo();
}
{
//
// build array of AliAlignObj objects based on fSm and fCh data
+ // at the same time, apply misalignment to the currently loaded geometry
+ // it is important to apply misalignment of supermodules before creating
+ // alignment objects for chambers
//
- LoadIdealGeometry();
+ if (!IsGeoLoaded()) return;
TClonesArray &alobj = *ar;
int nobj = 0;
for (int i = 0; i < 18; i++) {
- new(alobj[nobj]) AliAlignObjAngles(GetSmName(i)
+ new(alobj[nobj]) AliAlignObjParams(GetSmName(i)
,0
,fSm[i][0],fSm[i][1],fSm[i][2]
,fSm[i][3],fSm[i][4],fSm[i][5]
,0);
+ ((AliAlignObj *) alobj[nobj])->ApplyToGeometry();
nobj++;
}
for (int i = 0; i < 540; i++) {
- new(alobj[nobj]) AliAlignObjAngles(GetChName(i)
- ,GetVoi(i)
- ,fCh[i][0],fCh[i][1],fCh[i][2]
- ,fCh[i][3],fCh[i][4],fCh[i][5]
- ,0);
- nobj++;
+ if (gGeoManager->GetAlignableEntry(GetChName(i))) {
+ new(alobj[nobj]) AliAlignObjParams(GetChName(i)
+ ,GetVoi(i)
+ ,fCh[i][0],fCh[i][1],fCh[i][2]
+ ,fCh[i][3],fCh[i][4],fCh[i][5]
+ ,0);
+ ((AliAlignObj *) alobj[nobj])->ApplyToGeometry();
+ nobj++;
+ }
}
+ AliInfo("current geometry modified");
}
//_____________________________________________________________________________
-void AliTRDalignment::LoadIdealGeometry(char *filename)
+int AliTRDalignment::IsGeoLoaded()
{
//
- // load ideal geometry from filename
- // it is needed for operations on AliAlignObj objects
- // this needs to be straightened out
- // particularly, sequences LoadIdealGeometry("file1"); LoadIdealGeometry("file2");
- // do not work as one would naturally expect
+ // check whether a geometry is loaded
+ // issue a warning if geometry is not ideal
//
- static int attempt = 0; // which reload attempt is it? just to avoid endless loops
-
- if (!gGeoManager) TGeoManager::Import(filename);
- if (!gGeoManager) AliError(Form("cannot open geometry file %s",filename));
- if (gGeoManager->GetListOfPhysicalNodes()->GetEntries()) {
- if (attempt) AliError(Form("geometry on file %s is not ideal",filename));
- AliWarning("current geometry is not ideal - it contains physical nodes");
- AliWarning(Form("reloading geometry from %s - attempt nr %d",filename,attempt));
- gGeoManager = 0;
- attempt++;
- LoadIdealGeometry(filename);
+ if (gGeoManager) {
+ if (gGeoManager->GetListOfPhysicalNodes()->GetEntries()) AliWarning("current geometry is not ideal");
+ return 1;
+ } else {
+ AliError("first load geometry by calling TGeoManager::Import(filename)");
+ return 0;
}
- attempt = 0;
-
}
+
+//_____________________________________________________________________________