]>
Commit | Line | Data |
---|---|---|
ba8b0266 | 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 | /// \class AliMUONSurveyObj | |
18 | /// Base class for the survey processing of the ALICE DiMuon spectrometer | |
19 | /// | |
20 | /// This base object provides methods to process the survey+photogrammetry | |
21 | /// data of the Chambers (frames) and Detection Elements of the DiMuon | |
22 | /// Spectrometer and calculate their misalignments. | |
23 | /// | |
24 | /// \author Javier Castillo | |
25 | //----------------------------------------------------------------------------- | |
26 | ||
27 | #include <fstream> | |
28 | ||
29 | #include "TMath.h" | |
30 | #include "TVector3.h" | |
31 | #include "TGeoMatrix.h" | |
32 | #include "TFitter.h" | |
33 | #include "TMinuit.h" | |
34 | #include "TString.h" | |
35 | #include "TH2.h" | |
36 | #include "TF2.h" | |
37 | #include "TGraph2DErrors.h" | |
38 | #include "TArrayD.h" | |
39 | ||
40 | #include "AliLog.h" | |
41 | #include "AliSurveyPoint.h" | |
42 | ||
43 | #include "AliMUONSurveyObj.h" | |
44 | #include "AliMUONSurveyUtil.h" | |
45 | ||
46 | void SurveyFcn(int &npar, double *g, double &f, double *par, int iflag); | |
47 | ||
48 | /// \cond CLASSIMP | |
49 | ClassImp(AliMUONSurveyObj) | |
50 | /// \endcond | |
51 | ||
52 | AliMUONSurveyObj::AliMUONSurveyObj() | |
53 | : TObject() | |
54 | , fSTargets(0x0) | |
55 | , fGBTargets(0x0) | |
56 | , fLBTargets(0x0) | |
57 | , fLocalTrf(0x0) | |
58 | , fAlignTrf(0x0) | |
59 | , fBaseTrf(0x0) | |
60 | , fOwnerLocalTrf(kFALSE) | |
61 | , fOwnerAlignTrf(kTRUE) | |
62 | , fOwnerBaseTrf(kFALSE) | |
63 | , fPlane(0x0) | |
64 | , fFitter(0x0) | |
65 | , fXMin(-4000.) | |
66 | , fXMax(4000.) | |
67 | , fYMin(-4000.) | |
68 | , fYMax(4000.) | |
69 | , fZMin(-20000.) | |
70 | , fZMax(20000.) | |
71 | { | |
72 | /// Default constructor | |
73 | ||
74 | fSTargets = new TObjArray(); | |
75 | fSTargets->SetOwner(kFALSE); | |
76 | fGBTargets = new TObjArray(); | |
77 | fGBTargets->SetOwner(kFALSE); | |
78 | fLBTargets = new TObjArray(); | |
79 | fLBTargets->SetOwner(kFALSE); | |
80 | ||
81 | fAlignTrf = new TGeoCombiTrans(); | |
82 | ||
83 | fFitter = new TFitter(100); | |
84 | } | |
85 | ||
86 | AliMUONSurveyObj::~AliMUONSurveyObj() { | |
87 | /// Destructor | |
88 | if(fSTargets) { | |
89 | fSTargets->Delete(); | |
90 | fSTargets = 0x0; | |
91 | } | |
92 | if(fGBTargets) { | |
93 | fGBTargets->Delete(); | |
94 | fGBTargets = 0x0; | |
95 | } | |
96 | if(fLBTargets) { | |
97 | fLBTargets->Delete(); | |
98 | fLBTargets = 0x0; | |
99 | } | |
100 | if (fPlane) { | |
101 | fPlane->Delete(); | |
102 | fPlane = 0x0; | |
103 | } | |
104 | if(fOwnerLocalTrf && fLocalTrf) { | |
105 | fLocalTrf->Delete(); | |
106 | fLocalTrf = 0x0; | |
107 | } | |
108 | if(fOwnerAlignTrf && fAlignTrf) { | |
109 | fAlignTrf->Delete(); | |
110 | fAlignTrf = 0x0; | |
111 | } | |
112 | if(fOwnerBaseTrf && fBaseTrf) { | |
113 | fBaseTrf->Delete(); | |
114 | fBaseTrf = 0x0; | |
115 | } | |
116 | if (fFitter){ | |
117 | fFitter->Delete(); | |
118 | fFitter = 0x0; | |
119 | } | |
120 | } | |
121 | ||
122 | void AliMUONSurveyObj::AddStickerTarget(AliSurveyPoint *stPoint){ | |
123 | fSTargets->Add(stPoint); | |
124 | } | |
125 | ||
126 | void AliMUONSurveyObj::AddGButtonTarget(AliSurveyPoint *btPoint){ | |
127 | fGBTargets->Add(btPoint); | |
128 | } | |
129 | ||
130 | void AliMUONSurveyObj::AddLButtonTarget(AliSurveyPoint *btPoint){ | |
131 | fLBTargets->Add(btPoint); | |
132 | } | |
133 | ||
134 | void AliMUONSurveyObj::AddLButtonTarget(TVector3 *btVector){ | |
135 | fLBTargets->Add(btVector); | |
136 | } | |
137 | ||
138 | Int_t AliMUONSurveyObj::AddStickerTargets(TObjArray *pArray, TString stBaseName, Int_t lTargetMax){ | |
139 | if (!pArray) { | |
140 | AliError(Form("Survey points array is empty %p!",pArray)); | |
141 | return 0; | |
142 | } | |
143 | if (stBaseName.IsNull()) { | |
144 | AliError(Form("Need base name for sticker targets %s!",stBaseName.Data())); | |
145 | return 0; | |
146 | } | |
147 | ||
148 | Int_t stIndex = 0; | |
149 | AliSurveyPoint *pointSST = 0x0; | |
150 | ||
151 | TString stNumber; | |
152 | ||
153 | for (int iPoint=0; iPoint<lTargetMax; iPoint++) { | |
154 | TString stFullName(stBaseName); | |
155 | stNumber = Form("%d",iPoint+1); | |
156 | if(lTargetMax>9&&iPoint+1<10) { | |
157 | stFullName+="0"; | |
158 | } | |
159 | stFullName+=stNumber; | |
160 | ||
161 | pointSST = (AliSurveyPoint *)pArray->FindObject(stFullName.Data()); | |
162 | ||
163 | if(pointSST) { | |
164 | AddStickerTarget(pointSST); | |
165 | AliInfo(Form("Added survey sticker target %s at index %d",pointSST->GetName(),stIndex)); | |
166 | stIndex++; | |
167 | } | |
168 | } | |
169 | ||
170 | AliInfo(Form("Found %d sticker targets with base name %s",fSTargets->GetEntries(),stBaseName.Data())); | |
171 | return stIndex; | |
172 | } | |
173 | ||
174 | Int_t AliMUONSurveyObj::AddGButtonTargets(TObjArray *pArray, TString btBaseName, Int_t lTargetMax){ | |
175 | printf("%s \n",btBaseName.Data()); | |
176 | if (!pArray) { | |
177 | AliError(Form("Survey points array is empty %p!",pArray)); | |
178 | return 0; | |
179 | } | |
180 | if (btBaseName.IsNull()) { | |
181 | AliError(Form("Need base name for button targets %s!",btBaseName.Data())); | |
182 | return 0; | |
183 | } | |
184 | ||
185 | Int_t btIndex = 0; | |
186 | AliSurveyPoint *pointSBT = 0x0; | |
187 | ||
188 | TString btNumber; | |
189 | ||
190 | for (int iPoint=0; iPoint<lTargetMax; iPoint++) { | |
191 | TString btFullName(btBaseName); | |
192 | btNumber = Form("%d",iPoint+1); | |
193 | if(lTargetMax>9&&iPoint+1<10) { | |
194 | btFullName+="0"; | |
195 | } | |
196 | btFullName+=btNumber; | |
197 | printf("%s \n",btFullName.Data()); | |
198 | pointSBT = (AliSurveyPoint *)pArray->FindObject(btFullName.Data()); | |
199 | ||
200 | if(pointSBT) { | |
201 | AddGButtonTarget(pointSBT); | |
202 | AliInfo(Form("Added survey button target %s at index %d",pointSBT->GetName(),btIndex)); | |
203 | btIndex++; | |
204 | } | |
205 | } | |
206 | ||
207 | AliInfo(Form("Found %d button targets with base name %s",fGBTargets->GetEntries(),btBaseName.Data())); | |
208 | return btIndex; | |
209 | } | |
210 | ||
211 | Int_t AliMUONSurveyObj::AddLButtonTargets(TObjArray *pArray, TString btBaseName, Int_t lTargetMax){ | |
212 | printf("%s \n",btBaseName.Data()); | |
213 | if (!pArray) { | |
214 | AliError(Form("Local points array is empty %p!",pArray)); | |
215 | return 0; | |
216 | } | |
217 | if (btBaseName.IsNull()) { | |
218 | AliError(Form("Need base name for button targets %s!",btBaseName.Data())); | |
219 | return 0; | |
220 | } | |
221 | ||
222 | Int_t btIndex = 0; | |
223 | AliSurveyPoint *pointSBT = 0x0; | |
224 | ||
225 | TString btNumber; | |
226 | ||
227 | for (int iPoint=0; iPoint<lTargetMax; iPoint++) { | |
228 | TString btFullName(btBaseName); | |
229 | btNumber = Form("%d",iPoint+1); | |
230 | if(lTargetMax>9&&iPoint+1<10) { | |
231 | btFullName+="0"; | |
232 | } | |
233 | btFullName+=btNumber; | |
234 | printf("%s \n",btFullName.Data()); | |
235 | pointSBT = (AliSurveyPoint *)pArray->FindObject(btFullName.Data()); | |
236 | ||
237 | if(pointSBT) { | |
238 | AddLButtonTarget(pointSBT); | |
239 | AliInfo(Form("Added local button target %s at index %d",pointSBT->GetName(),btIndex)); | |
240 | btIndex++; | |
241 | } | |
242 | } | |
243 | ||
244 | AliInfo(Form("Found %d local button targets with base name %s",fLBTargets->GetEntries(),btBaseName.Data())); | |
245 | return btIndex; | |
246 | } | |
247 | ||
248 | Int_t AliMUONSurveyObj::GetNStickerTargets() { | |
249 | return fSTargets->GetEntriesFast(); | |
250 | } | |
251 | ||
252 | AliSurveyPoint* AliMUONSurveyObj::GetStickerTarget(Int_t stIndex){ | |
253 | if (stIndex<0||stIndex>=fSTargets->GetEntriesFast()) { | |
254 | AliError(Form("No sticker target at index %d",stIndex)); | |
255 | return 0x0; | |
256 | } | |
257 | else { | |
258 | return (AliSurveyPoint*)fSTargets->At(stIndex); | |
259 | } | |
260 | } | |
261 | ||
262 | Int_t AliMUONSurveyObj::GetNGButtonTargets() { | |
263 | return fGBTargets->GetEntriesFast(); | |
264 | } | |
265 | ||
266 | AliSurveyPoint* AliMUONSurveyObj::GetGButtonTarget(Int_t btIndex){ | |
267 | if (btIndex<0||btIndex>=fGBTargets->GetEntriesFast()) { | |
268 | AliError(Form("No surveyed button target at index %d",btIndex)); | |
269 | return 0x0; | |
270 | } | |
271 | else { | |
272 | return (AliSurveyPoint*)fGBTargets->At(btIndex); | |
273 | } | |
274 | } | |
275 | ||
276 | Int_t AliMUONSurveyObj::GetNLButtonTargets() { | |
277 | return fGBTargets->GetEntriesFast(); | |
278 | } | |
279 | ||
280 | AliSurveyPoint* AliMUONSurveyObj::GetLButtonTarget(Int_t btIndex){ | |
281 | if (btIndex<0||btIndex>=fLBTargets->GetEntriesFast()) { | |
282 | AliError(Form("No surveyed button target at index %d",btIndex)); | |
283 | return 0x0; | |
284 | } | |
285 | else { | |
286 | if(fLBTargets->At(btIndex)->IsA()==TVector3::Class()){ | |
287 | TVector3 *lBT = (TVector3*)fLBTargets->At(btIndex); | |
288 | TString str("B"); | |
289 | return (new AliSurveyPoint(TString("local"),(float)lBT->X(),(float)lBT->Y(),(float)lBT->Z(),(float)0.,(float)0.,(float)0.,'B',kTRUE)); | |
290 | } else if(fLBTargets->At(btIndex)->IsA()==AliSurveyPoint::Class()) { | |
291 | AliSurveyPoint *lBT = (AliSurveyPoint*)fLBTargets->At(btIndex); | |
292 | return lBT; | |
293 | } else { | |
294 | AliError(Form("Unexpected class %s ! Valid classes are TVector3 or AliSurveyPoint",fLBTargets->At(btIndex)->ClassName())); | |
295 | return 0; | |
296 | } | |
297 | } | |
298 | } | |
299 | ||
300 | void AliMUONSurveyObj::SetPlane(TString pName, Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax){ | |
301 | if(fPlane) { | |
302 | fPlane->Delete(); | |
303 | fPlane = 0x0; | |
304 | } | |
305 | fPlane = new TF2(pName,this,&AliMUONSurveyObj::eqPlane,xMin,xMax,yMin,yMax,3,"AliMUONSurveyObj","eqPlane"); | |
306 | } | |
307 | ||
308 | void AliMUONSurveyObj::SetPlaneParameters(Double_t p0, Double_t p1, Double_t p2) { | |
309 | if (!fPlane) { | |
310 | AliError("Must use SetPlane before SetPlaneParameters!!!"); | |
311 | } | |
312 | else { | |
313 | fPlane->SetParameter(0,p0); | |
314 | fPlane->SetParameter(1,p1); | |
315 | fPlane->SetParameter(2,p2); | |
316 | } | |
317 | } | |
318 | ||
319 | void AliMUONSurveyObj::DrawSTargets() { | |
320 | ||
321 | TGraph2DErrors *gST = new TGraph2DErrors(3); | |
322 | AliSurveyPoint *pST = 0x0; | |
323 | for (Int_t iPoint=0; iPoint<GetNStickerTargets(); iPoint++) { | |
324 | pST = GetStickerTarget(iPoint); | |
325 | // pST->PrintPoint(); | |
326 | gST->SetPoint(iPoint,pST->GetX(),pST->GetY(),pST->GetZ()); | |
327 | gST->SetPointError(iPoint,pST->GetPrecisionX(),pST->GetPrecisionY(),pST->GetPrecisionZ()); | |
328 | } | |
329 | gST->DrawClone("P0"); | |
330 | ||
331 | if (gST) gST->Delete(); | |
332 | } | |
333 | ||
334 | Double_t AliMUONSurveyObj::FitPlane() { | |
335 | if (!fPlane) { | |
336 | AliError("Must use SetPlane before FitPlane!!!"); | |
337 | return 0.; | |
338 | } | |
339 | if (fSTargets->GetEntriesFast()<3) { | |
340 | AliError("Not enough sticker targets (%d) for plane fitting!!!"); | |
341 | return 0.; | |
342 | } | |
343 | ||
344 | Double_t pl[3] = {0}; | |
345 | Double_t pg[3] = {0}; | |
346 | ||
347 | TGraph2DErrors *gST = new TGraph2DErrors(3); | |
348 | AliSurveyPoint *pST = 0x0; | |
349 | for (Int_t iPoint=0; iPoint<GetNStickerTargets(); iPoint++) { | |
350 | pST = GetStickerTarget(iPoint); | |
351 | // pST->PrintPoint(); | |
352 | pg[0] = pST->GetX(); | |
353 | pg[1] = pST->GetY(); | |
354 | pg[2] = pST->GetZ(); | |
355 | fBaseTrf->MasterToLocal(pg,pl); | |
356 | gST->SetPoint(iPoint,pl[0],pl[1],pl[2]); | |
357 | printf("%d %f %f %f\n",iPoint,pl[0],pl[1],pl[2]); | |
358 | gST->SetPointError(iPoint,pST->GetPrecisionX(),pST->GetPrecisionY(),pST->GetPrecisionZ()); | |
359 | } | |
360 | gST->Fit(fPlane); | |
361 | ||
362 | if (gST) gST->Delete(); | |
363 | ||
364 | return fPlane->GetChisquare(); | |
365 | } | |
366 | ||
367 | Double_t AliMUONSurveyObj::SurveyChi2(Double_t *par){ | |
368 | ||
369 | TGeoTranslation transTemp; | |
370 | TGeoRotation rotTemp; | |
371 | TGeoCombiTrans trfTemp; | |
372 | ||
373 | Double_t lChi2=0.; | |
374 | ||
375 | trfTemp.SetTranslation(transTemp); | |
376 | trfTemp.SetRotation(rotTemp); | |
377 | trfTemp.Clear(); | |
378 | trfTemp.RotateZ(TMath::RadToDeg()*par[5]); | |
379 | trfTemp.RotateY(TMath::RadToDeg()*par[4]); | |
380 | trfTemp.RotateX(TMath::RadToDeg()*par[3]); | |
381 | trfTemp.SetTranslation(par[0],par[1],par[2]); | |
382 | ||
383 | TGeoHMatrix matGlo = (*fBaseTrf)*trfTemp; | |
384 | TGeoCombiTrans trfGlo(matGlo); | |
385 | ||
386 | Double_t pl[3] = {0}; | |
387 | Double_t pg[3] = {0}; | |
388 | ||
389 | for(Int_t iPoint=0; iPoint<fGBTargets->GetEntries(); iPoint++){ | |
390 | AliSurveyPoint *gBT = (AliSurveyPoint*)fGBTargets->At(iPoint); | |
391 | if(fLBTargets->At(iPoint)->IsA()==TVector3::Class()){ | |
392 | TVector3 *lBT = (TVector3*)fLBTargets->At(iPoint); | |
393 | pl[0]=lBT->X(); | |
394 | pl[1]=lBT->Y(); | |
395 | pl[2]=lBT->Z(); | |
396 | } else if(fLBTargets->At(iPoint)->IsA()==AliSurveyPoint::Class()) { | |
397 | AliSurveyPoint *lBT = (AliSurveyPoint*)fLBTargets->At(iPoint); | |
398 | pl[0]=lBT->GetX(); | |
399 | pl[1]=lBT->GetY(); | |
400 | pl[2]=lBT->GetZ(); | |
401 | } else { | |
402 | AliError(Form("Unexpected class %s ! Valid classes are TVector3 or AliSurveyPoint",fLBTargets->At(iPoint)->ClassName())); | |
403 | return 0; | |
404 | } | |
405 | ||
406 | trfGlo.LocalToMaster(pl, pg); | |
407 | // printf("%d %f %f %f\n",iPoint,pg[0],pg[1],pg[2]); | |
408 | if(fLBTargets->At(iPoint)->IsA()==TVector3::Class()){ | |
409 | lChi2 += (pg[0]-gBT->GetX())*(pg[0]-gBT->GetX())/(gBT->GetPrecisionX()*gBT->GetPrecisionX()); | |
410 | lChi2 += (pg[1]-gBT->GetY())*(pg[1]-gBT->GetY())/(gBT->GetPrecisionY()*gBT->GetPrecisionY()); | |
411 | lChi2 += (pg[2]-gBT->GetZ())*(pg[2]-gBT->GetZ())/(gBT->GetPrecisionZ()*gBT->GetPrecisionZ()); | |
412 | } else if(fLBTargets->At(iPoint)->IsA()==AliSurveyPoint::Class()) { | |
413 | AliSurveyPoint *lBT = (AliSurveyPoint*)fLBTargets->At(iPoint); | |
414 | lChi2 += (pg[0]-gBT->GetX())*(pg[0]-gBT->GetX())/(gBT->GetPrecisionX()*gBT->GetPrecisionX()+lBT->GetPrecisionX()*lBT->GetPrecisionX()); | |
415 | lChi2 += (pg[1]-gBT->GetY())*(pg[1]-gBT->GetY())/(gBT->GetPrecisionY()*gBT->GetPrecisionY()+lBT->GetPrecisionY()*lBT->GetPrecisionY()); | |
416 | lChi2 += (pg[2]-gBT->GetZ())*(pg[2]-gBT->GetZ())/(gBT->GetPrecisionZ()*gBT->GetPrecisionZ()+lBT->GetPrecisionZ()*lBT->GetPrecisionZ()); | |
417 | } else { | |
418 | AliError(Form("Unexpected class %s ! Valid classes are TVector3 or AliSurveyPoint",fLBTargets->At(iPoint)->ClassName())); | |
419 | return 0; | |
420 | } | |
421 | } | |
422 | ||
423 | return lChi2; | |
424 | } | |
425 | ||
426 | //_____________________________________________________________________________ | |
427 | void SurveyFcn(int &npar, double *g, double &f, double *par, int iflag) { | |
428 | ||
429 | // | |
430 | // Standard function as needed by Minuit-like minimization procedures. | |
431 | // For the set of parameters par calculates and returns chi-squared. | |
432 | // | |
433 | ||
434 | // smuggle a C++ object into a C function | |
435 | AliMUONSurveyObj *aSurveyObj = (AliMUONSurveyObj*) gMinuit->GetObjectFit(); | |
436 | ||
437 | f = aSurveyObj->SurveyChi2(par); | |
438 | if (iflag==3); | |
439 | if (npar); | |
440 | if (g); // no warnings about unused stuff... | |
441 | ||
442 | } | |
443 | ||
444 | //_____________________________________________________________________________ | |
445 | Int_t AliMUONSurveyObj::SurveyToAlign(TGeoCombiTrans &quadTransf, Double_t *parErr, Double_t psi, Double_t tht, Double_t epsi, Double_t etht) { | |
446 | ||
447 | if (fGBTargets->GetEntries()!=fLBTargets->GetEntries()){ | |
448 | AliError(Form("Different number of button targets: %d survey points and %d local coord!", | |
449 | fGBTargets->GetEntries(),fLBTargets->GetEntries())); | |
450 | return 0; | |
451 | } | |
452 | ||
453 | TFitter fitter(100); | |
454 | gMinuit->SetObjectFit(this); | |
455 | fitter.SetFCN(SurveyFcn); | |
456 | fitter.SetParameter(0,"dx",0,0.1,-20,20); | |
457 | fitter.SetParameter(1,"dy",0,0.1,-20,20); | |
458 | fitter.SetParameter(2,"dz",0,0.1,0,0); | |
459 | fitter.SetParameter(3,"rx",psi,0.0001,-0.05,0.05); | |
460 | fitter.SetParameter(4,"ry",tht,0.0001,-0.05,0.05); | |
461 | // fitter.SetParameter(3,"rx",psi,0.0001,psi-5*epsi,psi+5*epsi); | |
462 | // fitter.SetParameter(4,"ry",tht,0.0001,tht-5*etht,tht+5*etht); | |
463 | fitter.SetParameter(5,"rz",0,0.0001,0,0); | |
464 | ||
465 | if(psi) fitter.FixParameter(3); | |
466 | if(tht) fitter.FixParameter(4); | |
467 | ||
468 | double arglist[100]; | |
469 | arglist[0] = 2; | |
470 | fitter.ExecuteCommand("SET PRINT", arglist, 1); | |
471 | fitter.ExecuteCommand("SET ERR", arglist, 1); | |
472 | arglist[0]=0; | |
473 | //fitter.ExecuteCommand("SIMPLEX", arglist, 1); | |
474 | // fitter.ExecuteCommand("MINIMIZE", arglist, 1); | |
475 | fitter.ExecuteCommand("MIGRAD", arglist, 1); | |
476 | fitter.ExecuteCommand("IMPROVE", arglist, 1); | |
477 | // fitter.ExecuteCommand("MINOS", arglist, 1); | |
478 | // fitter.ExecuteCommand("CALL 3", arglist,0); | |
479 | ||
480 | for (int j=0; j<3; j++) printf("%10.3f ",fitter.GetParameter(j)); | |
481 | for (int j=3; j<6; j++) printf("%10.3f ",1000*fitter.GetParameter(j)); | |
482 | printf("\n"); | |
483 | for (int j=0; j<3; j++) printf("%10.3f ",fitter.GetParError(j)); | |
484 | for (int j=3; j<6; j++) printf("%10.3f ",1000*fitter.GetParError(j)); | |
485 | printf("\n"); | |
486 | ||
487 | quadTransf.Clear(); | |
488 | quadTransf.RotateZ(TMath::RadToDeg()*fitter.GetParameter(5)); | |
489 | quadTransf.RotateY(TMath::RadToDeg()*fitter.GetParameter(4)); | |
490 | quadTransf.RotateX(TMath::RadToDeg()*fitter.GetParameter(3)); | |
491 | quadTransf.SetTranslation(fitter.GetParameter(0),fitter.GetParameter(1),fitter.GetParameter(2)); | |
492 | ||
493 | for(Int_t iPar=0; iPar<6; iPar++){ | |
494 | parErr[iPar] = fitter.GetParError(iPar); | |
495 | } | |
496 | if(epsi) parErr[3] = epsi; | |
497 | if(etht) parErr[4] = etht; | |
498 | ||
499 | return 1; | |
500 | ||
501 | } | |
502 | ||
503 | //_____________________________________________________________________________ | |
504 | Int_t AliMUONSurveyObj::SurveyToAlign(Double_t psi, Double_t tht, Double_t epsi, Double_t etht) { | |
505 | ||
506 | if (fGBTargets->GetEntries()!=fLBTargets->GetEntries()){ | |
507 | AliError(Form("Different number of button targets: %d survey points and %d local coord!", | |
508 | fGBTargets->GetEntries(),fLBTargets->GetEntries())); | |
509 | return 0; | |
510 | } | |
511 | ||
512 | // TFitter fitter(100); | |
513 | gMinuit->SetObjectFit(this); | |
514 | fFitter->SetFCN(SurveyFcn); | |
515 | fFitter->SetParameter(0,"dx",0,0.1,-20,20); | |
516 | fFitter->SetParameter(1,"dy",0,0.1,-20,20); | |
517 | fFitter->SetParameter(2,"dz",0,0.1,0,0); | |
518 | if(psi) | |
519 | fFitter->SetParameter(3,"rx",psi,epsi,psi-5*epsi,psi+5*epsi); | |
520 | else | |
521 | fFitter->SetParameter(3,"rx",psi,0.0001,-0.05,0.05); | |
522 | if(tht) | |
523 | fFitter->SetParameter(4,"ry",tht,etht,tht-5*etht,tht+5*etht); | |
524 | else | |
525 | fFitter->SetParameter(4,"ry",tht,0.0001,-0.05,0.05); | |
526 | // fFitter->SetParameter(3,"rx",psi,0.0001,psi-5*epsi,psi+5*epsi); | |
527 | // fFitter->SetParameter(4,"ry",tht,0.0001,tht-5*etht,tht+5*etht); | |
528 | fFitter->SetParameter(5,"rz",0,0.0001,0,0); | |
529 | ||
530 | if(psi) fFitter->FixParameter(3); | |
531 | if(tht) fFitter->FixParameter(4); | |
532 | ||
533 | double arglist[100]; | |
534 | arglist[0] = 2; | |
535 | fFitter->ExecuteCommand("SET PRINT", arglist, 1); | |
536 | fFitter->ExecuteCommand("SET ERR", arglist, 1); | |
537 | arglist[0]=0; | |
538 | //fFitter->ExecuteCommand("SIMPLEX", arglist, 1); | |
539 | // fFitter->ExecuteCommand("MINIMIZE", arglist, 1); | |
540 | fFitter->ExecuteCommand("MIGRAD", arglist, 1); | |
541 | fFitter->ExecuteCommand("IMPROVE", arglist, 1); | |
542 | // fFitter->ExecuteCommand("MINOS", arglist, 1); | |
543 | // fFitter->ExecuteCommand("CALL 3", arglist,0); | |
544 | ||
545 | for (int j=0; j<3; j++) printf("%10.3f ",fFitter->GetParameter(j)); | |
546 | for (int j=3; j<6; j++) printf("%10.3f ",1000*fFitter->GetParameter(j)); | |
547 | printf("\n"); | |
548 | for (int j=0; j<3; j++) printf("%10.3f ",fFitter->GetParError(j)); | |
549 | for (int j=3; j<6; j++) printf("%10.3f ",1000*fFitter->GetParError(j)); | |
550 | printf("\n"); | |
551 | ||
552 | fAlignTrf->Clear(); | |
553 | fAlignTrf->RotateZ(TMath::RadToDeg()*fFitter->GetParameter(5)); | |
554 | fAlignTrf->RotateY(TMath::RadToDeg()*fFitter->GetParameter(4)); | |
555 | fAlignTrf->RotateX(TMath::RadToDeg()*fFitter->GetParameter(3)); | |
556 | fAlignTrf->SetTranslation(fFitter->GetParameter(0),fFitter->GetParameter(1),fFitter->GetParameter(2)); | |
557 | ||
558 | if(epsi) fFitter->ReleaseParameter(3); // To get error | |
559 | if(etht) fFitter->ReleaseParameter(4); // To get error | |
560 | ||
561 | TGeoCombiTrans lGlobalTrf = TGeoCombiTrans((*fBaseTrf)*(*fAlignTrf)); | |
562 | AliSurveyPoint *pointGBT; | |
563 | AliSurveyPoint *pointLBT; | |
564 | Double_t pl[3] = {0}; | |
565 | Double_t pg[3] = {0}; | |
566 | for (int iPoint=0; iPoint<GetNGButtonTargets(); iPoint++){ | |
567 | pointGBT=GetGButtonTarget(iPoint); | |
568 | pointLBT=GetLButtonTarget(iPoint); | |
569 | pl[0] = pointLBT->GetX(); | |
570 | pl[1] = pointLBT->GetY(); | |
571 | pl[2] = pointLBT->GetZ(); | |
572 | lGlobalTrf.LocalToMaster(pl,pg); | |
573 | printf("Point %d local: %.3f %.3f %.3f\n",iPoint,pl[0],pl[1],pl[2]); | |
574 | printf("Point %d global: %.3f %.3f %.3f\n",iPoint,pg[0],pg[1],pg[2]); | |
575 | printf("Point %d survey: %.3f %.3f %.3f\n",iPoint,pointGBT->GetX(),pointGBT->GetY(),pointGBT->GetZ()); | |
576 | } | |
577 | ||
578 | return 1; | |
579 | ||
580 | } | |
581 | ||
582 | Double_t AliMUONSurveyObj::EvalFunction(TF2 *lFunction, Int_t iP1, Int_t iP2, Char_t *lCoord) { | |
583 | ||
584 | if (!lFunction) { | |
585 | AliError("No function given!!!"); | |
586 | return 0; | |
587 | } | |
588 | AliSurveyPoint *gP1 = GetGButtonTarget(iP1); | |
589 | AliSurveyPoint *gP2 = GetGButtonTarget(iP2); | |
590 | ||
591 | if(!gP1||!gP2){ | |
592 | AliError("Missing global button target!!!"); | |
593 | return 0; | |
594 | } | |
595 | ||
596 | // AliInfo(Form("Function %s parameters %f %f %f %f %f %f",lFunction->GetName(),lFunction->GetParameter(0),lFunction->GetParameter(1),lFunction->GetParameter(2),lFunction->GetParameter(3),lFunction->GetParameter(4),lFunction->GetParameter(5))); | |
597 | Double_t pl1[3] = {0}; | |
598 | Double_t pl2[3] = {0}; | |
599 | Double_t pg1[3] = {0}; | |
600 | Double_t pg2[3] = {0}; | |
601 | ||
602 | pg1[0] = gP1->GetX(); | |
603 | pg1[1] = gP1->GetY(); | |
604 | pg1[2] = gP1->GetZ(); | |
605 | pg2[0] = gP2->GetX(); | |
606 | pg2[1] = gP2->GetY(); | |
607 | pg2[2] = gP2->GetZ(); | |
608 | ||
609 | fBaseTrf->MasterToLocal(pg1,pl1); | |
610 | fBaseTrf->MasterToLocal(pg2,pl2); | |
611 | ||
612 | Double_t lVal = 0.; | |
613 | switch (lCoord[0]) { | |
614 | case 'X': | |
615 | { | |
616 | lVal = lFunction->Eval(pl1[0],pl2[0]); | |
617 | // lVal = lFunction->Eval(gP1->GetX(),gP2->GetX()); | |
618 | // AliInfo(Form("case X, lVal = %f",lVal)); | |
619 | return lVal; | |
620 | } | |
621 | case 'Y': | |
622 | { | |
623 | lVal = lFunction->Eval(pl1[1],pl2[1]); | |
624 | // lVal = lFunction->Eval(gP1->GetY(),gP2->GetY()); | |
625 | // AliInfo(Form("case Y, lVal = %f",lVal)); | |
626 | return lVal; | |
627 | } | |
628 | case 'Z': | |
629 | { | |
630 | lVal = lFunction->Eval(pl1[2],pl2[2]); | |
631 | // lVal = lFunction->Eval(gP1->GetZ(),gP2->GetZ()); | |
632 | // AliInfo(Form("case Z, lVal = %f",lVal)); | |
633 | return lVal; | |
634 | } | |
635 | default: | |
636 | { | |
637 | AliError(Form("Coordinate %c is not valid, options are X Y Z",lCoord)); | |
638 | return 0; | |
639 | } | |
640 | } | |
641 | } | |
642 | ||
643 | void AliMUONSurveyObj::CalculateTranslation(TF2 *xFunc, TF2 *yFunc, TF2 *zFunc, Int_t iP1, Int_t iP2, Double_t *lCenTemp) { | |
644 | ||
645 | lCenTemp[0] = EvalFunction(xFunc,iP1,iP2,"X"); | |
646 | lCenTemp[1] = EvalFunction(yFunc,iP1,iP2,"Y"); | |
647 | lCenTemp[2] = EvalFunction(zFunc,iP1,iP2,"Z"); | |
648 | ||
649 | } | |
650 | ||
651 | Double_t AliMUONSurveyObj::CalculateGlobalDiff(TGeoCombiTrans &lTransf, Int_t nPoints, TArrayD &lDiff){ | |
652 | ||
653 | if (nPoints > GetNGButtonTargets()) { | |
654 | nPoints = GetNGButtonTargets(); | |
655 | } | |
656 | ||
657 | for(Int_t iVal=0; iVal<nPoints*(3+1)+1; iVal++){ | |
658 | lDiff[iVal] = 0.; | |
659 | } | |
660 | ||
661 | Double_t pl[3] = {0}; | |
662 | Double_t pg[3] = {0}; | |
663 | Double_t pml[3] = {0}; | |
664 | Double_t pmg[3] = {0}; | |
665 | AliSurveyPoint *gBT = 0x0; | |
666 | for(Int_t iPoint=0; iPoint<nPoints; iPoint++){ | |
667 | gBT = GetGButtonTarget(iPoint); | |
668 | if(!gBT||!fLBTargets->At(iPoint)){ | |
669 | AliError(Form("The local or global target %d is missing!",iPoint)); | |
670 | lDiff[nPoints*(3+1)] = 1.e7; | |
671 | return lDiff[nPoints*(3+1)]; | |
672 | } | |
673 | if(fLBTargets->At(iPoint)->IsA()==TVector3::Class()){ | |
674 | TVector3 *lBT = (TVector3*)fLBTargets->At(iPoint); | |
675 | pl[0]=lBT->X(); | |
676 | pl[1]=lBT->Y(); | |
677 | pl[2]=lBT->Z(); | |
678 | } else if(fLBTargets->At(iPoint)->IsA()==AliSurveyPoint::Class()) { | |
679 | AliSurveyPoint *lBT = (AliSurveyPoint*)fLBTargets->At(iPoint); | |
680 | pl[0]=lBT->GetX(); | |
681 | pl[1]=lBT->GetY(); | |
682 | pl[2]=lBT->GetZ(); | |
683 | } else { | |
684 | AliError(Form("Unexpected class %s ! Valid classes are TVector3 or AliSurveyPoint",fLBTargets->At(iPoint)->ClassName())); | |
685 | return 0; | |
686 | } | |
687 | ||
688 | lTransf.LocalToMaster(pl,pg); | |
689 | pmg[0] = gBT->GetX(); | |
690 | pmg[1] = gBT->GetY(); | |
691 | pmg[2] = gBT->GetZ(); | |
692 | fBaseTrf->MasterToLocal(pmg,pml); | |
693 | // printf("l %d %f %f %f\n",iPoint,pl[0],pl[1],pl[2]); | |
694 | // printf("g %d %f %f %f\n",iPoint,pg[0],pg[1],pg[2]); | |
695 | // printf("ml %d %f %f %f\n",iPoint,pml[0],pml[1],pml[2]); | |
696 | // printf("mg %d %f %f %f\n",iPoint,gBT->GetX(),gBT->GetY(),gBT->GetZ()); | |
697 | lDiff[iPoint*(3+1)+0] = (pml[0]-pg[0]); | |
698 | lDiff[iPoint*(3+1)+1] = (pml[1]-pg[1]); | |
699 | lDiff[iPoint*(3+1)+2] = (pml[2]-pg[2]); | |
700 | ||
701 | lDiff[iPoint*(3+1)+3] = TMath::Sqrt(lDiff[iPoint*(3+1)+0]*lDiff[iPoint*(3+1)+0]+ | |
702 | lDiff[iPoint*(3+1)+1]*lDiff[iPoint*(3+1)+1]+ | |
703 | lDiff[iPoint*(3+1)+2]*lDiff[iPoint*(3+1)+2]); | |
704 | ||
705 | lDiff[nPoints*(3+1)] += lDiff[iPoint*(3+1)+3]*lDiff[iPoint*(3+1)+3]; | |
706 | } | |
707 | ||
708 | lDiff[nPoints*(3+1)] = TMath::Sqrt(lDiff[nPoints*(3+1)]); | |
709 | return lDiff[nPoints*(3+1)]; | |
710 | } | |
711 | ||
712 | Int_t AliMUONSurveyObj::CalculateBestTransf(Int_t iP1, Int_t iP2, Double_t *lXYZ, Double_t *lPTP) { | |
713 | ||
714 | Double_t lPsi = lPTP[0]; | |
715 | Double_t lTht = lPTP[1]; | |
716 | ||
717 | Double_t pl1[3] = {0}; | |
718 | Double_t pl2[3] = {0}; | |
719 | ||
720 | if(!fLBTargets->At(iP1)||!fLBTargets->At(iP2)){ | |
721 | AliError(Form("Local target %d or %d is missing!",iP1,iP2)); | |
722 | return 0; | |
723 | } | |
724 | ||
725 | if(fLBTargets->At(iP1)->IsA()==TVector3::Class()){ | |
726 | TVector3 *lBT1 = (TVector3*)fLBTargets->At(iP1); | |
727 | pl1[0]=lBT1->X(); | |
728 | pl1[1]=lBT1->Y(); | |
729 | pl1[2]=lBT1->Z(); | |
730 | } else if(fLBTargets->At(iP1)->IsA()==AliSurveyPoint::Class()) { | |
731 | AliSurveyPoint *lBT1 = (AliSurveyPoint*)fLBTargets->At(iP1); | |
732 | pl1[0]=lBT1->GetX(); | |
733 | pl1[1]=lBT1->GetY(); | |
734 | pl1[2]=lBT1->GetZ(); | |
735 | } else { | |
736 | AliError(Form("Unexpected class %s ! Valid classes are TVector3 or AliSurveyPoint",fLBTargets->At(iP1)->ClassName())); | |
737 | return 0; | |
738 | } | |
739 | if(fLBTargets->At(iP2)->IsA()==TVector3::Class()){ | |
740 | TVector3 *lBT2 = (TVector3*)fLBTargets->At(iP2); | |
741 | pl2[0]=lBT2->X(); | |
742 | pl2[1]=lBT2->Y(); | |
743 | pl2[2]=lBT2->Z(); | |
744 | } else if(fLBTargets->At(iP2)->IsA()==AliSurveyPoint::Class()) { | |
745 | AliSurveyPoint *lBT2 = (AliSurveyPoint*)fLBTargets->At(iP2); | |
746 | pl2[0]=lBT2->GetX(); | |
747 | pl2[1]=lBT2->GetY(); | |
748 | pl2[2]=lBT2->GetZ(); | |
749 | } else { | |
750 | AliError(Form("Unexpected class %s ! Valid classes are TVector3 or AliSurveyPoint",fLBTargets->At(iP2)->ClassName())); | |
751 | return 0; | |
752 | } | |
753 | ||
754 | ||
755 | AliMUONSurveyUtil *surveyUtil = AliMUONSurveyUtil::Instance(); | |
756 | ||
757 | // Xcenter functions | |
758 | char *fxcName = "fXcn00"; | |
759 | TF2 **fXc = new TF2*[2]; | |
760 | fxcName = "fXcn"; | |
761 | fXc[0] = new TF2(fxcName,surveyUtil,&AliMUONSurveyUtil::xnCenter,fXMin,fXMax,fYMin,fYMax,7,"AliMUONSurveyUtil","xnCenter"); | |
762 | fxcName = "fXcp"; | |
763 | fXc[1] = new TF2(fxcName,surveyUtil,&AliMUONSurveyUtil::xpCenter,fXMin,fXMax,fYMin,fYMax,7,"AliMUONSurveyUtil","xpCenter"); | |
764 | ||
765 | // Ycenter functions | |
766 | char *fycName = "fYcn00"; | |
767 | TF2 **fYc = new TF2*[2]; | |
768 | fycName = "fYcn"; | |
769 | fYc[0] = new TF2(fycName,surveyUtil,&AliMUONSurveyUtil::ynCenter,fYMin,fYMax,fYMin,fYMax,8,"AliMUONSurveyUtil","ynCenter"); | |
770 | fycName = "fYcp"; | |
771 | fYc[1] = new TF2(fycName,surveyUtil,&AliMUONSurveyUtil::ypCenter,fYMin,fYMax,fYMin,fYMax,8,"AliMUONSurveyUtil","ypCenter"); | |
772 | ||
773 | // Zcenter functions | |
774 | char *fzcName = "fZcn00"; | |
775 | TF2 **fZc = new TF2*[2]; | |
776 | fzcName = "fZcn"; | |
777 | fZc[0] = new TF2(fzcName,surveyUtil,&AliMUONSurveyUtil::znCenter,fZMin,fZMax,fZMin,fZMax,8,"AliMUONSurveyUtil","znCenter"); | |
778 | fzcName = "fZcp"; | |
779 | fZc[1] = new TF2(fzcName,surveyUtil,&AliMUONSurveyUtil::zpCenter,fZMin,fZMax,fZMin,fZMax,8,"AliMUONSurveyUtil","zpCenter"); | |
780 | ||
781 | // Phi rotation using xglobal coords functions | |
782 | char *fphixName = "fPhiXnn00"; | |
783 | TF2 ***fPhiX = new TF2**[2]; | |
784 | for (Int_t iX =0; iX<2; iX++) { | |
785 | fPhiX[iX] = new TF2*[2]; | |
786 | } | |
787 | fphixName = "fPhiXnn"; | |
788 | fPhiX[0][0] = new TF2(fphixName,surveyUtil,&AliMUONSurveyUtil::phixnn,fXMin,fXMax,fXMin,fXMax,7,"AliMUONSurveyUtil","phixnn"); | |
789 | fphixName = "fPhiXnp"; | |
790 | fPhiX[0][1] = new TF2(fphixName,surveyUtil,&AliMUONSurveyUtil::phixnp,fXMin,fXMax,fXMin,fXMax,7,"AliMUONSurveyUtil","phixnp"); | |
791 | fphixName = "fPhiXpn"; | |
792 | fPhiX[1][0] = new TF2(fphixName,surveyUtil,&AliMUONSurveyUtil::phixpn,fXMin,fXMax,fXMin,fXMax,7,"AliMUONSurveyUtil","phixpn"); | |
793 | fphixName = "fPhiXpp"; | |
794 | fPhiX[1][1] = new TF2(fphixName,surveyUtil,&AliMUONSurveyUtil::phixpp,fXMin,fXMax,fXMin,fXMax,7,"AliMUONSurveyUtil","phixpp"); | |
795 | ||
796 | // Phi rotation using yglobal coords functions | |
797 | char *fphiyName = "fPhiYnn00"; | |
798 | TF2 ***fPhiY = new TF2**[2]; | |
799 | for (Int_t iY =0; iY<2; iY++) { | |
800 | fPhiY[iY] = new TF2*[2]; | |
801 | } | |
802 | fphiyName = "fPhiYnn"; | |
803 | fPhiY[0][0] = new TF2(fphiyName,surveyUtil,&AliMUONSurveyUtil::phiynn,fYMin,fYMax,fYMin,fYMax,8,"AliMUONSurveyUtil","phiynn"); | |
804 | fphiyName = "fPhiYnp"; | |
805 | fPhiY[0][1] = new TF2(fphiyName,surveyUtil,&AliMUONSurveyUtil::phiynp,fYMin,fYMax,fYMin,fYMax,8,"AliMUONSurveyUtil","phiynp"); | |
806 | fphiyName = "fPhiYpn"; | |
807 | fPhiY[1][0] = new TF2(fphiyName,surveyUtil,&AliMUONSurveyUtil::phiypn,fYMin,fYMax,fYMin,fYMax,8,"AliMUONSurveyUtil","phiypn"); | |
808 | fphiyName = "fPhiYpp"; | |
809 | fPhiY[1][1] = new TF2(fphiyName,surveyUtil,&AliMUONSurveyUtil::phiypp,fYMin,fYMax,fYMin,fYMax,8,"AliMUONSurveyUtil","phiypp"); | |
810 | ||
811 | ||
812 | // Set Parameters of functions | |
813 | for(Int_t iS=0; iS<2; iS++){ | |
814 | fXc[iS]->SetParameters(pl1[0],pl1[1],pl1[2],pl2[0],pl2[1],pl2[2],lTht); | |
815 | fYc[iS]->SetParameters(pl1[0],pl1[1],pl1[2],pl2[0],pl2[1],pl2[2],lPsi,lTht); | |
816 | fZc[iS]->SetParameters(pl1[0],pl1[1],pl1[2],pl2[0],pl2[1],pl2[2],lPsi,lTht); | |
817 | // fXc[iS]->SetParameters(lBT1->X(),lBT1->Y(),lBT1->Z(),lBT2->X(),lBT2->Y(),lBT2->Z(),lTht); | |
818 | // fYc[iS]->SetParameters(lBT1->X(),lBT1->Y(),lBT1->Z(),lBT2->X(),lBT2->Y(),lBT2->Z(),lPsi,lTht); | |
819 | // fZc[iS]->SetParameters(lBT1->X(),lBT1->Y(),lBT1->Z(),lBT2->X(),lBT2->Y(),lBT2->Z(),lPsi,lTht); | |
820 | for(Int_t jS=0; jS<2; jS++){ | |
821 | fPhiX[iS][jS]->SetParameters(pl1[0],pl1[1],pl1[2],pl2[0],pl2[1],pl2[2],lTht); | |
822 | fPhiY[iS][jS]->SetParameters(pl1[0],pl1[1],pl1[2],pl2[0],pl2[1],pl2[2],lPsi,lTht); | |
823 | // fPhiX[iS][jS]->SetParameters(lBT1->X(),lBT1->Y(),lBT1->Z(),lBT2->X(),lBT2->Y(),lBT2->Z(),lTht); | |
824 | // fPhiY[iS][jS]->SetParameters(lBT1->X(),lBT1->Y(),lBT1->Z(),lBT2->X(),lBT2->Y(),lBT2->Z(),lPsi,lTht); | |
825 | } | |
826 | } | |
827 | ||
828 | Double_t lCenTemp[3]; | |
829 | Double_t lRotTemp[3]; | |
830 | ||
831 | TGeoCombiTrans trfTemp; | |
832 | ||
833 | Int_t nPoints = GetNGButtonTargets(); | |
834 | ||
835 | TArrayD lDiffTemp(nPoints*(3+1)+1); | |
836 | TArrayD lDiffMin(nPoints*(3+1)+1); | |
837 | ||
838 | for(Int_t i=0; i<nPoints*(3+1)+1; i++){ | |
839 | lDiffMin[i]=1000000.; | |
840 | lDiffTemp[i]=0.; | |
841 | } | |
842 | ||
843 | // | |
844 | // Calculate Detection Element Center from button targets | |
845 | // | |
846 | ||
847 | // Trying 2x*2y*2z*(2phi+2phi) possibilities | |
848 | for(Int_t iX=0; iX<2; iX++){ | |
849 | for(Int_t iY=0; iY<2; iY++){ | |
850 | for(Int_t iZ=0; iZ<2; iZ++){ | |
851 | CalculateTranslation(fXc[iX],fYc[iY],fZc[iZ],iP1,iP2,lCenTemp); | |
852 | ||
853 | lRotTemp[0] = lPsi; | |
854 | lRotTemp[1] = lTht; | |
855 | for(Int_t iP=0; iP<2; iP++){ | |
856 | lRotTemp[2] = EvalFunction(fPhiX[iX][iP],iP1,iP2,"X"); | |
857 | ||
858 | trfTemp.Clear(); | |
859 | trfTemp.RotateZ(TMath::RadToDeg()*lRotTemp[2]); | |
860 | trfTemp.RotateY(TMath::RadToDeg()*lRotTemp[1]); | |
861 | trfTemp.RotateX(TMath::RadToDeg()*lRotTemp[0]); | |
862 | trfTemp.SetTranslation(lCenTemp); | |
863 | ||
864 | if(CalculateGlobalDiff(trfTemp,nPoints,lDiffTemp)<lDiffMin[nPoints*(3+1)]){ | |
865 | printf("Diffs"); | |
866 | for(Int_t i=0; i<nPoints*(3+1)+1; i++){ | |
867 | printf(" %f",lDiffTemp[i]); | |
868 | } | |
869 | printf("\n"); | |
870 | printf(" : mycenX%dY%dZ%d(%f,%f,%f); rotx%d(%f,%f,%f)\n",iX,iY,iZ,lCenTemp[0],lCenTemp[1],lCenTemp[2],iP,lRotTemp[0],lRotTemp[1],lRotTemp[2]); | |
871 | printf("Transformation improved ...\n"); | |
872 | for (int i=0; i<3; i++) { | |
873 | lXYZ[i] = lCenTemp[i]; | |
874 | } | |
875 | lPTP[2] = lRotTemp[2]; | |
876 | for(Int_t i=0; i<nPoints*(3+1)+1; i++){ | |
877 | lDiffMin[i]=lDiffTemp[i]; | |
878 | } | |
879 | } | |
880 | } | |
881 | for(Int_t iP=0; iP<2; iP++){ | |
882 | lRotTemp[2] = EvalFunction(fPhiY[iY][iP],iP1,iP2,"Y"); | |
883 | ||
884 | trfTemp.Clear(); | |
885 | trfTemp.RotateZ(TMath::RadToDeg()*lRotTemp[2]); | |
886 | trfTemp.RotateY(TMath::RadToDeg()*lRotTemp[1]); | |
887 | trfTemp.RotateX(TMath::RadToDeg()*lRotTemp[0]); | |
888 | trfTemp.SetTranslation(lCenTemp); | |
889 | ||
890 | if(CalculateGlobalDiff(trfTemp,nPoints,lDiffTemp)<lDiffMin[nPoints*(3+1)]){ | |
891 | printf("Diffs"); | |
892 | for(Int_t i=0; i<nPoints*(3+1)+1; i++){ | |
893 | printf(" %f",lDiffTemp[i]); | |
894 | } | |
895 | printf("\n"); | |
896 | printf(" : mycenX%dY%dZ%d(%f,%f,%f); roty%d(%f,%f,%f)\n",iX,iY,iZ,lCenTemp[0],lCenTemp[1],lCenTemp[2],iP,lRotTemp[0],lRotTemp[1],lRotTemp[2]); | |
897 | printf("Transformation improved ...\n"); | |
898 | for (int i=0; i<3; i++) { | |
899 | lXYZ[i] = lCenTemp[i]; | |
900 | } | |
901 | lPTP[2] = lRotTemp[2]; | |
902 | for(Int_t i=0; i<nPoints*(3+1)+1; i++){ | |
903 | lDiffMin[i]=lDiffTemp[i]; | |
904 | } | |
905 | } | |
906 | } | |
907 | } | |
908 | } | |
909 | } | |
910 | ||
911 | for (Int_t i=0; i<2; i++) { | |
912 | delete fXc[i]; | |
913 | delete fYc[i]; | |
914 | delete fZc[i]; | |
915 | for (Int_t j=0; j<2; j++) { | |
916 | delete fPhiX[i][j]; | |
917 | delete fPhiY[i][j]; | |
918 | } | |
919 | delete[] fPhiX[i]; | |
920 | delete[] fPhiY[i]; | |
921 | } | |
922 | delete[] fXc; | |
923 | delete[] fYc; | |
924 | delete[] fZc; | |
925 | delete[] fPhiX; | |
926 | delete[] fPhiY; | |
927 | ||
928 | if (lDiffMin[nPoints*(3+1)]>20) return 0; | |
929 | ||
930 | return 1; | |
931 | } | |
932 | ||
933 | void AliMUONSurveyObj::CalculateMeanTransf(Double_t *lXYZ, Double_t *lPTP) { | |
934 | ||
935 | Double_t xce=0.; | |
936 | Double_t yce=0.; | |
937 | Double_t zce=0.; | |
938 | Double_t phi=0.; | |
939 | ||
940 | Int_t nPairs = 0; | |
941 | Int_t nPoints = GetNGButtonTargets(); | |
942 | // Loop over all possible pairs of button tragets | |
943 | for(Int_t iP1=0; iP1<nPoints; iP1++){ | |
944 | for(Int_t iP2=iP1+1; iP2<nPoints; iP2++){ | |
945 | printf("%d and %d\n",iP1,iP2); | |
946 | ||
947 | if(CalculateBestTransf(iP1,iP2,lXYZ,lPTP)) { | |
948 | nPairs++; | |
949 | ||
950 | xce+=lXYZ[0]; | |
951 | yce+=lXYZ[1]; | |
952 | zce+=lXYZ[2]; | |
953 | phi+=lPTP[2]; | |
954 | } | |
955 | } | |
956 | } | |
957 | ||
958 | if (!nPairs) return; | |
959 | ||
960 | lXYZ[0]=xce/nPairs; | |
961 | lXYZ[1]=yce/nPairs; | |
962 | lXYZ[2]=zce/nPairs; | |
963 | lPTP[2]=phi/nPairs; | |
964 | } | |
965 | ||
966 | void AliMUONSurveyObj::PrintLocalTrf() { | |
967 | Double_t lRotTemp[3]; | |
968 | AliMUONSurveyUtil::MatrixToAngles(fLocalTrf->GetRotationMatrix(),lRotTemp); | |
969 | printf("(%.3f %.3f %.3f), (%.6f %.6f %.6f)\n",fLocalTrf->GetTranslation()[0],fLocalTrf->GetTranslation()[1],fLocalTrf->GetTranslation()[2],lRotTemp[0],lRotTemp[1],lRotTemp[2]); | |
970 | } | |
971 | ||
972 | void AliMUONSurveyObj::PrintAlignTrf() { | |
973 | Double_t lRotTemp[3]; | |
974 | AliMUONSurveyUtil::MatrixToAngles(fAlignTrf->GetRotationMatrix(),lRotTemp); | |
975 | printf("(%.3f %.3f %.3f), (%.6f %.6f %.6f)\n",fAlignTrf->GetTranslation()[0],fAlignTrf->GetTranslation()[1],fAlignTrf->GetTranslation()[2],lRotTemp[0],lRotTemp[1],lRotTemp[2]); | |
976 | } | |
977 | ||
978 | void AliMUONSurveyObj::FillSTHistograms(TString baseNameC, TH2 *hSTc, TString baseNameA, TH2 *hSTa) { | |
979 | if(baseNameC.IsNull()||!hSTc){ | |
980 | AliError("Need base name for points on side C and/or a histogram for them!"); | |
981 | return; | |
982 | } | |
983 | AliSurveyPoint *pointST = 0x0; | |
984 | for (Int_t iPoint=0; iPoint<GetNStickerTargets(); iPoint++) { | |
985 | pointST = GetStickerTarget(iPoint); | |
986 | if (!pointST) continue; | |
987 | if (pointST->GetPointName().Contains(baseNameC)){ | |
988 | hSTc->Fill(pointST->GetX(),pointST->GetY(),-pointST->GetZ()); | |
989 | } else if ((!baseNameA.IsNull()) && | |
990 | (pointST->GetPointName().Contains(baseNameA))) { | |
991 | if (!hSTa){ | |
992 | AliError("Base name for points on side A provided but no histogram for them!"); | |
993 | continue; | |
994 | } | |
995 | hSTa->Fill(pointST->GetX(),pointST->GetY(),-pointST->GetZ()); | |
996 | } | |
997 | } | |
998 | } | |
999 | ||
1000 | Double_t AliMUONSurveyObj::GetAlignResX() { | |
1001 | if(!fFitter) { | |
1002 | AliError("There is no fitter for this object! X resolution will be 0."); | |
1003 | return 0.; | |
1004 | } | |
1005 | return fFitter->GetParError(0); | |
1006 | } | |
1007 | ||
1008 | Double_t AliMUONSurveyObj::GetAlignResY() { | |
1009 | if(!fFitter) { | |
1010 | AliError("There is no fitter for this object! Y resolution will be 0."); | |
1011 | return 0.; | |
1012 | } | |
1013 | return fFitter->GetParError(1); | |
1014 | } |