]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDGeometry.cxx
0. General code clean-up, including messages, and the like.
[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 **************************************************************************/
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>
54e415a8 71#include "AliFMDGeometryBuilder.h"
72#include <TArrayI.h>
73#include <TGeoManager.h>
74#include <TGeoVolume.h>
75#include <TGeoNode.h>
76static Int_t FindNodeDepth(const char* name, const char* volname);
54e415a8 77
1a1fdef7 78
79//====================================================================
80ClassImp(AliFMDGeometry)
81#if 0
82 ; // This is here to keep Emacs for indenting the next line
83#endif
84
85//____________________________________________________________________
86AliFMDGeometry* AliFMDGeometry::fgInstance = 0;
87
88//____________________________________________________________________
89AliFMDGeometry*
90AliFMDGeometry::Instance()
91{
69b696b9 92 // Return (newly created) singleton instance
1a1fdef7 93 if (!fgInstance) fgInstance = new AliFMDGeometry;
94 return fgInstance;
95}
96
97//____________________________________________________________________
98AliFMDGeometry::AliFMDGeometry()
a1f80595 99 : AliGeometry("FMD", "Forward multiplicity"),
100 fBuilder(0)
1a1fdef7 101{
69b696b9 102 // PROTECTED
103 // Default constructor
54e415a8 104 fUseFMD1 = kTRUE;
105 fUseFMD2 = kTRUE;
106 fUseFMD3 = kTRUE;
54e415a8 107 fDetailed = kTRUE;
108 fUseAssembly = kTRUE;
1a1fdef7 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;
54e415a8 115 fActive.Reset(-1);
1a1fdef7 116}
117
69b696b9 118//____________________________________________________________________
119AliFMDGeometry::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),
bf000c32 129 fUseFMD3(other.fUseFMD3),
130 fActive(other.fActive),
54e415a8 131 fDetailed(other.fDetailed),
132 fUseAssembly(other.fUseAssembly)
69b696b9 133{
134 // PROTECTED
135 // Copy constructor
136}
137
138
139
140//____________________________________________________________________
141AliFMDGeometry&
142AliFMDGeometry::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
1a1fdef7 158//____________________________________________________________________
159void
160AliFMDGeometry::Init()
161{
69b696b9 162 // Initialize the the singleton if not done so already
1a1fdef7 163 if (fIsInitialized) return;
164 fInner->Init();
165 fOuter->Init();
166 fFMD1->Init();
167 fFMD2->Init();
168 fFMD3->Init();
169}
170
bf000c32 171//____________________________________________________________________
172void
173AliFMDGeometry::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
54e415a8 185//____________________________________________________________________
186void
187AliFMDGeometry::Build()
188{
189 if (!fBuilder) fBuilder = new AliFMDGeometryBuilder(fDetailed);
190 fBuilder->SetDetailed(fDetailed);
191 fBuilder->UseAssembly(fUseAssembly);
192 fBuilder->Exec();
193}
194
195//____________________________________________________________________
196void
197AliFMDGeometry::SetActive(Int_t* active, Int_t n)
198{
199 fActive.Set(n);
088f8e79 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 }
54e415a8 204}
205
206//____________________________________________________________________
207void
208AliFMDGeometry::AddActive(Int_t active)
209{
210 Int_t n = fActive.fN;
211 fActive.Set(n+1);
212 fActive[n] = active;
213}
214
215//____________________________________________________________________
216Bool_t
217AliFMDGeometry::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}
54e415a8 223
1a1fdef7 224//____________________________________________________________________
225AliFMDDetector*
226AliFMDGeometry::GetDetector(Int_t i) const
227{
69b696b9 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.
1a1fdef7 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//____________________________________________________________________
239AliFMDRing*
240AliFMDGeometry::GetRing(Char_t i) const
241{
69b696b9 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.
1a1fdef7 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//____________________________________________________________________
255void
256AliFMDGeometry::Enable(Int_t i)
257{
69b696b9 258 // Enable the ith detector. i should be one of 1, 2, or 3
1a1fdef7 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//____________________________________________________________________
267void
268AliFMDGeometry::Disable(Int_t i)
269{
69b696b9 270 // Disable the ith detector. i should be one of 1, 2, or 3
1a1fdef7 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//____________________________________________________________________
279void
280AliFMDGeometry::Detector2XYZ(UShort_t detector,
69b696b9 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
1a1fdef7 287{
69b696b9 288 // Translate detector coordinates (detector, ring, sector, strip) to
289 // spatial coordinates (x, y, z) in the master reference frame of
290 // ALICE.
1a1fdef7 291 AliFMDDetector* det = GetDetector(detector);
bf000c32 292 if (!det) {
293 AliWarning(Form("Unknown detector %d", detector));
294 return;
295 }
1a1fdef7 296 det->Detector2XYZ(ring, sector, strip, x, y, z);
297}
298
54e415a8 299//____________________________________________________________________
300Bool_t
301AliFMDGeometry::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
1a1fdef7 328
329//____________________________________________________________________
330void
331AliFMDGeometry::GetGlobal(const AliRecPoint* p,
332 TVector3& pos,
e8d02863 333 TMatrixF& /* mat */) const
1a1fdef7 334{
69b696b9 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.
1a1fdef7 338 GetGlobal(p, pos);
339}
340
341//____________________________________________________________________
342void
343AliFMDGeometry::GetGlobal(const AliRecPoint* p, TVector3& pos) const
344{
69b696b9 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.
1a1fdef7 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//____________________________________________________________________
363Bool_t
364AliFMDGeometry::Impact(const TParticle* /* particle */) const
365{
69b696b9 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.
1a1fdef7 371 return kFALSE;
372}
373
54e415a8 374//____________________________________________________________________
375void
376AliFMDGeometry::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//____________________________________________________________________
442static Int_t
443CheckNodes(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//____________________________________________________________________
471Int_t
472FindNodeDepth(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}
54e415a8 491
1a1fdef7 492//____________________________________________________________________
493//
494// EOF
495//