]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDGeometry.cxx
Additiona TOF data members (S.Arcelli)
[u/mrichter/AliRoot.git] / FMD / AliFMDGeometry.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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
16 /* $Id$ */
17
18 //____________________________________________________________________
19 //                                                                          
20 // Forward Multiplicity Detector based on Silicon wafers. 
21 //
22 // This class is a singleton that handles the geometry parameters of
23 // the FMD detectors.  
24 //                                                       
25 // The actual code is done by various separate classes.   Below is
26 // diagram showing the relationship between the various FMD classes
27 // that handles the geometry 
28 //
29 //                               +------------+ 
30 //                            +- | AliFMDRing |
31 //                         2  |  +------------+
32 //      +----------------+<>--+        |                                
33 //      | AliFMDGeometry |             ^                        
34 //      +----------------+<>--+        V 1..2                           
35 //                         3  | +----------------+              
36 //                            +-| AliFMDDetector |              
37 //                              +----------------+              
38 //                                     ^
39 //                                     |
40 //                       +-------------+-------------+
41 //                       |             |             |        
42 //                  +---------+   +---------+   +---------+
43 //                  | AliFMD1 |   | AliFMD2 |   | AliFMD3 |
44 //                  +---------+   +---------+   +---------+
45 //      
46 //
47 // *  AliFMDRing 
48 //    This class contains all stuff needed to do with a ring.  It's
49 //    used by the AliFMDDetector objects to instantise inner and
50 //    outer rings.  The AliFMDRing objects are shared by the
51 //    AliFMDDetector objects, and owned by the AliFMDv1 object. 
52 //
53 // *  AliFMD1, AliFMD2, and AliFMD3 
54 //    These are specialisation of AliFMDDetector, that contains the
55 //    particularities of each of the sub-detector system.  It is
56 //    envisioned that the classes should also define the support
57 //    volumes and material for each of the detectors.                          
58 //                                                                          
59 //
60 #include "AliFMDGeometry.h"     // ALIFMDGEOMETRY_H
61 #include "AliFMDRing.h"         // ALIFMDRING_H
62 #include "AliFMD1.h"            // ALIFMD1_H
63 #include "AliFMD2.h"            // ALIFMD2_H
64 #include "AliFMD3.h"            // ALIFMD2_H
65 #include "AliRecPoint.h"        // ALIRECPOINT_H
66 #include "AliLog.h"             // ALIRECPOINT_H
67 #include <TVector3.h>           // ROOT_TVector3
68 #include <TMatrix.h>            // ROOT_TMatrix
69 #include <TParticle.h>          // ROOT_TParticle
70 #include <Riostream.h>
71 #include "AliFMDGeometryBuilder.h"
72 #include <TArrayI.h>
73 #include <TGeoManager.h>
74 #include <TGeoVolume.h>
75 #include <TGeoNode.h>
76 static Int_t FindNodeDepth(const char* name, const char* volname);
77
78
79 //====================================================================
80 ClassImp(AliFMDGeometry)
81 #if 0
82   ; // This is here to keep Emacs for indenting the next line
83 #endif
84
85 //____________________________________________________________________
86 AliFMDGeometry* AliFMDGeometry::fgInstance = 0;
87
88 //____________________________________________________________________
89 AliFMDGeometry* 
90 AliFMDGeometry::Instance() 
91 {
92   // Return (newly created) singleton instance 
93   if (!fgInstance) fgInstance = new AliFMDGeometry;
94   return fgInstance;
95 }
96
97 //____________________________________________________________________
98 AliFMDGeometry::AliFMDGeometry() 
99   : AliGeometry("FMD", "Forward multiplicity"), 
100     fBuilder(0)
101 {
102   // PROTECTED
103   // Default constructor 
104   fUseFMD1     = kTRUE;
105   fUseFMD2     = kTRUE;
106   fUseFMD3     = kTRUE;  
107   fDetailed    = kTRUE;
108   fUseAssembly = kTRUE;
109   fInner = new AliFMDRing('I');
110   fOuter = new AliFMDRing('O');
111   fFMD1  = new AliFMD1(fInner);
112   fFMD2  = new AliFMD2(fInner, fOuter);
113   fFMD3  = new AliFMD3(fInner, fOuter);
114   fIsInitialized = kFALSE;
115   fActive.Reset(-1);
116 }
117
118 //____________________________________________________________________
119 AliFMDGeometry::AliFMDGeometry(const AliFMDGeometry& other) 
120   : AliGeometry(other),
121     fIsInitialized(other.fIsInitialized),
122     fInner(other.fInner), 
123     fOuter(other.fOuter), 
124     fFMD1(other.fFMD1), 
125     fFMD2(other.fFMD2), 
126     fFMD3(other.fFMD3), 
127     fUseFMD1(other.fUseFMD1), 
128     fUseFMD2(other.fUseFMD2), 
129     fUseFMD3(other.fUseFMD3), 
130     fActive(other.fActive),
131     fDetailed(other.fDetailed),
132     fUseAssembly(other.fUseAssembly)
133 {
134   // PROTECTED
135   // Copy constructor
136 }
137
138
139
140 //____________________________________________________________________
141 AliFMDGeometry&
142 AliFMDGeometry::operator=(const AliFMDGeometry& other) 
143 {
144   // PROTECTED
145   // Assignment operator 
146   fUseFMD1              = other.fUseFMD1; 
147   fUseFMD2              = other.fUseFMD2; 
148   fUseFMD3              = other.fUseFMD3; 
149   fFMD1                 = other.fFMD1; 
150   fFMD2                 = other.fFMD2; 
151   fFMD3                 = other.fFMD3; 
152   fInner                = other.fInner; 
153   fOuter                = other.fOuter; 
154   fIsInitialized        = other.fIsInitialized;
155   return *this;
156 }
157
158 //____________________________________________________________________
159 void
160 AliFMDGeometry::Init()
161 {
162   // Initialize the the singleton if not done so already 
163   if (fIsInitialized) return;
164   fInner->Init();
165   fOuter->Init();
166   fFMD1->Init();
167   fFMD2->Init();
168   fFMD3->Init();
169 }
170
171 //____________________________________________________________________
172 void
173 AliFMDGeometry::InitTransformations()
174 {
175   if (!gGeoManager) {
176     AliError("No TGeoManager defined");
177     return;
178   }
179   AliDebug(0, "Initialising transforms for FMD geometry");
180   if (fFMD1) fFMD1->InitTransformations();
181   if (fFMD2) fFMD2->InitTransformations();
182   if (fFMD3) fFMD3->InitTransformations();
183 }
184
185 //____________________________________________________________________
186 void
187 AliFMDGeometry::Build()
188 {
189   if (!fBuilder) fBuilder = new AliFMDGeometryBuilder(fDetailed);
190   fBuilder->SetDetailed(fDetailed);
191   fBuilder->UseAssembly(fUseAssembly);
192   fBuilder->Exec();
193 }
194
195 //____________________________________________________________________
196 void
197 AliFMDGeometry::SetActive(Int_t* active, Int_t n) 
198 {
199   fActive.Set(n);
200   for (Int_t i = 0; i < n; i++) { 
201     AliDebug(1, Form("Active vol id # %d: %d", i, active[i]));
202     fActive[i] = active[i];
203   }
204 }
205
206 //____________________________________________________________________
207 void
208 AliFMDGeometry::AddActive(Int_t active)
209 {
210   Int_t n = fActive.fN;
211   fActive.Set(n+1);
212   fActive[n] = active;
213 }
214
215 //____________________________________________________________________
216 Bool_t
217 AliFMDGeometry::IsActive(Int_t vol) const
218 {
219   for (Int_t i = 0; i < fActive.fN; i++) 
220     if (fActive[i] == vol) return kTRUE;
221   return kFALSE;
222 }
223   
224 //____________________________________________________________________
225 AliFMDDetector*
226 AliFMDGeometry::GetDetector(Int_t i) const
227 {
228   // Get the ith detector.   i should be one of 1, 2, or 3.  If an
229   // invalid value is passed, 0 (NULL) is returned. 
230   switch (i) {
231   case 1: return fUseFMD1 ? static_cast<AliFMDDetector*>(fFMD1) : 0;
232   case 2: return fUseFMD2 ? static_cast<AliFMDDetector*>(fFMD2) : 0;
233   case 3: return fUseFMD3 ? static_cast<AliFMDDetector*>(fFMD3) : 0;
234   }
235   return 0;
236 }
237
238 //____________________________________________________________________
239 AliFMDRing*
240 AliFMDGeometry::GetRing(Char_t i) const
241 {
242   // Get the ith ring.  i should be one of 'I' or 'O' (case
243   // insensitive).  If an invalid parameter is passed, 0 (NULL) is
244   // returned. 
245   switch (i) {
246   case 'I':
247   case 'i': return fInner;
248   case 'O':
249   case 'o': return fOuter;
250   }
251   return 0;
252 }
253
254 //____________________________________________________________________
255 void
256 AliFMDGeometry::Enable(Int_t i)
257 {
258   // Enable the ith detector.  i should be one of 1, 2, or 3
259   switch (i) {
260   case 1: fUseFMD1 = kTRUE; break;
261   case 2: fUseFMD2 = kTRUE; break;
262   case 3: fUseFMD3 = kTRUE; break;
263   }
264 }
265
266 //____________________________________________________________________
267 void
268 AliFMDGeometry::Disable(Int_t i)
269 {
270   // Disable the ith detector.  i should be one of 1, 2, or 3
271   switch (i) {
272   case 1: fUseFMD1 = kFALSE; break;
273   case 2: fUseFMD2 = kFALSE; break;
274   case 3: fUseFMD3 = kFALSE; break;
275   }
276 }
277
278 //____________________________________________________________________
279 void
280 AliFMDGeometry::Detector2XYZ(UShort_t  detector, 
281                              Char_t    ring, 
282                              UShort_t  sector, 
283                              UShort_t  strip, 
284                              Double_t& x, 
285                              Double_t& y, 
286                              Double_t& z) const
287 {
288   // Translate detector coordinates (detector, ring, sector, strip) to
289   // spatial coordinates (x, y, z) in the master reference frame of
290   // ALICE. 
291   AliFMDDetector* det = GetDetector(detector);
292   if (!det) { 
293     AliWarning(Form("Unknown detector %d", detector));
294     return;
295   }
296   det->Detector2XYZ(ring, sector, strip, x, y, z);
297 }
298
299 //____________________________________________________________________
300 Bool_t
301 AliFMDGeometry::XYZ2Detector(Double_t  x, 
302                              Double_t  y, 
303                              Double_t  z,
304                              UShort_t& detector, 
305                              Char_t&   ring, 
306                              UShort_t& sector, 
307                              UShort_t& strip) const
308 {
309   // Translate spatial coordinates (x,y,z) in the master reference frame of
310   // ALICE to the detector coordinates (detector, ring, sector,
311   // strip).  Note, that if this method is to be used in
312   // reconstruction or the like, then the input z-coordinate should be
313   // corrected for the events interactions points z-coordinate, like 
314   // geom->XYZ2Detector(x,y,z-ipz,d,r,s,t);
315   AliFMDDetector* det = 0;
316   detector = 0;
317   for (int i = 1; i <= 3; i++) {
318     det = GetDetector(i);
319     if (!det) continue;
320     if (det->XYZ2Detector(x, y, z, ring, sector, strip)) {
321       detector = det->GetId();
322       return kTRUE;
323     }
324   }
325   return kFALSE;
326 }
327
328
329 //____________________________________________________________________
330 void
331 AliFMDGeometry::GetGlobal(const AliRecPoint* p, 
332                           TVector3& pos, 
333                           TMatrixF& /* mat */) const 
334 {
335   // Get the global coordinates cooresponding to the reconstructed
336   // point p.  The coordiates is returned in the 3-vector pos passed
337   // to this member function.  The matrix mat is used for rotations. 
338   GetGlobal(p, pos);
339 }
340
341 //____________________________________________________________________
342 void
343 AliFMDGeometry::GetGlobal(const AliRecPoint* p, TVector3& pos) const 
344 {
345   // Get the global coordinates cooresponding to the reconstructed
346   // point p.  The coordiates is returned in the 3-vector pos passed
347   // to this member function. Note, as AliRecPoint only has places for
348   // 3 indicies, it is assumed that the ring hit is an inner ring -
349   // which obviously needn't be the case. This makes the member
350   // function pretty darn useless. 
351   // FIXME: Implement this function to work with outer rings too. 
352   Double_t x, y, z;
353   TVector3 local;
354   p->GetLocalPosition(local);
355   UShort_t detector = UShort_t(local.X());
356   UShort_t sector   = UShort_t(local.Y());
357   UShort_t strip    = UShort_t(local.Z());
358   Detector2XYZ(detector, 'I', sector, strip, x, y, z);
359   pos.SetXYZ(x, y, z);
360 }
361
362 //____________________________________________________________________
363 Bool_t
364 AliFMDGeometry::Impact(const TParticle* /* particle */) const 
365
366   // Return true, if the particle will hit the active detector
367   // elements, and false if not.  Should be used for fast
368   // simulations.  Note, that the function currently return false
369   // always.  
370   // FIXME: Implement this function. 
371   return kFALSE; 
372 }
373
374 //____________________________________________________________________  
375 void  
376 AliFMDGeometry::ExtractGeomInfo()
377 {
378   // Check the volume depth of some nodes, get the active volume
379   // numbers, and so forth. 
380   // 
381   // TODO: Here, we should actually also get the parameters of the
382   // shapes, like the verticies of the polygon shape that makes up the
383   // silicon sensor, the strip pitch, the ring radii, the z-positions,
384   // and so on - that is, all the geometric information we need for
385   // futher processing, such as simulation, digitization,
386   // reconstruction, etc. 
387   Int_t detectorDepth = FindNodeDepth("FMD1_1", "ALIC");
388   Int_t ringDepth     = FindNodeDepth(Form("FMDI_%d", Int_t('I')), "ALIC");
389   Int_t moduleDepth   = FindNodeDepth("FIFV_0", "ALIC");
390   Int_t sectorDepth   = FindNodeDepth("FISE_1", "ALIC");
391   fActive.Reset(-1);
392   AliDebug(1, Form("Geometry depths:\n"
393                    "   Sector:     %d\n"
394                    "   Module:     %d\n"
395                    "   Ring:       %d\n"
396                    "   Detector:   %d", 
397                    sectorDepth, moduleDepth, ringDepth, detectorDepth));
398   if (sectorDepth < 0 && moduleDepth < 0) {
399     fDetailed    = kFALSE;
400     fSectorOff   = -1;
401     fModuleOff   = -1;
402     fRingOff     = 0;
403     fDetectorOff = (ringDepth - detectorDepth);
404     TGeoVolume* actiVol = gGeoManager->GetVolume("FIAC");
405     TGeoVolume* actoVol = gGeoManager->GetVolume("FOAC");
406     if (actiVol) AddActive(actiVol->GetNumber());
407     if (actiVol) AddActive(actoVol->GetNumber());
408   }
409   else if (sectorDepth < 0) {
410     fDetailed    = kFALSE;
411     fSectorOff   = -1;
412     fModuleOff   = 1;
413     fRingOff     = (moduleDepth - ringDepth) + 1;
414     fDetectorOff = (moduleDepth - detectorDepth) + 1;
415     TGeoVolume* modiVol = gGeoManager->GetVolume("FIMO");
416     TGeoVolume* modoVol = gGeoManager->GetVolume("FOMO");
417     if (modiVol) AddActive(modiVol->GetNumber());
418     if (modoVol) AddActive(modoVol->GetNumber());
419   }
420   else {
421     Int_t stripDepth    = FindNodeDepth("FIST_1", "ALIC");
422     fDetailed    = kTRUE;
423     fSectorOff   = (stripDepth - sectorDepth);
424     fModuleOff   = (moduleDepth >= 0 ? (stripDepth - moduleDepth) : -1);
425     fRingOff     = (stripDepth - ringDepth);
426     fDetectorOff = (stripDepth - detectorDepth );
427     TGeoVolume* striVol = gGeoManager->GetVolume("FIST");
428     TGeoVolume* stroVol = gGeoManager->GetVolume("FOST");
429     if (striVol) AddActive(striVol->GetNumber());
430     if (stroVol) AddActive(stroVol->GetNumber());
431   }    
432   AliDebug(1, Form("Geometry offsets:\n"
433                    "   Sector:     %d\n"
434                    "   Module:     %d\n"
435                    "   Ring:       %d\n"
436                    "   Detector:   %d", 
437                    fSectorOff, fModuleOff, fRingOff, fDetectorOff));
438 }
439
440   
441 //____________________________________________________________________  
442 static Int_t 
443 CheckNodes(TGeoNode* node, const char* name, Int_t& lvl)
444 {
445   // If there's no node here. 
446   if (!node) return -1;
447   // Check if it this one 
448   TString sname(name);
449   if (sname == node->GetName()) return lvl;
450
451   // Check if the node is an immediate daugther 
452   TObjArray* nodes = node->GetNodes();
453   if (!nodes) return -1;
454   // Increase the level, and search immediate sub nodes. 
455   lvl++;
456   TGeoNode*  found = static_cast<TGeoNode*>(nodes->FindObject(name));
457   if (found) return lvl;
458
459   // Check the sub node, if any of their sub-nodes match.
460   for (Int_t i = 0; i < nodes->GetEntries(); i++) {
461     TGeoNode* sub = static_cast<TGeoNode*>(nodes->At(i));
462     if (!sub) continue;
463     // Recurive check 
464     if (CheckNodes(sub, name, lvl) >= 0) return lvl;
465   }
466   // If not found, decrease the level 
467   lvl--;
468   return -1;
469 }
470 //____________________________________________________________________  
471 Int_t 
472 FindNodeDepth(const char* name, const char* volname) 
473 {
474   TGeoVolume* vol  = gGeoManager->GetVolume(volname);
475   if (!vol) {
476     std::cerr << "No top volume defined" << std::endl;
477     return -1;
478   }
479   TObjArray* nodes = vol->GetNodes();
480   if (!nodes) { 
481     std::cerr << "No nodes in top volume" << std::endl;
482     return -1;
483   }
484   TIter next(nodes);
485   TGeoNode* node = 0;
486   Int_t lvl = 0;
487   while ((node = static_cast<TGeoNode*>(next()))) 
488     if (CheckNodes(node, name, lvl) >= 0) return lvl;
489   return -1;
490 }
491
492 //____________________________________________________________________
493 //
494 // EOF
495 //