Finalised the survey to alignment conversion. Closing corresponding task
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 5 Feb 2009 23:44:19 +0000 (23:44 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 5 Feb 2009 23:44:19 +0000 (23:44 +0000)
in the dotProject planning tool.

FMD/AliFMDGeometryBuilder.cxx
FMD/AliFMDSurveyToAlignObjs.cxx
FMD/AliFMDSurveyToAlignObjs.h
FMD/Config.C
FMD/Survey_943928_FMD.txt
FMD/scripts/TestSurveyToAlignObjs.C

index 85a39f1..22d5a7d 100644 (file)
@@ -680,9 +680,10 @@ AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
                         {  6.80, 24.50, 24.65 },
                         {  6.80, 24.50, 26.00 },
                         {  6.95, 24.50, 26.00 } };
-  TGeoPcon* lidBaseS = new TGeoPcon("FMD1_lid_base", 0, 180, 12);
+  Double_t  lidZStart = lidP[11][0];
+  TGeoPcon* lidBaseS  = new TGeoPcon("FMD1_lid_base", 0, 180, 12);
   for (size_t i = 0; i < 12; i++) 
-    lidBaseS->DefineSection(i, lidP[i][0], lidP[i][1], lidP[i][2]);
+    lidBaseS->DefineSection(i, lidP[i][0] - lidZStart, lidP[i][1], lidP[i][2]);
   
   
   Double_t lidH[][2] = { {  7.84903, 24.15680  }, 
@@ -696,10 +697,10 @@ AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
   TString lidComp("FMD1_lid_base-(");
   TGeoTranslation* trans = 0;
   for (size_t i = 0; i < 4; i++) { 
-    trans = new TGeoTranslation(-lidH[i][0], lidH[i][1], 6.95-lidHL/2);
+    trans = new TGeoTranslation(-lidH[i][0], lidH[i][1], /*6.95*/-lidHL/2);
     trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+0));
     trans->RegisterYourself();
