]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDGeometry.cxx
Changing fabs into TMath::Abs
[u/mrichter/AliRoot.git] / FMD / AliFMDGeometry.cxx
CommitLineData
1a1fdef7 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 **************************************************************************/
1a1fdef7 15/* $Id$ */
c2fc1258 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*/
1a1fdef7 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
f95a63c4 69#include "AliFMDDebug.h" // ALILOG_H
1a1fdef7 70#include <TVector3.h> // ROOT_TVector3
02a27b50 71// #include <TMatrix.h> // ROOT_TMatrix
72// #include <TParticle.h> // ROOT_TParticle
1a1fdef7 73#include <Riostream.h>
54e415a8 74#include "AliFMDGeometryBuilder.h"
02a27b50 75// #include <TArrayI.h>
54e415a8 76#include <TGeoManager.h>
77#include <TGeoVolume.h>
78#include <TGeoNode.h>
79static Int_t FindNodeDepth(const char* name, const char* volname);
54e415a8 80
1a1fdef7 81
82//====================================================================
83ClassImp(AliFMDGeometry)
84#if 0
85 ; // This is here to keep Emacs for indenting the next line
86#endif
87
88//____________________________________________________________________
89AliFMDGeometry* AliFMDGeometry::fgInstance = 0;
90
91//____________________________________________________________________
92AliFMDGeometry*
93AliFMDGeometry::Instance()
94{
69b696b9 95 // Return (newly created) singleton instance
1a1fdef7 96 if (!fgInstance) fgInstance = new AliFMDGeometry;
97 return fgInstance;
98}
99
100//____________________________________________________________________
101AliFMDGeometry::AliFMDGeometry()
a1f80595 102 : AliGeometry("FMD", "Forward multiplicity"),
b5ee4425 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)
1a1fdef7 120{
69b696b9 121 // PROTECTED
122 // Default constructor
54e415a8 123 fUseFMD1 = kTRUE;
124 fUseFMD2 = kTRUE;
125 fUseFMD3 = kTRUE;
54e415a8 126 fDetailed = kTRUE;
127 fUseAssembly = kTRUE;
1a1fdef7 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;
54e415a8 134 fActive.Reset(-1);
1a1fdef7 135}
136
69b696b9 137//____________________________________________________________________
138AliFMDGeometry::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),
bf000c32 148 fUseFMD3(other.fUseFMD3),
b5ee4425 149 fBuilder(other.fBuilder),
150 fDetectorOff(other.fDetectorOff),
151 fModuleOff(other.fModuleOff),
152 fRingOff(other.fRingOff),
153 fSectorOff(other.fSectorOff),
bf000c32 154 fActive(other.fActive),
54e415a8 155 fDetailed(other.fDetailed),
156 fUseAssembly(other.fUseAssembly)
69b696b9 157{
158 // PROTECTED
159 // Copy constructor
160}
161
162
163
164//____________________________________________________________________
165AliFMDGeometry&
166AliFMDGeometry::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
1a1fdef7 182//____________________________________________________________________
183void
184AliFMDGeometry::Init()
185{
69b696b9 186 // Initialize the the singleton if not done so already
1a1fdef7 187 if (fIsInitialized) return;
188 fInner->Init();
189 fOuter->Init();
190 fFMD1->Init();
191 fFMD2->Init();
192 fFMD3->Init();
193}
194
bf000c32 195//____________________________________________________________________
196void
197AliFMDGeometry::InitTransformations()
198{
02a27b50 199 // Find all local <-> global transforms
bf000c32 200 if (!gGeoManager) {
201 AliError("No TGeoManager defined");
202 return;
203 }
f95a63c4 204 AliFMDDebug(0, ("Initialising transforms for FMD geometry"));
bf000c32 205 if (fFMD1) fFMD1->InitTransformations();
206 if (fFMD2) fFMD2->InitTransformations();
207 if (fFMD3) fFMD3->InitTransformations();
208}
209
54e415a8 210//____________________________________________________________________
211void
212AliFMDGeometry::Build()
213{
02a27b50 214 // Build the geometry
54e415a8 215 if (!fBuilder) fBuilder = new AliFMDGeometryBuilder(fDetailed);
216 fBuilder->SetDetailed(fDetailed);
217 fBuilder->UseAssembly(fUseAssembly);
218 fBuilder->Exec();
219}
220
221//____________________________________________________________________
222void
223AliFMDGeometry::SetActive(Int_t* active, Int_t n)
224{
02a27b50 225 // Set active volumes
54e415a8 226 fActive.Set(n);
088f8e79 227 for (Int_t i = 0; i < n; i++) {
f95a63c4 228 AliFMDDebug(1, ("Active vol id # %d: %d", i, active[i]));
088f8e79 229 fActive[i] = active[i];
230 }
54e415a8 231}
232
233//____________________________________________________________________
234void
235AliFMDGeometry::AddActive(Int_t active)
236{
02a27b50 237 // Add an active volume
54e415a8 238 Int_t n = fActive.fN;
239 fActive.Set(n+1);
240 fActive[n] = active;
241}
242
243//____________________________________________________________________
244Bool_t
245AliFMDGeometry::IsActive(Int_t vol) const
246{
02a27b50 247 // Check if a volume is active
54e415a8 248 for (Int_t i = 0; i < fActive.fN; i++)
249 if (fActive[i] == vol) return kTRUE;
250 return kFALSE;
251}
54e415a8 252
1a1fdef7 253//____________________________________________________________________
254AliFMDDetector*
255AliFMDGeometry::GetDetector(Int_t i) const
256{
69b696b9 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.
1a1fdef7 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//____________________________________________________________________
268AliFMDRing*
269AliFMDGeometry::GetRing(Char_t i) const
270{
69b696b9 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.
1a1fdef7 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//____________________________________________________________________
284void
285AliFMDGeometry::Enable(Int_t i)
286{
69b696b9 287 // Enable the ith detector. i should be one of 1, 2, or 3
1a1fdef7 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//____________________________________________________________________
296void
297AliFMDGeometry::Disable(Int_t i)
298{
69b696b9 299 // Disable the ith detector. i should be one of 1, 2, or 3
1a1fdef7 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//____________________________________________________________________
308void
309AliFMDGeometry::Detector2XYZ(UShort_t detector,
69b696b9 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
1a1fdef7 316{
69b696b9 317 // Translate detector coordinates (detector, ring, sector, strip) to
318 // spatial coordinates (x, y, z) in the master reference frame of
319 // ALICE.
1a1fdef7 320 AliFMDDetector* det = GetDetector(detector);
bf000c32 321 if (!det) {
322 AliWarning(Form("Unknown detector %d", detector));
323 return;
324 }
1a1fdef7 325 det->Detector2XYZ(ring, sector, strip, x, y, z);
326}
327
54e415a8 328//____________________________________________________________________
329Bool_t
330AliFMDGeometry::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
1a1fdef7 357
358//____________________________________________________________________
359void
360AliFMDGeometry::GetGlobal(const AliRecPoint* p,
361 TVector3& pos,
e8d02863 362 TMatrixF& /* mat */) const
1a1fdef7 363{
69b696b9 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.
1a1fdef7 367 GetGlobal(p, pos);
368}
369
370//____________________________________________________________________
371void
372AliFMDGeometry::GetGlobal(const AliRecPoint* p, TVector3& pos) const
373{
69b696b9 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.
1a1fdef7 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//____________________________________________________________________
392Bool_t
393AliFMDGeometry::Impact(const TParticle* /* particle */) const
394{
69b696b9 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.
1a1fdef7 400 return kFALSE;
401}
402
9de78b35 403//____________________________________________________________________
404void
405AliFMDGeometry::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
54e415a8 413//____________________________________________________________________
414void
415AliFMDGeometry::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);
f95a63c4 431 AliFMDDebug(1, ("Geometry depths:\n"
54e415a8 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 }
f95a63c4 471 AliFMDDebug(1, ("Geometry offsets:\n"
54e415a8 472 " Sector: %d\n"
473 " Module: %d\n"
474 " Ring: %d\n"
475 " Detector: %d",
476 fSectorOff, fModuleOff, fRingOff, fDetectorOff));
477}
478
479
480//____________________________________________________________________
481static Int_t
482CheckNodes(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//____________________________________________________________________
510Int_t
511FindNodeDepth(const char* name, const char* volname)
512{
02a27b50 513 // Find the depth of a node
54e415a8 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}
54e415a8 531
1a1fdef7 532//____________________________________________________________________
533//
534// EOF
535//