]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDSurveyToAlignObjs.cxx
Fixed a few issues in this code
[u/mrichter/AliRoot.git] / FMD / AliFMDSurveyToAlignObjs.cxx
CommitLineData
09b6c804 1//
2// Class to take survey data and
3// transform that to alignment objects.
4//
5// FMD
6//
b2e6f0b0 7#include "AliFMDSurveyToAlignObjs.h"
f567c3ce 8#include "AliLog.h"
b2e6f0b0 9#include "AliSurveyPoint.h"
10#include <TGraph2DErrors.h>
11#include <TF2.h>
12#include <TVector3.h>
13#include <iostream>
14#include <iomanip>
15#include <TMath.h>
16#include <TRotation.h>
17#include <TGeoMatrix.h>
18#include <TGeoManager.h>
19#include <TGeoPhysicalNode.h>
20#include "AliFMDGeometry.h"
21
faf80567 22//____________________________________________________________________
23Double_t
24AliFMDSurveyToAlignObjs::GetUnitFactor() const
25{
26 // Returns the conversion factor from the measured values to
27 // centimeters.
f567c3ce 28 if (!fSurveyObj) return 0;
faf80567 29 TString units(fSurveyObj->GetUnits());
30 if (units.CompareTo("mm", TString::kIgnoreCase) == 0) return .1;
31 else if (units.CompareTo("cm", TString::kIgnoreCase) == 0) return 1.;
32 else if (units.CompareTo("m", TString::kIgnoreCase) == 0) return 100.;
33 return 1;
34}
35
b2e6f0b0 36//____________________________________________________________________
37Bool_t
faf80567 38AliFMDSurveyToAlignObjs::GetPoint(const char* name,
39 TVector3& point,
40 TVector3& error) const
b2e6f0b0 41{
faf80567 42 // Get named point. On return, point will contain the point
43 // coordinates in centimeters, and error will contain the
44 // meassurement errors in centimeters too. If no point is found,
45 // returns false, otherwise true.
f567c3ce 46 if (!fSurveyPoints) return kFALSE;
47
faf80567 48 Double_t unit = GetUnitFactor();
f567c3ce 49 if (unit == 0) return kFALSE;
50
faf80567 51 TObject* obj = fSurveyPoints->FindObject(name);
52 if (!obj) return kFALSE;
53
f567c3ce 54 AliSurveyPoint* p = static_cast<AliSurveyPoint*>(obj);
55 point.SetXYZ(unit * p->GetX(),
56 unit * p->GetY(),
57 unit * p->GetZ());
58 error.SetXYZ(unit * p->GetPrecisionX(),
59 unit * p->GetPrecisionY(),
60 unit * p->GetPrecisionZ());
61 return kTRUE;
faf80567 62}
b2e6f0b0 63
faf80567 64//____________________________________________________________________
65Bool_t
66AliFMDSurveyToAlignObjs::CalculatePlane(const TVector3& a,
67 const TVector3& b,
68 const TVector3& c,
f567c3ce 69 Double_t depth,
faf80567 70 Double_t* trans,
71 Double_t* rot) const
72{
09b6c804 73 //
74 // Calculate the plane translation and rotation from 3 survey points
75 //
76 // Parameters:
77 // a 1st Survey point
78 // b 2nd Survey point
79 // c 3rd Survey point
80 // trans Translation vector
81 // rot Rotation matrix (direction cosines)
82 //
83 // Return:
84 //
85 //
86
faf80567 87 // Vector a->b, b->c, and normal to plane defined by these two
88 // vectors.
4c01505b 89 TVector3 ab(b-a), bc(c-a);
b2e6f0b0 90
faf80567 91 // Normal vector to the plane of the fiducial marks obtained
92 // as cross product of the two vectors on the plane d0^d1
93 TVector3 nn(ab.Cross(bc));
94 if (nn.Mag() < 1e-8) {
f567c3ce 95 Info("CalculatePlane", "Normal vector is null vector");
faf80567 96 return kFALSE;
97 }
b2e6f0b0 98
faf80567 99 // We express the plane in Hessian normal form.
100 //
101 // n x = -p,
102 //
103 // where n is the normalised normal vector given by
104 //
105 // n_x = a / l, n_y = b / l, n_z = c / l, p = d / l
106 //
107 // with l = sqrt(a^2+b^2+c^2) and a, b, c, and d are from the
108 // normal plane equation
109 //
110 // ax + by + cz + d = 0
111 //
112 // Normalize
113 TVector3 n(nn.Unit());
f567c3ce 114 // Double_t p = - (n * a);
faf80567 115
116 // The center of the square with the fiducial marks as the
117 // corners. The mid-point of one diagonal - md. Used to get the
118 // center of the surveyd box.
4c01505b 119 // TVector3 md(a + c);
120 // md *= 1/2.;
9956d453 121 //Info("CalculatePlane", "corner=(%8f,%8f,%8f)", c.X(),c.Y(),c.Z());
122 //Info("CalculatePlane", "corner=(%8f,%8f,%8f)", b.X(),b.Y(),b.Z());
4c01505b 123 TVector3 md(c + b);
124 md *= 1./2;
9956d453 125 //Info("CalculatePlane", "mid=(%8f,%8f,%8f)", md.X(),md.Y(),md.Z());
126 //Info("CalculatePlane", "normal=(%8f,%8f,%8f)", n.X(),n.Y(),n.Z());
f567c3ce 127
faf80567 128 // The center of the box.
f567c3ce 129 TVector3 orig(md - depth * n);
9956d453 130 // Info("CalculatePlane", "orig=(%8f,%8f,%8f)", orig.X(),orig.Y(),orig.Z());
faf80567 131 trans[0] = orig[0];
132 trans[1] = orig[1];
133 trans[2] = orig[2];
9956d453 134 //Info("CalculatePlane", "trans=(%8f,%8f,%8f)", trans[0],trans[1],trans[2]);
faf80567 135
136 // Normalize the spanning vectors
137 TVector3 uab(ab.Unit());
138 TVector3 ubc(bc.Unit());
139
140 for (size_t i = 0; i < 3; i++) {
9956d453 141 rot[i * 3 + 0] = ubc[i];
142 rot[i * 3 + 1] = uab[i];
143 // rot[i * 3 + 0] = uab[i];
144 // rot[i * 3 + 1] = ubc[i];
faf80567 145 rot[i * 3 + 2] = n[i];
146 }
147 return kTRUE;
148}
149
faf80567 150//____________________________________________________________________
f567c3ce 151Bool_t
152AliFMDSurveyToAlignObjs::FitPlane(const TObjArray& points,
153 const TObjArray& errors,
154 Double_t /* depth */,
155 Double_t* trans,
156 Double_t* rot) const
faf80567 157{
09b6c804 158 //
159 // Calculate the plane rotation and translation by doing a fit of
160 // the plane equation to the surveyed points. At least 4 points
161 // must be passed in the @a points array with corresponding errors
162 // in the array @a errors. The arrays are assumed to contain
163 // TVector3 objects.
164 //
165 // Parameters:
166 // points Array surveyed positions
167 // errors Array of errors corresponding to @a points
168 // depth Survey targets depth (perpendicular to the plane)
169 // trans On return, translation of the plane
170 // rot On return, rotation (direction cosines) of the plane
171 //
172 // Return:
173 // @c true on success, @c false otherwise
174 //
175
f567c3ce 176 Int_t nPoints = points.GetEntries();
177 if (nPoints < 4) {
178 AliError(Form("Cannot fit a plane equation to less than 4 survey points, "
179 "got only %d", nPoints));
faf80567 180 return kFALSE;
181 }
f567c3ce 182
faf80567 183 TGraph2DErrors g;
b2e6f0b0 184 // Loop and fill graph
f567c3ce 185 for (int i = 0; i < nPoints; i++) {
186 TVector3* p = static_cast<TVector3*>(points.At(i));
187 TVector3* e = static_cast<TVector3*>(errors.At(i));
b2e6f0b0 188
f567c3ce 189 if (!p || !e) continue;
190
191 g.SetPoint(i, p->X(), p->Y(), p->Z());
192 g.SetPointError(i, e->X(), e->Y(), e->Z());
9956d453 193
f567c3ce 194 }
195
b2e6f0b0 196 // Check that we have enough points
197 if (g.GetN() < 4) {
f567c3ce 198 AliError(Form("Only got %d survey points - no good for plane fit",
199 g.GetN()));
b2e6f0b0 200 return kFALSE;
201 }
202
203 // Next, declare fitting function and fit to graph.
204 // Fit to the plane equation:
205 //
206 // ax + by + cz + d = 0
207 //
208 // or
209 //
210 // z = - ax/c - by/c - d/c
211 //
f567c3ce 212 TF2 f("plane", "-[0]*x-[1]*y-[2]",
213 g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
b2e6f0b0 214 g.Fit(&f, "Q");
f567c3ce 215
b2e6f0b0 216 // Now, extract the normal and offset
217 TVector3 nv(f.GetParameter(0), f.GetParameter(1), 1);
218 TVector3 n(nv.Unit());
219 Double_t p = -f.GetParameter(2);
f567c3ce 220
b2e6f0b0 221 // Create two vectors spanning the plane
222 TVector3 a(1, 0, f.Eval(1, 0)-p);
223 TVector3 b(0, -1, f.Eval(0, -1)-p);
224 TVector3 ua(a.Unit());
225 TVector3 ub(b.Unit());
f567c3ce 226 // Double_t angAb = ua.Angle(ub);
faf80567 227 // PrintVector("ua: ", ua);
228 // PrintVector("ub: ", ub);
229 // std::cout << "Angle: " << angAb * 180 / TMath::Pi() << std::endl;
f567c3ce 230
b2e6f0b0 231 for (size_t i = 0; i < 3; i++) {
232 rot[i * 3 + 0] = ua[i];
233 rot[i * 3 + 1] = ub[i];
234 rot[i * 3 + 2] = n[i];
235 }
f567c3ce 236
b2e6f0b0 237 // The intersection of the plane is given by (0, 0, -d/c)
238 trans[0] = 0;
239 trans[1] = 0;
240 trans[2] = p;
f567c3ce 241
b2e6f0b0 242 return kTRUE;
243}
244
f567c3ce 245
b2e6f0b0 246//____________________________________________________________________
247Bool_t
f567c3ce 248AliFMDSurveyToAlignObjs::MakeDelta(const char* path,
09b6c804 249 const Double_t* rot,
250 const Double_t* trans,
f567c3ce 251 TGeoHMatrix& delta) const
b2e6f0b0 252{
09b6c804 253 //
254 // Create a delta transform from a global rotation matrix and
255 // translation.
256 //
257 // Parameters:
258 // path Path of element to transform.
259 // rot Rotation matrix (direction cosines)
260 // trans Translation
261 // delta On return, the delta transform
262 //
263 // Return:
264 // Newly
265 //
f567c3ce 266 if (!gGeoManager) return kFALSE;
267 if (!gGeoManager->cd(path)) return kFALSE;
b2e6f0b0 268
b2e6f0b0 269
f567c3ce 270 TGeoMatrix* global = gGeoManager->GetCurrentMatrix();
271#if 0
272 PrintRotation(Form("%s rot:", global->GetName()),global->GetRotationMatrix());
273 PrintVector(Form("%s trans:", global->GetName()),global->GetTranslation());
274#endif
b2e6f0b0 275
f567c3ce 276 return MakeDelta(global, rot, trans, delta);
277}
278
279//____________________________________________________________________
280Bool_t
09b6c804 281AliFMDSurveyToAlignObjs::MakeDelta(const TGeoMatrix* global,
282 const Double_t* rot,
283 const Double_t* trans,
f567c3ce 284 TGeoHMatrix& delta) const
285{
09b6c804 286 //
287 // Create a delta transform from a global rotation matrix and
288 // translation.
289 //
290 // Parameters:
291 // global Global matrix of element to transform.
292 // rot Rotation matrix (direction cosines)
293 // trans Translation
294 // delta On return, the delta transform
295 //
296 // Return:
297 // Newly
298 //
b2e6f0b0 299 TGeoHMatrix* geoM = new TGeoHMatrix;
b2e6f0b0 300 geoM->SetTranslation(trans);
f567c3ce 301 geoM->SetRotation(rot);
9956d453 302 // Info("MakeDelta", "The HMatrix from survey");
303 // geoM->Print();
304 // Info("MakeDelta", "The global matrix");
305 // global->Print();
f567c3ce 306
307 delta = global->Inverse();
9956d453 308 // Info("MakeDelta", "The inverse global matrix");
309 // delta.Print();
f567c3ce 310 delta.MultiplyLeft(geoM);
9956d453 311 // Info("MakeDelta", "The delta matrix");
312 // delta.Print();
f567c3ce 313 return true;
314}
315
9956d453 316namespace {
317 Double_t getFMD1Offset()
318 {
319 static Double_t off = 0;
320 return off;
321 if (off != 0) return off;
322
323 const char* lidN = "FMD1_lid_mat0";
324 TGeoMatrix* lidM = static_cast<TGeoMatrix*>(gGeoManager->GetListOfMatrices()
325 ->FindObject(lidN));
326 if (!lidM) {
327 Error("getFMD1Offset", "Couldn't find FMD1 lid transformation %s", lidN);
328 return 0;
329 }
330
331 const Double_t* lidT = lidM->GetTranslation();
332 Double_t lidZ = lidT[2];
333 off = lidZ-3.3;
334
335 return off;
336 }
337}
338
f567c3ce 339//____________________________________________________________________
340Bool_t
341AliFMDSurveyToAlignObjs::GetFMD1Plane(Double_t* rot, Double_t* trans) const
342{
09b6c804 343 //
344 // Get the FMD1 plane from the survey points
345 //
346 // Parameters:
347 // rot Rotation matrix (direction cosines)
348 // trans Translation
349 //
350 // Return:
351 // @c true on success, @c false otherwise.
352 //
f567c3ce 353
354 // The possile survey points
9956d453 355 TVector3 icb, ict, ocb, oct, eicb, eict, eocb, eoct;
f567c3ce 356 Int_t missing = 0;
9956d453 357 if (!GetPoint("V0L_ICB", icb, eicb)) missing++;
358 if (!GetPoint("V0L_ICT", ict, eict)) missing++;
359 if (!GetPoint("V0L_OCB", ocb, eocb)) missing++;
360 if (!GetPoint("V0L_OCT", oct, eoct)) missing++;
f567c3ce 361
362 // Check that we have enough points
363 if (missing > 1) {
364 AliWarning(Form("Only got %d survey points - no good for FMD1 plane",
365 4-missing));
366 return kFALSE;
367 }
f567c3ce 368#if 0
9956d453 369 TObjArray points;
370 TObjArray errors;
371 points.Add(&icb); errors.Add(&eicb);
372 points.Add(&ict); errors.Add(&eict);
373 points.Add(&oct); errors.Add(&eoct);
374 points.Add(&ocb); errors.Add(&eocb);
375
376 Bool_t ret = FitPlane(points, errors, 0, trans, rot);
377 if (!ret) {
378 Warning("GetFMD1Plane", "fit to plane failed");
379 }
380 for (Int_t i = 0; i < 4; i++) {
381 TVector3* v = static_cast<TVector3*>(points.At(i));
382 TVector3* e = static_cast<TVector3*>(errors.At(i));
383 Info("GetFMD1Plane", "p%d=(%8f,%8f,%8f)+/-(%8f,%8f,%8f)",
384 i, v->X(), v->Y(), v->Z(), e->X(), e->Y(), e->Z());
f567c3ce 385 }
f567c3ce 386#else
9956d453 387 Double_t off = getFMD1Offset();
388 Info("GetFMD1Plane", "Lid offset is %f", off);
f567c3ce 389
4c01505b 390 // if (!CalculatePlane(ocb, icb, ict, off, trans, rot)) return kFALSE;
9956d453 391 // Bool_t ret = CalculatePlane(ocb, icb, oct, off, trans, rot);
392 Bool_t ret = CalculatePlane(oct, ocb, ict, off, trans, rot);
393#endif
4c01505b 394 PrintRotation("FMD1 rotation:", rot);
395 PrintVector("FMD1 translation:", trans);
f567c3ce 396
9956d453 397 return ret;
f567c3ce 398}
399
400//____________________________________________________________________
401Bool_t
402AliFMDSurveyToAlignObjs::DoFMD1()
403{
09b6c804 404 //
405 // Do the FMD1 analysis. We have 4 survey targets on V0-A on the
406 // C-side. These are
407 //
408 // - V0A_ICT In-side, C-side, top.
409 // - V0A_ICB In-side, C-side, bottom.
410 // - V0A_OCT Out-side, C-side, top.
411 // - V0A_OCB Out-side, C-side, bottom.
412 //
413 // These 4 survey targets sit 3.3mm over the V0-A C-side surface, or
414 // 3.3mm over the back surface of FMD1.
415 //
416 // Since these are really sitting on a plane, we can use the method
417 // proposed by the CORE offline.
418 //
419 // Return:
420 // @c true on success, @c false otherwise.
421 //
422
f567c3ce 423 // Do the FMD1 stuff
424 Double_t rot[9], trans[3];
425 if (!GetFMD1Plane(rot, trans)) return kFALSE;
426 // const char* path = "/ALIC_1/F1MT_1/FMD1_lid_0";
4c01505b 427
428#if 0
f567c3ce 429 // TGeoHMatrix delta;
4c01505b 430 Double_t gRot[9], gTrans[3];
431 TVector3 ocb(-127, -220, 324.67);
432 TVector3 oct(-127, +220, 324.67);
433 TVector3 icb(+127, -220, 324.67);
434 TVector3 ict(+127, +220, 324.67);
435 if (!CalculatePlane(ocb, icb, oct, 0, gTrans, gRot)) {
436 Warning("DoFMD1", "Failed to make reference plane");
437 return kFALSE;
438 }
439 PrintRotation("FMD1 ref rotation:", gRot);
440 PrintVector("FMD1 ref translation:", gTrans);
441 TGeoRotation ggRot; ggRot.SetMatrix(gRot);
442 TGeoCombiTrans global(gTrans[0], gTrans[1], gTrans[2], &ggRot);
443#endif
9956d453 444 Double_t off = getFMD1Offset();
445 Info("DoFMD1", "Lid offset is %f", off);
4c01505b 446
9956d453 447 TGeoTranslation global(0,0,324.670-off);
f567c3ce 448 if (!MakeDelta(&global, rot, trans, fFMD1Delta))
449 return kFALSE;
b2e6f0b0 450
f567c3ce 451 // PrintRotation("FMD1 delta rotation:", fFMD1Delta.GetRotationMatrix());
452 // PrintVector("FMD1 delta translation:", fFMD1Delta.GetTranslation());
453
454 return kTRUE;
455}
456
457//____________________________________________________________________
458Bool_t
459AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
460{
09b6c804 461 //
462 // Get the surveyed plane corresponding to the backside of FMD2.
463 // The plane is done as a best fit of the plane equation to at least
464 // 4 of the available survey points.
465 //
466 // Parameters:
467 // rot Rotation matrix (direction cosines)
468 // trans Translation vector.
469 //
470 // Return:
471 // @c true on success, @c false otherwise
472 //
f567c3ce 473
474 // The possible survey points
475 const char* names[] = { "FMD2_ITOP", "FMD2_OTOP",
476 "FMD2_IBOTM", "FMD2_OBOTM",
477 "FMD2_IBOT", "FMD2_OBOT",
478 0 };
479 const char** name = names;
480
481 TObjArray points;
482 TObjArray errors;
b2e6f0b0 483
f567c3ce 484 // Loop and fill graph
9956d453 485 int i = 0;
f567c3ce 486 while (*name) {
487 TVector3 p, e;
9956d453 488 if (!GetPoint(*name, p, e)) {
489 name++;
490 i++;
491 continue;
492 }
f567c3ce 493
9956d453 494 if (i == 5) {
495 Warning("GetFMD2plane", "Setting error on %d, %s to 0.4", i, *name);
496 e.SetXYZ(0.4, 0.4, 0.4); // OBOT
497 }
f567c3ce 498 points.Add(new TVector3(p));
499 errors.Add(new TVector3(e));
9956d453 500 name++;
501 i++;
f567c3ce 502 }
503 if (points.GetEntries() < 4) {
504 AliWarning(Form("Only got %d survey points - no good for FMD2 plane",
505 points.GetEntries()));
506 return kFALSE;
507 }
508
509 return FitPlane(points, errors, 0, trans, rot);
510}
511
512#define M(I,J) rot[(J-1) * 3 + (I-1)]
513//____________________________________________________________________
514Bool_t
515AliFMDSurveyToAlignObjs::DoFMD2()
516{
09b6c804 517 //
518 // Do the FMD2 calculations. We have 6 survey points of which only
519 // 5 are normally surveyed. These are all sittings
520 //
521 // - FMD2_ITOP - In-side, top
522 // - FMD2_IBOTM - In-side, middle bottom
523 // - FMD2_IBOT - In-side, bottom
524 // - FMD2_OTOP - Out-side, top
525 // - FMD2_OBOTM - Out-side, middle bottom
526 // - FMD2_OBOT - Out-side, bottom
527 //
528 // The nominal coordinates of these retro-fitted survey stickers
529 // isn't known. Also, these stickers are put on a thin (0.3mm
530 // thick) carbon cover which flexes quite easily. This means, that
531 // to rotations and xy-translation obtained from the survey data
532 // cannot be used, and left is only the z-translation.
533 //
534 // Further more, since FMD2 to is attached to the ITS SPD thermal
535 // screen, it is questionable if the FMD2 survey will ever be used.
536 //
537 // Return:
538 // @c true on success, @c false otherwise.
539 //
540
f567c3ce 541 // Do the FMD2 stuff
542 Double_t rot[9], trans[3];
543 if (!GetFMD2Plane(rot, trans)) return kFALSE;
4c01505b 544 PrintRotation("FMD2 rotation:", rot);
545 PrintVector("FMD2 translation:", trans);
f567c3ce 546
4c01505b 547#if 0
f567c3ce 548 for (int i = 0; i < 3; i++) {
549 for (int j = 0; j < 3; j++) {
550 rot[i*3+j] = (i == j ? 1 : 0);
551 }
552 }
4c01505b 553#endif
f567c3ce 554 trans[0] = trans[1] = 0;
555 trans[2] += 0.015;
556 // PrintRotation("FMD2 rotation:", rot);
557 // PrintVector("FMD2 translation:", trans);
b2e6f0b0 558
f567c3ce 559 // TGeoHMatrix delta;
560 if (!MakeDelta("/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2",
561 rot, trans, fFMD2Delta)) return kFALSE;
b2e6f0b0 562
f567c3ce 563 // PrintRotation("FMD2 delta rotation:", fFMD2Delta.GetRotationMatrix());
564 // PrintVector("FMD2 delta translation:", fFMD2Delta.GetTranslation());
565
b2e6f0b0 566 return kTRUE;
567}
568
569//____________________________________________________________________
570void
571AliFMDSurveyToAlignObjs::Run()
572{
09b6c804 573 //
574 // Run the task.
575 //
576 //
577
b2e6f0b0 578 AliFMDGeometry* geom = AliFMDGeometry::Instance();
579 geom->Init();
580 geom->InitTransformations();
581
f567c3ce 582 DoFMD1();
b2e6f0b0 583 DoFMD2();
584}
585
4c01505b 586//____________________________________________________________________
587void
588AliFMDSurveyToAlignObjs::Run(const char** files)
589{
590 //
591 // Run the task.
592 //
593 //
594
595 AliFMDGeometry* geom = AliFMDGeometry::Instance();
596 geom->Init();
597 geom->InitTransformations();
598
599 const char** file = files;
600 while (*file) {
601 if ((*file)[0] == '\0') {
602 Warning("Run", "no file specified");
603 file++;
604 continue;
605 }
606 if (!LoadSurveyFromLocalFile(*file)) {
607 Warning("Run", "Failed to load %s", *file);
608 file++;
609 continue;
610 }
611 TString sDet(fSurveyObj->GetDetector());
612 Int_t d = Int_t(sDet[sDet.Length()-1] - '0');
613 Info("Run", "Making alignment for %s (%d)", sDet.Data(), d);
614 Bool_t ret = true;
615 switch (d) {
616 case 1: ret = DoFMD1(); break;
617 case 2: ret = DoFMD2(); break;
618 default:
619 Warning("Run", "Do not know how to deal with %s", sDet.Data());
620 break;
621 }
622 if (!ret) {
623 Warning("Run", "Calculation for %s failed", sDet.Data());
624 }
625 file++;
626 }
627 CreateAlignObjs();
9956d453 628 GetAlignObjArray()->Print();
4c01505b 629 FillDefaultAlignObjs();
630}
631
632//____________________________________________________________________
633AliAlignObjParams*
634AliFMDSurveyToAlignObjs::CreateDefaultAlignObj(const TString& path,
635 Int_t id)
636{
637 Int_t nAlign = fAlignObjArray->GetEntries();
638 AliAlignObjParams* obj =
639 new ((*fAlignObjArray)[nAlign]) AliAlignObjParams(path.Data(),
640 id,0,0,0,0,0,0,kTRUE);
641 if (!obj) {
642 AliError(Form("Failed to create alignment object for %s", path.Data()));
643 return 0;
644 }
645 if (!obj->SetLocalPars(0, 0, 0, 0, 0, 0)) {
646 AliError(Form("Failed to set local transforms on %s", path.Data()));
647 return obj;
648 }
649 return obj;
650}
651
652//____________________________________________________________________
653AliAlignObjParams*
654AliFMDSurveyToAlignObjs::FindAlignObj(const TString& path) const
655{
656 AliAlignObjParams* p = 0;
657 for (int i = 0; i < fAlignObjArray->GetEntries(); i++) {
658 p = static_cast<AliAlignObjParams*>(fAlignObjArray->At(i));
659 if (path.EqualTo(p->GetSymName())) return p;
660 }
661 return 0;
662}
663
664//____________________________________________________________________
665Bool_t
666AliFMDSurveyToAlignObjs::FillDefaultAlignObjs()
667{
668 for (int d = 1; d <= 3; d++) {
669 const char sides[] = { 'T', 'B', 0 };
670 const char* side = sides;
671 while (*side) {
672 TString path = TString::Format("FMD/FMD%d_%c", d, *side);
673 AliAlignObjParams* p = FindAlignObj(path);
9956d453 674 if (!p) p = CreateDefaultAlignObj(path, 0);
675
4c01505b 676 const char halves[] = { 'I', d == 1 ? '\0' : 'O', 0 };
677 const char* half = halves;
678 while (*half) {
679 int nsec = *half == 'I' ? 10 : 20;
680 int start = *side == 'T' ? 0 : nsec/2;
681 int end = *side == 'T' ? nsec/2 : nsec;
682 for (int s=start; s < end; s++) {
683 path = TString::Format("FMD/FMD%d_%c/FMD%c_%02d",
684 d, *side, *half, s);
685 CreateDefaultAlignObj(path, 0);
686 }
687 half++;
688 }
689 side++;
690 }
691
692 }
693 return true;
694}
695
f567c3ce 696//____________________________________________________________________
697Bool_t
698AliFMDSurveyToAlignObjs::CreateAlignObjs()
699{
09b6c804 700 //
701 //
702 // Method to create the alignment objects
703 //
704 // Return:
705 // @c true on success, @c false otherwise
706 //
f567c3ce 707 TClonesArray& array = *fAlignObjArray;
708 Int_t n = array.GetEntriesFast();
709
710 if (!fFMD1Delta.IsIdentity()) {
4c01505b 711 new (array[n++]) AliAlignObjParams("FMD/FMD1_T", 0, fFMD1Delta, kTRUE);
712 new (array[n++]) AliAlignObjParams("FMD/FMD1_B", 0, fFMD1Delta, kTRUE);
f567c3ce 713 }
714 if (!fFMD2Delta.IsIdentity()) {
4c01505b 715 new (array[n++]) AliAlignObjParams("FMD/FMD2_T", 0, fFMD2Delta, kTRUE);
716 new (array[n++]) AliAlignObjParams("FMD/FMD2_B", 0, fFMD2Delta, kTRUE);
f567c3ce 717 }
718 // array.Print();
719
720 return kTRUE;
721}
722
b2e6f0b0 723//____________________________________________________________________
724void
725AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
726{
09b6c804 727 //
728 // Service member function to print a vector
729 //
730 // Parameters:
731 // text Prefix text
732 // v Vector
733 //
b2e6f0b0 734 Double_t va[] = { v.X(), v.Y(), v.Z() };
735 PrintVector(text, va);
736}
737//____________________________________________________________________
738void
739AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
740{
09b6c804 741 //
742 // Service member function to print a vector
743 //
744 // Parameters:
745 // text Prefix text
746 // v Vector (array of 3 doubles)
747 //
b2e6f0b0 748 std::cout << text
749 << std::setw(15) << v[0]
750 << std::setw(15) << v[1]
751 << std::setw(15) << v[2]
752 << std::endl;
753}
754
755
756//____________________________________________________________________
757void
758AliFMDSurveyToAlignObjs::PrintRotation(const char* text, const Double_t* rot)
759{
09b6c804 760 //
761 // Service member function to print a rotation matrix
762 //
763 // Parameters:
764 // text Prefix text
765 // v Matrix (array of 9 doubles)
766 //
767
b2e6f0b0 768 std::cout << text << std::endl;
769 for (size_t i = 0; i < 3; i++) {
770 for (size_t j = 0; j < 3; j++)
771 std::cout << std::setw(15) << rot[i * 3 + j];
772 std::cout << std::endl;
773 }
774}
775
776//____________________________________________________________________
777//
778// EOF
779//