-    trans = new TGeoTranslation(+lidH[i][0], lidH[i][1], 6.95-lidHL/2);
+    trans = new TGeoTranslation(+lidH[i][0], lidH[i][1], /*6.95*/-lidHL/2);
     trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+1));
     trans->RegisterYourself();
     lidComp.Append(Form("FMD1_lid_hole:FMD1_lid_hole_mat%d+" 
@@ -712,7 +713,8 @@ AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
   lidV->SetTransparency(63);
   
   // Place top cover
-  Double_t lidZ = -(3.3 - r->GetModuleDepth() - r->GetModuleSpacing() / 2);
+  Double_t lidZ = (lidZStart - 
+                  (3.3 - r->GetModuleDepth() - r->GetModuleSpacing() / 2));
   AliFMDDebug(1, ("FMD1 lid offset in Z=%f", lidZ));
 
   for (Int_t i = 0; i  < 2; i++) {
index 3c43d8a..f236cfd 100644 (file)
@@ -1,4 +1,5 @@
 #include "AliFMDSurveyToAlignObjs.h"
+#include "AliLog.h"
 #include "AliSurveyPoint.h"
 #include <TGraph2DErrors.h>
 #include <TF2.h>
@@ -18,6 +19,7 @@ AliFMDSurveyToAlignObjs::GetUnitFactor() const
 {
   // Returns the conversion factor from the measured values to
   // centimeters. 
+  if (!fSurveyObj) return 0;
   TString units(fSurveyObj->GetUnits());
   if      (units.CompareTo("mm", TString::kIgnoreCase) == 0) return .1;
   else if (units.CompareTo("cm", TString::kIgnoreCase) == 0) return 1.;
@@ -35,18 +37,22 @@ AliFMDSurveyToAlignObjs::GetPoint(const char* name,
   // coordinates in centimeters, and error will contain the
   // meassurement errors in centimeters too.  If no point is found,
   // returns false, otherwise true. 
+  if (!fSurveyPoints) return kFALSE;
+  
   Double_t unit = GetUnitFactor();
+  if (unit == 0) return kFALSE;
+  
   TObject* obj  = fSurveyPoints->FindObject(name);
   if (!obj) return kFALSE;
   
-   AliSurveyPoint* p = static_cast<AliSurveyPoint*>(obj);
-   point.SetXYZ(unit * p->GetX(), 
-               unit * p->GetY(),
-               unit * p->GetZ());
-   error.SetXYZ(unit * p->GetPrecisionX(),
-               unit * p->GetPrecisionY(),
-               unit * p->GetPrecisionZ());
-   return kTRUE;
+  AliSurveyPoint* p = static_cast<AliSurveyPoint*>(obj);
+  point.SetXYZ(unit * p->GetX(), 
+              unit * p->GetY(),
+              unit * p->GetZ());
+  error.SetXYZ(unit * p->GetPrecisionX(),
+              unit * p->GetPrecisionY(),
+              unit * p->GetPrecisionZ());
+  return kTRUE;
 }
 
 //____________________________________________________________________
@@ -54,6 +60,7 @@ Bool_t
 AliFMDSurveyToAlignObjs::CalculatePlane(const     TVector3& a, 
                                        const     TVector3& b,
                                        const     TVector3& c, 
+                                       Double_t  depth,
                                        Double_t* trans,
                                        Double_t* rot) const
 {
@@ -65,7 +72,7 @@ AliFMDSurveyToAlignObjs::CalculatePlane(const     TVector3& a,
   // as cross product of the two vectors on the plane d0^d1
   TVector3 nn(ab.Cross(bc));
   if (nn.Mag() < 1e-8) { 
-    Info("DoIt", "Normal vector is null vector");
+    Info("CalculatePlane", "Normal vector is null vector");
     return kFALSE;
   }
   
@@ -84,16 +91,16 @@ AliFMDSurveyToAlignObjs::CalculatePlane(const     TVector3& a,
   // 
   // Normalize
   TVector3 n(nn.Unit());
-  Double_t p = - (n * a);
+  // Double_t p = - (n * a);
   
   // The center of the square with the fiducial marks as the
   // corners.  The mid-point of one diagonal - md.  Used to get the
   // center of the surveyd box. 
   TVector3 md(a + c);
   md *= 1/2.;
-  
+
   // The center of the box. 
-  TVector3 orig(md);
+  TVector3 orig(md - depth * n);
   trans[0] = orig[0];
   trans[1] = orig[1];
   trans[2] = orig[2];
@@ -103,73 +110,44 @@ AliFMDSurveyToAlignObjs::CalculatePlane(const     TVector3& a,
   TVector3 ubc(bc.Unit());
   
   for (size_t i = 0; i < 3; i++) { 
-    rot[i * 3 + 0] = uab[i];
-    rot[i * 3 + 1] = ubc[i];
+    rot[i * 3 + 0] = ubc[i];
+    rot[i * 3 + 1] = uab[i];
     rot[i * 3 + 2] = n[i];
   }
   return kTRUE;
 }
 
-
 //____________________________________________________________________
-Bool_t
-AliFMDSurveyToAlignObjs::GetFMD1Plane(Double_t* rot, Double_t* trans) const
+Bool_t 
+AliFMDSurveyToAlignObjs::FitPlane(const TObjArray& points, 
+                                 const TObjArray& errors,
+                                 Double_t         /* depth */,
+                                 Double_t*        trans,
+                                 Double_t*        rot) const
 {
-
-  // The possile survey points 
-  TVector3  icb, ict, ocb, oct, dummy;
-  Int_t     missing = 0;
-  if (!GetPoint("V0L_ICB", icb, dummy)) missing++;
-  if (!GetPoint("V0L_ICT", icb, dummy)) missing++;
-  if (!GetPoint("V0L_OCB", icb, dummy)) missing++;
-  if (!GetPoint("V0L_OCT", icb, dummy)) missing++;
-
-  // Check that we have enough points
-  if (missing > 1) { 
-    Error("GetFMD1Plane", "Only got %d survey points - no good for FMD1 plane",
-         4-missing);
+  Int_t nPoints = points.GetEntries();
+  if (nPoints < 4) { 
+    AliError(Form("Cannot fit a plane equation to less than 4 survey points, "
+                 "got only %d", nPoints));
     return kFALSE;
   }
-
-  if (!CalculatePlane(icb, ict, oct, rot, trans)) return kFALSE;
-
-  return kTRUE;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDSurveyToAlignObjs::DoFMD1()
-{
-  return kTRUE;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
-{
-
-  // The possile survey points 
-  const char*    names[] = { "FMD2_ITOP",  "FMD2_OTOP", 
-                            "FMD2_IBOTM", "FMD2_OBOTM", 
-                            "FMD2_IBOT",  "FMD2_OBOT", 
-                            0 };
-  const char**   name    = names;
-  Int_t          i       = 0;
+  
   TGraph2DErrors g;
   // Loop and fill graph 
-  while (*name) {
-    TVector3 p, e;
-    if (!GetPoint(*name++, p, e)) continue;
-
-    g.SetPoint(i, p.X(), p.Y(), p.Z());
-    g.SetPointError(i, e.X(), e.Y(), e.Z());
-    i++;
-  }
+  for (int i = 0; i < nPoints; i++) {
+    TVector3* p = static_cast<TVector3*>(points.At(i));
+    TVector3* e = static_cast<TVector3*>(errors.At(i));
   
+    if (!p || !e) continue;
+    
+    g.SetPoint(i, p->X(), p->Y(), p->Z());
+    g.SetPointError(i, e->X(), e->Y(), e->Z());
+  }
+
   // Check that we have enough points
   if (g.GetN() < 4) { 
-    Error("GetFMD2Plane", "Only got %d survey points - no good for FMD2 plane",
-         g.GetN());
+    AliError(Form("Only got %d survey points - no good for plane fit",
+                 g.GetN()));
     return kFALSE;
   }
 
@@ -182,111 +160,202 @@ AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
   // 
   //   z = - ax/c - by/c - d/c
   //
-  TF2 f("fmd2Plane", "-[0]*x-[1]*y-[2]", 
-       g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
+  TF2 f("plane", "-[0]*x-[1]*y-[2]", 
+        g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
   g.Fit(&f, "Q");
-
+  
   // Now, extract the normal and offset
   TVector3 nv(f.GetParameter(0), f.GetParameter(1), 1);
   TVector3 n(nv.Unit());
   Double_t p = -f.GetParameter(2);
-
+  
   // Create two vectors spanning the plane 
   TVector3 a(1, 0, f.Eval(1, 0)-p);
   TVector3 b(0, -1, f.Eval(0, -1)-p);
   TVector3 ua(a.Unit());
   TVector3 ub(b.Unit());
-  Double_t angAb = ua.Angle(ub);
+  // Double_t angAb = ua.Angle(ub);
   // PrintVector("ua: ", ua);
   // PrintVector("ub: ", ub);
   // std::cout << "Angle: " << angAb * 180 / TMath::Pi() << std::endl;
-  
+    
   for (size_t i = 0; i < 3; i++) { 
     rot[i * 3 + 0] = ua[i];
     rot[i * 3 + 1] = ub[i];
     rot[i * 3 + 2] = n[i];
   }
-  
+    
   // The intersection of the plane is given by (0, 0, -d/c)
   trans[0] = 0;
   trans[1] = 0;
   trans[2] = p;
-
+  
   return kTRUE;
 }
 
-#define M(I,J) rot[(J-1) * 3 + (I-1)]
+
 //____________________________________________________________________
 Bool_t
-AliFMDSurveyToAlignObjs::DoFMD2()
+AliFMDSurveyToAlignObjs::MakeDelta(const char*  path, 
+                                  Double_t*    rot, 
+                                  Double_t*    trans, 
+                                  TGeoHMatrix& delta) const
 {
-  Double_t rot[9], trans[3];
-  if (!GetFMD2Plane(rot, trans)) return kFALSE;
+  // Make delta transformation
+  if (!gGeoManager)           return kFALSE;
+  if (!gGeoManager->cd(path)) return kFALSE;
   
-  PrintRotation("Rotation: ", rot);
-  PrintVector("Translation: ", trans);
-
-#if 0
-  Double_t theta = TMath::ATan2(M(3,1), M(3,2));
-  Double_t phi   = TMath::ACos(M(3,3));
-  Double_t psi   = -TMath::ATan2(M(1,3), M(2,3));
   
-  std::cout << " Theta=" << theta * 180 / TMath::Pi() 
-           << " Phi="   << phi   * 180 / TMath::Pi() 
-           << " Psi="   << psi   * 180 / TMath::Pi() 
-           << std::endl;
+  TGeoMatrix*  global = gGeoManager->GetCurrentMatrix();
+#if 0
+  PrintRotation(Form("%s rot:", global->GetName()),global->GetRotationMatrix());
+  PrintVector(Form("%s trans:", global->GetName()),global->GetTranslation());
+#endif
 
-  TRotation r;
-  r.SetXEulerAngles(theta, phi, psi);
-  r.Print();
-  
-  TGeoRotation*   geoR = new TGeoRotation("FMD2_survey_rotation", 
-                                         r.GetYTheta(),
-                                         r.GetYPhi(),
-                                         r.GetYPsi());
-  TGeoCombiTrans* geoM = new TGeoCombiTrans(trans[0], trans[1], trans[2], geoR);
-#else
+  return MakeDelta(global, rot, trans, delta);
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::MakeDelta(TGeoMatrix*  global,
+                                  Double_t*    rot, 
+                                  Double_t*    trans, 
+                                  TGeoHMatrix& delta) const
+{
+  // Make delta transformation
   TGeoHMatrix* geoM = new TGeoHMatrix;
-  geoM->SetRotation(rot);
   geoM->SetTranslation(trans);
+  geoM->SetRotation(rot);
+
+  delta = global->Inverse();
+  delta.MultiplyLeft(geoM);
+  
+  return true;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::GetFMD1Plane(Double_t* rot, Double_t* trans) const
+{
+
+  // The possile survey points 
+  TVector3  icb, ict, ocb, oct, dummy;
+  Int_t     missing = 0;
+  if (!GetPoint("V0L_ICB", icb, dummy)) missing++;
+  if (!GetPoint("V0L_ICT", ict, dummy)) missing++;
+  if (!GetPoint("V0L_OCB", ocb, dummy)) missing++;
+  if (!GetPoint("V0L_OCT", oct, dummy)) missing++;
+
+  // Check that we have enough points
+  if (missing > 1) { 
+    AliWarning(Form("Only got %d survey points - no good for FMD1 plane",
+                   4-missing));
+    return kFALSE;
+  }
+
+#if 0
+  const char* lidN = "FMD1_lid_mat0";
+  TGeoMatrix* lidM = static_cast<TGeoMatrix*>(gGeoManager->GetListOfMatrices()
+                                             ->FindObject(lidN));
+  if (!lidM) { 
+    AliError(Form("Couldn't find FMD1 lid transformation %s", lidN));
+    return kFALSE;
+  }
+
+  const Double_t* lidT = lidM->GetTranslation();
+  Double_t        lidZ = lidT[2];
+  Double_t        off  = lidZ-3.3;
+#else
+  Double_t        off  = 0;
 #endif
-  geoM->Print();
-
-  const char* path = "/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2";
-  gGeoManager->cd(path);
-  TGeoMatrix* globalBack = gGeoManager->GetCurrentMatrix();
-  globalBack->Print();
-  PrintRotation("Back rotation:",    globalBack->GetRotationMatrix());
-  PrintVector("Back translation:",   globalBack->GetTranslation());
+
+  if (!CalculatePlane(ocb, icb, ict, off, trans, rot)) return kFALSE;
+  // PrintRotation("FMD1 rotation:",  rot);
+  // PrintVector("FMD1 translation:", trans);
+
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::DoFMD1()
+{
+  // Do the FMD1 stuff
+  Double_t rot[9], trans[3];
+  if (!GetFMD1Plane(rot, trans)) return kFALSE;
+  // const char* path = "/ALIC_1/F1MT_1/FMD1_lid_0";
+  
+  // TGeoHMatrix delta;
+  TGeoTranslation global(0,0,324.670);
+  if (!MakeDelta(&global, rot, trans, fFMD1Delta)) 
+    return kFALSE;
   
-  // TObjArray* pns = gGeoManager->GetListOfPhysicalNodes();
-  // TObject*   oT  = pns->FindObject("/ALIC_1/F2MT_2");
-  // TObject*   oB  = pns->FindObject("/ALIC_1/F2MB_2");
-  // if (!oT) { 
-  //   Warning("DoFMD2", Form("Physical node /ALIC_1/F2MT_2 not found"));
-  //   return kFALSE;
-  // }
-  // if (!oB) { 
-  //   Warning("DoFMD2", Form("Physical node /ALIC_1/F2MB_2 not found"));
-  //   return kFALSE;
-  // }
-  // TGeoPhysicalNode* top = static_cast<TGeoPhysicalNode*>(oT);
-  // TGeoPhysicalNode* bot = static_cast<TGeoPhysicalNode*>(oB);
-  TGeoHMatrix tDelta(globalBack->Inverse());
-  TGeoHMatrix bDelta(globalBack->Inverse());
-  PrintRotation("Back^-1 rotation:",    tDelta.GetRotationMatrix());
-  PrintVector("Back^-1 translation:",   tDelta.GetTranslation());
-
-  std::cout << "tDelta = 1? " << tDelta.IsIdentity() << std::endl;
+  // PrintRotation("FMD1 delta rotation:",  fFMD1Delta.GetRotationMatrix());
+  // PrintVector("FMD1 delta translation:", fFMD1Delta.GetTranslation());
+
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot, Double_t* trans) const
+{
+
+  // The possible survey points 
+  const char*    names[] = { "FMD2_ITOP",  "FMD2_OTOP", 
+                            "FMD2_IBOTM", "FMD2_OBOTM", 
+                            "FMD2_IBOT",  "FMD2_OBOT", 
+                            0 };
+  const char**   name    = names;
+
+  TObjArray points;
+  TObjArray errors;
   
-  tDelta.MultiplyLeft(geoM);
-  bDelta.MultiplyLeft(geoM);
+  // Loop and fill graph 
+  while (*name) {
+    TVector3 p, e;
+    if (!GetPoint(*name++, p, e)) continue;
+    
+    points.Add(new TVector3(p));
+    errors.Add(new TVector3(e));
+  }
+  if (points.GetEntries() < 4) { 
+    AliWarning(Form("Only got %d survey points - no good for FMD2 plane",
+                   points.GetEntries()));
+    return kFALSE;
+  }
+
+  return FitPlane(points, errors, 0, trans, rot);
+}
+
+#define M(I,J) rot[(J-1) * 3 + (I-1)]
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::DoFMD2()
+{
+  // Do the FMD2 stuff
+  Double_t rot[9], trans[3];
+  if (!GetFMD2Plane(rot, trans)) return kFALSE;
+  // PrintRotation("FMD2 rotation:",  rot);
+  // PrintVector("FMD2 translation:", trans);
+
+  for (int i = 0; i < 3; i++) { 
+    for (int j = 0; j < 3; j++) { 
+      rot[i*3+j] = (i == j ? 1 : 0);
+    }
+  }
+  trans[0] = trans[1] = 0;
+  trans[2] += 0.015;
+  // PrintRotation("FMD2 rotation:",  rot);
+  // PrintVector("FMD2 translation:", trans);
   
-  PrintRotation("tDelta rotation:",  tDelta.GetRotationMatrix());
-  PrintVector("tDelta translation:", tDelta.GetTranslation());
-  PrintRotation("bDelta rotation:",  bDelta.GetRotationMatrix());
-  PrintVector("bDelta translation:", bDelta.GetTranslation());
+  // TGeoHMatrix delta;
+  if (!MakeDelta("/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2", 
+                rot, trans, fFMD2Delta)) return kFALSE;
   
+  // PrintRotation("FMD2 delta rotation:",  fFMD2Delta.GetRotationMatrix());
+  // PrintVector("FMD2 delta translation:", fFMD2Delta.GetTranslation());
+
   return kTRUE;
 }
 
@@ -298,13 +367,35 @@ AliFMDSurveyToAlignObjs::Run()
   geom->Init();
   geom->InitTransformations();
   
+  DoFMD1();
   DoFMD2();
 }
 
 //____________________________________________________________________
+Bool_t 
+AliFMDSurveyToAlignObjs::CreateAlignObjs()
+{
+  TClonesArray& array = *fAlignObjArray;
+  Int_t         n     = array.GetEntriesFast();
+
+  if (!fFMD1Delta.IsIdentity()) { 
+    new (array[n++]) AliAlignObjParams("FMD1/FMD1_T", 0, fFMD1Delta, kTRUE);
+    new (array[n++]) AliAlignObjParams("FMD1/FMD1_B", 0, fFMD1Delta, kTRUE);
+  }
+  if (!fFMD2Delta.IsIdentity()) { 
+    new (array[n++]) AliAlignObjParams("FMD2/FMD2_T", 0, fFMD2Delta, kTRUE);
+    new (array[n++]) AliAlignObjParams("FMD2/FMD2_B", 0, fFMD2Delta, kTRUE);
+  }
+  // array.Print();
+  
+  return kTRUE;
+}
+
+//____________________________________________________________________
 void 
 AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
 {
+  // Print a vector
   Double_t va[] = { v.X(), v.Y(), v.Z() };
   PrintVector(text, va);
 }
@@ -312,6 +403,7 @@ AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
 void 
 AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
 {
+  // Print a vector
   std::cout << text 
            << std::setw(15) << v[0] 
            << std::setw(15) << v[1]
@@ -324,6 +416,7 @@ AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
 void 
 AliFMDSurveyToAlignObjs::PrintRotation(const char* text, const Double_t* rot)
 {
+  // Print a rotation matrix
   std::cout << text << std::endl;
   for (size_t i = 0; i < 3; i++) { 
     for (size_t j = 0; j < 3; j++) 
index 02b793c..8b27bad 100644 (file)
 #ifndef ALIFMDSURVEYTOALIGNOBJS_H
 #define ALIFMDSURVEYTOALIGNOBJS_H
 #include <AliSurveyToAlignObjs.h>
+#include <TGeoMatrix.h>
 
 // Forward decl
 class TVector3;
+class TGeoMatrix;
 
 
+/**
+ * Class to take survey data and transform that to alignment objects. 
+ * 
+ */
 class AliFMDSurveyToAlignObjs : public AliSurveyToAlignObjs
 {
 public:
+  /** 
+   * Constructor
+   * 
+   */
   AliFMDSurveyToAlignObjs() : AliSurveyToAlignObjs() {}
+  /** 
+   * Run the task.
+   * 
+   */  
   void Run();
-  Bool_t CreateAlignObjs() { return kTRUE; }
+  /** 
+   * 
+   * Method to create the alignment objects
+   * 
+   * @return @c true on success, @c false otherwise
+   */  
+  Bool_t CreateAlignObjs();
+
+  
+  TClonesArray* GetAlignObjArray() const { return fAlignObjArray; }
+  
 protected:
+  /** 
+   * Do the FMD1 analysis.  We have 4 survey targets on V0-A on the
+   * C-side.  These are 
+   *
+   *  - V0A_ICT  In-side, C-side, top.
+   *  - V0A_ICB  In-side, C-side, bottom.  
+   *  - V0A_OCT  Out-side, C-side, top.         
+   *  - V0A_OCB         Out-side, C-side, bottom.
+   * 
+   * These 4 survey targets sit 3.3mm over the V0-A C-side surface, or
+   * 3.3mm over the back surface of FMD1.  
+   *
+   * Since these are really sitting on a plane, we can use the method
+   * proposed by the CORE offline. 
+   * 
+   * @return @c true on success, @c false otherwise.
+   */
   Bool_t DoFMD1();
+  /** 
+   * Get the FMD1 plane from the survey points
+   * 
+   * @param rot    Rotation matrix (direction cosines)
+   * @param trans  Translation
+   * 
+   * @return @c true on success, @c false otherwise.
+   */
   Bool_t GetFMD1Plane(Double_t* rot, Double_t* trans) const;
+  /** 
+   * Do the FMD2 calculations.  We have 6 survey points of which only
+   * 5 are normally surveyed.  These are all sittings 
+   *
+   *  - FMD2_ITOP   - In-side, top
+   *  - FMD2_IBOTM  - In-side, middle bottom
+   *  - FMD2_IBOT   - In-side, bottom
+   *  - FMD2_OTOP   - Out-side, top
+   *  - FMD2_OBOTM  - Out-side, middle bottom
+   *  - FMD2_OBOT   - Out-side, bottom
+   *
+   * The nominal coordinates of these retro-fitted survey stickers
+   * isn't known.  Also, these stickers are put on a thin (0.3mm
+   * thick) carbon cover which flexes quite easily.  This means, that
+   * to rotations and xy-translation obtained from the survey data
+   * cannot be used, and left is only the z-translation.
+   *
+   * Further more, since FMD2 to is attached to the ITS SPD thermal
+   * screen, it is questionable if the FMD2 survey will ever be used. 
+   * 
+   * @return @c true on success, @c false otherwise.
+   */
   Bool_t DoFMD2();
+  /** 
+   * Get the surveyed plane corresponding to the backside of FMD2.
+   * The plane is done as a best fit of the plane equation to at least
+   * 4 of the available survey points.
+   * 
+   * @param rot    Rotation matrix (direction cosines)
+   * @param trans  Translation vector.
+   * 
+   * @return @c true on success, @c false otherwise
+   */
   Bool_t GetFMD2Plane(Double_t* rot, Double_t* trans) const;
-
+  /** 
+   * Get the factor to translate current coordinates to the canonical
+   * unit (centi-meters). 
+   * 
+   * @return Conversion factor
+   */
   Double_t GetUnitFactor() const;
+  /** 
+   * Get the coordinates of a survey point (if available).
+   * 
+   * @param name Name of the survey point.
+   * @param p    Coordinates.
+   * @param e    Error on the measurement.
+   * 
+   * @return @c true if the survey data is available, @c false otherwise.
+   */
   Bool_t   GetPoint(const char* name, TVector3& p, TVector3& e) const;
+  /** 
+   * Calculate the plane translation and rotation from 3 survey points
+   * 
+   * @param a     1st Survey point 
+   * @param b     2nd Survey point
+   * @param c     3rd Survey point
+   * @param trans Translation vector
+   * @param rot   Rotation matrix (direction cosines)
+   * 
+   * @return 
+   */
   Bool_t   CalculatePlane(const     TVector3& a, 
                          const     TVector3& b,
-                         const     TVector3& c, 
+                         const     TVector3& c,
+                         Double_t  depth,
                          Double_t* trans,
                          Double_t* rot) const;
+  /** 
+   * Calculate the plane rotation and translation by doing a fit of
+   * the plane equation to the surveyed points.  At least 4 points
+   * must be passed in the @a points array with corresponding errors
+   * in the array @a errors.  The arrays are assumed to contain
+   * TVector3 objects.
+   * 
+   * @param points Array surveyed positions
+   * @param errors Array of errors corresponding to @a points
+   * @param depth  Survey targets depth (perpendicular to the plane)
+   * @param trans  On return, translation of the plane
+   * @param rot    On return, rotation (direction cosines) of the plane
+   * 
+   * @return @c true on success, @c false otherwise
+   */
+  Bool_t FitPlane(const TObjArray& points, 
+                 const TObjArray& errors,
+                 Double_t         depth,
+                 Double_t*        trans,
+                 Double_t*        rot) const;
+  /** 
+   * Create a delta transform from a global rotation matrix and
+   * translation. 
+   * 
+   * @param global Global matrix of element to transform.
+   * @param rot    Rotation matrix (direction cosines)
+   * @param trans  Translation 
+   * @param delta  On return, the delta transform
+   * 
+   * @return Newly 
+   */
+  Bool_t MakeDelta(TGeoMatrix*  global,
+                  Double_t*    rot, 
+                  Double_t*    trans,
+                  TGeoHMatrix& delta) const;
+  /** 
+   * Create a delta transform from a global rotation matrix and
+   * translation. 
+   * 
+   * @param path   Path of element to transform.
+   * @param rot    Rotation matrix (direction cosines)
+   * @param trans  Translation 
+   * @param delta  On return, the delta transform
+   * 
+   * @return Newly 
+   */
+  Bool_t MakeDelta(const char*  path, 
+                  Double_t*    rot, 
+                  Double_t*    trans,
+                  TGeoHMatrix& delta) const;
+  /** 
+   * Service member function to print a vector
+   * 
+   * @param text Prefix text
+   * @param v    Vector (array of 3 doubles)
+   */
   static void PrintVector(const char* text, const Double_t* v);
+  /** 
+   * Service member function to print a vector
+   * 
+   * @param text Prefix text
+   * @param v    Vector
+   */
   static void PrintVector(const char* text, const TVector3& v);
+  /** 
+   * Service member function to print a rotation matrix
+   * 
+   * @param text Prefix text
+   * @param v    Matrix (array of 9 doubles)
+   */
   static void PrintRotation(const char* text, const Double_t* rot);
 
+  TGeoHMatrix fFMD1Delta; // FMD1 delta transform
+  TGeoHMatrix fFMD2Delta; // FMD2 delta transform 
   
   ClassDef(AliFMDSurveyToAlignObjs,0) // Convert FMD survey to alignments
 };
index 2e19aeb..2bdd919 100644 (file)
@@ -386,7 +386,7 @@ Config()
   Bool_t useFMD   = kTRUE; 
   Bool_t useFRAME = kFALSE; 
   Bool_t useHALL  = kFALSE; 
-  Bool_t useITS   = kFALSE;
+  Bool_t useITS   = kTRUE;
   Bool_t useMAG   = kFALSE; 
   Bool_t useMUON  = kFALSE; 
   Bool_t usePHOS  = kFALSE; 
index 4cb8b95..d992ed4 100644 (file)
@@ -1,6 +1,6 @@
 > Title:
 
-Measurement of targets on FMD2
+Measurement of targets on FMD1
 
 > Date:
 
@@ -25,6 +25,7 @@ Afterwards it has been moved close to final position and measured on
 25.07.2008.  The final alignment of the V0A detector has been done in
 three iterations (called sessions) on 12.08.2008.
 
+
 > Coordinate System:
 
 ALICEPH
@@ -43,7 +44,7 @@ Point Name,XPH,YPH,ZPH,Point Type,Target Used,Precision(mm)
 
 
 > Data:
-V0L_ICB                127.73  -220.41 3246.58 M       Y       1
-V0L_ICT                127.37  219.48  3247.24 M       Y       1
-V0L_OCB                -126.99 -220.40 3247.27 M       Y       1
-V0L_OCT                -126.99 219.51  3247.49 M       Y       1
+V0L_ICB        127.73  -220.41 3246.58 M       Y       1
+V0L_ICT        127.37  219.48  3247.24 M       Y       1
+V0L_OCB        -126.99 -220.40 3247.27 M       Y       1
+V0L_OCT        -126.99 219.51  3247.49 M       Y       1
index e473560..839df67 100644 (file)
@@ -1,10 +1,33 @@
 void
-TestSurveyToAlignObjs()
+TestSurveyToAlignObjs(Int_t det=1, Bool_t cdbStore=false)
 {
+  if (det < 1 || det > 2) { 
+    Error("TestSurveyToAlignObjs", "Invalid detector %d (must be 1,2, or 3)", 
+         det);
+    return;
+  }
+
+  const char* files[] = { 
+    "$ALICE_ROOT/FMD/Survey_943928_FMD.txt", 
+    "$ALICE_ROOT/FMD/Survey_976326_FMD.txt", 
+    0 
+  };
+  
+  
   AliGeomManager::LoadGeometry("geometry.root");
 
   AliFMDSurveyToAlignObjs convert;
-  convert.LoadSurveyFromLocalFile("$ALICE_ROOT/FMD/Survey_XXX_FMD.txt");
+  if (!convert.LoadSurveyFromLocalFile(files[det-1])) { 
+    Error("TestSurveyToAlignObjs", "Failed to load %s", files[det-1]);
+    return;
+  }
   convert.Run();
+  convert.CreateAlignObjs();
+  convert.GetAlignObjArray()->Print();
+
+  if (!cdbStore) 
+    convert.StoreAlignObjToFile("FMD_Survey.root", "FMD");
+  else 
+    convert.StoreAlignObjToCDB("FMD/Align/Data", "FMD");
 }