1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ////////////////////////////////////////////////////////////
17 // Factory for muon chambers, segmentations and response //
18 ////////////////////////////////////////////////////////////
22 #include "AliMUONFactoryV3.h"
26 #include "AliMpPlaneType.h"
29 #include "AliMUONConstants.h"
30 #include "AliMUONTriggerConstants.h"
31 #include "AliMUONChamber.h"
32 #include "AliMUONResponseV0.h"
33 #include "AliMUONGeometryModule.h"
34 #include "AliMUONGeometryStore.h"
35 #include "AliMUONGeometrySegmentation.h"
36 #include "AliMUONVGeometryDEIndexing.h"
37 #include "AliMUONSegmentationManager.h"
38 #include "AliMUONSt12QuadrantSegmentation.h"
39 #include "AliMUONSt345SlatSegmentationV2.h"
40 #include "AliMUONTriggerSegmentation.h"
41 #include "AliMUONResponseTrigger.h"
43 ClassImp(AliMUONFactoryV3)
45 //__________________________________________________________________________
46 AliMUONFactoryV3::AliMUONFactoryV3(const char* name)
52 AliDebug(1,Form("ctor this=%p",this));
53 fDESegmentations = new TObjArray();
54 fDESegmentations->SetOwner(kTRUE);
57 //__________________________________________________________________________
58 AliMUONFactoryV3::AliMUONFactoryV3()
64 AliDebug(1,Form("default (empty) ctor this=%p",this));
65 // Default constructor
68 //__________________________________________________________________________
69 AliMUONFactoryV3::AliMUONFactoryV3(const AliMUONFactoryV3& rhs)
72 // Protected copy constructor
74 AliFatal("Not implemented.");
77 //__________________________________________________________________________
79 AliMUONFactoryV3::~AliMUONFactoryV3()
82 AliDebug(1,Form("dtor this=%p",this));
83 delete fDESegmentations;
86 //__________________________________________________________________________
87 AliMUONFactoryV3& AliMUONFactoryV3::operator=(const AliMUONFactoryV3& rhs)
89 // Protected assignement operator
91 if (this == &rhs) return *this;
93 AliFatal("Not implemented.");
98 //__________________________________________________________________________
99 Bool_t AliMUONFactoryV3::IsGeometryDefined(Int_t ichamber)
101 // Return true, if det elements for the chamber with the given ichamber Id
102 // are defined in geometry (the geometry builder for this chamber was activated)
105 ! fMUON->Chamber(ichamber).GetGeometry() ||
106 ! fMUON->Chamber(ichamber).GetGeometry()->GetDEIndexing() ||
107 ! fMUON->Chamber(ichamber).GetGeometry()->GetDEIndexing()->GetNofDetElements() )
114 //__________________________________________________________________________
115 void AliMUONFactoryV3::BuildCommon()
118 // Construct the default response.
121 // Default response: 5 mm of gas
122 fResponse0 = new AliMUONResponseV0;
123 fResponse0->SetSqrtKx3AndDeriveKx2Kx4(0.7131); // sqrt(0.5085)
124 fResponse0->SetSqrtKy3AndDeriveKy2Ky4(0.7642); // sqrt(0.5840)
125 fResponse0->SetPitch(AliMUONConstants::Pitch()); // anode-cathode distance
126 fResponse0->SetSigmaIntegration(10.);
127 fResponse0->SetChargeSlope(10);
128 fResponse0->SetChargeSpread(0.18, 0.18);
129 fResponse0->SetMaxAdc(4096);
130 fResponse0->SetSaturation(3000);
131 fResponse0->SetZeroSuppression(6);
134 //__________________________________________________________________________
135 void AliMUONFactoryV3::BuildStation1()
137 //--------------------------------------------------------
138 // Configuration for Chamber TC1/2 (Station 1) ----------
139 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
142 // Response for 4 mm of gas (station 1)
143 // automatic consistency with width of sensitive medium in CreateGeometry ????
144 AliMUONResponseV0* responseSt1 = new AliMUONResponseV0;
145 // Mathieson parameters from L.Kharmandarian's thesis, page 190
146 responseSt1->SetSqrtKx3AndDeriveKx2Kx4(0.7000); // sqrt(0.4900)
147 responseSt1->SetSqrtKy3AndDeriveKy2Ky4(0.7550); // sqrt(0.5700)
148 responseSt1->SetPitch(AliMUONConstants::PitchSt1()); // anode-cathode distance
149 responseSt1->SetSigmaIntegration(10.);
150 // ChargeSlope larger to compensate for the smaller anode-cathode distance
151 // and keep the same most probable ADC channel for mip's
152 responseSt1->SetChargeSlope(62.5);
153 // assumed proportionality to anode-cathode distance for ChargeSpread
154 responseSt1->SetChargeSpread(0.144, 0.144);
155 responseSt1->SetMaxAdc(4096);
156 responseSt1->SetSaturation(3000);
157 responseSt1->SetZeroSuppression(6);
159 // Quadrant segmentations:
160 AliMUONSt12QuadrantSegmentation* bendSt1
161 = new AliMUONSt12QuadrantSegmentation(kStation1, kBendingPlane);
162 AliMUONSt12QuadrantSegmentation* nonbendSt1
163 = new AliMUONSt12QuadrantSegmentation(kStation1, kNonBendingPlane);
165 // Add in the array (for safe deleting)
166 fDESegmentations->Add(bendSt1);
167 fDESegmentations->Add(nonbendSt1);
169 AliMUONGeometrySegmentation* segmentation[2];
171 for (Int_t chamber = 0; chamber < 2; chamber++) {
173 segmentation[0] = new AliMUONGeometrySegmentation(fMUON->Chamber(chamber).GetGeometry());
174 segmentation[1] = new AliMUONGeometrySegmentation(fMUON->Chamber(chamber).GetGeometry());
176 // id detection elt for chamber 1
177 Int_t id0 = (chamber+1)*100;
179 //--------------------------------------------------------
180 // Configuration for Chamber TC1/2 (Station 1) ----------
184 segmentation[0]->Add(id0, bendSt1);
185 segmentation[0]->Add(id0 + 3, nonbendSt1);
186 segmentation[0]->Add(id0 + 2, bendSt1);
187 segmentation[0]->Add(id0 + 1, nonbendSt1);
188 fMUON->SetSegmentationModel(chamber, 1, segmentation[0]);
191 segmentation[1]->Add(id0, nonbendSt1);
192 segmentation[1]->Add(id0 + 3, bendSt1);
193 segmentation[1]->Add(id0 + 2, nonbendSt1);
194 segmentation[1]->Add(id0 + 1, bendSt1);
195 fMUON->SetSegmentationModel(chamber, 2, segmentation[1]);
197 fMUON->SetResponseModel(chamber, responseSt1); // special response
198 fMUON->Chamber(chamber).SetChargeCorrel(0.11); // 11% charge spread
203 //__________________________________________________________________________
204 void AliMUONFactoryV3::BuildStation2()
207 //--------------------------------------------------------
208 // Configuration for Chamber TC3/4 (Station 2) -----------
209 ///^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
212 // Quadrant segmentations:
213 AliMUONSt12QuadrantSegmentation* bendSt2
214 = new AliMUONSt12QuadrantSegmentation(kStation2, kBendingPlane);
215 AliMUONSt12QuadrantSegmentation* nonbendSt2
216 = new AliMUONSt12QuadrantSegmentation(kStation2, kNonBendingPlane);
218 // Add in the array (for safe deleting)
219 fDESegmentations->Add(bendSt2);
220 fDESegmentations->Add(nonbendSt2);
222 AliMUONGeometrySegmentation* segmentation[2];
224 for (Int_t chamber = 2; chamber < 4; chamber++) {
226 segmentation[0] = new AliMUONGeometrySegmentation(fMUON->Chamber(chamber).GetGeometry());
227 segmentation[1] = new AliMUONGeometrySegmentation(fMUON->Chamber(chamber).GetGeometry());
229 // id detection elt for chamber 1
230 Int_t id0 = (chamber+1)*100;
232 //--------------------------------------------------------
233 // Configuration for Chamber TC3/4 (Station 2) ----------
237 segmentation[0]->Add(id0, bendSt2);
238 segmentation[0]->Add(id0 + 3, nonbendSt2);
239 segmentation[0]->Add(id0 + 2, bendSt2);
240 segmentation[0]->Add(id0 + 1, nonbendSt2);
241 fMUON->SetSegmentationModel(chamber, 1, segmentation[0]);
244 segmentation[1]->Add(id0, nonbendSt2);
245 segmentation[1]->Add(id0 + 3, bendSt2);
246 segmentation[1]->Add(id0 + 2, nonbendSt2);
247 segmentation[1]->Add(id0 + 1, bendSt2);
248 fMUON->SetSegmentationModel(chamber, 2, segmentation[1]);
250 fMUON->SetResponseModel(chamber, fResponse0); // normal response
251 fMUON->Chamber(chamber).SetChargeCorrel(0.11); // 11% charge spread
256 //_____________________________________________________________________________
258 AliMUONFactoryV3::BuildChamber345(Int_t firstDetElemId, Int_t lastDetElemId)
260 // Build a single chamber for stations 345.
261 // The first and lastDetElemId must correspond to the same chamber.
263 Int_t ichamber = firstDetElemId/100 - 1;
264 Int_t test = lastDetElemId/100-1;
266 if ( test != ichamber )
268 AliFatal(Form("DetElemIds %d and %d not part of the same chamber !",
269 firstDetElemId,lastDetElemId));
272 const Int_t NPLANES = 2;
273 const AliMpPlaneType ptypes[NPLANES] = { kBendingPlane, kNonBendingPlane };
275 AliMUONChamber& chamber = fMUON->Chamber(ichamber);
277 for ( Int_t iplane = 0; iplane < NPLANES; ++iplane )
279 AliMUONGeometrySegmentation* segmentation =
280 new AliMUONGeometrySegmentation(chamber.GetGeometry());
282 for ( Int_t d = firstDetElemId; d <= lastDetElemId; ++d )
284 if ( !AliMUONSegmentationManager::IsValidDetElemId(d) )
286 AliWarning(Form("You are requesting an invalid detElemId = %d, I am skipping it",d));
290 AliMUONVGeometryDESegmentation* slatSeg =
291 new AliMUONSt345SlatSegmentationV2(d,ptypes[iplane]);
293 fDESegmentations->Add(slatSeg);
295 segmentation->Add(d,slatSeg);
298 fMUON->SetSegmentationModel(ichamber,iplane+1,segmentation);
301 fMUON->SetResponseModel(ichamber,fResponse0);
303 chamber.SetChargeCorrel(0.11); // 11% charge spread
306 //__________________________________________________________________________
307 void AliMUONFactoryV3::BuildStation3()
309 BuildChamber345(500,517);
310 BuildChamber345(600,617);
313 //__________________________________________________________________________
314 void AliMUONFactoryV3::BuildStation4()
316 BuildChamber345(700,725);
317 BuildChamber345(800,825);
320 //__________________________________________________________________________
321 void AliMUONFactoryV3::BuildStation5()
323 BuildChamber345(900,925);
324 BuildChamber345(1000,1025);
327 //__________________________________________________________________________
328 void AliMUONFactoryV3::BuildStation6()
330 // Create Trigger geometry segmentation for given chamber and cathod
333 AliMUONGeometrySegmentation *chamberSeg[2];
335 AliMUONResponseTrigger* responseTrigger0 = new AliMUONResponseTrigger;
337 // AliMUONResponseTriggerV1* responseTrigger0 = new AliMUONResponseTriggerV1;
339 for (Int_t chamber = 10; chamber < 14; chamber++) {
341 //Trigger Segmentation
342 AliMUONTriggerSegmentation *trigSegX[9];
343 AliMUONTriggerSegmentation *trigSegY[9];
344 for(Int_t i=0; i<9; i++) {
345 trigSegX[i] = new AliMUONTriggerSegmentation(1);
346 trigSegY[i] = new AliMUONTriggerSegmentation(0);
347 fDESegmentations->Add(trigSegX[i]);
348 fDESegmentations->Add(trigSegY[i]);
349 trigSegX[i]->SetLineNumber(9-i);
350 trigSegY[i]->SetLineNumber(9-i);
353 AliMUONChamber *iChamber, *iChamber1;
354 iChamber1 = &fMUON->Chamber(10);
355 iChamber = &fMUON->Chamber(chamber);
356 Float_t zpos1= iChamber1->Z();
357 Float_t zpos = iChamber->Z();
358 Float_t zRatio = zpos / zpos1;
361 Float_t stripWidth[3]={0.,0.,0.}; // 1.0625 2.125 4.25
362 Float_t stripLength[4]={0.,0.,0.,0.}; // 17. 34. 51. 68.
363 for (Int_t i=0; i<3; i++)
364 stripWidth[i]=AliMUONTriggerConstants::StripWidth(i)*zRatio;
365 for (Int_t i=0; i<4; i++)
366 stripLength[i]=AliMUONTriggerConstants::StripLength(i)*zRatio;
367 Int_t nStrip[7]={0,0,0,0,0,0,0};
368 Float_t stripYsize[7]={0.,0.,0.,0.,0.,0.,0.};
369 Float_t stripXsize[7]={0.,0.,0.,0.,0.,0.,0.};
371 // chamber 8 0 cathode 0
372 for (Int_t i=0; i<7; i++) nStrip[i]=16;
373 for (Int_t i=0; i<7; i++) stripYsize[i]=stripWidth[2];
374 for (Int_t i=0; i<6; i++) stripXsize[i]=stripLength[1];
375 stripXsize[6]=stripLength[2];
376 trigSegX[8]->Init(0,nStrip,stripYsize,stripXsize,0.);
377 trigSegX[0]->Init(0,nStrip,stripYsize,stripXsize,0.);
379 // chamber 8 7 1 0 cathode 1
380 for (Int_t i=0; i<6; i++) nStrip[i]=8;
382 for (Int_t i=0; i<7; i++) stripYsize[i]=stripLength[3];
383 for (Int_t i=0; i<7; i++) stripXsize[i]=stripWidth[2];
384 trigSegY[8]->Init(0,nStrip,stripYsize,stripXsize,0.);
385 trigSegY[7]->Init(0,nStrip,stripYsize,stripXsize,0.);
386 trigSegY[1]->Init(0,nStrip,stripYsize,stripXsize,0.);
387 trigSegY[0]->Init(0,nStrip,stripYsize,stripXsize,0.);
389 // chamber 7 6 2 1 cathode 0
390 for (Int_t i=0; i<6; i++) nStrip[i]=32;
392 for (Int_t i=0; i<6; i++) stripYsize[i]=stripWidth[1];
393 stripYsize[6]=stripWidth[2];
394 for (Int_t i=0; i<6; i++) stripXsize[i]=stripLength[1];
395 stripXsize[6]=stripLength[2];
396 trigSegX[7]->Init(0,nStrip,stripYsize,stripXsize,0.);
397 trigSegX[6]->Init(0,nStrip,stripYsize,stripXsize,0.);
398 trigSegX[2]->Init(0,nStrip,stripYsize,stripXsize,0.);
399 trigSegX[1]->Init(0,nStrip,stripYsize,stripXsize,0.);
401 // chamber 6 2 cathode 1
402 for (Int_t i=0; i<5; i++) nStrip[i]=16;
403 for (Int_t i=5; i<6; i++) nStrip[i]=8;
405 for (Int_t i=0; i<7; i++) stripYsize[i]=stripLength[3];
406 for (Int_t i=0; i<5; i++) stripXsize[i]=stripWidth[1];
407 for (Int_t i=5; i<7; i++) stripXsize[i]=stripWidth[2];
408 trigSegY[6]->Init(0,nStrip,stripYsize,stripXsize,0.);
409 trigSegY[2]->Init(0,nStrip,stripYsize,stripXsize,0.);
411 // chamber 5 3 cathode 0
413 for (Int_t i=1; i<3; i++) nStrip[i]=64;
414 for (Int_t i=3; i<6; i++) nStrip[i]=32;
416 for (Int_t i=0; i<3; i++) stripYsize[i]=stripWidth[0];
417 for (Int_t i=3; i<6; i++) stripYsize[i]=stripWidth[1];
418 stripYsize[6]=stripWidth[2];
419 for (Int_t i=0; i<6; i++) stripXsize[i]=stripLength[1];
420 stripXsize[6]=stripLength[2];
421 trigSegX[5]->Init(0,nStrip,stripYsize,stripXsize,stripLength[0]);
422 trigSegX[3]->Init(0,nStrip,stripYsize,stripXsize,0.);
424 // chamber 5 3 cathode 1
425 for (Int_t i=0; i<5; i++) nStrip[i]=16;
426 for (Int_t i=5; i<6; i++) nStrip[5]=8;
428 stripYsize[0]=stripLength[2];
429 for (Int_t i=1; i<7; i++) stripYsize[i]=stripLength[3];
430 for (Int_t i=0; i<5; i++) stripXsize[i]=stripWidth[1];
431 for (Int_t i=5; i<7; i++) stripXsize[i]=stripWidth[2];
432 trigSegY[5]->Init(0,nStrip,stripYsize,stripXsize,stripLength[0]);
433 trigSegY[3]->Init(0,nStrip,stripYsize,stripXsize,0.);
435 // chamber 4 cathode 0
437 for (Int_t i=1; i<3; i++) nStrip[i]=64;
438 for (Int_t i=3; i<6; i++) nStrip[i]=32;
441 for (Int_t i=1; i<3; i++) stripYsize[i]=stripWidth[0];
442 for (Int_t i=3; i<6; i++) stripYsize[i]=stripWidth[1];
443 stripYsize[6]=stripWidth[2];
445 stripXsize[1]=stripLength[0];
446 for (Int_t i=2; i<6; i++) stripXsize[i]=stripLength[1];
447 stripXsize[6]=stripLength[2];
448 trigSegX[4]->Init(0,nStrip,stripYsize,stripXsize,0.);
450 // chamber 4 cathode 1
453 for (Int_t i=2; i<5; i++) nStrip[i]=16;
454 for (Int_t i=5; i<6; i++) nStrip[i]=8;
457 for (Int_t i=1; i<7; i++) stripYsize[i]=stripLength[3];
459 for (Int_t i=1; i<5; i++) stripXsize[i]=stripWidth[1];
460 for (Int_t i=5; i<7; i++) stripXsize[i]=stripWidth[2];
461 trigSegY[4]->Init(0,nStrip,stripYsize,stripXsize,0.);
463 chamberSeg[0] = new AliMUONGeometrySegmentation(fMUON->Chamber(chamber).GetGeometry());
464 chamberSeg[1] = new AliMUONGeometrySegmentation(fMUON->Chamber(chamber).GetGeometry());
466 Int_t icount=chamber-10; // chamber counter (0 1 2 3)
467 Int_t id0=(10+icount+1)*100;
470 // printf("in CreateTriggerSegmentation here 0 id0=%i \n",id0);
471 chamberSeg[0]->Add(id0+0, trigSegX[4]);
472 chamberSeg[0]->Add(id0+1, trigSegX[5]);
473 chamberSeg[0]->Add(id0+2, trigSegX[6]);
474 chamberSeg[0]->Add(id0+3, trigSegX[7]);
475 chamberSeg[0]->Add(id0+4, trigSegX[8]);
476 chamberSeg[0]->Add(id0+5, trigSegX[8]);
477 chamberSeg[0]->Add(id0+6, trigSegX[7]);
478 chamberSeg[0]->Add(id0+7, trigSegX[6]);
479 chamberSeg[0]->Add(id0+8, trigSegX[5]);
480 chamberSeg[0]->Add(id0+9, trigSegX[4]);
481 chamberSeg[0]->Add(id0+10, trigSegX[3]);
482 chamberSeg[0]->Add(id0+11, trigSegX[2]);
483 chamberSeg[0]->Add(id0+12, trigSegX[1]);
484 chamberSeg[0]->Add(id0+13, trigSegX[0]);
485 chamberSeg[0]->Add(id0+14, trigSegX[0]);
486 chamberSeg[0]->Add(id0+15, trigSegX[1]);
487 chamberSeg[0]->Add(id0+16, trigSegX[2]);
488 chamberSeg[0]->Add(id0+17, trigSegX[3]);
490 chamberSeg[1]->Add(id0+0, trigSegY[4]);
491 chamberSeg[1]->Add(id0+1, trigSegY[5]);
492 chamberSeg[1]->Add(id0+2, trigSegY[6]);
493 chamberSeg[1]->Add(id0+3, trigSegY[7]);
494 chamberSeg[1]->Add(id0+4, trigSegY[8]);
495 chamberSeg[1]->Add(id0+5, trigSegY[8]);
496 chamberSeg[1]->Add(id0+6, trigSegY[7]);
497 chamberSeg[1]->Add(id0+7, trigSegY[6]);
498 chamberSeg[1]->Add(id0+8, trigSegY[5]);
499 chamberSeg[1]->Add(id0+9, trigSegY[4]);
500 chamberSeg[1]->Add(id0+10, trigSegY[3]);
501 chamberSeg[1]->Add(id0+11, trigSegY[2]);
502 chamberSeg[1]->Add(id0+12, trigSegY[1]);
503 chamberSeg[1]->Add(id0+13, trigSegY[0]);
504 chamberSeg[1]->Add(id0+14, trigSegY[0]);
505 chamberSeg[1]->Add(id0+15, trigSegY[1]);
506 chamberSeg[1]->Add(id0+16, trigSegY[2]);
507 chamberSeg[1]->Add(id0+17, trigSegY[3]);
509 fMUON->SetSegmentationModel(chamber, 1, chamberSeg[0]);
510 fMUON->SetSegmentationModel(chamber, 2, chamberSeg[1]);
512 fMUON->SetResponseModel(chamber, responseTrigger0);
513 fMUON->Chamber(chamber).SetChargeCorrel(0); // same charge on cathodes
515 // printf("in CreateTriggerSegmentation here 1\n");
518 AliWarning(Form("Segmentation for chamber %d is not yet defined",chamber));
523 //__________________________________________________________________________
524 void AliMUONFactoryV3::Build(AliMUON* where, const char* what)
527 // Construct MUON from chambers, segmentation and responses
534 if (strcmp(tmp, "default")==0) {
535 // Set default parameters
537 fMUON->SetMaxStepGas(0.1);
538 fMUON->SetMaxStepAlu(0.1);
542 if (IsGeometryDefined(0)) BuildStation1();
543 if (IsGeometryDefined(2)) BuildStation2();
544 if (IsGeometryDefined(4)) BuildStation3();
545 if (IsGeometryDefined(6)) BuildStation4();
546 if (IsGeometryDefined(8)) BuildStation5();
547 if (IsGeometryDefined(10)) BuildStation6();
550 AliDebug(0,"Non default version of MUON selected. You have to construct yourself the MUON elements !!");
553 //__________________________________________________________________________
554 void AliMUONFactoryV3::BuildStation(AliMUON* where, Int_t stationNumber)
557 // Construct MUON from chambers, segmentation and responses
561 if (!fResponse0) BuildCommon();
563 switch (stationNumber) {
564 case 1: BuildStation1(); break;
565 case 2: BuildStation2(); break;
566 case 3: BuildStation3(); break;
567 case 4: BuildStation4(); break;
568 case 5: BuildStation5(); break;
569 case 6: BuildStation6(); break;
571 default: AliFatal("Wrong station number");