]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDSurveyToAlignObjs.cxx
Fixed up some code for making alignment objects from survey
[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.;
121 TVector3 md(c + b);
122 md *= 1./2;
f567c3ce 123
faf80567 124 // The center of the box.
f567c3ce 125 TVector3 orig(md - depth * n);
faf80567 126 trans[0] = orig[0];
127 trans[1] = orig[1];
128 trans[2] = orig[2];
129
130 // Normalize the spanning vectors
131 TVector3 uab(ab.Unit());
132 TVector3 ubc(bc.Unit());
133
134 for (size_t i = 0; i < 3; i++) {
4c01505b 135 // rot[i * 3 + 0] = ubc[i];
136 // rot[i * 3 + 1] = uab[i];
137 rot[i * 3 + 0] = uab[i];
138 rot[i * 3 + 1] = ubc[i];
faf80567 139 rot[i * 3 + 2] = n[i];
140 }
141 return kTRUE;
142}
143
faf80567 144//____________________________________________________________________
f567c3ce 145Bool_t
146AliFMDSurveyToAlignObjs::FitPlane(const TObjArray& points,
147 const TObjArray& errors,
148 Double_t /* depth */,
149 Double_t* trans,
150 Double_t* rot) const
faf80567 151{
09b6c804 152 //
153 // Calculate the plane rotation and translation by doing a fit of
154 // the plane equation to the surveyed points. At least 4 points
155 // must be passed in the @a points array with corresponding errors
156 // in the array @a errors. The arrays are assumed to contain
157 // TVector3 objects.
158 //
159 // Parameters:
160 // points Array surveyed positions
161 // errors Array of errors corresponding to @a points
162 // depth Survey targets depth (perpendicular to the plane)
163 // trans On return, translation of the plane
164 // rot On return, rotation (direction cosines) of the plane
165 //
166 // Return:
167 // @c true on success, @c false otherwise
168 //
169
f567c3ce 170 Int_t nPoints = points.GetEntries();
171 if (nPoints < 4) {
172 AliError(Form("Cannot fit a plane equation to less than 4 survey points, "
173 "got only %d", nPoints));
faf80567 174 return kFALSE;
175 }
f567c3ce 176
faf80567 177 TGraph2DErrors g;
b2e6f0b0 178 // Loop and fill graph
f567c3ce 179 for (int i = 0; i < nPoints; i++) {
180 TVector3* p = static_cast<TVector3*>(points.At(i));
181 TVector3* e = static_cast<TVector3*>(errors.At(i));
b2e6f0b0 182
f567c3ce 183 if (!p || !e) continue;
184
185 g.SetPoint(i, p->X(), p->Y(), p->Z());
186 g.SetPointError(i, e->X(), e->Y(), e->Z());
187 }
188
b2e6f0b0 189 // Check that we have enough points
190 if (g.GetN() < 4) {
f567c3ce 191 AliError(Form("Only got %d survey points - no good for plane fit",
192 g.GetN()));
b2e6f0b0 193 return kFALSE;
194 }
195
196 // Next, declare fitting function and fit to graph.
197 // Fit to the plane equation:
198 //
199 // ax + by + cz + d = 0
200 //
201 // or
202 //
203 // z = - ax/c - by/c - d/c
204 //
f567c3ce 205 TF2 f("plane", "-[0]*x-[1]*y-[2]",
206 g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
b2e6f0b0 207 g.Fit(&f, "Q");
f567c3ce 208
b2e6f0b0 209 // Now, extract the normal and offset
210 TVector3 nv(f.GetParameter(0), f.GetParameter(1), 1);
211 TVector3 n(nv.Unit());
212 Double_t p = -f.GetParameter(2);
f567c3ce 213
b2e6f0b0 214 // Create two vectors spanning the plane
215 TVector3 a(1, 0, f.Eval(1, 0)-p);
216 TVector3 b(0, -1, f.Eval(0, -1)-p);
217 TVector3 ua(a.Unit());
218 TVector3 ub(b.Unit());
f567c3ce 219 // Double_t angAb = ua.Angle(ub);
faf80567 220 // PrintVector("ua: ", ua);
221 // PrintVector("ub: ", ub);
222 // std::cout << "Angle: " << angAb * 180 / TMath::Pi() << std::endl;
f567c3ce 223
b2e6f0b0 224 for (size_t i = 0; i < 3; i++) {
225 rot[i * 3 + 0] = ua[i];
226 rot[i * 3 + 1] = ub[i];
227 rot[i * 3 + 2] = n[i];
228 }
f567c3ce 229
b2e6f0b0 230 // The intersection of the plane is given by (0, 0, -d/c)
231 trans[0] = 0;
232 trans[1] = 0;
233 trans[2] = p;
f567c3ce 234
b2e6f0b0 235 return kTRUE;
236}
237
f567c3ce 238
b2e6f0b0 239//____________________________________________________________________
240Bool_t
f567c3ce 241AliFMDSurveyToAlignObjs::MakeDelta(const char* path,
09b6c804 242 const Double_t* rot,
243 const Double_t* trans,
f567c3ce 244 TGeoHMatrix& delta) const
b2e6f0b0 245{
09b6c804 246 //
247 // Create a delta transform from a global rotation matrix and
248 // translation.
249 //
250 // Parameters:
251 // path Path of element to transform.
252 // rot Rotation matrix (direction cosines)
253 // trans Translation
254 // delta On return, the delta transform
255 //
256 // Return:
257 // Newly
258 //
f567c3ce 259 if (!gGeoManager) return kFALSE;
260 if (!gGeoManager->cd(path)) return kFALSE;
b2e6f0b0 261
b2e6f0b0 262
f567c3ce 263 TGeoMatrix* global = gGeoManager->GetCurrentMatrix();
264#if 0
265 PrintRotation(Form("%s rot:", global->GetName()),global->GetRotationMatrix());
266 PrintVector(Form("%s trans:", global->GetName()),global->GetTranslation());
267#endif
b2e6f0b0 268
f567c3ce 269 return MakeDelta(global, rot, trans, delta);
270}
271
272//____________________________________________________________________
273Bool_t
09b6c804 274AliFMDSurveyToAlignObjs::MakeDelta(const TGeoMatrix* global,
275 const Double_t* rot,
276 const Double_t* trans,
f567c3ce 277 TGeoHMatrix& delta) const
278{
09b6c804 279 //
280 // Create a delta transform from a global rotation matrix and
281 // translation.
282 //
283 // Parameters:
284 // global Global matrix of element to transform.
285 // rot Rotation matrix (direction cosines)
286 // trans Translation
287 // delta On return, the delta transform
288 //
289 // Return:
290 // Newly
291 //
b2e6f0b0 292 TGeoHMatrix* geoM = new TGeoHMatrix;
b2e6f0b0 293 geoM->SetTranslation(trans);
f567c3ce 294 geoM->SetRotation(rot);
295
296 delta = global->Inverse();
297 delta.MultiplyLeft(geoM);
298
299 return true;
300}
301
302//____________________________________________________________________
303Bool_t
304AliFMDSurveyToAlignObjs::GetFMD1Plane(Double_t* rot, Double_t* trans) const
305{
09b6c804 306 //
307 // Get the FMD1 plane from the survey points
308 //
309 // Parameters:
310 // rot Rotation matrix (direction cosines)
311 // trans Translation
312 //
313 // Return:
314 // @c true on success, @c false otherwise.
315 //
f567c3ce 316
317 // The possile survey points
318 TVector3 icb, ict, ocb, oct, dummy;
319 Int_t missing = 0;
320 if (!GetPoint("V0L_ICB", icb, dummy)) missing++;
321 if (!GetPoint("V0L_ICT", ict, dummy)) missing++;
322 if (!GetPoint("V0L_OCB", ocb, dummy)) missing++;
323 if (!GetPoint("V0L_OCT", oct, dummy)) missing++;
324
325 // Check that we have enough points
326 if (missing > 1) {
327 AliWarning(Form("Only got %d survey points - no good for FMD1 plane",
328 4-missing));
329 return kFALSE;
330 }
331
332#if 0
333 const char* lidN = "FMD1_lid_mat0";
334 TGeoMatrix* lidM = static_cast<TGeoMatrix*>(gGeoManager->GetListOfMatrices()
335 ->FindObject(lidN));
336 if (!lidM) {
337 AliError(Form("Couldn't find FMD1 lid transformation %s", lidN));
338 return kFALSE;
339 }
340
341 const Double_t* lidT = lidM->GetTranslation();
342 Double_t lidZ = lidT[2];
343 Double_t off = lidZ-3.3;
344#else
345 Double_t off = 0;
b2e6f0b0 346#endif
f567c3ce 347
4c01505b 348 // if (!CalculatePlane(ocb, icb, ict, off, trans, rot)) return kFALSE;
349 if (!CalculatePlane(ocb, icb, oct, off, trans, rot)) return kFALSE;
350 PrintRotation("FMD1 rotation:", rot);
351 PrintVector("FMD1 translation:", trans);
f567c3ce 352
353 return kTRUE;
354}
355
356//____________________________________________________________________
357Bool_t
358AliFMDSurveyToAlignObjs::DoFMD1()
359{
09b6c804 360 //
361 // Do the FMD1 analysis. We have 4 survey targets on V0-A on the
362 // C-side. These are
363 //
364 // - V0A_ICT In-side, C-side, top.
365 // - V0A_ICB In-side, C-side, bottom.
366 // - V0A_OCT Out-side, C-side, top.
367 // - V0A_OCB Out-side, C-side, bottom.
368 //
369 // These 4 survey targets sit 3.3mm over the V0-A C-side surface, or
370 // 3.3mm over the back surface of FMD1.
371 //
372 // Since these are really sitting on a plane, we can use the method
373 // proposed by the CORE offline.
374 //
375 // Return:
376 // @c true on success, @c false otherwise.
377 //
378
f567c3ce 379 // Do the FMD1 stuff
380 Double_t rot[9], trans[3];
381 if (!GetFMD1Plane(rot, trans)) return kFALSE;
382 // const char* path = "/ALIC_1/F1MT_1/FMD1_lid_0";
4c01505b 383
384#if 0
f567c3ce 385 // TGeoHMatrix delta;
4c01505b 386 Double_t gRot[9], gTrans[3];
387 TVector3 ocb(-127, -220, 324.67);
388 TVector3 oct(-127, +220, 324.67);
389 TVector3 icb(+127, -220, 324.67);
390 TVector3 ict(+127, +220, 324.67);
391 if (!CalculatePlane(ocb, icb, oct, 0, gTrans, gRot)) {
392 Warning("DoFMD1", "Failed to make reference plane");
393 return kFALSE;
394 }
395 PrintRotation("FMD1 ref rotation:", gRot);
396 PrintVector("FMD1 ref translation:", gTrans);
397 TGeoRotation ggRot; ggRot.SetMatrix(gRot);
398 TGeoCombiTrans global(gTrans[0], gTrans[1], gTrans[2], &ggRot);
399#endif
400
f567c3ce 401 TGeoTranslation global(0,0,324.670);
402 if (!MakeDelta(&global, rot, trans, fFMD1Delta))
403 return kFALSE;
b2e6f0b0 404
f567c3ce 405 // PrintRotation("FMD1 delta rotation:", fFMD1Delta.GetRotationMatrix());
406 // PrintVector("FMD1 delta translation:", fFMD1Delta.GetTranslation());
407
408 return kTRUE;
409}
410
411//____________________________________________________________________
412Bool_t
413AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
414{
09b6c804 415 //
416 // Get the surveyed plane corresponding to the backside of FMD2.
417 // The plane is done as a best fit of the plane equation to at least
418 // 4 of the available survey points.
419 //
420 // Parameters:
421 // rot Rotation matrix (direction cosines)
422 // trans Translation vector.
423 //
424 // Return:
425 // @c true on success, @c false otherwise
426 //
f567c3ce 427
428 // The possible survey points
429 const char* names[] = { "FMD2_ITOP", "FMD2_OTOP",
430 "FMD2_IBOTM", "FMD2_OBOTM",
431 "FMD2_IBOT", "FMD2_OBOT",
432 0 };
433 const char** name = names;
434
435 TObjArray points;
436 TObjArray errors;
b2e6f0b0 437
f567c3ce 438 // Loop and fill graph
439 while (*name) {
440 TVector3 p, e;
441 if (!GetPoint(*name++, p, e)) continue;
442
443 points.Add(new TVector3(p));
444 errors.Add(new TVector3(e));
445 }
446 if (points.GetEntries() < 4) {
447 AliWarning(Form("Only got %d survey points - no good for FMD2 plane",
448 points.GetEntries()));
449 return kFALSE;
450 }
451
452 return FitPlane(points, errors, 0, trans, rot);
453}
454
455#define M(I,J) rot[(J-1) * 3 + (I-1)]
456//____________________________________________________________________
457Bool_t
458AliFMDSurveyToAlignObjs::DoFMD2()
459{
09b6c804 460 //
461 // Do the FMD2 calculations. We have 6 survey points of which only
462 // 5 are normally surveyed. These are all sittings
463 //
464 // - FMD2_ITOP - In-side, top
465 // - FMD2_IBOTM - In-side, middle bottom
466 // - FMD2_IBOT - In-side, bottom
467 // - FMD2_OTOP - Out-side, top
468 // - FMD2_OBOTM - Out-side, middle bottom
469 // - FMD2_OBOT - Out-side, bottom
470 //
471 // The nominal coordinates of these retro-fitted survey stickers
472 // isn't known. Also, these stickers are put on a thin (0.3mm
473 // thick) carbon cover which flexes quite easily. This means, that
474 // to rotations and xy-translation obtained from the survey data
475 // cannot be used, and left is only the z-translation.
476 //
477 // Further more, since FMD2 to is attached to the ITS SPD thermal
478 // screen, it is questionable if the FMD2 survey will ever be used.
479 //
480 // Return:
481 // @c true on success, @c false otherwise.
482 //
483
f567c3ce 484 // Do the FMD2 stuff
485 Double_t rot[9], trans[3];
486 if (!GetFMD2Plane(rot, trans)) return kFALSE;
4c01505b 487 PrintRotation("FMD2 rotation:", rot);
488 PrintVector("FMD2 translation:", trans);
f567c3ce 489
4c01505b 490#if 0
f567c3ce 491 for (int i = 0; i < 3; i++) {
492 for (int j = 0; j < 3; j++) {
493 rot[i*3+j] = (i == j ? 1 : 0);
494 }
495 }
4c01505b 496#endif
f567c3ce 497 trans[0] = trans[1] = 0;
498 trans[2] += 0.015;
499 // PrintRotation("FMD2 rotation:", rot);
500 // PrintVector("FMD2 translation:", trans);
b2e6f0b0 501
f567c3ce 502 // TGeoHMatrix delta;
503 if (!MakeDelta("/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2",
504 rot, trans, fFMD2Delta)) return kFALSE;
b2e6f0b0 505
f567c3ce 506 // PrintRotation("FMD2 delta rotation:", fFMD2Delta.GetRotationMatrix());
507 // PrintVector("FMD2 delta translation:", fFMD2Delta.GetTranslation());
508
b2e6f0b0 509 return kTRUE;
510}
511
512//____________________________________________________________________
513void
514AliFMDSurveyToAlignObjs::Run()
515{
09b6c804 516 //
517 // Run the task.
518 //
519 //
520
b2e6f0b0 521 AliFMDGeometry* geom = AliFMDGeometry::Instance();
522 geom->Init();
523 geom->InitTransformations();
524
f567c3ce 525 DoFMD1();
b2e6f0b0 526 DoFMD2();
527}
528
4c01505b 529//____________________________________________________________________
530void
531AliFMDSurveyToAlignObjs::Run(const char** files)
532{
533 //
534 // Run the task.
535 //
536 //
537
538 AliFMDGeometry* geom = AliFMDGeometry::Instance();
539 geom->Init();
540 geom->InitTransformations();
541
542 const char** file = files;
543 while (*file) {
544 if ((*file)[0] == '\0') {
545 Warning("Run", "no file specified");
546 file++;
547 continue;
548 }
549 if (!LoadSurveyFromLocalFile(*file)) {
550 Warning("Run", "Failed to load %s", *file);
551 file++;
552 continue;
553 }
554 TString sDet(fSurveyObj->GetDetector());
555 Int_t d = Int_t(sDet[sDet.Length()-1] - '0');
556 Info("Run", "Making alignment for %s (%d)", sDet.Data(), d);
557 Bool_t ret = true;
558 switch (d) {
559 case 1: ret = DoFMD1(); break;
560 case 2: ret = DoFMD2(); break;
561 default:
562 Warning("Run", "Do not know how to deal with %s", sDet.Data());
563 break;
564 }
565 if (!ret) {
566 Warning("Run", "Calculation for %s failed", sDet.Data());
567 }
568 file++;
569 }
570 CreateAlignObjs();
571 FillDefaultAlignObjs();
572}
573
574//____________________________________________________________________
575AliAlignObjParams*
576AliFMDSurveyToAlignObjs::CreateDefaultAlignObj(const TString& path,
577 Int_t id)
578{
579 Int_t nAlign = fAlignObjArray->GetEntries();
580 AliAlignObjParams* obj =
581 new ((*fAlignObjArray)[nAlign]) AliAlignObjParams(path.Data(),
582 id,0,0,0,0,0,0,kTRUE);
583 if (!obj) {
584 AliError(Form("Failed to create alignment object for %s", path.Data()));
585 return 0;
586 }
587 if (!obj->SetLocalPars(0, 0, 0, 0, 0, 0)) {
588 AliError(Form("Failed to set local transforms on %s", path.Data()));
589 return obj;
590 }
591 return obj;
592}
593
594//____________________________________________________________________
595AliAlignObjParams*
596AliFMDSurveyToAlignObjs::FindAlignObj(const TString& path) const
597{
598 AliAlignObjParams* p = 0;
599 for (int i = 0; i < fAlignObjArray->GetEntries(); i++) {
600 p = static_cast<AliAlignObjParams*>(fAlignObjArray->At(i));
601 if (path.EqualTo(p->GetSymName())) return p;
602 }
603 return 0;
604}
605
606//____________________________________________________________________
607Bool_t
608AliFMDSurveyToAlignObjs::FillDefaultAlignObjs()
609{
610 for (int d = 1; d <= 3; d++) {
611 const char sides[] = { 'T', 'B', 0 };
612 const char* side = sides;
613 while (*side) {
614 TString path = TString::Format("FMD/FMD%d_%c", d, *side);
615 AliAlignObjParams* p = FindAlignObj(path);
616 if (!p)
617 p = CreateDefaultAlignObj(path, 0);
618 else
619 Info("FillDefaultAlignObjs", "Alignment object %s exists", path.Data());
620 const char halves[] = { 'I', d == 1 ? '\0' : 'O', 0 };
621 const char* half = halves;
622 while (*half) {
623 int nsec = *half == 'I' ? 10 : 20;
624 int start = *side == 'T' ? 0 : nsec/2;
625 int end = *side == 'T' ? nsec/2 : nsec;
626 for (int s=start; s < end; s++) {
627 path = TString::Format("FMD/FMD%d_%c/FMD%c_%02d",
628 d, *side, *half, s);
629 CreateDefaultAlignObj(path, 0);
630 }
631 half++;
632 }
633 side++;
634 }
635
636 }
637 return true;
638}
639
f567c3ce 640//____________________________________________________________________
641Bool_t
642AliFMDSurveyToAlignObjs::CreateAlignObjs()
643{
09b6c804 644 //
645 //
646 // Method to create the alignment objects
647 //
648 // Return:
649 // @c true on success, @c false otherwise
650 //
f567c3ce 651 TClonesArray& array = *fAlignObjArray;
652 Int_t n = array.GetEntriesFast();
653
654 if (!fFMD1Delta.IsIdentity()) {
4c01505b 655 new (array[n++]) AliAlignObjParams("FMD/FMD1_T", 0, fFMD1Delta, kTRUE);
656 new (array[n++]) AliAlignObjParams("FMD/FMD1_B", 0, fFMD1Delta, kTRUE);
f567c3ce 657 }
658 if (!fFMD2Delta.IsIdentity()) {
4c01505b 659 new (array[n++]) AliAlignObjParams("FMD/FMD2_T", 0, fFMD2Delta, kTRUE);
660 new (array[n++]) AliAlignObjParams("FMD/FMD2_B", 0, fFMD2Delta, kTRUE);
f567c3ce 661 }
662 // array.Print();
663
664 return kTRUE;
665}
666
b2e6f0b0 667//____________________________________________________________________
668void
669AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
670{
09b6c804 671 //
672 // Service member function to print a vector
673 //
674 // Parameters:
675 // text Prefix text
676 // v Vector
677 //
b2e6f0b0 678 Double_t va[] = { v.X(), v.Y(), v.Z() };
679 PrintVector(text, va);
680}
681//____________________________________________________________________
682void
683AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
684{
09b6c804 685 //
686 // Service member function to print a vector
687 //
688 // Parameters:
689 // text Prefix text
690 // v Vector (array of 3 doubles)
691 //
b2e6f0b0 692 std::cout << text
693 << std::setw(15) << v[0]
694 << std::setw(15) << v[1]
695 << std::setw(15) << v[2]
696 << std::endl;
697}
698
699
700//____________________________________________________________________
701void
702AliFMDSurveyToAlignObjs::PrintRotation(const char* text, const Double_t* rot)
703{
09b6c804 704 //
705 // Service member function to print a rotation matrix
706 //
707 // Parameters:
708 // text Prefix text
709 // v Matrix (array of 9 doubles)
710 //
711
b2e6f0b0 712 std::cout << text << std::endl;
713 for (size_t i = 0; i < 3; i++) {
714 for (size_t j = 0; j < 3; j++)
715 std::cout << std::setw(15) << rot[i * 3 + j];
716 std::cout << std::endl;
717 }
718}
719
720//____________________________________________________________________
721//
722// EOF
723//