Compatibility with the trunk of ROOT
[u/mrichter/AliRoot.git] / FMD / AliFMDDetector.cxx
index 2674f63..78cc6ff 100644 (file)
 //
 // Latest changes by Christian Holm Christensen
 //
-#include "AliFMDDetector.h"    // ALIFMDSUBDETECTOR_H
-#include "AliFMDRing.h"                // ALIFMDRING_H
-#include "AliLog.h"             // ALILOG_H
+
 #include <TGeoManager.h>       // ROOT_TGeoManager 
+#include <TGeoPhysicalNode.h>   // ROOT_TGeoPhysicalNode
 #include <TGeoMatrix.h>                // ROOT_TGeoMatrix 
-// #include <TMath.h>              // ROOT_TMath
+#include <TMath.h>              // ROOT_TMath
+
+#include "AliFMDDetector.h"    // ALIFMDSUBDETECTOR_H
+#include "AliFMDRing.h"                // ALIFMDRING_H
+#include "AliFMDDebug.h"               // ALIFMDDEBUG_H ALILOG_H
 
 //====================================================================
 ClassImp(AliFMDDetector)
@@ -53,8 +56,6 @@ AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer)
     fId(id), 
     fInnerZ(0.),
     fOuterZ(0.),
-    fHoneycombThickness(0.),
-    fAlThickness(0.),
     fInnerHoneyLowR(0.),
     fInnerHoneyHighR(0.),
     fOuterHoneyLowR(0.),
@@ -70,8 +71,6 @@ AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer)
   //   INNER      Inner ring geometry 
   //   OUTER      Outer ring geometry (if any)
   // 
-  SetHoneycombThickness();
-  SetAlThickness();
   SetInnerHoneyLowR(0);
   SetInnerHoneyHighR(0);
   SetInnerZ(0);
@@ -86,8 +85,6 @@ AliFMDDetector::AliFMDDetector(const AliFMDDetector& other)
     fId(other.fId),
     fInnerZ(0.),
     fOuterZ(0.),
-    fHoneycombThickness(0.),
-    fAlThickness(0.),
     fInnerHoneyLowR(0.),
     fInnerHoneyHighR(0.),
     fOuterHoneyLowR(0.),
