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