Simulation of RAW data (T.Kuhr)
[u/mrichter/AliRoot.git] / TRD / AliTRD.cxx
CommitLineData
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 **************************************************************************/
15
88cb7938 16/* $Id$ */
4c039060 17
fe4da5cc 18///////////////////////////////////////////////////////////////////////////////
19// //
20// Transition Radiation Detector //
21// This class contains the basic functions for the Transition Radiation //
6f1e466d 22// Detector. //
fe4da5cc 23// //
24///////////////////////////////////////////////////////////////////////////////
25
5c7f4665 26#include <stdlib.h>
a2cb5b3d 27#include <Riostream.h>
5c7f4665 28
88cb7938 29#include <TFile.h>
30#include <TGeometry.h>
31#include <TLorentzVector.h>
fe4da5cc 32#include <TMath.h>
fe4da5cc 33#include <TNode.h>
793ff80c 34#include <TPGON.h>
332e9569 35#include <TParticle.h>
88cb7938 36#include <TROOT.h>
37#include <TTree.h>
38#include <TVirtualMC.h>
39
d3f347ff 40#include "AliConst.h"
793ff80c 41#include "AliDigit.h"
88cb7938 42#include "AliLoader.h"
793ff80c 43#include "AliMagF.h"
88cb7938 44#include "AliRun.h"
793ff80c 45#include "AliTRD.h"
793ff80c 46#include "AliTRDdigit.h"
851d3db9 47#include "AliTRDdigitizer.h"
88cb7938 48#include "AliTRDdigitsManager.h"
851d3db9 49#include "AliTRDgeometryFull.h"
88cb7938 50#include "AliTRDgeometryHole.h"
51#include "AliTRDhit.h"
52#include "AliTRDpoints.h"
332e9569 53#include "AliTRDtrackHits.h"
b864d801 54#include "AliTRDrawData.h"
88cb7938 55#include "AliTrackReference.h"
5d12ce38 56#include "AliMC.h"
793ff80c 57
fe4da5cc 58ClassImp(AliTRD)
59
60//_____________________________________________________________________________
61AliTRD::AliTRD()
62{
63 //
64 // Default constructor
65 //
82bbf98a 66
6244debe 67 fIshunt = 0;
68 fGasMix = 0;
69 fHits = 0;
70 fDigits = 0;
5c7f4665 71
6244debe 72 fGeometry = 0;
82bbf98a 73
6244debe 74 fGasDensity = 0;
75 fFoilDensity = 0;
793ff80c 76
6244debe 77 fDrawTR = 0;
332e9569 78 fDisplayType = 0;
79
80 fTrackHits = 0;
81 fHitType = 0;
6244debe 82
fe4da5cc 83}
84
85//_____________________________________________________________________________
86AliTRD::AliTRD(const char *name, const char *title)
87 : AliDetector(name,title)
88{
89 //
90 // Standard constructor for the TRD
91 //
92
5c7f4665 93 // Check that FRAME is there otherwise we have no place where to
94 // put TRD
8230f242 95 AliModule* frame = gAlice->GetModule("FRAME");
96 if (!frame) {
5c7f4665 97 Error("Ctor","TRD needs FRAME to be present\n");
98 exit(1);
99 }
100
d37eec5e 101 // Define the TRD geometry
102 if ((frame->IsVersion() == 0) ||
103 (frame->IsVersion() == 1)) {
851d3db9 104 fGeometry = new AliTRDgeometryFull();
105 }
106 else {
107 Error("Ctor","Could not find valid FRAME version\n");
108 exit(1);
109 }
5c7f4665 110
bdbb05bb 111 // Save the geometry
112 TDirectory* saveDir = gDirectory;
113 gAlice->GetRunLoader()->CdGAFile();
114 fGeometry->Write("TRDgeometry");
115 saveDir->cd();
116
fe4da5cc 117 // Allocate the hit array
f73816f5 118 fHits = new TClonesArray("AliTRDhit" ,405);
5d12ce38 119 gAlice->GetMCApp()->AddHitList(fHits);
99d5402e 120
121 // Allocate the digits array
f73816f5 122 fDigits = 0;
5c7f4665 123
6244debe 124 fIshunt = 0;
125 fGasMix = 1;
793ff80c 126
6244debe 127 fGasDensity = 0;
128 fFoilDensity = 0;
793ff80c 129
6244debe 130 fDrawTR = 0;
131 fDisplayType = 0;
132
332e9569 133 fTrackHits = 0;
134 fHitType = 2;
135
fe4da5cc 136 SetMarkerColor(kWhite);
82bbf98a 137
fe4da5cc 138}
99d5402e 139
140//_____________________________________________________________________________
73ae7b59 141AliTRD::AliTRD(const AliTRD &trd):AliDetector(trd)
8230f242 142{
143 //
144 // Copy constructor
145 //
146
dd9a6ee3 147 ((AliTRD &) trd).Copy(*this);
8230f242 148
149}
150
151//_____________________________________________________________________________
99d5402e 152AliTRD::~AliTRD()
153{
154 //
155 // TRD destructor
156 //
157
158 fIshunt = 0;
159
abaf1f1d 160 if (fGeometry) {
161 delete fGeometry;
332e9569 162 fGeometry = 0;
abaf1f1d 163 }
164 if (fHits) {
165 delete fHits;
332e9569 166 fHits = 0;
abaf1f1d 167 }
bdbb05bb 168// if (fRecPoints) {
169// delete fRecPoints;
170// fRecPoints = 0;
171// }
332e9569 172 if (fTrackHits) {
173 delete fTrackHits;
174 fTrackHits = 0;
6244debe 175 }
5c7f4665 176
177}
178
179//_____________________________________________________________________________
6244debe 180void AliTRD::Hits2Digits()
2ab0c725 181{
182 //
183 // Create digits
184 //
be385a87 185 AliTRDdigitizer digitizer("TRDdigitizer","TRD digitizer class");
186 digitizer.SetDebug(GetDebug());
88cb7938 187
6244debe 188 // Initialization
be385a87 189 digitizer.InitDetector();
6244debe 190
85a5290f 191 if (!fLoader->TreeH()) fLoader->LoadHits("read");
192 fLoader->LoadDigits("recreate");
193 AliRunLoader* runLoader = fLoader->GetRunLoader();
6244debe 194
85a5290f 195 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
be385a87 196 digitizer.Open(runLoader->GetFileName().Data(), iEvent);
197 digitizer.MakeDigits();
198 digitizer.WriteDigits();
6244debe 199 }
200
85a5290f 201 fLoader->UnloadHits();
202 fLoader->UnloadDigits();
6244debe 203}
204
205//_____________________________________________________________________________
206void AliTRD::Hits2SDigits()
207{
208 //
209 // Create summable digits
210 //
be385a87 211 AliTRDdigitizer digitizer("TRDdigitizer","TRD digitizer class");
6244debe 212 // For the summable digits
be385a87 213 digitizer.SetSDigits(kTRUE);
214 digitizer.SetDebug(GetDebug());
6244debe 215
216 // Initialization
be385a87 217 digitizer.InitDetector();
2ab0c725 218
85a5290f 219 if (!fLoader->TreeH()) fLoader->LoadHits("read");
220 fLoader->LoadSDigits("recreate");
221 AliRunLoader* runLoader = fLoader->GetRunLoader();
6244debe 222
85a5290f 223 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
be385a87 224 digitizer.Open(runLoader->GetFileName().Data(), iEvent);
225 digitizer.MakeDigits();
226 digitizer.WriteDigits();
85a5290f 227 }
2ab0c725 228
85a5290f 229 fLoader->UnloadHits();
230 fLoader->UnloadSDigits();
2ab0c725 231 }
6244debe 232
85a5290f 233//_____________________________________________________________________________
c92eb8ad 234AliDigitizer* AliTRD::CreateDigitizer(AliRunDigitizer* manager) const
85a5290f 235{
236 return new AliTRDdigitizer(manager);
6244debe 237}
238
239//_____________________________________________________________________________
240void AliTRD::SDigits2Digits()
241{
242 //
243 // Create final digits from summable digits
244 //
245
abaf1f1d 246 // Create the TRD digitizer
be385a87 247 AliTRDdigitizer digitizer("TRDdigitizer","TRD digitizer class");
248 digitizer.SetDebug(GetDebug());
99d5402e 249
abaf1f1d 250 // Set the parameter
be385a87 251 digitizer.SetEvent(gAlice->GetEvNumber());
abaf1f1d 252
253 // Initialization
be385a87 254 digitizer.InitDetector();
abaf1f1d 255
256 // Read the s-digits via digits manager
be385a87 257 AliTRDdigitsManager sdigitsManager;
88cb7938 258
be385a87 259 sdigitsManager.SetDebug(GetDebug());
260 sdigitsManager.SetSDigits(kTRUE);
261 sdigitsManager.CreateArrays();
88cb7938 262
263 if (!fLoader->TreeS())
264 if (fLoader->LoadSDigits("read"))
265 {
266 Error("SDigits2Digits","Error while reading SDigits for event %d",gAlice->GetEvNumber());
267 return;
268 }
269 if (!fLoader->TreeS()) return;
270
be385a87 271 sdigitsManager.ReadDigits(fLoader->TreeS());
abaf1f1d 272
273 // Add the s-digits to the input list
be385a87 274 digitizer.AddSDigitsManager(&sdigitsManager);
99d5402e 275
abaf1f1d 276 // Convert the s-digits to normal digits
be385a87 277 digitizer.SDigits2Digits();
abaf1f1d 278
279 // Store the digits
88cb7938 280 if (!fLoader->TreeD()) fLoader->MakeTree("D");
be385a87 281 if (digitizer.MakeBranch(fLoader->TreeD())){
282 digitizer.WriteDigits();
abaf1f1d 283 }
99d5402e 284
285}
286
fe4da5cc 287//_____________________________________________________________________________
b864d801 288void AliTRD::Digits2Raw()
289{
290 //
291 // convert digits of the current event to raw data
292 //
293
294 fLoader->LoadDigits();
295 TTree* digits = fLoader->TreeD();
296 if (!digits) {
297 Error("Digits2Raw", "no digits tree");
298 return;
299 }
300
301 AliTRDrawData rawWriter;
302// rawWriter.SetDebug(2);
303 if (!rawWriter.Digits2Raw(digits)) {
304 Error("AliTRD::Digits2Raw","The raw writer could not load the digits tree");
305 }
306
307 fLoader->UnloadDigits();
308
309}
310
311//_____________________________________________________________________________
332e9569 312void AliTRD::AddHit(Int_t track, Int_t det, Float_t *hits, Int_t q
313 , Bool_t inDrift)
fe4da5cc 314{
315 //
316 // Add a hit for the TRD
332e9569 317 //
318 // The data structure is set according to fHitType:
319 // bit0: standard TClonesArray
320 // bit1: compressed trackHits structure
fe4da5cc 321 //
82bbf98a 322
332e9569 323 if (fHitType & 1) {
324 TClonesArray &lhits = *fHits;
325 new(lhits[fNhits++]) AliTRDhit(fIshunt,track,det,hits,q);
326 }
327
328 if (fHitType > 1) {
329 AddHit2(track,det,hits,q,inDrift);
330 }
82bbf98a 331
fe4da5cc 332}
333
334//_____________________________________________________________________________
335void AliTRD::BuildGeometry()
336{
337 //
338 // Create the ROOT TNode geometry for the TRD
339 //
82bbf98a 340
8230f242 341 TNode *node, *top;
fe4da5cc 342 TPGON *pgon;
793ff80c 343
344 Float_t rmin, rmax;
345 Float_t zmax1, zmax2;
db30bf0f 346
347 Int_t iPlan;
793ff80c 348
fe4da5cc 349 const Int_t kColorTRD = 46;
d3f347ff 350
fe4da5cc 351 // Find the top node alice
8230f242 352 top = gAlice->GetGeometry()->GetNode("alice");
d3f347ff 353
db30bf0f 354 if (fDisplayType == 0) {
793ff80c 355
356 pgon = new TPGON("S_TRD","TRD","void",0,360,AliTRDgeometry::Nsect(),4);
357 rmin = AliTRDgeometry::Rmin();
358 rmax = AliTRDgeometry::Rmax();
359 pgon->DefineSection(0,-AliTRDgeometry::Zmax1(),rmax,rmax);
360 pgon->DefineSection(1,-AliTRDgeometry::Zmax2(),rmin,rmax);
361 pgon->DefineSection(2, AliTRDgeometry::Zmax2(),rmin,rmax);
362 pgon->DefineSection(3, AliTRDgeometry::Zmax1(),rmax,rmax);
363 top->cd();
364 node = new TNode("TRD","TRD","S_TRD",0,0,0,"");
365 node->SetLineColor(kColorTRD);
366 fNodes->Add(node);
367
db30bf0f 368 }
369 else if (fDisplayType == 1) {
793ff80c 370
f73816f5 371 Char_t name[7];
372
793ff80c 373 Float_t slope = (AliTRDgeometry::Zmax1() - AliTRDgeometry::Zmax2())
374 / (AliTRDgeometry::Rmax() - AliTRDgeometry::Rmin());
375
332e9569 376 rmin = AliTRDgeometry::Rmin() + AliTRDgeometry::CraHght();
377 rmax = rmin + AliTRDgeometry::CdrHght();
f73816f5 378
379 Float_t thickness = rmin - AliTRDgeometry::Rmin();
380 zmax2 = AliTRDgeometry::Zmax2() + slope * thickness;
793ff80c 381 zmax1 = zmax2 + slope * AliTRDgeometry::DrThick();
793ff80c 382
db30bf0f 383 for (iPlan = 0; iPlan < AliTRDgeometry::Nplan(); iPlan++) {
793ff80c 384
f73816f5 385 sprintf(name,"S_TR1%d",iPlan);
386 pgon = new TPGON(name,"TRD","void",0,360,AliTRDgeometry::Nsect(),4);
387 pgon->DefineSection(0,-zmax1,rmax,rmax);
388 pgon->DefineSection(1,-zmax2,rmin,rmax);
389 pgon->DefineSection(2, zmax2,rmin,rmax);
390 pgon->DefineSection(3, zmax1,rmax,rmax);
391 top->cd();
392 node = new TNode("TRD","TRD",name,0,0,0,"");
393 node->SetLineColor(kColorTRD);
394 fNodes->Add(node);
395
396 Float_t height = AliTRDgeometry::Cheight() + AliTRDgeometry::Cspace();
397 rmin = rmin + height;
398 rmax = rmax + height;
399 zmax1 = zmax1 + slope * height;
400 zmax2 = zmax2 + slope * height;
401
402 }
403
404 thickness += AliTRDgeometry::DrThick();
405 rmin = AliTRDgeometry::Rmin() + thickness;
406 rmax = rmin + AliTRDgeometry::AmThick();
407 zmax2 = AliTRDgeometry::Zmax2() + slope * thickness;
408 zmax1 = zmax2 + slope * AliTRDgeometry::AmThick();
409
db30bf0f 410 for (iPlan = 0; iPlan < AliTRDgeometry::Nplan(); iPlan++) {
f73816f5 411
412 sprintf(name,"S_TR2%d",iPlan);
793ff80c 413 pgon = new TPGON(name,"TRD","void",0,360,AliTRDgeometry::Nsect(),4);
414 pgon->DefineSection(0,-zmax1,rmax,rmax);
415 pgon->DefineSection(1,-zmax2,rmin,rmax);
416 pgon->DefineSection(2, zmax2,rmin,rmax);
417 pgon->DefineSection(3, zmax1,rmax,rmax);
418 top->cd();
419 node = new TNode("TRD","TRD",name,0,0,0,"");
420 node->SetLineColor(kColorTRD);
421 fNodes->Add(node);
422
423 Float_t height = AliTRDgeometry::Cheight() + AliTRDgeometry::Cspace();
424 rmin = rmin + height;
425 rmax = rmax + height;
426 zmax1 = zmax1 + slope * height;
427 zmax2 = zmax2 + slope * height;
428
429 }
430
db30bf0f 431 }
d3f347ff 432
fe4da5cc 433}
434
435//_____________________________________________________________________________
dd9a6ee3 436void AliTRD::Copy(TObject &trd)
8230f242 437{
438 //
439 // Copy function
440 //
441
793ff80c 442 ((AliTRD &) trd).fGasMix = fGasMix;
443 ((AliTRD &) trd).fGeometry = fGeometry;
793ff80c 444 ((AliTRD &) trd).fGasDensity = fGasDensity;
445 ((AliTRD &) trd).fFoilDensity = fFoilDensity;
446 ((AliTRD &) trd).fDrawTR = fDrawTR;
447 ((AliTRD &) trd).fDisplayType = fDisplayType;
332e9569 448 ((AliTRD &) trd).fHitType = fHitType;
8230f242 449
450 //AliDetector::Copy(trd);
451
452}
453
454//_____________________________________________________________________________
82bbf98a 455void AliTRD::CreateGeometry()
fe4da5cc 456{
82bbf98a 457 //
458 // Creates the volumes for the TRD chambers
459 //
82bbf98a 460
461 // Check that FRAME is there otherwise we have no place where to put the TRD
8230f242 462 AliModule* frame = gAlice->GetModule("FRAME");
463 if (!frame) {
851d3db9 464 printf(" The TRD needs the FRAME to be defined first\n");
465 return;
82bbf98a 466 }
d3f347ff 467
851d3db9 468 fGeometry->CreateGeometry(fIdtmed->GetArray() - 1299);
5c7f4665 469
82bbf98a 470}
471
472//_____________________________________________________________________________
473void AliTRD::CreateMaterials()
474{
fe4da5cc 475 //
476 // Create the materials for the TRD
477 // Origin Y.Foka
478 //
479
8230f242 480 Int_t isxfld = gAlice->Field()->Integ();
481 Float_t sxmgmx = gAlice->Field()->Max();
fe4da5cc 482
d3f347ff 483 // For polyethilene (CH2)
484 Float_t ape[2] = { 12., 1. };
485 Float_t zpe[2] = { 6., 1. };
486 Float_t wpe[2] = { 1., 2. };
487 Float_t dpe = 0.95;
488
489 // For mylar (C5H4O2)
490 Float_t amy[3] = { 12., 1., 16. };
491 Float_t zmy[3] = { 6., 1., 8. };
492 Float_t wmy[3] = { 5., 4., 2. };
fe4da5cc 493 Float_t dmy = 1.39;
d3f347ff 494
495 // For CO2
496 Float_t aco[2] = { 12., 16. };
497 Float_t zco[2] = { 6., 8. };
498 Float_t wco[2] = { 1., 2. };
499 Float_t dco = 0.001977;
500
501 // For water
502 Float_t awa[2] = { 1., 16. };
503 Float_t zwa[2] = { 1., 8. };
504 Float_t wwa[2] = { 2., 1. };
505 Float_t dwa = 1.0;
506
507 // For isobutane (C4H10)
508 Float_t ais[2] = { 12., 1. };
509 Float_t zis[2] = { 6., 1. };
510 Float_t wis[2] = { 4., 10. };
511 Float_t dis = 0.00267;
512
db30bf0f 513 // For plexiglas (C5H8O2)
514 Float_t apg[3] = { 12.011 , 1.0 , 15.9994 };
515 Float_t zpg[3] = { 6.0 , 1.0 , 8.0 };
516 Float_t wpg[3] = { 5.0 , 8.0 , 2.0 };
517 Float_t dpg = 1.18;
518
d3f347ff 519 // For Xe/CO2-gas-mixture
db30bf0f 520 // Xe-content of the Xe/CO2-mixture (85% / 15%)
521 Float_t fxc = .85;
d3f347ff 522 // Xe-content of the Xe/Isobutane-mixture (97% / 3%)
523 Float_t fxi = .97;
fe4da5cc 524 Float_t dxe = .005858;
525
d3f347ff 526 // General tracking parameter
fe4da5cc 527 Float_t tmaxfd = -10.;
528 Float_t stemax = -1e10;
d3f347ff 529 Float_t deemax = -0.1;
530 Float_t epsil = 1e-4;
531 Float_t stmin = -0.001;
fe4da5cc 532
533 Float_t absl, radl, d, buf[1];
793ff80c 534 Float_t agm[2], zgm[2], wgm[2];
535 Float_t dgm1, dgm2;
d3f347ff 536 Int_t nbuf;
fe4da5cc 537
d3f347ff 538 //////////////////////////////////////////////////////////////////////////
fe4da5cc 539 // Define Materials
d3f347ff 540 //////////////////////////////////////////////////////////////////////////
541
16bf9884 542 AliMaterial( 1, "Al" , 26.98, 13.0, 2.7 , 8.9 , 37.2);
543 AliMaterial( 2, "Air" , 14.61, 7.3, 0.001205, 30420.0 , 67500.0);
544 AliMaterial( 4, "Xe" , 131.29, 54.0, dxe , 1447.59, 0.0);
545 AliMaterial( 5, "Cu" , 63.54, 29.0, 8.96 , 1.43, 14.8);
546 AliMaterial( 6, "C" , 12.01, 6.0, 2.265 , 18.8 , 74.4);
547 AliMaterial(12, "G10" , 20.00, 10.0, 1.7 , 19.4 , 999.0);
548 AliMaterial(15, "Sn" , 118.71, 50.0, 7.31 , 1.21, 14.8);
549 AliMaterial(16, "Si" , 28.09, 14.0, 2.33 , 9.36, 37.2);
550 AliMaterial(17, "Epoxy", 17.75, 8.9, 1.8 , 21.82, 999.0);
d3f347ff 551
552 // Mixtures
db30bf0f 553 AliMixture(3, "Polyethilene", ape, zpe, dpe, -2, wpe);
554 AliMixture(7, "Mylar", amy, zmy, dmy, -3, wmy);
555 AliMixture(8, "CO2", aco, zco, dco, -2, wco);
556 AliMixture(9, "Isobutane", ais, zis, dis, -2, wis);
557 AliMixture(13,"Water", awa, zwa, dwa, -2, wwa);
558 AliMixture(14,"Plexiglas", apg, zpg, dpg, -3, wpg);
d3f347ff 559
560 // Gas mixtures
00d6d986 561 Char_t namate[21]="";
d3f347ff 562 // Xe/CO2-mixture
563 // Get properties of Xe
cfce8870 564 gMC->Gfmate((*fIdmate)[4], namate, agm[0], zgm[0], d, radl, absl, buf, nbuf);
d3f347ff 565 // Get properties of CO2
cfce8870 566 gMC->Gfmate((*fIdmate)[8], namate, agm[1], zgm[1], d, radl, absl, buf, nbuf);
d3f347ff 567 // Create gas mixture
568 wgm[0] = fxc;
569 wgm[1] = 1. - fxc;
793ff80c 570 dgm1 = wgm[0] * dxe + wgm[1] * dco;
db30bf0f 571 AliMixture(10, "Gas mixture 1", agm, zgm, dgm1, 2, wgm);
d3f347ff 572 // Xe/Isobutane-mixture
573 // Get properties of Xe
cfce8870 574 gMC->Gfmate((*fIdmate)[4], namate, agm[0], zgm[0], d, radl, absl, buf, nbuf);
d3f347ff 575 // Get properties of Isobutane
cfce8870 576 gMC->Gfmate((*fIdmate)[9], namate, agm[1], zgm[1], d, radl, absl, buf, nbuf);
d3f347ff 577 // Create gas mixture
578 wgm[0] = fxi;
579 wgm[1] = 1. - fxi;
793ff80c 580 dgm2 = wgm[0] * dxe + wgm[1] * dis;
db30bf0f 581 AliMixture(11, "Gas mixture 2", agm, zgm, dgm2, 2, wgm);
d3f347ff 582
583 //////////////////////////////////////////////////////////////////////////
fe4da5cc 584 // Tracking Media Parameters
d3f347ff 585 //////////////////////////////////////////////////////////////////////////
586
587 // Al Frame
db30bf0f 588 AliMedium(1, "Al Frame", 1, 0, isxfld, sxmgmx
d3f347ff 589 , tmaxfd, stemax, deemax, epsil, stmin);
590 // Air
db30bf0f 591 AliMedium(2, "Air", 2, 0, isxfld, sxmgmx
d3f347ff 592 , tmaxfd, stemax, deemax, epsil, stmin);
593 // Polyethilene
db30bf0f 594 AliMedium(3, "Radiator", 3, 0, isxfld, sxmgmx
d3f347ff 595 , tmaxfd, stemax, deemax, epsil, stmin);
596 // Xe
db30bf0f 597 AliMedium(4, "Xe", 4, 1, isxfld, sxmgmx
d3f347ff 598 , tmaxfd, stemax, deemax, epsil, stmin);
599 // Cu pads
db30bf0f 600 AliMedium(5, "Padplane", 5, 1, isxfld, sxmgmx
d3f347ff 601 , tmaxfd, stemax, deemax, epsil, stmin);
602 // Fee + cables
db30bf0f 603 AliMedium(6, "Readout", 1, 0, isxfld, sxmgmx
d3f347ff 604 , tmaxfd, stemax, deemax, epsil, stmin);
605 // C frame
db30bf0f 606 AliMedium(7, "C Frame", 6, 0, isxfld, sxmgmx
d3f347ff 607 , tmaxfd, stemax, deemax, epsil, stmin);
608 // Mylar foils
db30bf0f 609 AliMedium(8, "Mylar", 7, 0, isxfld, sxmgmx
d3f347ff 610 , tmaxfd, stemax, deemax, epsil, stmin);
611 if (fGasMix == 1) {
612 // Gas-mixture (Xe/CO2)
db30bf0f 613 AliMedium(9, "Gas-mix", 10, 1, isxfld, sxmgmx
d3f347ff 614 , tmaxfd, stemax, deemax, epsil, stmin);
615 }
616 else {
617 // Gas-mixture (Xe/Isobutane)
db30bf0f 618 AliMedium(9, "Gas-mix", 11, 1, isxfld, sxmgmx
d3f347ff 619 , tmaxfd, stemax, deemax, epsil, stmin);
620 }
621 // Nomex-honeycomb (use carbon for the time being)
db30bf0f 622 AliMedium(10, "Nomex", 6, 0, isxfld, sxmgmx
d3f347ff 623 , tmaxfd, stemax, deemax, epsil, stmin);
624 // Kapton foils (use Mylar for the time being)
db30bf0f 625 AliMedium(11, "Kapton", 7, 0, isxfld, sxmgmx
d3f347ff 626 , tmaxfd, stemax, deemax, epsil, stmin);
627 // Gas-filling of the radiator
db30bf0f 628 AliMedium(12, "CO2", 8, 0, isxfld, sxmgmx
d3f347ff 629 , tmaxfd, stemax, deemax, epsil, stmin);
630 // G10-plates
db30bf0f 631 AliMedium(13, "G10-plates",12, 0, isxfld, sxmgmx
d3f347ff 632 , tmaxfd, stemax, deemax, epsil, stmin);
633 // Cooling water
db30bf0f 634 AliMedium(14, "Water", 13, 0, isxfld, sxmgmx
635 , tmaxfd, stemax, deemax, epsil, stmin);
636 // Rohacell (plexiglas) for the radiator
637 AliMedium(15, "Rohacell", 14, 0, isxfld, sxmgmx
d3f347ff 638 , tmaxfd, stemax, deemax, epsil, stmin);
16bf9884 639 // Al layer in MCMs
640 AliMedium(16, "MCM-Al" , 1, 0, isxfld, sxmgmx
641 , tmaxfd, stemax, deemax, epsil, stmin);
642 // Sn layer in MCMs
643 AliMedium(17, "MCM-Sn" , 15, 0, isxfld, sxmgmx
644 , tmaxfd, stemax, deemax, epsil, stmin);
645 // Cu layer in MCMs
646 AliMedium(18, "MCM-Cu" , 5, 0, isxfld, sxmgmx
647 , tmaxfd, stemax, deemax, epsil, stmin);
648 // G10 layer in MCMs
649 AliMedium(19, "MCM-G10" , 12, 0, isxfld, sxmgmx
650 , tmaxfd, stemax, deemax, epsil, stmin);
651 // Si in readout chips
652 AliMedium(20, "Chip-Si" , 16, 0, isxfld, sxmgmx
653 , tmaxfd, stemax, deemax, epsil, stmin);
654 // Epoxy in readout chips
655 AliMedium(21, "Chip-Ep" , 17, 0, isxfld, sxmgmx
656 , tmaxfd, stemax, deemax, epsil, stmin);
657 // PE in connectors
658 AliMedium(22, "Conn-PE" , 3, 0, isxfld, sxmgmx
659 , tmaxfd, stemax, deemax, epsil, stmin);
660 // Cu in connectors
661 AliMedium(23, "Chip-Cu" , 5, 0, isxfld, sxmgmx
662 , tmaxfd, stemax, deemax, epsil, stmin);
663 // Al of cooling pipes
664 AliMedium(24, "Cooling" , 1, 0, isxfld, sxmgmx
665 , tmaxfd, stemax, deemax, epsil, stmin);
73ae7b59 666 // Cu in services
667 AliMedium(25, "Serv-Cu" , 5, 0, isxfld, sxmgmx
668 , tmaxfd, stemax, deemax, epsil, stmin);
d3f347ff 669
793ff80c 670 // Save the density values for the TRD absorbtion
671 fFoilDensity = dmy;
672 if (fGasMix == 1)
673 fGasDensity = dgm1;
674 else
675 fGasDensity = dgm2;
676
fe4da5cc 677}
678
679//_____________________________________________________________________________
0a29d0f1 680void AliTRD::DrawModule() const
82bbf98a 681{
682 //
683 // Draw a shaded view of the Transition Radiation Detector version 0
684 //
685
686 // Set everything unseen
687 gMC->Gsatt("*" ,"SEEN",-1);
688
689 // Set ALIC mother transparent
690 gMC->Gsatt("ALIC","SEEN", 0);
691
692 // Set the volumes visible
851d3db9 693 if (fGeometry->IsVersion() == 0) {
5c7f4665 694 gMC->Gsatt("B071","SEEN", 0);
695 gMC->Gsatt("B074","SEEN", 0);
696 gMC->Gsatt("B075","SEEN", 0);
697 gMC->Gsatt("B077","SEEN", 0);
698 gMC->Gsatt("BTR1","SEEN", 0);
699 gMC->Gsatt("BTR2","SEEN", 0);
700 gMC->Gsatt("BTR3","SEEN", 0);
332e9569 701 gMC->Gsatt("UTR1","SEEN", 0);
702 gMC->Gsatt("UTR2","SEEN", 0);
703 gMC->Gsatt("UTR3","SEEN", 0);
5c7f4665 704 }
705 else {
706 gMC->Gsatt("B071","SEEN", 0);
707 gMC->Gsatt("B074","SEEN", 0);
708 gMC->Gsatt("B075","SEEN", 0);
709 gMC->Gsatt("B077","SEEN", 0);
710 gMC->Gsatt("BTR1","SEEN", 0);
711 gMC->Gsatt("BTR2","SEEN", 0);
712 gMC->Gsatt("BTR3","SEEN", 0);
332e9569 713 gMC->Gsatt("UTR1","SEEN", 0);
6f1e466d 714 if (fGeometry->GetPHOShole())
332e9569 715 gMC->Gsatt("UTR2","SEEN", 0);
6f1e466d 716 if (fGeometry->GetRICHhole())
332e9569 717 gMC->Gsatt("UTR3","SEEN", 0);
5c7f4665 718 }
332e9569 719// gMC->Gsatt("UCII","SEEN", 0);
720// gMC->Gsatt("UCIM","SEEN", 0);
721// gMC->Gsatt("UCIO","SEEN", 0);
722// gMC->Gsatt("UL02","SEEN", 1);
723// gMC->Gsatt("UL05","SEEN", 1);
724// gMC->Gsatt("UL06","SEEN", 1);
82bbf98a 725
726 gMC->Gdopt("hide", "on");
727 gMC->Gdopt("shad", "on");
728 gMC->Gsatt("*", "fill", 7);
729 gMC->SetClipBox(".");
730 gMC->SetClipBox("*", 0, 2000, -2000, 2000, -2000, 2000);
731 gMC->DefaultRange();
732 gMC->Gdraw("alic", 40, 30, 0, 12, 9.4, .021, .021);
733 gMC->Gdhead(1111, "Transition Radiation Detector");
734 gMC->Gdman(18, 4, "MAN");
735
736}
737
738//_____________________________________________________________________________
0a29d0f1 739Int_t AliTRD::DistancetoPrimitive(Int_t , Int_t ) const
fe4da5cc 740{
741 //
742 // Distance between the mouse and the TRD detector on the screen
743 // Dummy routine
82bbf98a 744
745 return 9999;
746
fe4da5cc 747}
748
749//_____________________________________________________________________________
750void AliTRD::Init()
751{
752 //
851d3db9 753 // Initialize the TRD detector after the geometry has been created
fe4da5cc 754 //
82bbf98a 755
5c7f4665 756 Int_t i;
851d3db9 757
abaf1f1d 758 if (fDebug) {
9e1a0ddb 759 printf("\n%s: ",ClassName());
760 for (i = 0; i < 35; i++) printf("*");
761 printf(" TRD_INIT ");
762 for (i = 0; i < 35; i++) printf("*");
763 printf("\n");
764 }
5c7f4665 765
d37eec5e 766 if (fGeometry->IsVersion() == 1) {
767 printf("%s: Full geometry version initialized\n",ClassName());
6f1e466d 768 if (fGeometry->GetPHOShole())
9e1a0ddb 769 printf("%s: Leave space in front of PHOS free\n",ClassName());
6f1e466d 770 if (fGeometry->GetRICHhole())
9e1a0ddb 771 printf("%s: Leave space in front of RICH free\n",ClassName());
5c7f4665 772 }
d37eec5e 773 else {
774 printf("%s: Not a valid geometry\n",ClassName());
775 }
9e1a0ddb 776
abaf1f1d 777 if (fGasMix == 1) {
db30bf0f 778 printf("%s: Gas Mixture: 85%% Xe + 15%% CO2\n",ClassName());
abaf1f1d 779 }
780 else {
9e1a0ddb 781 printf("%s: Gas Mixture: 97%% Xe + 3%% Isobutane\n",ClassName());
abaf1f1d 782 }
5c7f4665 783
784}
785
786//_____________________________________________________________________________
73ae7b59 787void AliTRD::LoadPoints(Int_t )
793ff80c 788{
789 //
790 // Store x, y, z of all hits in memory.
791 // Hit originating from TR photons are given a different color
792 //
793
332e9569 794 //if (!fDrawTR) {
795 // AliDetector::LoadPoints(track);
796 // return;
797 //}
793ff80c 798
332e9569 799 if ((fHits == 0) && (fTrackHits == 0)) return;
793ff80c 800
332e9569 801 Int_t nhits;
802 if (fHitType < 2) {
803 nhits = fHits->GetEntriesFast();
804 }
805 else {
806 nhits = fTrackHits->GetEntriesFast();
807 }
793ff80c 808 if (nhits == 0) return;
809
5d12ce38 810 Int_t tracks = gAlice->GetMCApp()->GetNtrack();
793ff80c 811 if (fPoints == 0) fPoints = new TObjArray(tracks);
812
813 AliTRDhit *ahit;
814
815 Int_t *ntrkE = new Int_t[tracks];
816 Int_t *ntrkT = new Int_t[tracks];
817 Int_t *limiE = new Int_t[tracks];
818 Int_t *limiT = new Int_t[tracks];
819 Float_t **coorE = new Float_t*[tracks];
820 Float_t **coorT = new Float_t*[tracks];
821 for(Int_t i = 0; i < tracks; i++) {
822 ntrkE[i] = 0;
823 ntrkT[i] = 0;
824 coorE[i] = 0;
825 coorT[i] = 0;
826 limiE[i] = 0;
827 limiT[i] = 0;
828 }
829
332e9569 830 AliTRDpoints *points = 0;
831 Float_t *fp = 0;
832 Int_t trk;
833 Int_t chunk = nhits / 4 + 1;
793ff80c 834
835 // Loop over all the hits and store their position
332e9569 836 ahit = (AliTRDhit *) FirstHit(-1);
837 while (ahit) {
793ff80c 838
839 // dEdx hits
332e9569 840 if (ahit->GetCharge() >= 0) {
793ff80c 841
842 trk = ahit->GetTrack();
843 if (ntrkE[trk] == limiE[trk]) {
844 // Initialise a new track
845 fp = new Float_t[3*(limiE[trk]+chunk)];
846 if (coorE[trk]) {
847 memcpy(fp,coorE[trk],sizeof(Float_t)*3*limiE[trk]);
848 delete [] coorE[trk];
849 }
850 limiE[trk] += chunk;
851 coorE[trk] = fp;
852 }
853 else {
854 fp = coorE[trk];
855 }
856 fp[3*ntrkE[trk] ] = ahit->X();
857 fp[3*ntrkE[trk]+1] = ahit->Y();
858 fp[3*ntrkE[trk]+2] = ahit->Z();
859 ntrkE[trk]++;
860
861 }
862 // TR photon hits
332e9569 863 else if ((ahit->GetCharge() < 0) && (fDrawTR)) {
793ff80c 864
865 trk = ahit->GetTrack();
866 if (ntrkT[trk] == limiT[trk]) {
867 // Initialise a new track
868 fp = new Float_t[3*(limiT[trk]+chunk)];
869 if (coorT[trk]) {
870 memcpy(fp,coorT[trk],sizeof(Float_t)*3*limiT[trk]);
871 delete [] coorT[trk];
872 }
873 limiT[trk] += chunk;
874 coorT[trk] = fp;
875 }
876 else {
877 fp = coorT[trk];
878 }
879 fp[3*ntrkT[trk] ] = ahit->X();
880 fp[3*ntrkT[trk]+1] = ahit->Y();
881 fp[3*ntrkT[trk]+2] = ahit->Z();
882 ntrkT[trk]++;
883
884 }
885
332e9569 886 ahit = (AliTRDhit *) NextHit();
887
793ff80c 888 }
889
890 for (trk = 0; trk < tracks; ++trk) {
891
892 if (ntrkE[trk] || ntrkT[trk]) {
893
894 points = new AliTRDpoints();
895 points->SetDetector(this);
896 points->SetParticle(trk);
897
898 // Set the dEdx points
899 if (ntrkE[trk]) {
900 points->SetMarkerColor(GetMarkerColor());
901 points->SetMarkerSize(GetMarkerSize());
902 points->SetPolyMarker(ntrkE[trk],coorE[trk],GetMarkerStyle());
903 delete [] coorE[trk];
904 coorE[trk] = 0;
905 }
906
907 // Set the TR photon points
908 if (ntrkT[trk]) {
909 points->SetTRpoints(ntrkT[trk],coorT[trk]);
910 delete [] coorT[trk];
911 coorT[trk] = 0;
912 }
913
914 fPoints->AddAt(points,trk);
915
916 }
917
918 }
919
920 delete [] coorE;
921 delete [] coorT;
922 delete [] ntrkE;
923 delete [] ntrkT;
924 delete [] limiE;
925 delete [] limiT;
926
927}
928
929//_____________________________________________________________________________
88cb7938 930void AliTRD::MakeBranch(Option_t* option)
5c7f4665 931{
932 //
abaf1f1d 933 // Create Tree branches for the TRD digits.
5c7f4665 934 //
935
abaf1f1d 936 Int_t buffersize = 4000;
937 Char_t branchname[15];
938 sprintf(branchname,"%s",GetName());
5c7f4665 939
aa9d00f0 940 const char *cD = strstr(option,"D");
941
88cb7938 942 AliDetector::MakeBranch(option);
5c7f4665 943
abaf1f1d 944 if (fDigits && gAlice->TreeD() && cD) {
88cb7938 945 MakeBranchInTree(gAlice->TreeD(),branchname,&fDigits,buffersize,0);
abaf1f1d 946 }
947
332e9569 948 if (fHitType > 1) {
88cb7938 949 MakeBranch2(option,0);
332e9569 950 }
951
851d3db9 952}
953
954//_____________________________________________________________________________
6244debe 955void AliTRD::ResetDigits()
956{
957 //
abaf1f1d 958 // Reset number of digits and the digits array for this detector
6244debe 959 //
960
abaf1f1d 961 fNdigits = 0;
962 if (fDigits) fDigits->Clear();
6244debe 963
964}
965
966//_____________________________________________________________________________
5c7f4665 967void AliTRD::SetTreeAddress()
968{
969 //
970 // Set the branch addresses for the trees.
971 //
972
88cb7938 973 if ( fLoader->TreeH() && (fHits == 0x0)) fHits = new TClonesArray("AliTRDhit",405);
5c7f4665 974 AliDetector::SetTreeAddress();
975
332e9569 976 if (fHitType > 0) {
977 SetTreeAddress2();
978 }
979
fe4da5cc 980}
981
d3f347ff 982//_____________________________________________________________________________
b060c36f 983void AliTRD::SetGasMix(Int_t imix)
d3f347ff 984{
82bbf98a 985 //
986 // Defines the gas mixture (imix=0: Xe/Isobutane imix=1: Xe/CO2)
987 //
988
d3f347ff 989 if ((imix < 0) || (imix > 1)) {
990 printf("Wrong input value: %d\n",imix);
991 printf("Use standard setting\n");
6244debe 992 fGasMix = 1;
d3f347ff 993 return;
994 }
995
996 fGasMix = imix;
997
998}
999
dd9a6ee3 1000//_____________________________________________________________________________
793ff80c 1001void AliTRD::SetPHOShole()
1002{
1003 //
1004 // Selects a geometry with a hole in front of the PHOS
1005 //
1006
1007 fGeometry->SetPHOShole();
1008
1009}
1010
1011//_____________________________________________________________________________
1012void AliTRD::SetRICHhole()
1013{
1014 //
1015 // Selects a geometry with a hole in front of the RICH
1016 //
1017
1018 fGeometry->SetRICHhole();
1019
1020}
1021
1022//_____________________________________________________________________________
dd9a6ee3 1023AliTRD &AliTRD::operator=(const AliTRD &trd)
1024{
1025 //
1026 // Assignment operator
1027 //
1028
1029 if (this != &trd) ((AliTRD &) trd).Copy(*this);
1030 return *this;
1031
f73816f5 1032}
abaf1f1d 1033
332e9569 1034//_____________________________________________________________________________
1035void AliTRD::FinishPrimary()
1036{
1037 //
1038 // Store the hits in the containers after all primaries are finished
1039 //
1040
1041 if (fTrackHits) {
1042 fTrackHits->FlushHitStack();
1043 }
1044
1045}
1046
1047//_____________________________________________________________________________
1048void AliTRD::RemapTrackHitIDs(Int_t *map)
1049{
1050 //
1051 // Remap the track IDs
1052 //
1053
1054 if (!fTrackHits) {
1055 return;
1056 }
1057
1058 if (fTrackHits) {
1059 TClonesArray *arr = fTrackHits->GetArray();;
1060 for (Int_t i = 0; i < arr->GetEntriesFast(); i++){
1061 AliTrackHitsParamV2 *info = (AliTrackHitsParamV2 *) (arr->At(i));
1062 info->fTrackID = map[info->fTrackID];
1063 }
1064 }
1065
1066}
1067
1068//_____________________________________________________________________________
1069void AliTRD::ResetHits()
1070{
1071 //
1072 // Reset the hits
1073 //
1074
1075 AliDetector::ResetHits();
1076 if (fTrackHits) {
1077 fTrackHits->Clear();
1078 }
1079
1080}
1081
1082//_____________________________________________________________________________
1083AliHit* AliTRD::FirstHit(Int_t track)
1084{
1085 //
1086 // Return the first hit of a track
1087 //
1088
1089 if (fHitType > 1) {
1090 return FirstHit2(track);
1091 }
abaf1f1d 1092
332e9569 1093 return AliDetector::FirstHit(track);
abaf1f1d 1094
332e9569 1095}
1096
1097//_____________________________________________________________________________
1098AliHit* AliTRD::NextHit()
1099{
1100 //
1101 // Returns the next hit of a track
1102 //
1103
1104 if (fHitType > 1) {
1105 return NextHit2();
1106 }
1107
1108 return AliDetector::NextHit();
1109
1110}
1111
1112//_____________________________________________________________________________
0a29d0f1 1113AliHit* AliTRD::FirstHit2(Int_t track)
332e9569 1114{
1115 //
1116 // Initializes the hit iterator.
1117 // Returns the address of the first hit of a track.
1118 // If <track> >= 0 the track is read from disk,
1119 // while if <track> < 0 the first hit of the current
1120 // track is returned.
1121 //
1122
1123 if (track >= 0) {
1124 gAlice->ResetHits();
88cb7938 1125 TreeH()->GetEvent(track);
332e9569 1126 }
1127
1128 if (fTrackHits) {
1129 fTrackHits->First();
1130 return (AliHit*) fTrackHits->GetHit();
1131 }
1132 else {
1133 return 0;
1134 }
1135
1136}
1137
1138//_____________________________________________________________________________
1139AliHit* AliTRD::NextHit2()
1140{
1141 //
1142 // Returns the next hit of the current track
1143 //
1144
1145 if (fTrackHits) {
1146 fTrackHits->Next();
1147 return (AliHit *) fTrackHits->GetHit();
1148 }
1149 else {
1150 return 0;
1151 }
1152
1153}
1154
1155//_____________________________________________________________________________
73ae7b59 1156void AliTRD::MakeBranch2(Option_t *option, const char* )
332e9569 1157{
1158 //
1159 // Create a new branch in the current Root tree.
1160 // The branch of fHits is automatically split.
1161 //
1162
1163 if (fHitType < 2) {
1164 return;
1165 }
1166
1167 char branchname[10];
1168 sprintf(branchname,"%s2",GetName());
1169
1170 // Get the pointer to the header
1171 const char *cH = strstr(option,"H");
1172
1173 if (!fTrackHits) {
1174 fTrackHits = new AliTRDtrackHits();
88cb7938 1175 }
332e9569 1176
332e9569 1177
88cb7938 1178 if (fTrackHits && TreeH() && cH)
1179 {
1180 TreeH()->Branch(branchname,"AliTRDtrackHits",&fTrackHits,fBufferSize,99);
1181 Info("MakeBranch2","Making Branch %s for trackhits",branchname);
1182 }
332e9569 1183}
1184
1185//_____________________________________________________________________________
1186void AliTRD::SetTreeAddress2()
1187{
1188 //
1189 // Set the branch address for the trackHits tree
1190 //
f2a509af 1191 if (GetDebug()) Info("SetTreeAddress2","");
332e9569 1192
1193 TBranch *branch;
332e9569 1194 char branchname[20];
332e9569 1195 sprintf(branchname,"%s2",GetName());
1196
1197 // Branch address for hit tree
88cb7938 1198 TTree *treeH = TreeH();
332e9569 1199 if ((treeH) && (fHitType > 0)) {
1200 branch = treeH->GetBranch(branchname);
88cb7938 1201 if (branch)
1202 {
1203 branch->SetAddress(&fTrackHits);
f2a509af 1204 if (GetDebug())
1205 Info("SetTreeAddress2","Success.");
88cb7938 1206 }
1207 else
1208 {
f2a509af 1209 if (GetDebug())
1210 Info("SetTreeAddress2","Can NOT get the branch %s",branchname);
88cb7938 1211 }
332e9569 1212 }
1213
1214}
1215
1216//_____________________________________________________________________________
1217void AliTRD::AddHit2(Int_t track, Int_t det, Float_t *hits, Int_t q
1218 , Bool_t inDrift)
1219{
1220 //
1221 // Add a hit to the list
1222 //
1223
1224 Int_t rtrack;
1225
1226 if (fIshunt) {
5d12ce38 1227 Int_t primary = gAlice->GetMCApp()->GetPrimary(track);
1228 gAlice->GetMCApp()->Particle(primary)->SetBit(kKeepBit);
332e9569 1229 rtrack = primary;
1230 }
1231 else {
1232 rtrack = track;
5d12ce38 1233 gAlice->GetMCApp()->FlagTrack(track);
332e9569 1234 }
1235
1236 if ((fTrackHits) && (fHitType > 0)) {
1237 fTrackHits->AddHitTRD(det,rtrack,hits[0],hits[1],hits[2],q,inDrift);
1238 }
1239
1240}
abaf1f1d 1241
1242
abaf1f1d 1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577