]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDDetector.cxx
Added AliBalance to PWG2LinkDef.
[u/mrichter/AliRoot.git] / FMD / AliFMDDetector.cxx
CommitLineData
1a1fdef7 1/**************************************************************************
2 * Copyright(c) 2004, 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 AliFMDDetector.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:36:27 2006
19 @brief Sub-detector base class implementation
02a27b50 20 @ingroup FMD_base
c2fc1258 21*/
1a1fdef7 22
23//____________________________________________________________________
24//
6169f936 25// AliFMDDetector.
26//
27// Base class for concrete FMD detectors, like AliFMD1, AliFMD2,
28// AliFMD3.
1a1fdef7 29// Utility class to help implement the FMD geometry. This provides
30// the interface for the concrete geometry implementations of the FMD
31// sub-detectors.
32//
33// The AliFMDGeometry object owns the AliFMDDetector objects
34//
35// Latest changes by Christian Holm Christensen
36//
37#include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
38#include "AliFMDRing.h" // ALIFMDRING_H
bf000c32 39#include "AliLog.h" // ALILOG_H
40#include <TGeoManager.h> // ROOT_TGeoManager
41#include <TGeoMatrix.h> // ROOT_TGeoMatrix
02a27b50 42// #include <TMath.h> // ROOT_TMath
1a1fdef7 43
44//====================================================================
45ClassImp(AliFMDDetector)
46#if 0
47 ; // This is here to keep Emacs for indenting the next line
48#endif
49
50//____________________________________________________________________
51AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer)
52 : TNamed(Form("FMD%d", id), "Forward multiplicity ring"),
53 fId(id),
54 fInner(inner),
bf000c32 55 fOuter(outer),
56 fInnerTransforms(0),
57 fOuterTransforms(0)
1a1fdef7 58{
088f8e79 59 // Constructor
60 //
61 // ID Id of detector (1,2, or 3)
62 // INNER Inner ring geometry
63 // OUTER Outer ring geometry (if any)
64 //
1a1fdef7 65 SetHoneycombThickness();
66 SetAlThickness();
67 SetInnerHoneyLowR(0);
68 SetInnerHoneyHighR(0);
69 SetInnerZ(0);
70 SetOuterZ(0);
71 SetOuterHoneyLowR(0);
72 SetOuterHoneyHighR(0);
73}
74
088f8e79 75//____________________________________________________________________
76AliFMDDetector::AliFMDDetector(const AliFMDDetector& other)
77 : TNamed(other),
78 fId(other.fId),
79 fInner(other.fInner),
bf000c32 80 fOuter(other.fOuter),
81 fInnerTransforms(other.fInnerTransforms),
82 fOuterTransforms(other.fOuterTransforms)
088f8e79 83{
84 // Copy constructor
85 SetHoneycombThickness(other.GetHoneycombThickness());
86 SetAlThickness(other.GetAlThickness());
87 SetInnerHoneyLowR(other.GetInnerHoneyLowR());
88 SetInnerHoneyHighR(other.GetInnerHoneyHighR());
89 SetInnerZ(other.GetInnerZ());
90 SetOuterZ(other.GetOuterZ());
91 SetOuterHoneyLowR(other.GetOuterHoneyLowR());
92 SetOuterHoneyHighR(other.GetOuterHoneyHighR());
93}
94
95//____________________________________________________________________
96AliFMDDetector&
97AliFMDDetector::operator=(const AliFMDDetector& other)
98{
99 // Assignment operator
100 SetName(other.GetName());
101 SetTitle(other.GetTitle());
bf000c32 102 fId = other.fId;
103 fInner = other.fInner;
104 fOuter = other.fOuter;
105 fInnerTransforms = other.fInnerTransforms;
106 fOuterTransforms = other.fOuterTransforms;
088f8e79 107 SetHoneycombThickness(other.GetHoneycombThickness());
108 SetAlThickness(other.GetAlThickness());
109 SetInnerHoneyLowR(other.GetInnerHoneyLowR());
110 SetInnerHoneyHighR(other.GetInnerHoneyHighR());
111 SetInnerZ(other.GetInnerZ());
112 SetOuterZ(other.GetOuterZ());
113 SetOuterHoneyLowR(other.GetOuterHoneyLowR());
114 SetOuterHoneyHighR(other.GetOuterHoneyHighR());
115 return *this;
116}
117
1a1fdef7 118//____________________________________________________________________
119void
120AliFMDDetector::Init()
121{
088f8e79 122 // Initialize.
1a1fdef7 123 if (fInner) {
124 SetInnerHoneyLowR(fInner->GetLowR() + 1.);
125 SetInnerHoneyHighR(fInner->GetHighR() + 1.);
126 }
127 if (fOuter) {
128 SetOuterHoneyLowR(fOuter->GetLowR() + 1.);
129 SetOuterHoneyHighR(fOuter->GetHighR() + 1.);
bf000c32 130 }
131}
132
133//____________________________________________________________________
134Bool_t
135AliFMDDetector::HasAllTransforms(Char_t ring) const
136{
02a27b50 137 // Check if we got all transformations for a given ring. Return
138 // true in that case.
bf000c32 139 AliFMDRing* r = GetRing(ring);
140 if (!r) return kTRUE;
141 TObjArray* matricies = (r == fInner ? fInnerTransforms : fOuterTransforms);
142 if (!matricies) return kTRUE;
143 if (matricies->GetEntries() == r->GetNModules()) return kTRUE;
144 return kFALSE;
145}
146
147#define IS_NODE_THIS(name) \
148 (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
149 (name[3] == 'T' || name[3] == 'B'))
150#define IS_NODE_SENSOR(name) \
151 (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
152
153//____________________________________________________________________
154void
155AliFMDDetector::InitTransformations()
156{
02a27b50 157 // Find all local<->global transformations for this detector.
bf000c32 158 if ((!fInner || (fInner && fInnerTransforms)) &&
159 (!fOuter || (fOuter && fOuterTransforms))) {
160 AliDebug(5, Form("Transforms for FMD%d already registered", fId));
161 return;
162 }
163 AliDebug(5, Form("Initializing transforms for FMD%d", fId));
164 if (!gGeoManager) {
165 AliFatal("No TGeoManager defined");
166 return;
167 }
168 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
169 if (!topVolume) {
170 AliFatal("No top-level volume defined");
171 return;
172 }
173 // Make container of transforms
174 if (fInner && !fInnerTransforms)
175 fInnerTransforms = new TObjArray(fInner->GetNModules());
176 if (fOuter && !fOuterTransforms)
177 fOuterTransforms = new TObjArray(fOuter->GetNModules());
178
179 // Make an iterator
180 TGeoIterator next(topVolume);
181 TGeoNode* node = 0;
182
183 // Find the node corresponding to this detector, and then find the
184 // sensor volumes
185 Bool_t thisNodeFound = kFALSE;
186 Bool_t allInners = HasAllTransforms('I');
187 Bool_t allOuters = HasAllTransforms('O');
188
189 while ((node = static_cast<TGeoNode*>(next()))
190 && !(allInners && allOuters)) {
191 // Get nodes names
192 const Char_t* name = node->GetName();
193 if (!name) continue;
194 AliDebug(50, Form("Got volume %s", name));
195 // Check if this node is this detector
196 // The base offset for numbers in the ASCII table is 48
197 if (IS_NODE_THIS(name)) {
198 AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
199 thisNodeFound = kTRUE;
200 }
201 // if the detector was found, then we're on that branch, and we
202 // check if this node represents a module in that branch.
203 if (thisNodeFound && IS_NODE_SENSOR(name)) {
204 AliDebug(20, Form("Found sensor node '%s' for FMD%d", name, fId));
205 // Get the ring Id.
206 Char_t ringid = name[1];
207
208 // Get the approprate ring
209 AliFMDRing* ring = GetRing(ringid);
210 if (!ring) continue;
211
212 // Check whether we have all the modules we need for this ring,
213 // and if so, go on to the next node.
214 Bool_t& done = (ring == fInner ? allInners : allOuters);
215 if ((done = HasAllTransforms(ringid))) {
216 AliDebug(20, Form("Already has all module transforms for ring %c",
217 ringid));
218 continue;
219 }
220
221 // Get the approprate container
222 TObjArray* matricies = (ringid == 'i' || ringid == 'I'
223 ? fInnerTransforms : fOuterTransforms);
224
225 // Get the copy (module) number, and check that it hasn't
226 // already been added to the container.
227 Int_t copy = node->GetNumber();
228 if (matricies->At(copy)) {
229 AliWarning(Form("Have a transformation for module %d in ring %c",
230 copy, ringid));
231 continue;
232 }
233
234 // Get the global transformation matrix, and store it.
235 TGeoMatrix* trans = new TGeoHMatrix(*(next.GetCurrentMatrix()));
236 matricies->AddAt(trans, copy);
237
238 }
1a1fdef7 239 }
1a1fdef7 240}
241
242//____________________________________________________________________
243AliFMDRing*
244AliFMDDetector::GetRing(Char_t id) const
245{
088f8e79 246 // Get the specified ring
247 //
248 // ID Id of ring ('I' or 'O')
249 //
1a1fdef7 250 switch (id) {
251 case 'i':
252 case 'I': return GetInner();
253 case 'o':
254 case 'O': return GetOuter();
255 }
256 return 0;
257}
258
259//____________________________________________________________________
260Double_t
261AliFMDDetector::GetRingZ(Char_t id) const
262{
088f8e79 263 // Get the z-coordinate specified ring
264 //
265 // ID Id of ring ('I' or 'O')
266 //
1a1fdef7 267 switch (id) {
268 case 'i':
269 case 'I': return GetInnerZ();
270 case 'o':
271 case 'O': return GetOuterZ();
272 }
273 return 0;
274}
bf000c32 275
276//____________________________________________________________________
277TGeoMatrix*
278AliFMDDetector::FindTransform(Char_t ring, UShort_t sector) const
279{
280 // Find the transformation that corresponds to sector sector in ring
281 // ring.
282 TObjArray* matricies = 0;
283 switch (ring) {
284 case 'i': case 'I': matricies = fInnerTransforms; break;
285 case 'o': case 'O': matricies = fOuterTransforms; break;
286 }
287 if (!matricies) {
288 AliWarning(Form("Unknown ring %c of FMD%d", ring, fId));
289 return 0;
290 }
291 UInt_t module = sector / 2;
292 TGeoMatrix* m = static_cast<TGeoMatrix*>(matricies->At(module));
293 if (!m) {
294 AliWarning(Form("No matrix found for sector %d in FMD%d%c",
295 sector, fId, ring));
296 return 0;
297 }
298 return m;
299}
300
301
1a1fdef7 302//____________________________________________________________________
303void
bf000c32 304AliFMDDetector::Detector2XYZ(Char_t ring,
1a1fdef7 305 UShort_t sector,
306 UShort_t strip,
307 Double_t& x,
308 Double_t& y,
309 Double_t& z) const
310{
088f8e79 311 // Translate detector coordinates (this,ring,sector,strip) into
312 // (x,y,z) coordinates (in global reference frame)
1a1fdef7 313 AliFMDRing* r = GetRing(ring);
314 if (!r) return;
bf000c32 315 TGeoMatrix* m = FindTransform(ring, sector);
316 if (!m) return;
317 Double_t rho = r->GetStripRadius(strip);
318 Double_t phi = ((sector % 2) - .5) * r->GetTheta();
319 Double_t siThick = r->GetSiThickness();
320 Double_t modThick = (siThick
321 + r->GetPrintboardThickness()
322 + r->GetCopperThickness()
323 + r->GetChipThickness()
324 + r->GetSpacing());
15b17c89 325 AliDebug(30,Form("Rho %7.3f, angle %7.3f", rho, phi));
bf000c32 326# define DEGRAD TMath::Pi() / 180.
327 Double_t local[] = { rho * TMath::Cos(phi * DEGRAD),
328 rho * TMath::Sin(phi * DEGRAD),
329 -modThick + siThick / 2 };
330 Double_t master[3];
15b17c89 331 AliDebug(30, Form("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
bf000c32 332 m->LocalToMaster(local, master);
15b17c89 333 AliDebug(30, Form("Master (%7.3f,%7.3f,%7.3f)",
bf000c32 334 master[0],master[1],master[2]));
335 x = master[0];
336 y = master[1];
337 z = master[2];
1a1fdef7 338}
339
54e415a8 340//____________________________________________________________________
341Bool_t
342AliFMDDetector::XYZ2Detector(Double_t x,
343 Double_t y,
344 Double_t z,
345 Char_t& ring,
346 UShort_t& sector,
347 UShort_t& strip) const
348{
088f8e79 349 // Translate (x,y,z) coordinates (in global reference frame) into
350 // detector coordinates (this,ring,sector,strip).
54e415a8 351 AliFMDRing* rng = 0;
352 ring = -1;
353 for (int j = 0; j < 2; j++) {
354 rng = GetRing(j == 0 ? 'I' : 'O');
355 if (!rng) continue;
356 Double_t ringZ = GetRingZ(j == 0 ? 'I' : 'O');
357 Double_t modSpace = TMath::Sign(rng->GetModuleSpacing(), ringZ);
358 if (TMath::Abs(z - ringZ) < 0.01 ||
359 TMath::Abs(z - ringZ + modSpace) < 0.01) break;
360 rng = 0;
361 }
362 if (rng && rng->XYZ2Detector(x, y, z - GetRingZ(rng->GetId()),
363 sector, strip)) {
364 ring = rng->GetId();
365 return kTRUE;
366 }
367 return kFALSE;
368}
369
370
371
1a1fdef7 372//____________________________________________________________________
373//
374// EOF
375//