LCOV - code coverage report
Current view: top level - FMD/FMDbase - AliFMDDetector.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 163 296 55.1 %
Date: 2016-06-14 17:26:59 Functions: 9 15 60.0 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved.      *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : /* $Id$ */
      16             : /** @file    AliFMDDetector.cxx
      17             :     @author  Christian Holm Christensen <cholm@nbi.dk>
      18             :     @date    Mon Mar 27 12:36:27 2006
      19             :     @brief   Sub-detector base class implementation
      20             :     @ingroup FMD_base
      21             : */
      22             : 
      23             : //____________________________________________________________________
      24             : //
      25             : // AliFMDDetector.   
      26             : //
      27             : // Base class for concrete FMD detectors, like AliFMD1, AliFMD2,
      28             : // AliFMD3. 
      29             : // Utility class to help implement the FMD geometry.  This provides
      30             : // the interface for the concrete geometry implementations of the FMD
      31             : // sub-detectors. 
      32             : //
      33             : // The AliFMDGeometry object owns the AliFMDDetector objects
      34             : //
      35             : // Latest changes by Christian Holm Christensen
      36             : //
      37             : 
      38             : #include <TGeoManager.h>  // ROOT_TGeoManager 
      39             : #include <TGeoPhysicalNode.h>   // ROOT_TGeoPhysicalNode
      40             : #include <TGeoMatrix.h>           // ROOT_TGeoMatrix 
      41             : #include <TMath.h>              // ROOT_TMath
      42             : 
      43             : #include "AliFMDDetector.h"   // ALIFMDSUBDETECTOR_H
      44             : #include "AliFMDRing.h"               // ALIFMDRING_H
      45             : #include "AliFMDDebug.h"              // ALIFMDDEBUG_H ALILOG_H
      46             : 
      47             : //====================================================================
      48          12 : ClassImp(AliFMDDetector)
      49             : #if 0
      50             :   ; // This is here to keep Emacs for indenting the next line
      51             : #endif
      52             : 
      53             : //____________________________________________________________________
      54             : AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer) 
      55           9 :   : TNamed(Form("FMD%d", id), "Forward multiplicity ring"), 
      56           9 :     fId(id), 
      57           9 :     fInnerZ(0.),
      58           9 :     fOuterZ(0.),
      59           9 :     fInnerHoneyLowR(0.),
      60           9 :     fInnerHoneyHighR(0.),
      61           9 :     fOuterHoneyLowR(0.),
      62           9 :     fOuterHoneyHighR(0.),
      63           9 :     fInner(inner),
      64           9 :     fOuter(outer), 
      65           9 :     fInnerTransforms(0),
      66           9 :     fOuterTransforms(0)
      67          27 : {
      68             :   // Constructor
      69             :   // 
      70             :   //   ID         Id of detector (1,2, or 3)
      71             :   //   INNER      Inner ring geometry 
      72             :   //   OUTER      Outer ring geometry (if any)
      73             :   // 
      74           9 :   SetInnerHoneyLowR(0);
      75           9 :   SetInnerHoneyHighR(0);
      76           9 :   SetInnerZ(0);
      77           9 :   SetOuterZ(0);
      78           9 :   SetOuterHoneyLowR(0);
      79           9 :   SetOuterHoneyHighR(0);
      80           9 : }
      81             : 
      82             : //____________________________________________________________________
      83             : AliFMDDetector::AliFMDDetector(const AliFMDDetector& other)
      84           0 :   : TNamed(other), 
      85           0 :     fId(other.fId),
      86           0 :     fInnerZ(0.),
      87           0 :     fOuterZ(0.),
      88           0 :     fInnerHoneyLowR(0.),
      89           0 :     fInnerHoneyHighR(0.),
      90           0 :     fOuterHoneyLowR(0.),
      91           0 :     fOuterHoneyHighR(0.),
      92           0 :     fInner(other.fInner),
      93           0 :     fOuter(other.fOuter),
      94           0 :     fInnerTransforms(other.fInnerTransforms),
      95           0 :     fOuterTransforms(other.fOuterTransforms)
      96           0 : {
      97             :   // Copy constructor 
      98           0 :   SetInnerHoneyLowR(other.GetInnerHoneyLowR());
      99           0 :   SetInnerHoneyHighR(other.GetInnerHoneyHighR());
     100           0 :   SetInnerZ(other.GetInnerZ());
     101           0 :   SetOuterZ(other.GetOuterZ());
     102           0 :   SetOuterHoneyLowR(other.GetOuterHoneyLowR());
     103           0 :   SetOuterHoneyHighR(other.GetOuterHoneyHighR());
     104           0 : }
     105             : 
     106             : //____________________________________________________________________
     107             : AliFMDDetector&
     108             : AliFMDDetector::operator=(const AliFMDDetector& other)
     109             : {
     110             :   // Assignment operator
     111           0 :   if (&other == this) return *this; 
     112           0 :   SetName(other.GetName());
     113           0 :   SetTitle(other.GetTitle());
     114           0 :   fId              = other.fId;
     115           0 :   fInner           = other.fInner;
     116           0 :   fOuter           = other.fOuter;
     117           0 :   fInnerTransforms = other.fInnerTransforms;
     118           0 :   fOuterTransforms = other.fOuterTransforms;
     119           0 :   SetInnerHoneyLowR(other.GetInnerHoneyLowR());
     120           0 :   SetInnerHoneyHighR(other.GetInnerHoneyHighR());
     121           0 :   SetInnerZ(other.GetInnerZ());
     122           0 :   SetOuterZ(other.GetOuterZ());
     123           0 :   SetOuterHoneyLowR(other.GetOuterHoneyLowR());
     124           0 :   SetOuterHoneyHighR(other.GetOuterHoneyHighR());
     125           0 :   return *this;
     126           0 : }
     127             : 
     128             : //____________________________________________________________________
     129             : void
     130             : AliFMDDetector::Init()
     131             : {
     132             :   // Initialize. 
     133          66 :   if (fInner) {
     134          33 :     SetInnerHoneyLowR(fInner->GetLowR() + 1.);
     135          33 :     SetInnerHoneyHighR(fInner->GetHighR() + 1.);
     136          33 :   }
     137          33 :   if (fOuter) {
     138          22 :     SetOuterHoneyLowR(fOuter->GetLowR() + 1.);
     139          22 :     SetOuterHoneyHighR(fOuter->GetHighR() + 1.);
     140          22 :   }  
     141          33 : }
     142             : 
     143             : //____________________________________________________________________
     144             : Bool_t
     145             : AliFMDDetector::HasAllTransforms(Char_t ring) const
     146             : {
     147             :   // Check if we got all transformations for a given ring.  Return
     148             :   // true in that case. 
     149          24 :   AliFMDRing* r = GetRing(ring);
     150          14 :   if (!r) return kTRUE;
     151          30 :   TObjArray* matricies = (r == fInner ? fInnerTransforms : fOuterTransforms);
     152          10 :   if (!matricies) return kTRUE;
     153          20 :   if (matricies->GetEntries() == r->GetNModules()) return kTRUE;
     154           0 :   return kFALSE;
     155          12 : }
     156             : 
     157             : #define IS_NODE_THIS(name) \
     158             :   (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
     159             :    (name[3] == 'T' || name[3] == 'B'))
     160             : #define IS_NODE_SENSOR(name)                            \
     161             :   (name[0] == 'F' && (name[2] == 'B' || name[2] == 'F') && name[3] == 'H')
     162             : //#define IS_NODE_SENSOR(name)                          
     163             : //  (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
     164             : #define IS_NODE_HALF(name) \
     165             :   (name[0] == 'F' && name[2] == 'M' && (name[3] == 'B' || name[3] == 'T'))
     166             : #define HALF_FORMAT   "FMD/FMD%d_%c"
     167             : #define SENSOR_FORMAT "FMD/FMD%d_%c/FMD%c_%02d"
     168             : 
     169             : //____________________________________________________________________
     170             : void
     171             : AliFMDDetector::InitTransformations()
     172             : {
     173             :   // Find all local<->global transformations for this detector. 
     174          24 :   if ((!fInner || (fInner && fInnerTransforms)) && 
     175           0 :       (!fOuter || (fOuter && fOuterTransforms))) {
     176           0 :     AliFMDDebug(5, ("Transforms for FMD%d already registered", fId));
     177             :     return;
     178             :   }
     179          12 :   AliFMDDebug(5, ("Initializing transforms for FMD%d", fId));
     180           6 :   if (!gGeoManager) {
     181           0 :     AliFatal("No TGeoManager defined");
     182           0 :     return;
     183             :   }
     184             : 
     185             :   // Implementation using alignable volume names. 
     186             :   // Make container of transforms 
     187          12 :   if (fInner && !fInnerTransforms) 
     188          18 :     fInnerTransforms = new TObjArray(fInner->GetNModules());
     189          10 :   if (fOuter && !fOuterTransforms) 
     190          12 :     fOuterTransforms = new TObjArray(fOuter->GetNModules());
     191             :   
     192             :   // Loop over bottom/top 
     193          36 :   for (size_t ihalf = 0; ihalf < 2; ihalf++) {
     194          12 :     char  half = (ihalf == 0 ? 'T' : 'B');
     195          12 :     TString path(Form(HALF_FORMAT, fId, half));
     196          24 :     TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
     197          12 :     if (!entry) {
     198           0 :       AliError(Form("Alignable entry for half-detector \"%s\" not found!", 
     199             :                     path.Data()));
     200           0 :       continue;
     201             :     }
     202          12 :     TGeoPhysicalNode* pn = entry->GetPhysicalNode();
     203          12 :     if (!pn) {
     204           0 :       AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
     205           0 :       pn = gGeoManager->MakeAlignablePN(entry);
     206           0 :       if (!pn) {
     207           0 :         AliError(Form("No physical node for \"%s\"", path.Data()));
     208           0 :         continue;
     209             :       }
     210             :     }
     211          24 :   }
     212             :   
     213             :   // Loop over rings 
     214          36 :   for (size_t iring = 0; iring < 2; iring++) {
     215          24 :     char ring = (iring == 0 ? 'I' : 'O');
     216             :     TObjArray*  trans = 0;
     217             :     AliFMDRing* r     = 0; 
     218          24 :     switch (ring) {
     219           6 :     case 'I': r = fInner; trans = fInnerTransforms; break;
     220           6 :     case 'O': r = fOuter; trans = fOuterTransforms; break; 
     221             :     }
     222          14 :     if (!r || !trans) continue;
     223             : 
     224          10 :     Int_t nModules = r->GetNModules();
     225          10 :     if (nModules <= 0) continue;
     226             : 
     227             :     // Loop over bottom/top 
     228          60 :     for (size_t ihalf = 0; ihalf < 2; ihalf++) {
     229          20 :       char  half = (ihalf == 0 ? 'T' : 'B');
     230          50 :       Int_t base = (half == 'T' ? 0 : nModules / 2);
     231             :       
     232             :       // Loop over modules in this half ring 
     233         320 :       for (Int_t imod = 0; imod < nModules / 2; imod++) {
     234             :         // Find physical node entry
     235         140 :         TString path(Form(SENSOR_FORMAT, fId, half, ring, base+imod));
     236         280 :         TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
     237         140 :         if (!entry) {
     238           0 :           AliError(Form("Alignable entry for sensor \"%s\" not found!", 
     239             :                         path.Data()));
     240           0 :           continue;
     241             :         }
     242         140 :         TGeoPhysicalNode* pn = entry->GetPhysicalNode();
     243         140 :         if (!pn) {
     244           0 :           AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
     245           0 :           pn = gGeoManager->MakeAlignablePN(entry);
     246           0 :           if (!pn) {
     247           0 :             AliError(Form("No physical node for \"%s\"", path.Data()));
     248           0 :             continue;
     249             :           }
     250             :         }
     251             :         
     252         280 :         const TGeoMatrix* pm = pn->GetMatrix();
     253         140 :         if (!pm) {
     254           0 :           AliError(Form("No matrix for path \"%s\"", path.Data()));
     255           0 :           continue;
     256             :         }
     257             :         // Get transformation matrix for this node, and store it. 
     258         420 :         TGeoMatrix*  t = new TGeoHMatrix(*pm);
     259         140 :         trans->AddAt(t, base+imod);
     260         560 :         AliFMDDebug(5, ("Found matrix for path \"%s\": %p",path.Data(),pm));
     261         280 :       }
     262             :     }
     263          10 :   }
     264          12 :   if (HasAllTransforms('I') && HasAllTransforms('O')) return;
     265             : 
     266             :   // Alternative implementation using TGeoIter. 
     267           0 :   TGeoVolume* topVolume = gGeoManager->GetTopVolume();
     268           0 :   if (!topVolume) {
     269           0 :     AliFatal("No top-level volume defined");
     270           0 :     return;
     271             :   }
     272             :   // Make an iterator
     273           0 :   TGeoIterator next(topVolume);
     274             :   TGeoNode* node = 0;
     275             :   
     276             :   // Find the node corresponding to this detector, and then find the
     277             :   // sensor volumes 
     278             :   Bool_t thisNodeFound = kFALSE;
     279           0 :   Bool_t allInners     = HasAllTransforms('I');
     280           0 :   Bool_t allOuters     = HasAllTransforms('O');
     281             :   
     282           0 :   while ((node = static_cast<TGeoNode*>(next())) 
     283           0 :          && !(allInners && allOuters)) {
     284             :     // Get nodes names 
     285           0 :     const Char_t* name = node->GetName();
     286           0 :     if (!name) continue;
     287           0 :     AliFMDDebug(50, ("Got volume %s", name));
     288             :     // Check if this node is this detector 
     289             :     // The base offset for numbers in the ASCII table is 48
     290           0 :     if (IS_NODE_THIS(name)) {
     291           0 :       AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
     292             :       thisNodeFound = kTRUE;
     293           0 :     }
     294             :     // if the detector was found, then we're on that branch, and we
     295             :     // check if this node represents a module in that branch.
     296           0 :     if (thisNodeFound && IS_NODE_SENSOR(name)) {
     297           0 :       AliFMDDebug(20, ("Found sensor node '%s' for FMD%d", name, fId));
     298             :       // Get the ring Id.
     299           0 :       Char_t ringid = name[1];
     300             : 
     301             :       // Get the approprate ring
     302           0 :       AliFMDRing* ring = GetRing(ringid);
     303           0 :       if (!ring) continue;
     304             : 
     305             :       // Check whether we have all the modules we need for this ring,
     306             :       // and if so, go on to the next node. 
     307           0 :       Bool_t& done = (ring == fInner ? allInners : allOuters);
     308           0 :       if ((done = HasAllTransforms(ringid))) {
     309           0 :         AliFMDDebug(20, ("Already has all module transforms for ring %c", 
     310             :                          ringid));
     311           0 :         continue;
     312             :       }
     313             : 
     314             :       // Get the approprate container
     315           0 :       TObjArray* matricies = (ringid == 'i' || ringid == 'I' 
     316           0 :                               ? fInnerTransforms : fOuterTransforms);
     317             : 
     318             :       // Get the copy (module) number, and check that it hasn't
     319             :       // already been added to the container. 
     320           0 :       Int_t copy  = node->GetNumber();
     321           0 :       if (matricies->At(copy)) {
     322           0 :         AliWarning(Form("Have a transformation for module %d in ring %c", 
     323             :                         copy, ringid));
     324           0 :         continue;
     325             :       }
     326             : 
     327             :       // Get the global transformation matrix, and store it. 
     328           0 :       TGeoMatrix*  trans = new TGeoHMatrix(*(next.GetCurrentMatrix()));
     329           0 :       matricies->AddAt(trans, copy);
     330             : 
     331           0 :     }
     332           0 :   }
     333           6 : }
     334             : 
     335             : //____________________________________________________________________
     336             : void
     337             : AliFMDDetector::SetAlignableVolumes() const
     338             : {
     339             :   // Set alignable volumes. 
     340             :   // This will define the alignable volumes. 
     341             :   // That is currently, the modules and the half-rings. 
     342             :   
     343           9 :   AliFMDDebug(10, ("Making alignable volumes for FMD%d", fId));
     344           3 :   if (!gGeoManager) {
     345           0 :     AliFatal("No TGeoManager defined");
     346           0 :     return;
     347             :   }
     348           3 :   TGeoVolume* topVolume = gGeoManager->GetTopVolume();
     349           3 :   if (!topVolume) {
     350           0 :     AliFatal("No top-level volume defined");
     351           0 :     return;
     352             :   }
     353             : 
     354             :   // Make an iterator
     355           3 :   TGeoIterator next(topVolume);
     356           3 :   next.Reset(topVolume);
     357           9 :   next.SetTopName(Form("/%s_1", topVolume->GetName()));
     358             :   TGeoNode* node = 0;
     359             :   
     360           9 :   Int_t nInnerSensor = (fInner ? fInner->GetNModules() : 0);
     361           8 :   Int_t nOuterSensor = (fOuter ? fOuter->GetNModules() : 0);
     362             :   // Find the node corresponding to this detector, and then find the
     363             :   // sensor volumes 
     364             :   Bool_t thisNodeFound = kFALSE;
     365             :   Char_t thisHalf      = '\0';
     366             :   Int_t  iInnerSensor  = 0;
     367             :   Int_t  iOuterSensor  = 0;
     368             :   Bool_t hasTop        = false;
     369             :   Bool_t hasBottom     = false;
     370             :   
     371           6 :   TString path, align;
     372    16223345 :   while ((node = static_cast<TGeoNode*>(next())) 
     373    16234839 :          && (iInnerSensor < nInnerSensor || iOuterSensor < nOuterSensor
     374       11503 :              || !hasBottom || !hasTop)) {
     375             :     // Get nodes names 
     376     8111668 :     const Char_t* name = node->GetName();
     377     8111668 :     if (!name) continue;
     378    32446672 :     AliFMDDebug((name[0] == 'F' ? 40 : 50), ("Got volume %s", name));
     379             :     // Check if this node is this detector 
     380             :     // The base offset for numbers in the ASCII table is 48
     381     8986939 :     if (IS_NODE_THIS(name)) {
     382          24 :       AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
     383             :       thisNodeFound = kTRUE;
     384           6 :     }
     385             : 
     386             :     // if a half ring is found, then we're on that branch, and we
     387             :     // check if this node represents a half ring on that branch 
     388     8211701 :     if (thisNodeFound && IS_NODE_HALF(name)) {
     389          24 :       AliFMDDebug(30, ("Found half node '%s' for FMD%d", name, fId));
     390             :       // Get the half Id.
     391           6 :       thisHalf = name[3];
     392             : 
     393             :       // Check if we're done 
     394           6 :       Bool_t done = (thisHalf == 'T' ? hasTop : hasBottom);
     395           6 :       if (done) {
     396           0 :         AliFMDDebug(20, ("Already has all halves for detector %c",name[1]));
     397           0 :         continue;
     398             :       }
     399             : 
     400           6 :       switch (thisHalf) {
     401           3 :       case 'T': hasTop = true; break;
     402           3 :       case 'B': hasBottom = true; break;
     403             :       default:  
     404           0 :         AliWarning(Form("Unknown part '%c' of FMD%d", thisHalf, fId));
     405           0 :         continue; // because the node is unknown. 
     406             :       }
     407             :       
     408             :       // Get the node path 
     409           6 :       next.GetPath(path);
     410          12 :       align = Form(HALF_FORMAT, fId, thisHalf);
     411           6 :     }
     412             :     
     413             :     // if the detector was found, then we're on that branch, and we
     414             :     // check if this node represents a module in that branch.
     415     8261738 :     if (thisNodeFound && thisHalf && IS_NODE_SENSOR(name)) {
     416         280 :       AliFMDDebug(30, ("Found sensor node '%s' for FMD%d", name, fId));
     417             :       // Get the ring Id.
     418          70 :       Char_t ringid = name[1];
     419             : 
     420             :       // check that the ring is valid 
     421         140 :       if (!GetRing(ringid)) {
     422           0 :         AliWarning(Form("Invalid ring %c for FMD%d", ringid, fId));
     423           0 :         continue;
     424             :       }
     425             : 
     426             :       // Check if we're done
     427             :       Bool_t done = false;
     428          70 :       switch (ringid) {
     429          30 :       case 'I': done = iInnerSensor >= nInnerSensor; break;
     430          40 :       case 'O': done = iOuterSensor >= nOuterSensor; break;
     431           0 :       default: continue;
     432             :       }
     433          70 :       if (done) {
     434           0 :         AliFMDDebug(20, ("Already has all sensor volumes for ring %c",ringid));
     435           0 :         continue;
     436             :       }
     437             :       // Get the copy (module) number, and check that it hasn't
     438             :       // already been added to the container. 
     439          70 :       Int_t copy  = node->GetNumber();
     440          70 :       next.GetPath(path);
     441             :       // path.Replace("ALIC", "/ALIC_1");
     442         140 :       align = Form(SENSOR_FORMAT, fId, thisHalf, ringid, copy);
     443             :       
     444         140 :       switch (ringid) {
     445          30 :       case 'I': iInnerSensor++; break;
     446          40 :       case 'O': iOuterSensor++; break;
     447             :       }
     448          70 :     }
     449    16223488 :     if (!align.IsNull() && !path.IsNull()) {
     450         304 :       AliFMDDebug(20, ("Got %s -> %s", path.Data(), align.Data()));
     451             :       TGeoPNEntry* entry = 
     452         228 :         gGeoManager->SetAlignableEntry(align.Data(),path.Data());
     453          76 :       if(!entry)
     454           0 :         AliFatal(Form("Alignable entry %s not created. "
     455             :                       "Volume path %s not valid", 
     456             :                         align.Data(),path.Data()));
     457             : #ifdef MAKE_ALIGNABLE_PHYSICAL
     458             :       TGeoPhysicalNode* phys = gGeoManager->MakeAlignablePN(entry);
     459             :       if (!phys) 
     460             :         AliWarning(Form("Physical node entry %s not created. "
     461             :                         "Volume path %s not valid", 
     462             :                         align.Data(),path.Data()));
     463             : #endif
     464          76 :       align = "";
     465          76 :     }
     466    32446672 :     AliFMDDebug(20, ("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d", 
     467             :                       fId, hasTop, hasBottom, iInnerSensor,  nInnerSensor, 
     468             :                       iOuterSensor, nOuterSensor));
     469     8111668 :   }
     470           6 : }
     471             : 
     472             :   
     473             : 
     474             : //____________________________________________________________________
     475             : AliFMDRing*
     476             : AliFMDDetector::GetRing(Char_t id) const
     477             : {
     478             :   // Get the specified ring 
     479             :   // 
     480             :   //   ID      Id of ring ('I' or 'O')
     481             :   // 
     482      885672 :   switch (id) {
     483             :   case 'i':
     484      270671 :   case 'I': return GetInner();
     485             :   case 'o':
     486      172165 :   case 'O': return GetOuter();
     487             :   }
     488           0 :   return 0;
     489      442836 : }
     490             : 
     491             : //____________________________________________________________________
     492             : Double_t
     493             : AliFMDDetector::GetRingZ(Char_t id) const
     494             : {
     495             :   // Get the z-coordinate specified ring 
     496             :   // 
     497             :   //   ID      Id of ring ('I' or 'O')
     498             :   // 
     499           0 :   switch (id) {
     500             :   case 'i':
     501           0 :   case 'I': return GetInnerZ();
     502             :   case 'o':
     503           0 :   case 'O': return GetOuterZ();
     504             :   }
     505           0 :   return 0;
     506           0 : }
     507             : 
     508             : //____________________________________________________________________
     509             : TGeoMatrix*
     510             : AliFMDDetector::FindTransform(Char_t ring, UShort_t sector) const 
     511             : {
     512             :   // Find the transformation that corresponds to sector sector in ring
     513             :   // ring. 
     514             :   TObjArray* matricies = 0;
     515     1327104 :   switch (ring) {
     516      270336 :   case 'i': case 'I': matricies = fInnerTransforms; break;
     517      172032 :   case 'o': case 'O': matricies = fOuterTransforms; break;
     518             :   }
     519      442368 :   if (!matricies) { 
     520           0 :     AliWarning(Form("Unknown ring %c of FMD%d", ring, fId));
     521           0 :     return 0;
     522             :   }
     523      442368 :   UInt_t module = sector / 2;
     524      442368 :   TGeoMatrix* m = static_cast<TGeoMatrix*>(matricies->At(module));
     525      442368 :   if (!m) {
     526           0 :     AliWarning(Form("No matrix found for sector %d in FMD%d%c", 
     527             :                     sector, fId, ring));
     528           0 :     return 0;
     529             :   }
     530      442368 :   return m;
     531      442368 : }
     532             : 
     533             :   
     534             : //____________________________________________________________________
     535             : void
     536             : AliFMDDetector::Detector2XYZ(Char_t   ring, 
     537             :                              UShort_t sector,
     538             :                              UShort_t strip, 
     539             :                              Double_t& x, 
     540             :                              Double_t& y, 
     541             :                              Double_t& z) const
     542             : {
     543             :   // Translate detector coordinates (this,ring,sector,strip) into
     544             :   // (x,y,z) coordinates (in global reference frame)
     545      884736 :   AliFMDRing* r = GetRing(ring);
     546      442368 :   if (!r) { 
     547           0 :     AliWarning(Form("No such ring FMD%d%c ", fId, ring));
     548           0 :     return;
     549             :   }
     550      442368 :   TGeoMatrix* m = FindTransform(ring, sector);
     551      442368 :   if (!m) { 
     552           0 :     AliWarning(Form("No transfrmation found for FMD%d%c[%02d]", 
     553             :                     fId, ring, sector));
     554           0 :     return;
     555             :   }
     556      442368 :   Double_t rho      = r->GetStripRadius(strip);
     557      442368 :   Double_t phi      = ((sector % 2) - .5) * r->GetTheta();
     558      442368 :   Double_t siThick  = r->GetSiThickness();
     559             : #if 0 
     560             :   Double_t modThick = (siThick
     561             :                        + r->GetPrintboardThickness()
     562             :                        + r->GetCopperThickness()
     563             :                        + r->GetChipThickness()
     564             :                        + r->GetSpacing());
     565             : #endif
     566      884736 :   AliFMDDebug(30, ("Rho %7.3f, angle %7.3f", rho, phi));
     567     1327104 :   Double_t local[]  = { rho * TMath::Cos(phi * TMath::DegToRad()), 
     568      442368 :                         rho * TMath::Sin(phi * TMath::DegToRad()), 
     569      442368 :                         /* -modThick + */ siThick / 2 };
     570      442368 :   Double_t master[3];
     571      884736 :   AliFMDDebug(30, ("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
     572      442368 :   m->LocalToMaster(local, master);
     573      884736 :   AliFMDDebug(30, ("Master (%7.3f,%7.3f,%7.3f)",
     574             :                     master[0],master[1],master[2]));
     575      442368 :   x = master[0];
     576      442368 :   y = master[1];
     577      442368 :   z = master[2];
     578      884736 : }
     579             : 
     580             : //____________________________________________________________________
     581             : Bool_t
     582             : AliFMDDetector::XYZ2Detector(Double_t  x,
     583             :                              Double_t  y,
     584             :                              Double_t  z,
     585             :                              Char_t&   ring, 
     586             :                              UShort_t& sector,
     587             :                              UShort_t& strip) const
     588             : {
     589             :   // Translate (x,y,z) coordinates (in global reference frame) into 
     590             :   // detector coordinates (this,ring,sector,strip).
     591             :   AliFMDRing* rng = 0;
     592           0 :   ring = -1;
     593           0 :   for (int j = 0; j < 2; j++) {
     594           0 :     rng = GetRing(j == 0 ? 'I'  : 'O');
     595           0 :     if (!rng) continue;
     596           0 :     Double_t ringZ    = GetRingZ(j == 0 ? 'I'  : 'O');
     597           0 :     Double_t modSpace = TMath::Sign(rng->GetModuleSpacing(), ringZ);
     598           0 :     if (TMath::Abs(z - ringZ) < 0.01 || 
     599           0 :         TMath::Abs(z - ringZ + modSpace) < 0.01) break;
     600             :     rng = 0;
     601           0 :   }
     602           0 :   if (rng && rng->XYZ2Detector(x, y, z - GetRingZ(rng->GetId()),
     603             :                                sector, strip)) {
     604           0 :     ring = rng->GetId();
     605           0 :     return kTRUE;
     606             :   }
     607           0 :   return kFALSE;
     608           0 : }
     609             : 
     610             :   
     611             : 
     612             : //____________________________________________________________________
     613             : // 
     614             : // EOF
     615             : //

Generated by: LCOV version 1.11