Implemented the AliModule::AddAlignableVolumes properly via call to
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 14 Dec 2006 22:57:50 +0000 (22:57 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 14 Dec 2006 22:57:50 +0000 (22:57 +0000)
AliFMDGeometry.  We search through the TGeo geometry for nodes that
we should make alignable.   If needed, we can make them physical too.
Added a small test macro to check that everything works as expected.

FMD/AliFMD.cxx
FMD/AliFMDDetector.cxx
FMD/AliFMDDetector.h
FMD/AliFMDGeometry.cxx
FMD/AliFMDGeometry.h
FMD/scripts/TestAlignable.C [new file with mode: 0644]

index 38d8e11..bc744f3 100644 (file)
@@ -1086,6 +1086,8 @@ AliFMD::AddAlignableVolumes() const
   // This code was made by Raffaele Grosso <rgrosso@mail.cern.ch>.  I
   // (cholm) will probably want to change it.   For one, I think it
   // should be the job of the geometry manager to deal with this. 
+  AliFMDGeometry::Instance()->SetAlignableVolumes();
+#if 0  
   for(size_t f = 1; f <= 3; f++){ // Detector 1,2,3
     for(size_t tb =  0; tb <2 ; tb++){ // Top/Bottom 
       char     stb = tb == 0 ? 'T' : 'B';
@@ -1116,7 +1118,7 @@ AliFMD::AddAlignableVolumes() const
       }
     }
   }
-
+#endif
 }
 //___________________________________________________________________
 //
index 2a890d5..2674f63 100644 (file)
@@ -165,6 +165,8 @@ AliFMDDetector::HasAllTransforms(Char_t ring) const
    (name[3] == 'T' || name[3] == 'B'))
 #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'))
 
 //____________________________________________________________________
 void
@@ -256,6 +258,141 @@ AliFMDDetector::InitTransformations()
 }
 
 //____________________________________________________________________
+void
+AliFMDDetector::SetAlignableVolumes() const
+{
+  AliDebug(10, Form("Making alignable volumes for FMD%d", fId));
+  if (!gGeoManager) {
+    AliFatal("No TGeoManager defined");
+    return;
+  }
+  TGeoVolume* topVolume = gGeoManager->GetTopVolume();
+  if (!topVolume) {
+    AliFatal("No top-level volume defined");
+    return;
+  }
+
+  // Make an iterator
+  TGeoIterator next(topVolume);
+  next.Reset(topVolume);
+  next.SetTopName(Form("/%s_1", topVolume->GetName()));
+  TGeoNode* node = 0;
+  
+  Int_t nInnerSensor = (fInner ? fInner->GetNModules() : 0);
+  Int_t nOuterSensor = (fOuter ? fOuter->GetNModules() : 0);
+  // Find the node corresponding to this detector, and then find the
+  // sensor volumes 
+  Bool_t thisNodeFound = kFALSE;
+  Char_t thisHalf      = '\0';
+  Int_t  iInnerSensor  = 0;
+  Int_t  iOuterSensor  = 0;
+  Bool_t hasTop        = false;
+  Bool_t hasBottom     = false;
+  
+  TString path, align;
+  while ((node = static_cast<TGeoNode*>(next())) 
+        && (iInnerSensor < nInnerSensor || iOuterSensor < nOuterSensor
+            || !hasBottom || !hasTop)) {
+    // Get nodes names 
+    const Char_t* name = node->GetName();
+    if (!name) continue;
+    AliDebug((name[0] == 'F' ? 40 : 50), Form("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));
+      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));
+      // 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]));
+       continue;
+      }
+
+      switch (thisHalf) {
+      case 'T': hasTop = true; break;
+      case 'B': hasBottom = true; break;
+      default:  
+       AliWarning(Form("Unknown part '%c' of FMD%d", fId));
+       continue; // because the node is unknown. 
+      }
+      
+      // Get the node path 
+      next.GetPath(path);
+      align = Form("FMD/FMD%d%c", 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));
+      // Get the ring Id.
+      Char_t ringid = name[1];
+
+      // check that the ring is valid 
+      if (!GetRing(ringid)) {
+       AliWarning(Form("Invalid ring %c for FMD%d", ringid, fId));
+       continue;
+      }
+
+      // Check if we're done
+      Bool_t done = false;
+      switch (ringid) {
+      case 'I': done = iInnerSensor >= nInnerSensor; break;
+      case 'O': done = iOuterSensor >= nOuterSensor; break;
+      default: continue;
+      }
+      if (done) {
+       AliDebug(20,Form("Already has all sensor volumes for ring %c",ringid));
+       continue;
+      }
+      // Get the copy (module) number, and check that it hasn't
+      // already been added to the container. 
+      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);
+      
+      switch (ringid) {
+      case 'I': iInnerSensor++; break;
+      case 'O': iOuterSensor++; break;
+      }
+    }
+    if (!align.IsNull() && !path.IsNull()) {
+      AliDebug(20, Form("Got %s -> %s", path.Data(), align.Data()));
+      TGeoPNEntry* entry = 
+       gGeoManager->SetAlignableEntry(align.Data(),path.Data());
+      if(!entry)
+       AliFatal(Form("Alignable entry %s not created. "
+                     "Volume path %s not valid", 
+                       align.Data(),path.Data()));
+#ifdef MAKE_ALIGNABLE_PHYSICAL
+      TGeoPhysicalNode* phys = gGeoManager->MakeAlignablePN(entry);
+      if (!phys) 
+       AliWarning(Form("Physical node entry %s not created. "
+                       "Volume path %s not valid", 
+                       align.Data(),path.Data()));
+#endif
+      align = "";
+    }
+    AliDebug(20, Form("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d", 
+                     fId, hasTop, hasBottom, iInnerSensor,  nInnerSensor, 
+                     iOuterSensor, nOuterSensor));
+  }
+}
+
+  
+
+//____________________________________________________________________
 AliFMDRing*
 AliFMDDetector::GetRing(Char_t id) const
 {
index 3740256..aaf40a4 100644 (file)
@@ -135,6 +135,9 @@ public:
       detector.  */
   Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z, 
                      Char_t& ring, UShort_t& sector, UShort_t& strip) const;
