+//____________________________________________________________________
+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
+ // numbers, and so forth.
+ //
+ // TODO: Here, we should actually also get the parameters of the
+ // shapes, like the verticies of the polygon shape that makes up the
+ // silicon sensor, the strip pitch, the ring radii, the z-positions,
+ // and so on - that is, all the geometric information we need for
+ // futher processing, such as simulation, digitization,
+ // reconstruction, etc.
+ Int_t detectorDepth = FindNodeDepth("FMD1_1", "ALIC");
+ Int_t ringDepth = FindNodeDepth(Form("FMDI_%d", Int_t('I')), "ALIC");
+ Int_t moduleDepth = FindNodeDepth("FIFV_0", "ALIC");
+ Int_t sectorDepth = FindNodeDepth("FISE_1", "ALIC");
+ fActive.Reset(-1);
+ AliDebug(1, Form("Geometry depths:\n"
+ " Sector: %d\n"
+ " Module: %d\n"
+ " Ring: %d\n"
+ " Detector: %d",
+ sectorDepth, moduleDepth, ringDepth, detectorDepth));
+ if (sectorDepth < 0 && moduleDepth < 0) {
+ fDetailed = kFALSE;
+ fSectorOff = -1;
+ fModuleOff = -1;
+ fRingOff = 0;
+ fDetectorOff = (ringDepth - detectorDepth);
+ TGeoVolume* actiVol = gGeoManager->GetVolume("FIAC");
+ TGeoVolume* actoVol = gGeoManager->GetVolume("FOAC");
+ if (actiVol) AddActive(actiVol->GetNumber());
+ if (actiVol) AddActive(actoVol->GetNumber());
+ }
+ else if (sectorDepth < 0) {
+ fDetailed = kFALSE;
+ fSectorOff = -1;
+ fModuleOff = 1;
+ fRingOff = (moduleDepth - ringDepth) + 1;
+ fDetectorOff = (moduleDepth - detectorDepth) + 1;
+ TGeoVolume* modiVol = gGeoManager->GetVolume("FIMO");
+ TGeoVolume* modoVol = gGeoManager->GetVolume("FOMO");
+ if (modiVol) AddActive(modiVol->GetNumber());
+ if (modoVol) AddActive(modoVol->GetNumber());
+ }
+ else {
+ Int_t stripDepth = FindNodeDepth("FIST_1", "ALIC");
+ fDetailed = kTRUE;
+ fSectorOff = (stripDepth - sectorDepth);
+ fModuleOff = (moduleDepth >= 0 ? (stripDepth - moduleDepth) : -1);
+ fRingOff = (stripDepth - ringDepth);
+ fDetectorOff = (stripDepth - detectorDepth );
+ TGeoVolume* striVol = gGeoManager->GetVolume("FIST");
+ TGeoVolume* stroVol = gGeoManager->GetVolume("FOST");
+ if (striVol) AddActive(striVol->GetNumber());
+ if (stroVol) AddActive(stroVol->GetNumber());
+ }
+ AliDebug(1, Form("Geometry offsets:\n"
+ " Sector: %d\n"
+ " Module: %d\n"
+ " Ring: %d\n"
+ " Detector: %d",
+ fSectorOff, fModuleOff, fRingOff, fDetectorOff));
+}
+
+
+//____________________________________________________________________
+static Int_t
+CheckNodes(TGeoNode* node, const char* name, Int_t& lvl)
+{
+ // If there's no node here.
+ if (!node) return -1;
+ // Check if it this one
+ TString sname(name);
+ if (sname == node->GetName()) return lvl;
+
+ // Check if the node is an immediate daugther
+ TObjArray* nodes = node->GetNodes();
+ if (!nodes) return -1;
+ // Increase the level, and search immediate sub nodes.
+ lvl++;
+ TGeoNode* found = static_cast<TGeoNode*>(nodes->FindObject(name));
+ if (found) return lvl;
+
+ // Check the sub node, if any of their sub-nodes match.
+ for (Int_t i = 0; i < nodes->GetEntries(); i++) {
+ TGeoNode* sub = static_cast<TGeoNode*>(nodes->At(i));
+ if (!sub) continue;
+ // Recurive check
+ if (CheckNodes(sub, name, lvl) >= 0) return lvl;
+ }
+ // If not found, decrease the level
+ lvl--;
+ return -1;
+}
+//____________________________________________________________________
+Int_t
+FindNodeDepth(const char* name, const char* volname)
+{
+ // Find the depth of a node
+ TGeoVolume* vol = gGeoManager->GetVolume(volname);
+ if (!vol) {
+ std::cerr << "No top volume defined" << std::endl;
+ return -1;
+ }
+ TObjArray* nodes = vol->GetNodes();
+ if (!nodes) {
+ std::cerr << "No nodes in top volume" << std::endl;
+ return -1;
+ }
+ TIter next(nodes);
+ TGeoNode* node = 0;
+ Int_t lvl = 0;
+ while ((node = static_cast<TGeoNode*>(next())))
+ if (CheckNodes(node, name, lvl) >= 0) return lvl;
+ return -1;
+}
+