LCOV - code coverage report
Current view: top level - FMD/FMDbase - AliFMDSurveyToAlignObjs.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 236 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 20 0.0 %

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

Generated by: LCOV version 1.11