Class creating the aligmnent object fro the surveyor measurements.
[u/mrichter/AliRoot.git] / TPC / AliTPCAlign.cxx
CommitLineData
2574314d 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/*
17$Log$
18*/
19
20//
21// Creates the TPC align object
22//
23
24#include "AliTPCAlign.h"
25//
26#include "TROOT.h"
27#include "Riostream.h"
28#include "TFile.h"
29#include "TMath.h"
30#include "TSystem.h"
31#include "AliSurveyObj.h"
32#include "AliAlignObjParams.h"
33#include "AliCDBStorage.h"
34#include <TClonesArray.h>
35#include <TFile.h>
36#include "AliLog.h"
37#include "AliCDBManager.h"
38
39ClassImp(AliTPCAlign);
40
41AliTPCAlign::AliTPCAlign() :
42 TObject(),
43 fFileLoc(0x0),
44 fFileGlob(0x0),
45 fTPCAlignObj(0x0),
46 fX(),
47 fA(),
48 fY(),
49 fDebug(0)
50{
51 //
52 // default constructor
53 //
54}
55//________________________________________________________________________
56AliTPCAlign::AliTPCAlign(Int_t reportloc, Int_t reportglob) :
57 TObject(),
58 fFileLoc(0x0),
59 fFileGlob(0x0),
60 fTPCAlignObj(0x0),
61 fX(6,1),
62 fA(24,6),
63 fY(24,1),
64 fDebug(0)
65{
66 //
67 // constructor - defines data files
68 //
69 fFileLoc = new Char_t[80];
70 fFileGlob = new Char_t[80];
71 Char_t path[50];
72 sprintf(path,gSystem->Getenv("ALICE_ROOT"));
73 //
74 sprintf(fFileLoc,"%s/TPC/Survey_%d_TPC.txt",path,reportloc);
75 sprintf(fFileGlob,"%s/TPC/Survey_%d_TPC.txt",path,reportglob);
76 //
77
78}
79//_________________________________________________________________________
80AliTPCAlign::AliTPCAlign(const AliTPCAlign &align) :
81 TObject(),
82 fFileLoc(0x0),
83 fFileGlob(0x0),
84 fTPCAlignObj(0x0),
85 fX(),
86 fA(),
87 fY(),
88 fDebug(0)
89{
90 //
91 // copy constructor - dummy
92 //
93 fDebug = align.fDebug;
94}
95//__________________________________________________________________________
96AliTPCAlign & AliTPCAlign::operator =(const AliTPCAlign & align)
97{
98 //
99 // assignment operator - dummy
100 //
101 fDebug=align.fDebug;
102 return (*this);
103}
104
105//__________________________________________________________________________
106AliTPCAlign::~AliTPCAlign(){
107 //
108 // destructor
109 //
110 if(fTPCAlignObj) delete fTPCAlignObj;
111}
112//__________________________________________________________________________
113Bool_t AliTPCAlign::LoadSurveyData(){
114 //
115 // for a time being it loads from the local file the surveyed point
116 // and has the ideal points hardwired. I am waiting until Ricardo
117 // completes his job
118 //
119
120 AliSurveyObj * s1 = new AliSurveyObj();
121 s1->FillFromLocalFile(fFileGlob);
122 //
123 Int_t numberPoints = 8;
124 //
125 TString pointNames[8] = {"T1Final_R04241","T1Final_R05241","T1Final_R06241",
126 "T1Final_R07241","T1Final_R08241","T1Final_R10241",
127 "T1Final_R11241","T1Final_R12241"};
128 //
129 Float_t surveyedPoints[8][3];
130 AliSurveyPoint *currPoint;
131 //
132 for(Int_t i=0;i<numberPoints;i++){
133 currPoint=0;
134 currPoint = (AliSurveyPoint *) s1->GetData()->FindObject(pointNames[i]);
135 //
136 if(currPoint){
137 surveyedPoints[i][0]=currPoint->GetX();
138 surveyedPoints[i][1]=currPoint->GetY();
139 surveyedPoints[i][2]=currPoint->GetZ();
140 if(fDebug)
141 Printf(Form("INFO: Point \"%s\" coordinates read.", pointNames[i].Data()));
142 }
143 else {
144 if(fDebug){
145 Printf(Form("ERROR: Essential point missing: \"%s\"", pointNames[i].Data()));
146 return 1;
147 }
148 }
149 }
150 //
151 // Ideal points
152 //
153 Float_t idealPoints[8][3];
154 //
155 idealPoints[0][0]=0.7973;
156 idealPoints[0][1]=-2.5278;
157 idealPoints[0][2]=3.0165;
158 //
159 idealPoints[1][0]=2.5873;
160 idealPoints[1][1]=-0.5738;
161 idealPoints[1][2]=3.0166;
162 //
163 idealPoints[2][0]=1.7898;
164 idealPoints[2][1]=1.9540;
165 idealPoints[2][2]=3.0164;
166 //
167 idealPoints[3][0]=-0.2237;
168 idealPoints[3][1]=0.7055;
169 idealPoints[3][2]=3.0161;
170 //
171 idealPoints[4][0]=-0.7230;
172 idealPoints[4][1]=0.1598;
173 idealPoints[4][2]=3.0162;
174//
175 idealPoints[5][0]=0.2225;
176 idealPoints[5][1]=-0.7058;
177 idealPoints[5][2]=3.0166;
178 //
179 idealPoints[6][0]=0.7224;
180 idealPoints[6][1]=-0.1608;
181 idealPoints[6][2]=3.0164;
182 //
183 idealPoints[7][0]=0.4999;
184 idealPoints[7][1]=0.5452;
185 idealPoints[7][2]=3.0164;
186 //
187 // Create and fill matrices a & y
188 //
189 for(Int_t i = 0;i<numberPoints;i++){
190 for(Int_t j=0;j<3;j++){
191 fY(i*3+j,0)=surveyedPoints[i][j]-idealPoints[i][j];
192
193 }
194 }
195 fA.Zero();
196 //
197 //
198 // setting matrix a
199 //
200 for(Int_t i=0;i<numberPoints;i++){
201 fA(3*i,0)= -idealPoints[i][1];
202 fA(3*i,1)= idealPoints[i][2];
203 fA(3*i,3)=1.;
204 fA(3*i+1,0)= idealPoints[i][0];
205 fA(3*i+1,2)= -idealPoints[i][2];
206 fA(3*i+1,4)= 1.;
207 fA(3*i+2,1)= -idealPoints[i][0];
208 fA(3*i+2,2)= idealPoints[i][1];
209 fA(3*i+2,5)=1.;
210 }
211 //
212 delete s1;
213 //
214 return 0;
215}
216//_________________________________________________________________
217Double_t AliTPCAlign::ComputeTransform(){
218 //
219 // Here simple matrix operations for the linear least square
220 // The trigonometric function sin is approximated by the angle
221 // and the cos by "1", because angles are very small (Y-convention!)
222 // This secures the linearity of the problem
223 // This method returns a sum of squares of residuals
224 //
225 TMatrixD tt1(TMatrixD::kInverted,(TMatrixD(fA,TMatrixD::kTransposeMult,fA)));
226 fX=TMatrixD(tt1,TMatrixD::kMult,TMatrixD(fA,TMatrixD::kTransposeMult,fY));
227 //
228 TMatrixD Unit(24,24);
229 Unit.UnitMatrix();
230 TMatrixD xxt1(TMatrixD::kInverted,TMatrixD(fA,TMatrixD::kTransposeMult,fA));
231 TMatrixD t(fA,TMatrixD::kMult,TMatrixD(xxt1,TMatrixD::kMultTranspose,fA));
232 TMatrixD t2(Unit,TMatrixD::kMinus,t);
233 TMatrixD chi2(fY,TMatrixD::kTransposeMult,TMatrixD(t2,TMatrixD::kMult,fY));
234 //
235
236 return chi2(0,0);
237
238}
239//_______________________________________________________________________
240void AliTPCAlign::CreateAlignObj(){
241 //
242 // This method creates AliAlignObj and fills it with Euler angles
243 // and shifts. The units are degrees and cm.
244 //
245 fTPCAlignObj = new AliAlignObjParams();
246 fTPCAlignObj->SetSymName("ALIC_1/TPC_M_1");
247 fTPCAlignObj->SetVolUID(0);
248 Double_t raddeg = TMath::RadToDeg();
249 Double_t phi,theta,psi;
250 //
251 phi=fX(0,0)*raddeg;
252 theta=fX(1,0)*raddeg;
253 psi=fX(2,0)*raddeg;
254 //
255 Double_t dx,dy,dz;
256 dx=fX(3,0)*100.;
257 dy=fX(4,0)*100.;
258 dz=fX(5,0)*100.;
259 fTPCAlignObj->SetRotation(psi,theta,phi);
260 fTPCAlignObj->SetTranslation(dx,dy,dz);
261 fTPCAlignObj->Print("");
262}
263//______________________________________________________________________
264void AliTPCAlign::Run(){
265 //
266 // runs the full chain
267 //
268 SetDebug(0);
269 Bool_t flag = LoadSurveyData();
270 if(flag) {
271 cout<<"Missing points"<<endl;
272 return;
273 }
274 Double_t chi2 = ComputeTransform();
275 if(chi2>0.01) return;
276 CreateAlignObj();
277 StoreAlignObj();
278 //
279}
280//_________________________________________________________________________
281void AliTPCAlign::StoreAlignObj(){
282 //
283AliCDBManager* cdb = AliCDBManager::Instance();
284 if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://$ALICE_ROOT");
285 //
286TClonesArray *array = new TClonesArray("AliAlignObjParams",1);
287//
288 Double_t shifts[3];
289 Double_t rots[3];
290 //
291 fTPCAlignObj->GetPars(shifts,rots);
292 new((*array)[0]) AliAlignObjParams(fTPCAlignObj->GetSymName(),0,shifts[0],
293 shifts[1],shifts[2],rots[0],rots[1],rots[2],kTRUE);
294
295//
296// storing either in the OCDB or local file
297//
298 if( TString(gSystem->Getenv("TOCDB")) != TString("kTRUE") ){
299 // save on file
300 const char* filename = "TPCSurveyMisalignment.root";
301 Char_t fullname[80];
302 sprintf(fullname,"%s/TPC/%s",gSystem->Getenv("ALICE_ROOT"),filename);
303 TFile *f = new TFile(fullname,"RECREATE");
304 if(!f){
305 AliError("cannot open file for output\n");
306 return;
307 }
308 AliInfo(Form("Saving alignment objects to the file %s", filename));
309 f->cd();
310 f->WriteObject(array,"TPCAlignObjs","kSingleKey");
311 f->Close();
312 }else{
313 // save in CDB storage
314 AliCDBStorage* storage;
315 //
316 TString Storage = gSystem->Getenv("STORAGE");
317 if(!Storage.BeginsWith("local://") && !Storage.BeginsWith("alien://")) {
318 AliError(Form(
319 "STORAGE variable set to %s is not valid. Exiting\n",Storage.Data()));
320 return;
321 }
322 storage = cdb->GetStorage(Storage.Data());
323 if(!storage){
324 AliError(Form("Unable to open storage %s\n",Storage.Data()));
325 return;
326 }
327 //
328 AliCDBMetaData* md = new AliCDBMetaData();
329 md->SetResponsible("Marek Kowalski");
330 md->SetComment("Full misalignment of entire TPC from surveyors");
331 AliCDBId id("TPC/Align/Data",0,AliCDBRunRange::Infinity());
332 storage->Put(array,id,md);
333 }
334
335}