+
+  /** Declare alignable volumes */
+  virtual void SetAlignableVolumes() const;
 protected:
   /** Check if we have all transformations for a ring 
       @param ring Ring to check for 
index 176ff2f..ab4ac16 100644 (file)
@@ -402,6 +402,16 @@ AliFMDGeometry::Impact(const TParticle* /* particle */) const
 
 //____________________________________________________________________ 
 void  
+AliFMDGeometry::SetAlignableVolumes() const
+{
+  // Declare alignable volumes
+  for (Int_t d = 1; d <= 3; d++) 
+    if (GetDetector(d)) GetDetector(d)->SetAlignableVolumes();
+}
+
+
+//____________________________________________________________________ 
+void  
 AliFMDGeometry::ExtractGeomInfo()
 {
   // Check the volume depth of some nodes, get the active volume
index 38fa18c..8a41c9a 100644 (file)
@@ -205,6 +205,8 @@ public:
       @param particle Track 
       @return @c true if @a particle will hit this detector */
   virtual Bool_t Impact(const TParticle* particle) const;
+  /** Declare alignable volumes */
+  virtual void SetAlignableVolumes() const;
 protected:
   Bool_t        fIsInitialized; // Whether singleton is initalized
   AliFMDRing*  fInner;         // Inner ring geometry information
diff --git a/FMD/scripts/TestAlignable.C b/FMD/scripts/TestAlignable.C
new file mode 100644 (file)
index 0000000..2fef52e
--- /dev/null
@@ -0,0 +1,15 @@
+void
+TestAlignable(const char* file="geom.root", Int_t lvl=35)
+{
+  TGeoManager::Import(file);
+  if (!gGeoManager) return;
+  
+  AliFMDGeometry* g = AliFMDGeometry::Instance();
+  g->Init();
+  
+  AliLog::SetModuleDebugLevel("FMD", lvl);
+  
+
+  g->SetAlignableVolumes();
+}
+