1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //////////////////////////////////////////////////////////////////////////////////
20 // An AliTRDalignment object contains the alignment data (3 shifts and 3 tilts) //
21 // for all the alignable volumes of the TRD, i.e. for 18 supermodules and 540 //
22 // chambers. The class provides simple tools for reading and writing these data //
23 // in different formats, and for generating fake data that can be used to //
24 // simulate misalignment. //
25 // The six alignment variables have the following meaning: //
29 // tilt around rphi //
32 // The shifts are in cm and the tilts are in degrees. //
33 // The currently supported formats are: //
35 // - root file containing a TClonesArray of alignment objects //
36 // - offline conditions database //
37 // - OCDB-like root file //
38 // - geometry file (like misaligned_geometry.root) //
40 // D.Miskowiec, November 2006 //
42 //////////////////////////////////////////////////////////////////////////////////
49 #include "TGeoManager.h"
50 #include "TGeoPhysicalNode.h"
51 #include "TClonesArray.h"
54 #include "AliAlignObj.h"
55 #include "AliAlignObjAngles.h"
56 #include "AliCDBManager.h"
57 #include "AliCDBStorage.h"
58 #include "AliCDBMetaData.h"
59 #include "AliCDBEntry.h"
62 #include "AliTRDalignment.h"
64 ClassImp(AliTRDalignment)
66 //_____________________________________________________________________________
67 AliTRDalignment::AliTRDalignment()
79 //_____________________________________________________________________________
80 AliTRDalignment::AliTRDalignment(const AliTRDalignment& source)
88 for (int i = 0; i < 18; i++) {
89 SetSm(i,source.fSm[i]);
91 for (int i = 0; i < 540; i++) {
92 SetCh(i,source.fCh[i]);
97 //_____________________________________________________________________________
98 AliTRDalignment& AliTRDalignment::operator=(const AliTRDalignment &source)
101 // assignment operator
104 if (this != &source) {
105 for (int i = 0; i < 18; i++) SetSm(i,source.fSm[i]);
106 for (int i = 0; i < 540; i++) SetCh(i,source.fCh[i]);
113 //_____________________________________________________________________________
114 AliTRDalignment& AliTRDalignment::operator+=(const AliTRDalignment &source)
120 for (int i = 0; i < 18; i++) {
121 for (int j = 0; j < 6; j++) {
122 this->fSm[i][j] =+ source.fSm[i][j];
125 for (int i = 0; i < 540; i++) {
126 for (int j = 0; j < 6; j++) {
127 this->fCh[i][j] =+ source.fCh[i][j];
135 //_____________________________________________________________________________
136 AliTRDalignment& AliTRDalignment::operator-=(const AliTRDalignment &source)
139 // subtraction operator
142 for (int i = 0; i < 18; i++) {
143 for (int j = 0; j < 6; j++) {
144 fSm[i][j] -= source.fSm[i][j];
147 for (int i = 0; i < 540; i++) {
148 for (int j = 0; j < 6; j++) {
149 fCh[i][j] -= source.fCh[i][j];
157 //_____________________________________________________________________________
158 Bool_t AliTRDalignment::operator==(const AliTRDalignment &source) const
161 // comparison operator
166 for (int i = 0; i < 18; i++) {
167 for (int j = 0; j < 6; j++) {
168 areEqual &= (fSm[i][j] == source.fSm[i][j]);
171 for (int i = 0; i < 540; i++) {
172 for (int j = 0; j < 6; j++) {
173 areEqual &= (fCh[i][j] == source.fCh[i][j]);
181 //_____________________________________________________________________________
182 void AliTRDalignment::SetSmZero()
185 // reset to zero supermodule data
188 memset(&fSm[0][0],0,sizeof(fSm));
192 //_____________________________________________________________________________
193 void AliTRDalignment::SetChZero()
196 // reset to zero chamber data
199 memset(&fCh[0][0],0,sizeof(fCh));
203 //_____________________________________________________________________________
204 void AliTRDalignment::SetSmRandom(Double_t a[6])
207 // generate random gaussian supermodule data with sigmas a
212 for (Int_t i = 0; i < 18; i++) {
213 fRan.Rannor(x[0],x[1]);
214 fRan.Rannor(x[2],x[3]);
215 fRan.Rannor(x[4],x[5]);
216 for (Int_t j = 0; j < 6; j++) {
225 //_____________________________________________________________________________
226 void AliTRDalignment::SetChRandom(Double_t a[6])
229 // generate random gaussian chamber data with sigmas a
234 for (Int_t i = 0; i < 540; i++) {
235 fRan.Rannor(x[0],x[1]);
236 fRan.Rannor(x[2],x[3]);
237 fRan.Rannor(x[4],x[5]);
238 for (Int_t j = 0; j < 6; j++) {
247 //_____________________________________________________________________________
248 void AliTRDalignment::SetSmFull()
251 // generate random gaussian supermodule data similar to the misalignment
252 // expected from the mechanical precision
260 a[3] = 0.4/1000.0 / TMath::Pi()*180.0; // phi
261 a[4] = 2.0/1000.0 / TMath::Pi()*180.0; // z
262 a[5] = 0.4/1000.0 / TMath::Pi()*180.0; // r
268 //_____________________________________________________________________________
269 void AliTRDalignment::SetChFull()
272 // generate random gaussian chamber data similar to the misalignment
273 // expected from the mechanical precision
281 a[3] = 1.0/1000.0 / TMath::Pi()*180.0; // phi
282 a[4] = 1.0/1000.0 / TMath::Pi()*180.0; // z
283 a[5] = 0.7/1000.0 / TMath::Pi()*180.0; // r
289 //_____________________________________________________________________________
290 void AliTRDalignment::SetSmResidual()
293 // generate random gaussian supermodule data similar to the misalignment
294 // remaining after full calibration
295 // I assume that it will be negligible
302 //_____________________________________________________________________________
303 void AliTRDalignment::SetChResidual()
306 // generate random gaussian chamber data similar to the misalignment
307 // remaining after full calibration
315 a[3] = 0.3/1000.0 / TMath::Pi()*180.0; // phi
316 a[4] = 0.3/1000.0 / TMath::Pi()*180.0; // z
317 a[5] = 0.1/1000.0 / TMath::Pi()*180.0; // r
323 //_____________________________________________________________________________
324 void AliTRDalignment::PrintSm(Int_t i, FILE *fp) const
327 // print the supermodule data
330 fprintf(fp,"%4d %11.4f %11.4f %11.4f %11.5f %11.5f %11.5f %6d %s\n"
331 ,i,fSm[i][0],fSm[i][1],fSm[i][2],fSm[i][3],fSm[i][4],fSm[i][5]
336 //_____________________________________________________________________________
337 void AliTRDalignment::PrintCh(Int_t i, FILE *fp) const
340 // print the chamber data
343 fprintf(fp,"%4d %11.4f %11.4f %11.4f %11.5f %11.5f %11.5f %6d %s\n"
344 ,i,fCh[i][0],fCh[i][1],fCh[i][2],fCh[i][3],fCh[i][4],fCh[i][5]
345 ,GetVoi(i),GetChName(i));
349 //_____________________________________________________________________________
350 void AliTRDalignment::ReadAscii(char *filename)
353 // read the alignment data from ascii file
356 double x[6]; // alignment data
357 int volid; // volume id
358 std::string syna; // symbolic name
359 int j; // dummy index
361 fstream fi(filename,fstream::in);
363 AliFatal(Form("cannot open input file %s",filename));
368 for (int i = 0; i < 18; i++) {
369 fi>>j>>x[0]>>x[1]>>x[2]>>x[3]>>x[4]>>x[5]>>volid>>syna;
371 AliError(Form("sm %d expected, %d found",i,j));
374 AliError(Form("sm %d volume id %d expected, %d found",i,0,volid));
376 std::string symnam = GetSmName(i);
377 if (syna != symnam) {
378 AliError(Form("sm %d name %s expected, %s found",i,symnam.data(),syna.data()));
385 for (int i = 0; i < 540; i++) {
386 fi>>j>>x[0]>>x[1]>>x[2]>>x[3]>>x[4]>>x[5]>>volid>>syna;
388 AliError(Form("ch %d expected, %d found",i,j));
390 if (volid != GetVoi(i)) {
391 AliError(Form("ch %d volume id %d expected, %d found",i,GetVoi(i),volid));
393 std::string symnam = GetChName(i);
394 if (syna != symnam) {
395 AliError(Form("ch %d name %s expected, %s found",i,symnam.data(),syna.data()));
404 //_____________________________________________________________________________
405 void AliTRDalignment::ReadRoot(char *filename)
408 // read the alignment data from root file
409 // here I expect a fixed order and number of elements
410 // it would be much better to identify the alignment objects
411 // one by one and set the parameters of the corresponding sm or ch
414 TFile fi(filename,"READ");
417 TClonesArray *ar = (TClonesArray*) fi.Get("TRDAlignObjs");
422 AliError(Form("cannot open input file %s",filename));
429 //_____________________________________________________________________________
430 void AliTRDalignment::ReadDB(char *filename)
433 // read the alignment data from database file
436 TFile fi(filename,"READ");
439 AliCDBEntry *e = (AliCDBEntry *) fi.Get("AliCDBEntry");
441 TClonesArray *ar = (TClonesArray *) e->GetObject();
446 AliError(Form("cannot open input file %s",filename));
453 //_____________________________________________________________________________
454 void AliTRDalignment::ReadDB(char *db, char *path, Int_t run
455 , Int_t version, Int_t subversion)
458 // read the alignment data from database
461 AliCDBManager *cdb = AliCDBManager::Instance();
462 AliCDBStorage *storLoc = cdb->GetStorage(db);
463 AliCDBEntry *e = storLoc->Get(path,run,version,subversion);
465 TClonesArray *ar = (TClonesArray *) e->GetObject();
470 //_____________________________________________________________________________
471 void AliTRDalignment::ReadGeo(char *misaligned)
474 // determine misalignment by comparing original and misaligned matrix
475 // of the last node on the misaligned_geometry file
476 // an alternative longer way is in attic.C
479 TGeoHMatrix *ideSm[18]; // ideal
480 TGeoHMatrix *ideCh[540];
481 TGeoHMatrix *misSm[18]; // misaligned
482 TGeoHMatrix *misCh[540];
484 // read misaligned and original matrices
486 TGeoManager::Import(misaligned);
487 for (int i = 0; i < 18; i++) {
488 TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(GetSmName(i));
490 AliError(Form("no such physical node entry: %s",GetSmName(i)));
493 TGeoPhysicalNode *node = pne->GetPhysicalNode();
495 AliError(Form("physical node entry %s has no physical node",GetSmName(i)));
498 misSm[i] = new TGeoHMatrix(*node->GetNode(node->GetLevel())->GetMatrix());
499 ideSm[i] = new TGeoHMatrix(*node->GetOriginalMatrix());
501 for (int i = 0; i < 540; i++) {
502 TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(GetChName(i));
504 AliError(Form("no such physical node entry: %s",GetChName(i)));
507 TGeoPhysicalNode *node = pne->GetPhysicalNode();
509 AliError(Form("physical node entry %s has no physical node",GetChName(i)));
512 misCh[i] = new TGeoHMatrix(*node->GetNode(node->GetLevel())->GetMatrix());
513 ideCh[i] = new TGeoHMatrix(*node->GetOriginalMatrix());
516 // calculate the local misalignment matrices as inverse misaligned times ideal
518 for (int i = 0; i < 18; i++) {
519 TGeoHMatrix mat(ideSm[i]->Inverse());
520 mat.Multiply(misSm[i]);
521 double *tra = mat.GetTranslation();
522 double *rot = mat.GetRotationMatrix();
527 if (TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) {
528 AliError("Failed to extract roll-pitch-yall angles!");
531 double raddeg = TMath::RadToDeg();
532 pars[3] = raddeg * TMath::ATan2(-rot[5],rot[8]);
533 pars[4] = raddeg * TMath::ASin(rot[2]);
534 pars[5] = raddeg * TMath::ATan2(-rot[1],rot[0]);
538 for (int i = 0; i < 540; i++) {
539 TGeoHMatrix mat(ideCh[i]->Inverse());
540 mat.Multiply(misCh[i]);
541 double *tra = mat.GetTranslation();
542 double *rot = mat.GetRotationMatrix();
547 if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) {
548 AliError("Failed to extract roll-pitch-yall angles!");
551 double raddeg = TMath::RadToDeg();
552 pars[3] = raddeg * TMath::ATan2(-rot[5],rot[8]);
553 pars[4] = raddeg * TMath::ASin(rot[2]);
554 pars[5] = raddeg * TMath::ATan2(-rot[1],rot[0]);
559 for (int i = 0; i < 18; i++) delete ideSm[i];
560 for (int i = 0; i < 18; i++) delete misSm[i];
561 for (int i = 0; i < 540; i++) delete ideCh[i];
562 for (int i = 0; i < 540; i++) delete misCh[i];
568 //_____________________________________________________________________________
569 void AliTRDalignment::ReadSurveyReport(char *filename)
571 // read survey report and set the supermodule parameters correspondingly
573 fstream fi(filename,fstream::in);
575 AliFatal(Form("cannot open input file %s",filename));
578 // to be continued...
582 //_____________________________________________________________________________
583 void AliTRDalignment::ReadAny(char *filename)
586 // read the alignment data from any kind of file
589 TString fist(filename);
590 if (fist.EndsWith(".txt")) {
593 if (fist.EndsWith(".dat")) {
596 if (fist.EndsWith(".root")) {
597 if (fist.Contains("Run")) {
607 //_____________________________________________________________________________
608 void AliTRDalignment::WriteAscii(char *filename) const
611 // store the alignment data on ascii file
614 FILE *fp = fopen(filename, "w");
616 AliError(Form("cannot open output file %s",filename));
627 //_____________________________________________________________________________
628 void AliTRDalignment::WriteRoot(char *filename)
631 // store the alignment data on root file
634 TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
636 TFile fo(filename,"RECREATE");
639 fo.WriteObject(ar,"TRDAlignObjs","kSingleKey");
643 AliError(Form("cannot open output file %s",filename));
650 //_____________________________________________________________________________
651 void AliTRDalignment::WriteDB(char *filename, char *comment, Int_t run0, Int_t run1)
654 // dumping on a DB-like file
657 TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
659 char *path = "di1/di2/di3";
660 AliCDBId id(path,run0,run1);
661 AliCDBMetaData *md = new AliCDBMetaData();
662 md->SetResponsible("Dariusz Miskowiec");
663 md->SetComment(comment);
664 AliCDBEntry *e = new AliCDBEntry(ar, id, md);
665 TFile fi(filename,"RECREATE");
671 AliError(Form("cannot open input file %s",filename));
682 //_____________________________________________________________________________
683 void AliTRDalignment::WriteDB(char *db, char *path, char *comment, Int_t run0, Int_t run1)
686 // store the alignment data in database
689 TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
691 AliCDBManager *cdb = AliCDBManager::Instance();
692 AliCDBStorage *storLoc = cdb->GetStorage(db);
693 AliCDBMetaData *md = new AliCDBMetaData();
694 md->SetResponsible("Dariusz Miskowiec");
695 md->SetComment(comment);
696 AliCDBId id(path,run0,run1);
697 storLoc->Put(ar,id,md);
703 //_____________________________________________________________________________
704 void AliTRDalignment::WriteGeo(char *filename)
707 // apply misalignment to (currently loaded ideal) geometry and store the
708 // resulting geometry on a root file
711 TClonesArray *ar = new TClonesArray("AliAlignObjAngles",10000);
713 for (int i = 0; i < ar->GetEntriesFast(); i++) {
714 AliAlignObj *alobj = (AliAlignObj *) ar->UncheckedAt(i);
715 alobj->ApplyToGeometry();
718 gGeoManager->Export(filename);
722 //_____________________________________________________________________________
723 Double_t AliTRDalignment::GetSmRMS(Int_t xyz) const
731 for (int i = 0; i < 18; i++) {
733 s2 += fSm[i][xyz]*fSm[i][xyz];
735 Double_t rms2 = s2/18.0 - s1*s1/18.0/18.0;
737 return rms2>0 ? sqrt(rms2) : 0.0;
741 //_____________________________________________________________________________
742 Double_t AliTRDalignment::GetChRMS(Int_t xyz) const
750 for (int i = 0; i < 540; i++) {
752 s2 += fCh[i][xyz]*fCh[i][xyz];
754 Double_t rms2 = s2/540.0 - s1*s1/540.0/540.0;
756 return rms2>0 ? sqrt(rms2) : 0.0;
760 //_____________________________________________________________________________
761 void AliTRDalignment::PrintSmRMS() const
767 printf(" %11.4f %11.4f %11.4f %11.5f %11.5f %11.5f supermodule rms\n"
768 ,GetSmRMS(0),GetSmRMS(1),GetSmRMS(2),GetSmRMS(3),GetSmRMS(4),GetSmRMS(5));
772 //_____________________________________________________________________________
773 void AliTRDalignment::PrintChRMS() const
779 printf(" %11.4f %11.4f %11.4f %11.5f %11.5f %11.5f chamber rms\n"
780 ,GetChRMS(0),GetChRMS(1),GetChRMS(2),GetChRMS(3),GetChRMS(4),GetChRMS(5));
784 //_____________________________________________________________________________
785 void AliTRDalignment::ArToNumbers(TClonesArray *ar)
788 // read numbers from the array of AliAlignObj objects and fill fSm and fCh
794 for (int i = 0; i < 18; i++) {
795 AliAlignObj *aao = (AliAlignObj *) ar->At(i);
796 aao->GetLocalPars(pa,pa+3);
799 for (int i = 0; i < 540; i++) {
800 AliAlignObj *aao = (AliAlignObj *) ar->At(18+i);
801 aao->GetLocalPars(pa,pa+3);
807 //_____________________________________________________________________________
808 void AliTRDalignment::NumbersToAr(TClonesArray *ar)
811 // build array of AliAlignObj objects based on fSm and fCh data
815 TClonesArray &alobj = *ar;
817 for (int i = 0; i < 18; i++) {
818 new(alobj[nobj]) AliAlignObjAngles(GetSmName(i)
820 ,fSm[i][0],fSm[i][1],fSm[i][2]
821 ,fSm[i][3],fSm[i][4],fSm[i][5]
826 for (int i = 0; i < 540; i++) {
827 new(alobj[nobj]) AliAlignObjAngles(GetChName(i)
829 ,fCh[i][0],fCh[i][1],fCh[i][2]
830 ,fCh[i][3],fCh[i][4],fCh[i][5]
837 //_____________________________________________________________________________
838 void AliTRDalignment::LoadIdealGeometry(char *filename)
841 // load ideal geometry from filename
842 // it is needed for operations on AliAlignObj objects
843 // this needs to be straightened out
844 // particularly, sequences LoadIdealGeometry("file1"); LoadIdealGeometry("file2");
845 // do not work as one would naturally expect
848 static int attempt = 0; // which reload attempt is it? just to avoid endless loops
851 TGeoManager::Import(filename);
854 AliFatal(Form("cannot open geometry file %s",filename));
856 if (gGeoManager->GetListOfPhysicalNodes()->GetEntries()) {
858 AliFatal(Form("geometry on file %s is not ideal",filename));
860 AliWarning("current geometry is not ideal - it contains physical nodes");
861 AliWarning(Form("reloading geometry from %s - attempt nr %d",filename,attempt));
864 LoadIdealGeometry(filename);