@@ -98,8 +95,6 @@ AliFMDDetector::AliFMDDetector(const AliFMDDetector& other)
     fOuterTransforms(other.fOuterTransforms)
 {
   // Copy constructor 
-  SetHoneycombThickness(other.GetHoneycombThickness());
-  SetAlThickness(other.GetAlThickness());
   SetInnerHoneyLowR(other.GetInnerHoneyLowR());
   SetInnerHoneyHighR(other.GetInnerHoneyHighR());
   SetInnerZ(other.GetInnerZ());
@@ -113,6 +108,7 @@ AliFMDDetector&
 AliFMDDetector::operator=(const AliFMDDetector& other)
 {
   // Assignment operator
+  if (&other == this) return *this; 
   SetName(other.GetName());
   SetTitle(other.GetTitle());
   fId              = other.fId;
@@ -120,8 +116,6 @@ AliFMDDetector::operator=(const AliFMDDetector& other)
   fOuter           = other.fOuter;
   fInnerTransforms = other.fInnerTransforms;
   fOuterTransforms = other.fOuterTransforms;
-  SetHoneycombThickness(other.GetHoneycombThickness());
-  SetAlThickness(other.GetAlThickness());
   SetInnerHoneyLowR(other.GetInnerHoneyLowR());
   SetInnerHoneyHighR(other.GetInnerHoneyHighR());
   SetInnerZ(other.GetInnerZ());
@@ -163,10 +157,14 @@ AliFMDDetector::HasAllTransforms(Char_t ring) const
 #define IS_NODE_THIS(name) \
   (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
    (name[3] == 'T' || name[3] == 'B'))
-#define IS_NODE_SENSOR(name) \
-  (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
+#define IS_NODE_SENSOR(name)                           \
+  (name[0] == 'F' && (name[2] == 'B' || name[2] == 'F') && name[3] == 'H')
+//#define IS_NODE_SENSOR(name)                         
+//  (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
 #define IS_NODE_HALF(name) \
   (name[0] == 'F' && name[2] == 'M' && (name[3] == 'B' || name[3] == 'T'))
+#define HALF_FORMAT   "FMD/FMD%d_%c"
+#define SENSOR_FORMAT "FMD/FMD%d_%c/FMD%c_%02d"
 
 //____________________________________________________________________
 void
@@ -175,25 +173,102 @@ AliFMDDetector::InitTransformations()
   // Find all local<->global transformations for this detector. 
   if ((!fInner || (fInner && fInnerTransforms)) && 
       (!fOuter || (fOuter && fOuterTransforms))) {
-    AliDebug(5, Form("Transforms for FMD%d already registered", fId));
+    AliFMDDebug(5, ("Transforms for FMD%d already registered", fId));
     return;
   }
-  AliDebug(5, Form("Initializing transforms for FMD%d", fId));
+  AliFMDDebug(5, ("Initializing transforms for FMD%d", fId));
   if (!gGeoManager) {
     AliFatal("No TGeoManager defined");
     return;
   }
-  TGeoVolume* topVolume = gGeoManager->GetTopVolume();
-  if (!topVolume) {
-    AliFatal("No top-level volume defined");
-    return;
-  }
+
+  // Implementation using alignable volume names. 
   // Make container of transforms 
   if (fInner && !fInnerTransforms) 
     fInnerTransforms = new TObjArray(fInner->GetNModules());
   if (fOuter && !fOuterTransforms) 
     fOuterTransforms = new TObjArray(fOuter->GetNModules());
   
+  // Loop over bottom/top 
+  for (size_t ihalf = 0; ihalf < 2; ihalf++) {
+    char  half = (ihalf == 0 ? 'T' : 'B');
+    TString path(Form(HALF_FORMAT, fId, half));
+    TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
+    if (!entry) {
+      AliError(Form("Alignable entry for half-detector \"%s\" not found!", 
+                   path.Data()));
+      continue;
+    }
+    TGeoPhysicalNode* pn = entry->GetPhysicalNode();
+    if (!pn) {
+      AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
+      pn = gGeoManager->MakeAlignablePN(entry);
+      if (!pn) {
+       AliError(Form("No physical node for \"%s\"", path.Data()));
+       continue;
+      }
+    }
+  }
+  
+  // Loop over rings 
+  for (size_t iring = 0; iring < 2; iring++) {
+    char ring = (iring == 0 ? 'I' : 'O');
+    TObjArray*  trans = 0;
+    AliFMDRing* r     = 0; 
+    switch (ring) {
+    case 'I': r = fInner; trans = fInnerTransforms; break;
+    case 'O': r = fOuter; trans = fOuterTransforms; break; 
+    }
+    if (!r || !trans) continue;
+
+    Int_t nModules = r->GetNModules();
+    if (nModules <= 0) continue;
+
+    // Loop over bottom/top 
+    for (size_t ihalf = 0; ihalf < 2; ihalf++) {
+      char  half = (ihalf == 0 ? 'T' : 'B');
+      Int_t base = (half == 'T' ? 0 : nModules / 2);
+      
+      // Loop over modules in this half ring 
+      for (Int_t imod = 0; imod < nModules / 2; imod++) {
+       // Find physical node entry
+       TString path(Form(SENSOR_FORMAT, fId, half, ring, base+imod));
+       TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
+       if (!entry) {
+         AliError(Form("Alignable entry for sensor \"%s\" not found!", 
+                       path.Data()));
+         continue;
+       }
+       TGeoPhysicalNode* pn = entry->GetPhysicalNode();
+       if (!pn) {
+         AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
+         pn = gGeoManager->MakeAlignablePN(entry);
+         if (!pn) {
+           AliError(Form("No physical node for \"%s\"", path.Data()));
+           continue;
+         }
+       }
+       
+       const TGeoMatrix* pm = pn->GetMatrix();
+       if (!pm) {
+         AliError(Form("No matrix for path \"%s\"", path.Data()));
+         continue;
+       }
+       // Get transformation matrix for this node, and store it. 
+       TGeoMatrix*  t = new TGeoHMatrix(*pm);
+       trans->AddAt(t, base+imod);
+       AliFMDDebug(5, ("Found matrix for path \"%s\": %p",path.Data(),pm));
+      }
+    }
+  }
+  if (HasAllTransforms('I') && HasAllTransforms('O')) return;
+
+  // Alternative implementation using TGeoIter. 
+  TGeoVolume* topVolume = gGeoManager->GetTopVolume();
+  if (!topVolume) {
+    AliFatal("No top-level volume defined");
+    return;
+  }
   // Make an iterator
   TGeoIterator next(topVolume);
   TGeoNode* node = 0;
@@ -209,17 +284,17 @@ AliFMDDetector::InitTransformations()
     // Get nodes names 
     const Char_t* name = node->GetName();
     if (!name) continue;
-    AliDebug(50, Form("Got volume %s", name));
+    AliFMDDebug(50, ("Got volume %s", name));
     // Check if this node is this detector 
     // The base offset for numbers in the ASCII table is 48
     if (IS_NODE_THIS(name)) {
-      AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
+      AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
       thisNodeFound = kTRUE;
     }
     // if the detector was found, then we're on that branch, and we
     // check if this node represents a module in that branch.
     if (thisNodeFound && IS_NODE_SENSOR(name)) {
-      AliDebug(20, Form("Found sensor node '%s' for FMD%d", name, fId));
+      AliFMDDebug(20, ("Found sensor node '%s' for FMD%d", name, fId));
       // Get the ring Id.
       Char_t ringid = name[1];
 
@@ -231,7 +306,7 @@ AliFMDDetector::InitTransformations()
       // and if so, go on to the next node. 
       Bool_t& done = (ring == fInner ? allInners : allOuters);
       if ((done = HasAllTransforms(ringid))) {
-       AliDebug(20, Form("Already has all module transforms for ring %c", 
+       AliFMDDebug(20, ("Already has all module transforms for ring %c", 
                         ringid));
        continue;
       }
@@ -261,7 +336,11 @@ AliFMDDetector::InitTransformations()
 void
 AliFMDDetector::SetAlignableVolumes() const
 {
-  AliDebug(10, Form("Making alignable volumes for FMD%d", fId));
+  // Set alignable volumes. 
+  // This will define the alignable volumes. 
+  // That is currently, the modules and the half-rings. 
+  
+  AliFMDDebug(10, ("Making alignable volumes for FMD%d", fId));
   if (!gGeoManager) {
     AliFatal("No TGeoManager defined");
     return;
@@ -296,25 +375,25 @@ AliFMDDetector::SetAlignableVolumes() const
     // Get nodes names 
     const Char_t* name = node->GetName();
     if (!name) continue;
-    AliDebug((name[0] == 'F' ? 40 : 50), Form("Got volume %s", name));
+    AliFMDDebug((name[0] == 'F' ? 40 : 50), ("Got volume %s", name));
     // Check if this node is this detector 
     // The base offset for numbers in the ASCII table is 48
     if (IS_NODE_THIS(name)) {
-      AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
+      AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
       thisNodeFound = kTRUE;
     }
 
     // if a half ring is found, then we're on that branch, and we
     // check if this node represents a half ring on that branch 
     if (thisNodeFound && IS_NODE_HALF(name)) {
-      AliDebug(30, Form("Found half node '%s' for FMD%d", name, fId));
+      AliFMDDebug(30, ("Found half node '%s' for FMD%d", name, fId));
       // Get the half Id.
       thisHalf = name[3];
 
       // Check if we're done 
       Bool_t done = (thisHalf == 'T' ? hasTop : hasBottom);
       if (done) {
-       AliDebug(20,Form("Already has all halves for detector %c",name[1]));
+       AliFMDDebug(20, ("Already has all halves for detector %c",name[1]));
        continue;
       }
 
@@ -322,19 +401,19 @@ AliFMDDetector::SetAlignableVolumes() const
       case 'T': hasTop = true; break;
       case 'B': hasBottom = true; break;
       default:  
-       AliWarning(Form("Unknown part '%c' of FMD%d", fId));
+       AliWarning(Form("Unknown part '%c' of FMD%d", thisHalf, fId));
        continue; // because the node is unknown. 
       }
       
       // Get the node path 
       next.GetPath(path);
-      align = Form("FMD/FMD%d%c", fId, thisHalf);
+      align = Form(HALF_FORMAT, fId, thisHalf);
     }
     
     // if the detector was found, then we're on that branch, and we
     // check if this node represents a module in that branch.
     if (thisNodeFound && thisHalf && IS_NODE_SENSOR(name)) {
-      AliDebug(30, Form("Found sensor node '%s' for FMD%d", name, fId));
+      AliFMDDebug(30, ("Found sensor node '%s' for FMD%d", name, fId));
       // Get the ring Id.
       Char_t ringid = name[1];
 
@@ -352,7 +431,7 @@ AliFMDDetector::SetAlignableVolumes() const
       default: continue;
       }
       if (done) {
-       AliDebug(20,Form("Already has all sensor volumes for ring %c",ringid));
+       AliFMDDebug(20, ("Already has all sensor volumes for ring %c",ringid));
        continue;
       }
       // Get the copy (module) number, and check that it hasn't
@@ -360,7 +439,7 @@ AliFMDDetector::SetAlignableVolumes() const
       Int_t copy  = node->GetNumber();
       next.GetPath(path);
       // path.Replace("ALIC", "/ALIC_1");
-      align = Form("FMD/FMD%d_%c/FMD%c_%02d", fId, thisHalf, ringid, copy);
+      align = Form(SENSOR_FORMAT, fId, thisHalf, ringid, copy);
       
       switch (ringid) {
       case 'I': iInnerSensor++; break;
@@ -368,7 +447,7 @@ AliFMDDetector::SetAlignableVolumes() const
       }
     }
     if (!align.IsNull() && !path.IsNull()) {
-      AliDebug(20, Form("Got %s -> %s", path.Data(), align.Data()));
+      AliFMDDebug(20, ("Got %s -> %s", path.Data(), align.Data()));
       TGeoPNEntry* entry = 
        gGeoManager->SetAlignableEntry(align.Data(),path.Data());
       if(!entry)
@@ -384,7 +463,7 @@ AliFMDDetector::SetAlignableVolumes() const
 #endif
       align = "";
     }
-    AliDebug(20, Form("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d", 
+    AliFMDDebug(20, ("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d", 
                      fId, hasTop, hasBottom, iInnerSensor,  nInnerSensor, 
                      iOuterSensor, nOuterSensor));
   }
@@ -464,26 +543,34 @@ AliFMDDetector::Detector2XYZ(Char_t   ring,
   // Translate detector coordinates (this,ring,sector,strip) into
   // (x,y,z) coordinates (in global reference frame)
   AliFMDRing* r = GetRing(ring);
-  if (!r) return;
+  if (!r) { 
+    AliWarning(Form("No such ring FMD%d%c ", fId, ring));
+    return;
+  }
   TGeoMatrix* m = FindTransform(ring, sector);
-  if (!m) return;
+  if (!m) { 
+    AliWarning(Form("No transfrmation found for FMD%d%c[%02d]", 
+                   fId, ring, sector));
+    return;
+  }
   Double_t rho      = r->GetStripRadius(strip);
   Double_t phi      = ((sector % 2) - .5) * r->GetTheta();
   Double_t siThick  = r->GetSiThickness();
+#if 0 
   Double_t modThick = (siThick
                       + r->GetPrintboardThickness()
                       + r->GetCopperThickness()
                       + r->GetChipThickness()
                       + r->GetSpacing());
-  AliDebug(30,Form("Rho %7.3f, angle %7.3f", rho, phi));
-# define DEGRAD TMath::Pi() / 180. 
-  Double_t local[]  = { rho * TMath::Cos(phi * DEGRAD), 
-                       rho * TMath::Sin(phi * DEGRAD), 
-                       -modThick + siThick / 2 };
+#endif
+  AliFMDDebug(30, ("Rho %7.3f, angle %7.3f", rho, phi));
+  Double_t local[]  = { rho * TMath::Cos(phi * TMath::DegToRad()), 
+                       rho * TMath::Sin(phi * TMath::DegToRad()), 
+                       /* -modThick + */ siThick / 2 };
   Double_t master[3];
-  AliDebug(30, Form("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
+  AliFMDDebug(30, ("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
   m->LocalToMaster(local, master);
-  AliDebug(30, Form("Master (%7.3f,%7.3f,%7.3f)",
+  AliFMDDebug(30, ("Master (%7.3f,%7.3f,%7.3f)",
                    master[0],master[1],master[2]));
   x = master[0];
   y = master[1];