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