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