4c039060 |
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 | **************************************************************************/ |
88cb7938 |
15 | |
16 | /* $Id$ */ |
17 | |
4347b38f |
18 | ////////////////////////////////////////////////////////////////////////////// |
19 | // |
37c4363a |
20 | // Forward Multiplicity Detector based on Silicon wafers. This class |
21 | // contains the base procedures for the Forward Multiplicity detector |
22 | // Detector consists of 5 Si volumes covered pseudorapidity interval |
23 | // from 1.7 to 5.1. |
24 | // |
25 | // This is the base class for all FMD manager classes. |
26 | // |
4347b38f |
27 | // The actual code is done by various separate classes. Below is |
28 | // diagram showing the relationship between the various FMD classes |
29 | // that handles the geometry |
30 | // |
31 | // |
32 | // +----------+ +----------+ |
33 | // | AliFMDv1 | | AliFMDv1 | |
34 | // +----------+ +----------+ |
35 | // | | |
36 | // +----+--------------+ |
37 | // | |
38 | // | +------------+ 1 +---------------+ |
39 | // | +- | AliFMDRing |<>--| AliFMDPolygon | |
40 | // V 2 | +------------+ +---------------+ |
41 | // +--------+<>--+ | |
42 | // | AliFMD | ^ |
43 | // +--------+<>--+ V 1..2 |
44 | // 3 | +-------------------+ |
45 | // +-| AliFMDSubDetector | |
46 | // +-------------------+ |
47 | // ^ |
48 | // | |
49 | // +-------------+-------------+ |
50 | // | | | |
51 | // +---------+ +---------+ +---------+ |
52 | // | AliFMD1 | | AliFMD2 | | AliFMD3 | |
53 | // +---------+ +---------+ +---------+ |
54 | // |
55 | // |
56 | // * AliFMD |
57 | // This defines the interface for the various parts of AliROOT that |
58 | // uses the FMD, like AliFMDDigitizer, AliFMDReconstructor, and so |
59 | // on. |
60 | // |
61 | // * AliFMDv1 |
62 | // This is a concrete implementation of the AliFMD interface. |
63 | // It is the responsibility of this class to create the FMD |
64 | // geometry, process hits in the FMD, and serve hits and digits to |
65 | // the various clients. |
66 | // |
67 | // It uses the objects of class AliFMDSubDetector to do the various |
68 | // stuff for FMD1, 2, and 3 |
69 | // |
70 | // * AliFMDRing |
71 | // This class contains all stuff needed to do with a ring. It's |
72 | // used by the AliFMDSubDetector objects to instantise inner and |
73 | // outer rings. The AliFMDRing objects are shared by the |
74 | // AliFMDSubDetector objects, and owned by the AliFMDv1 object. |
75 | // |
76 | // * AliFMDPolygon |
77 | // The code I lifted from TGeoPolygon to help with the geometry of |
78 | // the modules, as well as to decide wether a hit is actually with |
79 | // in the real module shape. The point is, that the shape of the |
80 | // various ring modules are really polygons (much like the lid of a |
81 | // coffin), but it's segmented at constant radius. That is very |
82 | // hard to implement using GEANT 3.21 shapes, so instead the |
83 | // modules are implemented as TUBS (tube sections), and in the step |
84 | // procedure we do the test whether the track was inside the real |
85 | // shape of the module. |
86 | // |
87 | // * AliFMD1, AliFMD2, and AliFMD3 |
88 | // These are specialisation of AliFMDSubDetector, that contains the |
89 | // particularities of each of the sub-detector system. It is |
90 | // envisioned that the classes should also define the support |
91 | // volumes and material for each of the detectors. |
92 | // |
37c4363a |
93 | // The responsible person for this module is Alla Maevskaia |
94 | // <Alla.Maevskaia@cern.ch>. |
95 | // |
96 | // Many modifications by Christian Holm Christensen <cholm@nbi.dk> |
97 | // |
fe4da5cc |
98 | |
4347b38f |
99 | #ifndef ROOT_TClonesArray |
100 | #include <TClonesArray.h> |
101 | #endif |
102 | #ifndef ROOT_TGeomtry |
103 | # include <TGeometry.h> |
104 | #endif |
105 | #ifndef ROOT_TNode |
106 | # include <TNode.h> |
107 | #endif |
108 | #ifndef ROOT_TTUBE |
109 | # include <TTUBE.h> |
110 | #endif |
111 | #ifndef ROOT_TTree |
112 | # include <TTree.h> |
113 | #endif |
114 | #ifndef ROOT_TVirtualMC |
115 | # include <TVirtualMC.h> |
116 | #endif |
117 | #ifndef ROOT_TBrowser |
118 | # include <TBrowser.h> |
119 | #endif |
120 | #ifndef ROOT_TMath |
121 | # include <TMath.h> |
122 | #endif |
88cb7938 |
123 | |
4347b38f |
124 | #ifndef ALIRUNDIGITIZER_H |
125 | # include "AliRunDigitizer.h" |
126 | #endif |
127 | #ifndef ALILOADER_H |
128 | # include "AliLoader.h" |
129 | #endif |
130 | #ifndef ALIRUN_H |
131 | # include "AliRun.h" |
132 | #endif |
133 | #ifndef ALIMC_H |
134 | # include "AliMC.h" |
135 | #endif |
37c4363a |
136 | #ifndef ALILOG_H |
4347b38f |
137 | # include "AliLog.h" |
138 | #endif |
139 | #ifndef ALIMAGF_H |
140 | # include "AliMagF.h" |
141 | #endif |
142 | #ifndef ALIFMD_H |
143 | # include "AliFMD.h" |
144 | #endif |
145 | #ifndef ALIFMDDIGIG_H |
146 | # include "AliFMDDigit.h" |
147 | #endif |
148 | #ifndef ALIFMDHIT_H |
149 | # include "AliFMDHit.h" |
150 | #endif |
151 | #ifndef ALIFMDDIGITIZER_H |
152 | # include "AliFMDDigitizer.h" |
153 | #endif |
154 | #ifndef ALIFMD1_H |
155 | # include "AliFMD1.h" |
156 | #endif |
157 | #ifndef ALIFMD2_H |
158 | # include "AliFMD2.h" |
159 | #endif |
160 | #ifndef ALIFMD3_H |
161 | # include "AliFMD3.h" |
162 | #endif |
163 | #ifndef ALIALTROBUFFER_H |
164 | # include "AliAltroBuffer.h" |
165 | #endif |
88cb7938 |
166 | |
4347b38f |
167 | //____________________________________________________________________ |
168 | ClassImp(AliFMD); |
169 | |
170 | //____________________________________________________________________ |
171 | AliFMD::AliFMD() |
172 | : fInner(0), |
173 | fOuter(0), |
174 | fFMD1(0), |
175 | fFMD2(0), |
afddaa11 |
176 | fFMD3(0), |
177 | fSDigits(0), |
178 | fNsdigits(0), |
179 | fSiDensity(0), |
180 | fPrintboardRotationId(0), |
181 | fIdentityRotationId(0), |
182 | fShortLegId(0), |
183 | fLongLegId(0), |
184 | fLegLength(0), |
185 | fLegRadius(0), |
186 | fModuleSpacing(0) |
fe4da5cc |
187 | { |
188 | // |
189 | // Default constructor for class AliFMD |
190 | // |
4347b38f |
191 | AliDebug(0, "Default CTOR"); |
dc8af42e |
192 | fHits = 0; |
193 | fDigits = 0; |
4347b38f |
194 | fIshunt = 0; |
fe4da5cc |
195 | } |
dc8af42e |
196 | |
4347b38f |
197 | //____________________________________________________________________ |
198 | AliFMD::AliFMD(const char *name, const char *title, bool detailed) |
199 | : AliDetector (name, title), |
200 | fInner(0), |
201 | fOuter(0), |
202 | fFMD1(0), |
203 | fFMD2(0), |
afddaa11 |
204 | fFMD3(0), |
205 | fSDigits(0), |
206 | fNsdigits(0), |
207 | fSiDensity(0), |
208 | fPrintboardRotationId(0), |
209 | fIdentityRotationId(0), |
210 | fShortLegId(0), |
211 | fLongLegId(0), |
212 | fLegLength(0), |
213 | fLegRadius(0), |
214 | fModuleSpacing(0) |
fe4da5cc |
215 | { |
216 | // |
217 | // Standard constructor for Forward Multiplicity Detector |
218 | // |
4347b38f |
219 | AliDebug(0, "Standard CTOR"); |
dc8af42e |
220 | |
fe4da5cc |
221 | // Initialise Hit array |
4347b38f |
222 | HitsArray(); |
223 | gAlice->GetMCApp()->AddHitList(fHits); |
d1280e40 |
224 | |
4347b38f |
225 | // (S)Digits for the detectors disk |
226 | DigitsArray(); |
227 | SDigitsArray(); |
228 | |
229 | // CHC: What is this? |
dc8af42e |
230 | fIshunt = 0; |
4347b38f |
231 | SetMarkerColor(kRed); |
232 | SetLineColor(kYellow); |
233 | SetSiDensity(); |
234 | |
235 | // Create sub-volume managers |
236 | fInner = new AliFMDRing('I', detailed); |
237 | fOuter = new AliFMDRing('O', detailed); |
238 | fFMD1 = new AliFMD1(); |
239 | fFMD2 = new AliFMD2(); |
240 | fFMD3 = new AliFMD3(); |
241 | |
242 | // Specify parameters of sub-volume managers |
243 | fFMD1->SetInner(fInner); |
244 | fFMD1->SetOuter(0); |
245 | |
246 | fFMD2->SetInner(fInner); |
247 | fFMD2->SetOuter(fOuter); |
248 | |
249 | fFMD3->SetInner(fInner); |
250 | fFMD3->SetOuter(fOuter); |
251 | |
252 | SetLegLength(); |
253 | SetLegRadius(); |
254 | SetLegOffset(); |
255 | SetModuleSpacing(); |
256 | |
257 | fInner->SetLowR(4.3); |
258 | fInner->SetHighR(17.2); |
259 | fInner->SetWaferRadius(13.4/2); |
260 | fInner->SetTheta(36/2); |
261 | fInner->SetNStrips(512); |
262 | fInner->SetSiThickness(.03); |
263 | fInner->SetPrintboardThickness(.11); |
264 | fInner->SetBondingWidth(.5); |
265 | |
266 | fOuter->SetLowR(15.6); |
267 | fOuter->SetHighR(28.0); |
268 | fOuter->SetWaferRadius(13.4/2); |
269 | fOuter->SetTheta(18/2); |
270 | fOuter->SetNStrips( 256); |
271 | fOuter->SetSiThickness(.03); |
272 | fOuter->SetPrintboardThickness(.1); |
273 | fOuter->SetBondingWidth(.5); |
274 | |
275 | |
276 | fFMD1->SetHoneycombThickness(1); |
277 | fFMD1->SetInnerZ(340.0); |
278 | |
279 | fFMD2->SetHoneycombThickness(1); |
280 | fFMD2->SetInnerZ(83.4); |
281 | fFMD2->SetOuterZ(75.2); |
282 | |
283 | fFMD3->SetHoneycombThickness(1); |
284 | fFMD3->SetInnerZ(-62.8); |
285 | fFMD3->SetOuterZ(-75.2); |
fe4da5cc |
286 | } |
d28dcc0d |
287 | |
4347b38f |
288 | //____________________________________________________________________ |
dc8af42e |
289 | AliFMD::~AliFMD () |
d28dcc0d |
290 | { |
4347b38f |
291 | // Destructor for base class AliFMD |
292 | if (fHits) { |
293 | fHits->Delete(); |
294 | delete fHits; |
295 | fHits = 0; |
296 | } |
297 | if (fDigits) { |
298 | fDigits->Delete(); |
299 | delete fDigits; |
300 | fDigits = 0; |
301 | } |
302 | if (fSDigits) { |
303 | fSDigits->Delete(); |
304 | delete fSDigits; |
305 | fSDigits = 0; |
306 | } |
307 | } |
308 | |
309 | //==================================================================== |
310 | // |
311 | // GEometry ANd Traking |
312 | // |
313 | //____________________________________________________________________ |
314 | void |
315 | AliFMD::CreateGeometry() |
316 | { |
4347b38f |
317 | // |
37c4363a |
318 | // Create the geometry of Forward Multiplicity Detector. The actual |
319 | // construction of the geometry is delegated to the class AliFMDRing |
320 | // and AliFMDSubDetector and the relevant derived classes. |
321 | // |
322 | // The flow of this member function is: |
323 | // |
324 | // FOR rings fInner and fOuter DO |
325 | // AliFMDRing::Init(); |
326 | // END FOR |
327 | // |
328 | // Set up hybrud card support (leg) volume shapes |
329 | // |
330 | // FOR rings fInner and fOuter DO |
331 | // AliFMDRing::SetupGeometry(); |
332 | // END FOR |
333 | // |
334 | // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO |
335 | // AliFMDSubDetector::SetupGeomtry(); |
336 | // END FOR |
337 | // |
338 | // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO |
339 | // AliFMDSubDetector::Geomtry(); |
340 | // END FOR |
341 | // |
342 | |
4347b38f |
343 | // DebugGuard guard("AliFMD::CreateGeometry"); |
344 | AliDebug(10, "Creating geometry"); |
dc8af42e |
345 | |
4347b38f |
346 | fInner->Init(); |
347 | fOuter->Init(); |
348 | |
349 | TString name; |
350 | Double_t par[3]; |
351 | |
352 | par[0] = fLegRadius - .1; |
353 | par[1] = fLegRadius; |
354 | par[2] = fLegLength / 2; |
42403906 |
355 | name = "FSL"; |
4347b38f |
356 | fShortLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3); |
357 | |
358 | par[2] += fModuleSpacing / 2; |
42403906 |
359 | name = "FLL"; |
4347b38f |
360 | fLongLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3); |
361 | |
362 | fInner->SetupGeometry((*fIdtmed)[kAirId], |
363 | (*fIdtmed)[kSiId], |
364 | (*fIdtmed)[kPcbId], |
365 | fPrintboardRotationId, |
366 | fIdentityRotationId); |
367 | fOuter->SetupGeometry((*fIdtmed)[kAirId], |
368 | (*fIdtmed)[kSiId], |
369 | (*fIdtmed)[kPcbId], |
370 | fPrintboardRotationId, |
371 | fIdentityRotationId); |
372 | |
373 | fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]); |
374 | fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]); |
375 | fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]); |
376 | |
377 | fFMD1->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId); |
378 | fFMD2->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId); |
379 | fFMD3->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId); |
380 | } |
381 | |
382 | //____________________________________________________________________ |
383 | void AliFMD::CreateMaterials() |
384 | { |
385 | // Register various materials and tracking mediums with the |
386 | // backend. |
387 | // |
388 | // Currently defined materials and mediums are |
389 | // |
390 | // FMD Air Normal air |
391 | // FMD Si Active silicon of sensors |
392 | // FMD Carbon Normal carbon used in support, etc. |
393 | // FMD Kapton Carbon used in Honeycomb |
394 | // FMD PCB Printed circuit board material |
395 | // FMD Plastic Material for support legs |
396 | // |
397 | // Also defined are two rotation matricies. |
398 | // |
399 | // DebugGuard guard("AliFMD::CreateMaterials"); |
400 | AliDebug(10, "Creating materials"); |
401 | Int_t id; |
402 | Double_t a = 0; |
403 | Double_t z = 0; |
404 | Double_t density = 0; |
405 | Double_t radiationLength = 0; |
406 | Double_t absorbtionLength = 999; |
407 | Int_t fieldType = gAlice->Field()->Integ(); // Field type |
408 | Double_t maxField = gAlice->Field()->Max(); // Field max. |
409 | Double_t maxBending = 0; // Max Angle |
410 | Double_t maxStepSize = 0.001; // Max step size |
411 | Double_t maxEnergyLoss = 1; // Max Delta E |
412 | Double_t precision = 0.001; // Precision |
413 | Double_t minStepSize = 0.001; // Minimum step size |
414 | |
415 | // Silicon |
416 | a = 28.0855; |
417 | z = 14.; |
418 | density = fSiDensity; |
419 | radiationLength = 9.36; |
420 | maxBending = 1; |
421 | maxStepSize = .001; |
422 | precision = .001; |
423 | minStepSize = .001; |
424 | id = kSiId; |
425 | AliMaterial(id, "FMD Si$", a, z, density, radiationLength, absorbtionLength); |
426 | AliMedium(kSiId, "FMD Si$",id,1,fieldType,maxField,maxBending, |
427 | maxStepSize,maxEnergyLoss,precision,minStepSize); |
428 | |
429 | |
430 | // Carbon |
431 | a = 12.011; |
432 | z = 6.; |
433 | density = 2.265; |
434 | radiationLength = 18.8; |
435 | maxBending = 10; |
436 | maxStepSize = .01; |
437 | precision = .003; |
438 | minStepSize = .003; |
439 | id = kCarbonId; |
440 | AliMaterial(id, "FMD Carbon$", a, z, density, radiationLength, |
441 | absorbtionLength); |
442 | AliMedium(kCarbonId, "FMD Carbon$",id,0,fieldType,maxField,maxBending, |
443 | maxStepSize,maxEnergyLoss,precision,minStepSize); |
444 | |
445 | // Silicon chip |
446 | { |
447 | Float_t as[] = { 12.0107, 14.0067, 15.9994, |
448 | 1.00794, 28.0855, 107.8682 }; |
449 | Float_t zs[] = { 6., 7., 8., |
450 | 1., 14., 47. }; |
451 | Float_t ws[] = { 0.039730642, 0.001396798, 0.01169634, |
452 | 0.004367771, 0.844665, 0.09814344903 }; |
453 | density = 2.36436; |
454 | maxBending = 10; |
455 | maxStepSize = .01; |
456 | precision = .003; |
457 | minStepSize = .003; |
458 | id = kSiChipId; |
459 | AliMixture(id, "FMD Si Chip$", as, zs, density, 6, ws); |
460 | AliMedium(kSiChipId, "FMD Si Chip$", id, 0, fieldType, maxField, |
461 | maxBending, maxStepSize, maxEnergyLoss, precision, minStepSize); |
462 | } |
463 | |
464 | |
465 | // Kaption |
466 | { |
467 | Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994}; |
468 | Float_t zs[] = { 1., 6., 7., 8.}; |
469 | Float_t ws[] = { 0.026362, 0.69113, 0.07327, 0.209235}; |
470 | density = 1.42; |
471 | maxBending = 1; |
472 | maxStepSize = .001; |
473 | precision = .001; |
474 | minStepSize = .001; |
475 | id = kKaptionId; |
476 | AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws); |
477 | AliMedium(kKaptionId, "FMD Kaption$",id,0,fieldType,maxField,maxBending, |
478 | maxStepSize,maxEnergyLoss,precision,minStepSize); |
479 | } |
480 | |
481 | // Air |
482 | { |
483 | Float_t as[] = { 12.0107, 14.0067, 15.9994, 39.948 }; |
484 | Float_t zs[] = { 6., 7., 8., 18. }; |
485 | Float_t ws[] = { 0.000124, 0.755267, 0.231781, 0.012827 }; |
486 | density = .00120479; |
487 | maxBending = 1; |
488 | maxStepSize = .001; |
489 | precision = .001; |
490 | minStepSize = .001; |
491 | id = kAirId; |
492 | AliMixture(id, "FMD Air$", as, zs, density, 4, ws); |
493 | AliMedium(kAirId, "FMD Air$", id,0,fieldType,maxField,maxBending, |
494 | maxStepSize,maxEnergyLoss,precision,minStepSize); |
495 | } |
496 | |
497 | // PCB |
498 | { |
499 | Float_t zs[] = { 14., 20., 13., 12., |
500 | 5., 22., 11., 19., |
501 | 26., 9., 8., 6., |
502 | 7., 1.}; |
503 | Float_t as[] = { 28.0855, 40.078, 26.981538, 24.305, |
504 | 10.811, 47.867, 22.98977, 39.0983, |
505 | 55.845, 18.9984, 15.9994, 12.0107, |
506 | 14.0067, 1.00794}; |
507 | Float_t ws[] = { 0.15144894, 0.08147477, 0.04128158, 0.00904554, |
508 | 0.01397570, 0.00287685, 0.00445114, 0.00498089, |
509 | 0.00209828, 0.00420000, 0.36043788, 0.27529426, |
510 | 0.01415852, 0.03427566}; |
511 | density = 1.8; |
512 | maxBending = 1; |
513 | maxStepSize = .001; |
514 | precision = .001; |
515 | minStepSize = .001; |
516 | id = kPcbId; |
517 | AliMixture(id, "FMD PCB$", as, zs, density, 14, ws); |
518 | AliMedium(kPcbId, "FMD PCB$", id,1,fieldType,maxField,maxBending, |
519 | maxStepSize,maxEnergyLoss,precision,minStepSize); |
520 | } |
521 | |
522 | // Plastic |
523 | { |
524 | Float_t as[] = { 1.01, 12.01 }; |
525 | Float_t zs[] = { 1., 6. }; |
526 | Float_t ws[] = { 1., 1. }; |
527 | density = 1.03; |
528 | maxBending = 10; |
529 | maxStepSize = .01; |
530 | precision = .003; |
531 | minStepSize = .003; |
532 | id = kPlasticId; |
533 | AliMixture(id, "FMD Plastic$", as, zs, density, -2, ws); |
534 | AliMedium(kPlasticId, "FMD Plastic$", id,0,fieldType,maxField,maxBending, |
535 | maxStepSize,maxEnergyLoss,precision,minStepSize); |
536 | } |
537 | AliMatrix(fPrintboardRotationId, 90, 90, 0, 90, 90, 0); |
538 | AliMatrix(fIdentityRotationId, 90, 0, 90, 90, 0, 0); |
d28dcc0d |
539 | } |
dc8af42e |
540 | |
4347b38f |
541 | //____________________________________________________________________ |
542 | void |
543 | AliFMD::Init() |
fe4da5cc |
544 | { |
545 | // |
4347b38f |
546 | // Initialis the FMD after it has been built |
547 | Int_t i; |
548 | // |
549 | if (fDebug) { |
550 | std::cout << "\n" << ClassName() << ": " << std::flush; |
551 | for (i = 0; i < 35; i++) std::cout << "*"; |
552 | std::cout << " FMD_INIT "; |
553 | for (i = 0; i < 35; i++) std::cout << "*"; |
554 | std::cout << "\n" << ClassName() << ": " << std::flush; |
555 | // |
556 | // Here the FMD initialisation code (if any!) |
557 | for (i = 0; i < 80; i++) std::cout << "*"; |
558 | std::cout << std::endl; |
559 | } |
560 | // |
fe4da5cc |
561 | // |
fe4da5cc |
562 | } |
dc8af42e |
563 | |
4347b38f |
564 | //==================================================================== |
565 | // |
566 | // Graphics and event display |
567 | // |
568 | //____________________________________________________________________ |
569 | void |
570 | AliFMD::BuildGeometry() |
b9a2d5e4 |
571 | { |
4347b38f |
572 | // |
573 | // Build simple ROOT TNode geometry for event display |
574 | // |
575 | // Build a simplified geometry of the FMD used for event display |
576 | // |
37c4363a |
577 | // The actual building of the TNodes is done by |
578 | // AliFMDSubDetector::SimpleGeometry. |
4347b38f |
579 | AliDebug(10, "Creating a simplified geometry"); |
b9a2d5e4 |
580 | |
4347b38f |
581 | TNode* top = gAlice->GetGeometry()->GetNode("alice"); |
582 | |
583 | fFMD1->SimpleGeometry(fNodes, top, GetLineColor(), 0); |
584 | fFMD2->SimpleGeometry(fNodes, top, GetLineColor(), 0); |
585 | fFMD3->SimpleGeometry(fNodes, top, GetLineColor(), 0); |
37c55dc0 |
586 | } |
88cb7938 |
587 | |
4347b38f |
588 | //____________________________________________________________________ |
589 | void |
590 | AliFMD::DrawDetector() |
fe4da5cc |
591 | { |
592 | // |
37c4363a |
593 | // Draw a shaded view of the Forward multiplicity detector |
fe4da5cc |
594 | // |
4347b38f |
595 | // DebugGuard guard("AliFMD::DrawDetector"); |
596 | AliDebug(10, "Draw detector"); |
597 | |
598 | //Set ALIC mother transparent |
599 | gMC->Gsatt("ALIC","SEEN",0); |
600 | |
601 | //Set volumes visible |
602 | fFMD1->Gsatt(); |
603 | fFMD2->Gsatt(); |
604 | fFMD3->Gsatt(); |
605 | fInner->Gsatt(); |
606 | fOuter->Gsatt(); |
607 | |
608 | // |
609 | gMC->Gdopt("hide", "on"); |
610 | gMC->Gdopt("shad", "on"); |
611 | gMC->Gsatt("*", "fill", 7); |
612 | gMC->SetClipBox("."); |
613 | gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000); |
614 | gMC->DefaultRange(); |
615 | gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055); |
616 | gMC->Gdhead(1111, "Forward Multiplicity Detector"); |
617 | gMC->Gdman(16, 10, "MAN"); |
618 | gMC->Gdopt("hide", "off"); |
fe4da5cc |
619 | } |
dc8af42e |
620 | |
4347b38f |
621 | //____________________________________________________________________ |
622 | const Int_t |
623 | AliFMD::DistanceToPrimitive(Int_t, Int_t) |
fe4da5cc |
624 | { |
625 | // |
626 | // Calculate the distance from the mouse to the FMD on the screen |
627 | // Dummy routine |
628 | // |
629 | return 9999; |
630 | } |
dc8af42e |
631 | |
4347b38f |
632 | //==================================================================== |
633 | // |
634 | // Hit and Digit managment |
635 | // |
636 | //____________________________________________________________________ |
637 | void |
638 | AliFMD::MakeBranch(Option_t * option) |
639 | { |
640 | // Create Tree branches for the FMD. |
37c4363a |
641 | // |
642 | // Options: |
643 | // |
644 | // H Make a branch of TClonesArray of AliFMDHit's |
645 | // D Make a branch of TClonesArray of AliFMDDigit's |
646 | // S Make a branch of TClonesArray of AliFMDSDigit's |
647 | // |
4347b38f |
648 | const Int_t kBufferSize = 16000; |
649 | TString branchname(GetName()); |
650 | TString opt(option); |
651 | |
652 | if (opt.Contains("H", TString::kIgnoreCase)) { |
653 | HitsArray(); |
654 | AliDetector::MakeBranch(option); |
655 | } |
656 | if (opt.Contains("D", TString::kIgnoreCase)) { |
657 | DigitsArray(); |
658 | MakeBranchInTree(fLoader->TreeD(), branchname.Data(), |
659 | &fDigits, kBufferSize, 0); |
660 | } |
661 | if (opt.Contains("S", TString::kIgnoreCase)) { |
662 | SDigitsArray(); |
663 | MakeBranchInTree(fLoader->TreeS(), branchname.Data(), |
664 | &fSDigits, kBufferSize, 0); |
665 | } |
666 | } |
667 | |
668 | //____________________________________________________________________ |
669 | void |
670 | AliFMD::SetTreeAddress() |
671 | { |
afddaa11 |
672 | // Set branch address for the Hits, Digits, and SDigits Tree. |
4347b38f |
673 | if (fLoader->TreeH()) HitsArray(); |
674 | AliDetector::SetTreeAddress(); |
675 | |
676 | TTree *treeD = fLoader->TreeD(); |
677 | if (treeD) { |
678 | DigitsArray(); |
679 | TBranch* branch = treeD->GetBranch ("FMD"); |
680 | if (branch) branch->SetAddress(&fDigits); |
681 | } |
682 | |
683 | TTree *treeS = fLoader->TreeS(); |
684 | if (treeS) { |
685 | SDigitsArray(); |
686 | TBranch* branch = treeS->GetBranch ("FMD"); |
687 | if (branch) branch->SetAddress(&fSDigits); |
688 | } |
689 | } |
690 | |
691 | |
692 | |
693 | //____________________________________________________________________ |
694 | void |
695 | AliFMD::SetHitsAddressBranch(TBranch *b) |
b9a2d5e4 |
696 | { |
37c4363a |
697 | // Set the TClonesArray to read hits into. |
4347b38f |
698 | b->SetAddress(&fHits); |
b9a2d5e4 |
699 | } |
700 | |
4347b38f |
701 | //____________________________________________________________________ |
702 | void |
703 | AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits) |
704 | { |
705 | // Add a hit to the hits tree |
706 | // |
707 | // The information of the two arrays are decoded as |
708 | // |
709 | // Parameters |
710 | // track Track # |
711 | // ivol[0] [UShort_t ] Detector # |
712 | // ivol[1] [Char_t ] Ring ID |
713 | // ivol[2] [UShort_t ] Sector # |
714 | // ivol[3] [UShort_t ] Strip # |
715 | // hits[0] [Float_t ] Track's X-coordinate at hit |
716 | // hits[1] [Float_t ] Track's Y-coordinate at hit |
717 | // hits[3] [Float_t ] Track's Z-coordinate at hit |
718 | // hits[4] [Float_t ] X-component of track's momentum |
719 | // hits[5] [Float_t ] Y-component of track's momentum |
720 | // hits[6] [Float_t ] Z-component of track's momentum |
721 | // hits[7] [Float_t ] Energy deposited by track |
722 | // hits[8] [Int_t ] Track's particle Id # |
37c4363a |
723 | // hits[9] [Float_t ] Time when the track hit |
724 | // |
725 | // |
4347b38f |
726 | AddHit(track, |
727 | UShort_t(vol[0]), // Detector # |
728 | Char_t(vol[1]), // Ring ID |
729 | UShort_t(vol[2]), // Sector # |
730 | UShort_t(vol[3]), // Strip # |
731 | hits[0], // X |
732 | hits[1], // Y |
733 | hits[2], // Z |
734 | hits[3], // Px |
735 | hits[4], // Py |
736 | hits[5], // Pz |
737 | hits[6], // Energy loss |
738 | Int_t(hits[7]), // PDG |
739 | hits[8]); // Time |
740 | } |
741 | |
742 | //____________________________________________________________________ |
743 | void |
744 | AliFMD::AddHit(Int_t track, |
745 | UShort_t detector, |
746 | Char_t ring, |
747 | UShort_t sector, |
748 | UShort_t strip, |
749 | Float_t x, |
750 | Float_t y, |
751 | Float_t z, |
752 | Float_t px, |
753 | Float_t py, |
754 | Float_t pz, |
755 | Float_t edep, |
756 | Int_t pdg, |
757 | Float_t t) |
b9a2d5e4 |
758 | { |
dc8af42e |
759 | // |
4347b38f |
760 | // Add a hit to the list |
dc8af42e |
761 | // |
4347b38f |
762 | // Parameters: |
763 | // |
764 | // track Track # |
765 | // detector Detector # (1, 2, or 3) |
766 | // ring Ring ID ('I' or 'O') |
767 | // sector Sector # (For inner/outer rings: 0-19/0-39) |
768 | // strip Strip # (For inner/outer rings: 0-511/0-255) |
769 | // x Track's X-coordinate at hit |
770 | // y Track's Y-coordinate at hit |
771 | // z Track's Z-coordinate at hit |
772 | // px X-component of track's momentum |
773 | // py Y-component of track's momentum |
774 | // pz Z-component of track's momentum |
775 | // edep Energy deposited by track |
776 | // pdg Track's particle Id # |
777 | // t Time when the track hit |
778 | // |
779 | TClonesArray& a = *(HitsArray()); |
780 | // Search through the list of already registered hits, and see if we |
781 | // find a hit with the same parameters. If we do, then don't create |
782 | // a new hit, but rather update the energy deposited in the hit. |
783 | // This is done, so that a FLUKA based simulation will get the |
784 | // number of hits right, not just the enerrgy deposition. |
785 | for (Int_t i = 0; i < fNhits; i++) { |
786 | if (!a.At(i)) continue; |
787 | AliFMDHit* hit = static_cast<AliFMDHit*>(a.At(i)); |
788 | if (hit->Detector() == detector |
789 | && hit->Ring() == ring |
790 | && hit->Sector() == sector |
791 | && hit->Strip() == strip |
792 | && hit->Track() == track) { |
37c4363a |
793 | Warning("AddHit", "already had a hit in FMD%d%c[%2d,%3d] for track # %d," |
794 | " adding energy (%f) to that hit (%f) -> %f", |
795 | detector, ring, sector, strip, track, edep, hit->Edep(), |
796 | hit->Edep() + edep); |
4347b38f |
797 | hit->SetEdep(hit->Edep() + edep); |
798 | return; |
799 | } |
800 | } |
801 | // If hit wasn't already registered, do so know. |
802 | new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector, strip, |
803 | x, y, z, px, py, pz, edep, pdg, t); |
804 | fNhits++; |
b9a2d5e4 |
805 | } |
fe4da5cc |
806 | |
4347b38f |
807 | //____________________________________________________________________ |
808 | void |
809 | AliFMD::AddDigit(Int_t* digits) |
fe4da5cc |
810 | { |
4347b38f |
811 | // Add a digit to the Digit tree |
812 | // |
813 | // Paramters |
fe4da5cc |
814 | // |
4347b38f |
815 | // digits[0] [UShort_t] Detector # |
816 | // digits[1] [Char_t] Ring ID |
817 | // digits[2] [UShort_t] Sector # |
818 | // digits[3] [UShort_t] Strip # |
819 | // digits[4] [UShort_t] ADC Count |
820 | // digits[5] [Short_t] ADC Count, -1 if not used |
821 | // digits[6] [Short_t] ADC Count, -1 if not used |
822 | // |
823 | AddDigit(UShort_t(digits[0]), // Detector # |
824 | Char_t(digits[1]), // Ring ID |
825 | UShort_t(digits[2]), // Sector # |
826 | UShort_t(digits[3]), // Strip # |
827 | UShort_t(digits[4]), // ADC Count1 |
828 | Short_t(digits[5]), // ADC Count2 |
829 | Short_t(digits[6])); // ADC Count3 |
830 | } |
831 | |
832 | //____________________________________________________________________ |
833 | void |
834 | AliFMD::AddDigit(UShort_t detector, |
835 | Char_t ring, |
836 | UShort_t sector, |
837 | UShort_t strip, |
838 | UShort_t count1, |
839 | Short_t count2, |
840 | Short_t count3) |
841 | { |
842 | // add a real digit - as coming from data |
843 | // |
844 | // Parameters |
fe4da5cc |
845 | // |
4347b38f |
846 | // detector Detector # (1, 2, or 3) |
847 | // ring Ring ID ('I' or 'O') |
848 | // sector Sector # (For inner/outer rings: 0-19/0-39) |
849 | // strip Strip # (For inner/outer rings: 0-511/0-255) |
850 | // count1 ADC count (a 10-bit word) |
851 | // count2 ADC count (a 10-bit word), or -1 if not used |
852 | // count3 ADC count (a 10-bit word), or -1 if not used |
853 | TClonesArray& a = *(DigitsArray()); |
854 | |
855 | new (a[fNdigits++]) |
856 | AliFMDDigit(detector, ring, sector, strip, count1, count2, count3); |
857 | } |
858 | |
859 | //____________________________________________________________________ |
860 | void |
861 | AliFMD::AddSDigit(Int_t* digits) |
862 | { |
863 | // Add a digit to the SDigit tree |
864 | // |
865 | // Paramters |
b9a2d5e4 |
866 | // |
4347b38f |
867 | // digits[0] [UShort_t] Detector # |
868 | // digits[1] [Char_t] Ring ID |
869 | // digits[2] [UShort_t] Sector # |
870 | // digits[3] [UShort_t] Strip # |
871 | // digits[4] [Float_t] Total energy deposited |
872 | // digits[5] [UShort_t] ADC Count |
873 | // digits[6] [Short_t] ADC Count, -1 if not used |
874 | // digits[7] [Short_t] ADC Count, -1 if not used |
875 | // |
876 | AddSDigit(UShort_t(digits[0]), // Detector # |
877 | Char_t(digits[1]), // Ring ID |
878 | UShort_t(digits[2]), // Sector # |
879 | UShort_t(digits[3]), // Strip # |
880 | Float_t(digits[4]), // Edep |
881 | UShort_t(digits[5]), // ADC Count1 |
882 | Short_t(digits[6]), // ADC Count2 |
883 | Short_t(digits[7])); // ADC Count3 |
884 | } |
885 | |
886 | //____________________________________________________________________ |
887 | void |
888 | AliFMD::AddSDigit(UShort_t detector, |
889 | Char_t ring, |
890 | UShort_t sector, |
891 | UShort_t strip, |
892 | Float_t edep, |
893 | UShort_t count1, |
894 | Short_t count2, |
895 | Short_t count3) |
896 | { |
897 | // add a summable digit |
898 | // |
899 | // Parameters |
b9a2d5e4 |
900 | // |
4347b38f |
901 | // detector Detector # (1, 2, or 3) |
902 | // ring Ring ID ('I' or 'O') |
903 | // sector Sector # (For inner/outer rings: 0-19/0-39) |
904 | // strip Strip # (For inner/outer rings: 0-511/0-255) |
905 | // edep Total energy deposited |
906 | // count1 ADC count (a 10-bit word) |
907 | // count2 ADC count (a 10-bit word), or -1 if not used |
908 | // count3 ADC count (a 10-bit word), or -1 if not used |
37c4363a |
909 | // |
4347b38f |
910 | TClonesArray& a = *(SDigitsArray()); |
911 | |
912 | new (a[fNsdigits++]) |
913 | AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3); |
fe4da5cc |
914 | } |
4347b38f |
915 | |
916 | //____________________________________________________________________ |
917 | void |
918 | AliFMD::ResetSDigits() |
d28dcc0d |
919 | { |
4347b38f |
920 | // |
921 | // Reset number of digits and the digits array for this detector |
922 | // |
923 | fNsdigits = 0; |
924 | if (fSDigits) fSDigits->Clear(); |
925 | } |
926 | |
927 | |
928 | //____________________________________________________________________ |
929 | TClonesArray* |
930 | AliFMD::HitsArray() |
931 | { |
932 | // Initialize hit array if not already, and return pointer to it. |
933 | if (!fHits) { |
934 | fHits = new TClonesArray("AliFMDHit", 1000); |
935 | fNhits = 0; |
936 | } |
937 | return fHits; |
938 | } |
939 | |
940 | //____________________________________________________________________ |
941 | TClonesArray* |
942 | AliFMD::DigitsArray() |
943 | { |
944 | // Initialize digit array if not already, and return pointer to it. |
945 | if (!fDigits) { |
946 | fDigits = new TClonesArray("AliFMDDigit", 1000); |
947 | fNdigits = 0; |
948 | } |
949 | return fDigits; |
950 | } |
951 | |
952 | //____________________________________________________________________ |
953 | TClonesArray* |
954 | AliFMD::SDigitsArray() |
955 | { |
956 | // Initialize digit array if not already, and return pointer to it. |
957 | if (!fSDigits) { |
958 | fSDigits = new TClonesArray("AliFMDSDigit", 1000); |
959 | fNsdigits = 0; |
960 | } |
961 | return fSDigits; |
962 | } |
963 | |
964 | //==================================================================== |
965 | // |
966 | // Digitization |
967 | // |
968 | //____________________________________________________________________ |
969 | void |
970 | AliFMD::Hits2Digits() |
971 | { |
37c4363a |
972 | // Create AliFMDDigit's from AliFMDHit's. This is done by making a |
973 | // AliFMDDigitizer, and executing that code. |
974 | // |
4347b38f |
975 | AliRunDigitizer* manager = new AliRunDigitizer(1, 1); |
976 | manager->SetInputStream(0, "galice.root"); |
977 | manager->SetOutputFile("H2Dfile"); |
dc8af42e |
978 | |
4347b38f |
979 | /* AliDigitizer* dig =*/ CreateDigitizer(manager); |
980 | manager->Exec(""); |
981 | } |
982 | |
983 | //____________________________________________________________________ |
984 | void |
985 | AliFMD::Hits2SDigits() |
986 | { |
37c4363a |
987 | // Create AliFMDSDigit's from AliFMDHit's. This is done by creating |
988 | // an AliFMDSDigitizer object, and executing it. |
989 | // |
4347b38f |
990 | AliDigitizer* sdig = new AliFMDSDigitizer("galice.root"); |
991 | sdig->Exec(""); |
992 | } |
993 | |
dc8af42e |
994 | |
4347b38f |
995 | //____________________________________________________________________ |
996 | AliDigitizer* |
997 | AliFMD::CreateDigitizer(AliRunDigitizer* manager) const |
998 | { |
999 | // Create a digitizer object |
1000 | return new AliFMDDigitizer(manager); |
1001 | } |
b9a2d5e4 |
1002 | |
4347b38f |
1003 | //==================================================================== |
1004 | // |
1005 | // Raw data simulation |
1006 | // |
1007 | //__________________________________________________________________ |
1008 | void |
1009 | AliFMD::Digits2Raw() |
1010 | { |
37c4363a |
1011 | // Turn digits into raw data. |
1012 | // |
1013 | // Digits are read from the Digit branch, and processed to make |
1014 | // three DDL files, one for each of the sub-detectors FMD1, FMD2, |
1015 | // and FMD3. |
1016 | // |
1017 | // The raw data files consists of a header, followed by ALTRO |
1018 | // formatted blocks. |
1019 | // |
1020 | // +-------------+ |
1021 | // | Header | |
1022 | // +-------------+ |
1023 | // | ALTRO Block | |
1024 | // | ... | |
1025 | // +-------------+ |
1026 | // DDL file |
1027 | // |
1028 | // An ALTRO formatted block, in the FMD context, consists of a |
1029 | // number of counts followed by a trailer. |
1030 | // |
1031 | // +------------------+ |
1032 | // | Count | |
1033 | // | ... | |
1034 | // | possible fillers | |
1035 | // +------------------+ |
1036 | // | Trailer | |
1037 | // +------------------+ |
1038 | // ALTRO block |
1039 | // |
1040 | // The counts are listed backwards, that is, starting with the |
1041 | // latest count, and ending in the first. |
1042 | // |
1043 | // Each count consist of 1 or more ADC samples of the VA1_ALICE |
1044 | // pre-amp. signal. Just how many samples are used depends on |
1045 | // whether the ALTRO over samples the pre-amp. Each sample is a |
1046 | // 10-bit word, and the samples are grouped into 40-bit blocks |
1047 | // |
1048 | // +------------------------------------+ |
1049 | // | S(n) | S(n-1) | S(n-2) | S(n-3) | |
1050 | // | ... | ... | ... | ... | |
1051 | // | S(2) | S(1) | AA | AA | |
1052 | // +------------------------------------+ |
1053 | // Counts + possible filler |
1054 | // |
1055 | // The trailer of the number of words of signales, the starting |
1056 | // strip number, the sector number, and the ring ID; each 10-bit |
1057 | // words, packed into 40-bits. |
1058 | // |
1059 | // +------------------------------------+ |
1060 | // | # words | start | sector | ring | |
1061 | // +------------------------------------+ |
1062 | // Trailer |
1063 | // |
1064 | // Note, that this method assumes that the digits are ordered. |
1065 | // |
4347b38f |
1066 | AliFMD* fmd = static_cast<AliFMD*>(gAlice->GetDetector(GetName())); |
1067 | fLoader->LoadDigits(); |
1068 | TTree* digitTree = fLoader->TreeD(); |
1069 | if (!digitTree) { |
1070 | Error("Digits2Raw", "no digit tree"); |
1071 | return; |
1072 | } |
88cb7938 |
1073 | |
4347b38f |
1074 | TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000); |
1075 | fmd->SetTreeAddress(); |
1076 | TBranch* digitBranch = digitTree->GetBranch(GetName()); |
1077 | if (!digitBranch) { |
1078 | Error("Digits2Raw", "no branch for %s", GetName()); |
1079 | return; |
dc8af42e |
1080 | } |
4347b38f |
1081 | digitBranch->SetAddress(&digits); |
1082 | |
0d0e6995 |
1083 | Int_t nEvents = Int_t(digitTree->GetEntries()); |
4347b38f |
1084 | for (Int_t event = 0; event < nEvents; event++) { |
1085 | fmd->ResetDigits(); |
1086 | digitTree->GetEvent(event); |
1087 | |
1088 | Int_t nDigits = digits->GetEntries(); |
1089 | if (nDigits < 1) continue; |
88cb7938 |
1090 | |
dc8af42e |
1091 | |
4347b38f |
1092 | UShort_t prevDetector = 0; |
1093 | Char_t prevRing = '\0'; |
1094 | UShort_t prevSector = 0; |
1095 | // UShort_t prevStrip = 0; |
88cb7938 |
1096 | |
4347b38f |
1097 | // The first seen strip number for a channel |
1098 | UShort_t startStrip = 0; |
1099 | |
1100 | // Which channel number in the ALTRO channel we're at |
1101 | UShort_t offset = 0; |
88cb7938 |
1102 | |
4347b38f |
1103 | // How many times the ALTRO Samples one VA1_ALICE channel |
1104 | Int_t sampleRate = 1; |
b9a2d5e4 |
1105 | |
4347b38f |
1106 | // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel |
1107 | // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' |
1108 | TArrayI channel(128 * sampleRate); |
1109 | |
1110 | // The Altro buffer |
1111 | AliAltroBuffer* altro = 0; |
1112 | |
1113 | // Loop over the digits in the event. Note, that we assume the |
1114 | // the digits are in order in the branch. If they were not, we'd |
1115 | // have to cache all channels before we could write the data to |
1116 | // the ALTRO buffer, or we'd have to set up a map of the digits. |
1117 | for (Int_t i = 0; i < nDigits; i++) { |
1118 | // Get the digit |
1119 | AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i)); |
1120 | |
1121 | UShort_t det = digit->Detector(); |
1122 | Char_t ring = digit->Ring(); |
1123 | UShort_t sector = digit->Sector(); |
1124 | UShort_t strip = digit->Strip(); |
1125 | if (det != prevDetector) { |
1126 | AliDebug(10, Form("FMD: New DDL, was %d, now %d", |
1127 | kBaseDDL + prevDetector - 1, |
1128 | kBaseDDL + det - 1)); |
1129 | // If an altro exists, delete the object, flushing the data to |
1130 | // disk, and closing the file. |
1131 | if (altro) { |
1132 | // When the first argument is false, we write the real |
1133 | // header. |
1134 | AliDebug(10, Form("New altro: Write channel at %d Strip: %d " |
1135 | "Sector: %d Ring: %d", |
1136 | i, startStrip, prevSector, prevRing)); |
1137 | // TPC to FMD translations |
1138 | // |
1139 | // TPC FMD |
1140 | // ----------+----------- |
1141 | // pad | strip |
1142 | // row | sector |
1143 | // sector | ring |
1144 | // |
1145 | altro->WriteChannel(Int_t(startStrip), |
1146 | Int_t(prevSector), |
1147 | Int_t((prevRing == 'I' ? 0 : 1)), |
1148 | channel.fN, channel.fArray, 0); |
1149 | altro->Flush(); |
1150 | altro->WriteDataHeader(kFALSE, kFALSE); |
1151 | delete altro; |
1152 | altro = 0; |
1153 | } |
1154 | |
1155 | prevDetector = det; |
1156 | // Need to open a new DDL! |
1157 | Int_t ddlId = kBaseDDL + det - 1; |
1158 | TString filename(Form("%s_%d.ddl", GetName(), ddlId)); |
1159 | |
1160 | AliDebug(10, Form("New altro buffer with DDL file %s", |
1161 | filename.Data())); |
1162 | AliDebug(10, Form("New altro at %d", i)); |
1163 | // Create a new altro buffer - a `1' as the second argument |
1164 | // means `write mode' |
1165 | altro = new AliAltroBuffer(filename.Data(), 1); |
1166 | |
1167 | // Write a dummy (first argument is true) header to the DDL |
1168 | // file - later on, when we close the file, we write the real |
1169 | // header |
1170 | altro->WriteDataHeader(kTRUE, kFALSE); |
1171 | |
1172 | // Figure out the sample rate |
1173 | if (digit->Count2() > 0) sampleRate = 2; |
1174 | if (digit->Count3() > 0) sampleRate = 3; |
1175 | |
1176 | channel.Set(128 * sampleRate); |
1177 | offset = 0; |
1178 | prevRing = ring; |
1179 | prevSector = sector; |
1180 | startStrip = strip; |
1181 | } |
1182 | else if (offset == 128 |
1183 | || digit->Ring() != prevRing |
1184 | || digit->Sector() != prevSector) { |
1185 | // Force a new Altro channel |
1186 | AliDebug(10, Form("Flushing channel to disk because %s", |
1187 | (offset == 128 ? "channel is full" : |
1188 | (ring != prevRing ? "new ring up" : |
1189 | "new sector up")))); |
1190 | AliDebug(10, Form("New Channel: Write channel at %d Strip: %d " |
1191 | "Sector: %d Ring: %d", |
1192 | i, startStrip, prevSector, prevRing)); |
1193 | altro->WriteChannel(Int_t(startStrip), |
1194 | Int_t(prevSector), |
1195 | Int_t((prevRing == 'I' ? 0 : 1)), |
1196 | channel.fN, channel.fArray, 0); |
1197 | // Reset and update channel variables |
1198 | channel.Reset(0); |
1199 | offset = 0; |
1200 | startStrip = strip; |
1201 | prevRing = ring; |
1202 | prevSector = sector; |
1203 | } |
b9a2d5e4 |
1204 | |
4347b38f |
1205 | // Store the counts of the ADC in the channel buffer |
1206 | channel[offset * sampleRate] = digit->Count1(); |
1207 | if (sampleRate > 1) |
1208 | channel[offset * sampleRate + 1] = digit->Count2(); |
1209 | if (sampleRate > 2) |
1210 | channel[offset * sampleRate + 2] = digit->Count3(); |
1211 | offset++; |
dc8af42e |
1212 | } |
4347b38f |
1213 | // Finally, we need to close the final ALTRO buffer if it wasn't |
1214 | // already |
1215 | if (altro) { |
1216 | altro->Flush(); |
1217 | altro->WriteDataHeader(kFALSE, kFALSE); |
1218 | delete altro; |
1219 | } |
1220 | } |
1221 | fLoader->UnloadDigits(); |
b9a2d5e4 |
1222 | } |
1223 | |
4347b38f |
1224 | //================================================================== |
1225 | // |
1226 | // Various setter functions for the common paramters |
1227 | // |
b9a2d5e4 |
1228 | |
4347b38f |
1229 | //__________________________________________________________________ |
1230 | void |
1231 | AliFMD::SetLegLength(Double_t length) |
1232 | { |
37c4363a |
1233 | // Set lenght of plastic legs that hold the hybrid (print board and |
4347b38f |
1234 | // silicon sensor) onto the honeycomp support |
1235 | // |
1236 | // DebugGuard guard("AliFMD::SetLegLength"); |
37c4363a |
1237 | AliDebug(10, "AliFMD::SetLegLength"); |
4347b38f |
1238 | fLegLength = length; |
1239 | fInner->SetLegLength(fLegLength); |
1240 | fOuter->SetLegLength(fLegLength); |
1241 | } |
b9a2d5e4 |
1242 | |
4347b38f |
1243 | //__________________________________________________________________ |
1244 | void |
1245 | AliFMD::SetLegOffset(Double_t offset) |
1246 | { |
1247 | // Set offset from edge of hybrid to plastic legs that hold the |
1248 | // hybrid (print board and silicon sensor) onto the honeycomp |
1249 | // support |
1250 | // |
1251 | // DebugGuard guard("AliFMD::SetLegOffset"); |
1252 | AliDebug(10, "AliFMD::SetLegOffset"); |
1253 | fInner->SetLegOffset(offset); |
1254 | fOuter->SetLegOffset(offset); |
1255 | } |
4110645f |
1256 | |
4347b38f |
1257 | //__________________________________________________________________ |
1258 | void |
1259 | AliFMD::SetLegRadius(Double_t radius) |
4110645f |
1260 | { |
4347b38f |
1261 | // Set the diameter of the plastic legs that hold the hybrid (print |
1262 | // board and silicon sensor) onto the honeycomp support |
1263 | // |
1264 | // DebugGuard guard("AliFMD::SetLegRadius"); |
1265 | AliDebug(10, "AliFMD::SetLegRadius"); |
1266 | fLegRadius = radius; |
1267 | fInner->SetLegRadius(fLegRadius); |
1268 | fOuter->SetLegRadius(fLegRadius); |
4110645f |
1269 | } |
37c55dc0 |
1270 | |
4347b38f |
1271 | //__________________________________________________________________ |
1272 | void |
1273 | AliFMD::SetModuleSpacing(Double_t spacing) |
85a5290f |
1274 | { |
4347b38f |
1275 | // Set the distance between the front and back sensor modules |
1276 | // (module staggering). |
1277 | // |
1278 | // DebugGuard guard("AliFMD::SetModuleSpacing"); |
1279 | AliDebug(10, "AliFMD::SetModuleSpacing"); |
1280 | fModuleSpacing = spacing; |
1281 | fInner->SetModuleSpacing(fModuleSpacing); |
1282 | fOuter->SetModuleSpacing(fModuleSpacing); |
1283 | } |
1284 | |
1285 | //==================================================================== |
1286 | // |
1287 | // Utility |
1288 | // |
1289 | //__________________________________________________________________ |
1290 | void |
1291 | AliFMD::Browse(TBrowser* b) |
1292 | { |
37c4363a |
1293 | // Browse this object. |
1294 | // |
4347b38f |
1295 | AliDebug(10, "AliFMD::Browse"); |
1296 | AliDetector::Browse(b); |
1297 | if (fInner) b->Add(fInner, "Inner Ring"); |
1298 | if (fOuter) b->Add(fOuter, "Outer Ring"); |
1299 | if (fFMD1) b->Add(fFMD1, "FMD1 SubDetector"); |
1300 | if (fFMD2) b->Add(fFMD2, "FMD2 SubDetector"); |
1301 | if (fFMD3) b->Add(fFMD3, "FMD3 SubDetector"); |
1302 | } |
1303 | |
1304 | |
4347b38f |
1305 | //___________________________________________________________________ |
1306 | // |
1307 | // EOF |
1308 | // |