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 **************************************************************************/
20 #include "AliMUONTriggerCircuit.h"
23 #include "AliMUONTriggerConstants.h"
24 #include "AliSegmentation.h"
25 #include "AliMUONGeometrySegmentation.h"
26 #include "AliMUONChamber.h"
27 #include "AliMUONConstants.h"
30 ClassImp(AliMUONTriggerCircuit)
32 //----------------------------------------------------------------------
33 AliMUONTriggerCircuit::AliMUONTriggerCircuit()
38 // fSegmentationType(1)
42 fOrMud[0]=fOrMud[1]=0;
45 for (Int_t j=0; j<32; j++) {
50 for (i=0; i<16; i++) { fXpos11[i]=0.; }
51 for (i=0; i<31; i++) { fYpos11[i]=0.; }
52 for (i=0; i<63; i++) { fYpos21[i]=0.; }
55 //----------------------------------------------------------------------
56 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& theMUONTriggerCircuit)
57 : TObject(theMUONTriggerCircuit)
59 // Protected copy constructor
61 AliFatal("Not implemented.");
64 //----------------------------------------------------------------------
65 AliMUONTriggerCircuit &
66 AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& rhs)
68 // Protected assignement operator
70 if (this == &rhs) return *this;
72 AliFatal("Not implemented.");
77 //----------------------------------------------------------------------
78 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
79 // initialize circuit characteristics
80 fIdCircuit=AliMUONTriggerConstants::CircuitId(iCircuit);
81 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
87 if (pMUON->WhichSegmentation() == 1) {
96 //----------------------------------------------------------------------
97 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit) const {
98 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
100 for (Int_t i=0; i<234; i++) {
101 if (AliMUONTriggerConstants::CircuitId(i)==idCircuit) {
108 //----------------------------------------------------------------------
109 Int_t AliMUONTriggerCircuit::ModuleNumber(Int_t idModule) const {
110 // returns module number imod (from 0 to 63) corresponding to module idmodule
111 Int_t absidModule=TMath::Abs(idModule);
113 for (Int_t i=0; i<63; i++) {
114 if (AliMUONTriggerConstants::ModuleId(i)==absidModule) {
122 //----------------------------------------------------------------------
123 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) const {
124 // returns ModuleId where Circuit idCircuit is sitting
125 return Int_t(idCircuit/10);
127 //----------------------------------------------------------------------
128 Int_t AliMUONTriggerCircuit::Position(Int_t idCircuit) const {
129 // returns position of idCircuit in correcponding Module
130 return TMath::Abs(idCircuit)-TMath::Abs(Module(idCircuit))*10;
133 //----------------------------------------------------------------------
134 void AliMUONTriggerCircuit::LoadX2() {
135 // initialize fX2m, fX2ud and fOrMud
137 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
138 // and its number of X strips
139 Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
140 // and its number of Y strips
141 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
142 Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
144 // first step : look at lower part
145 if (iPosCircuit==1) { // need to scan lower module
146 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) {
148 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
149 Int_t nStrD=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleD));
152 &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {
153 if (nStrY==8) fX2m=1;
154 if (nStrD==8) fX2ud=1;
158 } else { // lower strips within same module
162 // second step : look at upper part
163 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
164 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
165 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
167 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
168 Int_t nStrU=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleU));
171 &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {
172 if (nStrY==8) fX2m=1;
173 if (nStrU==8) fX2ud=1;
177 } else { // upper strips within same module
182 //----------------------------------------------------------------------
183 void AliMUONTriggerCircuit::LoadXCode(){
184 // assign a Id. number to each X strip of current circuit
185 // Id.=(corresponding module Id.)*100+(Id. strip of module)
187 // first part : fill XMC11 XMC12 and strips 8 to 24 (middle) XMC21 XMC22
188 Int_t iStripCircMT1=0, iStripCircMT2=8;
189 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
190 // and its number of strips
191 Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
192 Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
193 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
196 for (istrip=(iPosCircuit-1)*16;
197 istrip<(iPosCircuit-1)*16+16; istrip++) {
199 fXcode[0][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
200 fXcode[1][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
201 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
202 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
208 // XMC21 XMC22 strips 0 to 7 and 24 to 31
209 Int_t idModuleD, idModuleU;
212 idModule=Module(fIdCircuit); // corresponding module Id.
213 // number of X strips
214 nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
215 sign=TMath::Abs(idModule)/idModule;
217 // fill lower part (0 to 7)
218 if (iPosCircuit==1) { // need to scan lower module
219 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { // non-existing
220 idModuleD=sign*(TMath::Abs(idModule)+10); // lower module Id
221 // and its number of strips
222 nStrD=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleD));
225 for (istrip=nStrD-8; istrip<nStrD; istrip++) {
226 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
227 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
232 } else { // lower strips within same module
235 for (istrip=(iPosCircuit-1)*16-8;
236 istrip<(iPosCircuit-1)*16; istrip++) {
237 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
238 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
243 // fill upper part (24 to 31)
244 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
245 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
246 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
247 idModuleU=sign*(TMath::Abs(idModule)-10); // upper module Id
248 // and its number of strips
249 nStrU=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleU));
252 for (istrip=0; istrip<8; istrip++) {
253 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
254 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
259 } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)||
260 (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod.
263 for (istrip=(iPosCircuit-1)*16+16;
264 istrip<(iPosCircuit-1)*16+24; istrip++) {
265 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
266 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
272 //----------------------------------------------------------------------
273 void AliMUONTriggerCircuit::LoadYCode(){
274 // assign a Id. number to each Y strip of current circuit
275 // Id.=(corresponding module Id.)*100+(Id. strip of module)
276 // note : for Y plane fill only "central part" of circuit
277 // (upper and lower parts are filled in PreHandlingY of AliMUONTriggerDecision)
279 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
280 // and its number of Y strips
281 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
282 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
284 for (Int_t istrip=0; istrip<nStrY; istrip++) {
285 fYcode[0][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
286 fYcode[1][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
287 fYcode[2][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
288 fYcode[3][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
292 //----------------------------------------------------------------------
293 void AliMUONTriggerCircuit::LoadYPos(){
294 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
296 Int_t chamber, cathode;
297 Int_t code, idModule, idStrip, idSector;
298 Float_t x, y, z, width;
301 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
302 AliMUONChamber* iChamber;
303 AliSegmentation* segmentation;
308 iChamber = &(pMUON->Chamber(chamber-1));
309 segmentation=iChamber->SegmentationModel(cathode);
311 for (istrip=0; istrip<16; istrip++) {
312 code=fXcode[0][istrip]; // decode current strip
313 idModule=Int_t(code/100); // corresponding module Id.
314 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
315 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
316 width=segmentation->Dpy(idSector); // corresponding strip width
317 segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
320 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
326 iChamber = &(pMUON->Chamber(chamber-1));
327 segmentation=iChamber->SegmentationModel(cathode);
329 for (istrip=0; istrip<32; istrip++) {
330 code=fXcode[2][istrip]; // decode current strip
331 idModule=Int_t(code/100); // corresponding module Id.
332 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
333 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
334 width=segmentation->Dpy(idSector); // corresponding strip width
335 segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
337 // using idModule!=0 prevents to fill garbage in case of circuits
338 // in the first and last rows
341 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
346 //----------------------------------------------------------------------
347 void AliMUONTriggerCircuit::LoadXPos(){
348 // fill fXpos11 -> x position of Y strips for the first plane only
349 // fXpos11 contains the x position of Y strip for the current circuit
350 // taking into account whether or nor not part(s) of the circuit
351 // (middle, up or down) has(have) 16 strips
358 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
359 AliMUONChamber* iChamber;
360 AliSegmentation* segmentation;
361 iChamber = &(pMUON->Chamber(chamber-1));
362 segmentation=iChamber->SegmentationModel(cathode);
364 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
365 // number of Y strips
366 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
367 Int_t idSector=segmentation->Sector(idModule,0); // corresp. sector
368 Float_t width=segmentation->Dpx(idSector); // corresponding strip width
370 // first case : up middle and down parts have all 8 or 16 strip
371 if ((nStrY==16)||(nStrY==8&&fX2m==0&&fX2ud==0)) {
372 for (istrip=0; istrip<nStrY; istrip++) {
373 segmentation->GetPadC(idModule,istrip,x,y,z);
376 // second case : mixing 8 and 16 strips within same circuit
378 for (istrip=0; istrip<nStrY; istrip++) {
379 if (nStrY!=8) { printf(" bug in LoadXpos \n");}
380 segmentation->GetPadC(idModule,istrip,x,y,z);
381 fXpos11[2*istrip]=x-width/4.;
382 fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.;
387 //----------------------------------------------------------------------
388 Float_t AliMUONTriggerCircuit::PtCal(Int_t istripX, Int_t idev, Int_t istripY){
389 // returns calculated pt for circuit/istripX/idev/istripY according
390 // to the formula of the TRD. Note : idev (input) is in [0+30]
392 // Int_t jdev = idev - 15; // jdev in [-15+15]
393 Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
395 Float_t yPosX1=fYpos11[istripX];
396 Float_t yPosX2=fYpos21[istripX2];
397 Float_t xPosY1=fXpos11[istripY];
400 Float_t z1=AliMUONConstants::DefaultChamberZ(10);
401 Float_t z2=AliMUONConstants::DefaultChamberZ(12);
402 Float_t thetaDev=(1./zf)*(yPosX1*z2-yPosX2*z1)/(z2-z1);
403 Float_t xf=xPosY1*zf/z1;
404 Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1);
405 return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/zf;
407 //---------------------------------------------------------------------
408 //----------------------- New Segmentation ----------------------------
409 //---------------------------------------------------------------------
411 //---------------------------------------------------------------------
412 void AliMUONTriggerCircuit::LoadYPos2(){
413 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
415 Int_t chamber, cathode;
416 Int_t code, idModule, idStrip, idSector;
417 Float_t x, y, z, width;
420 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
421 AliMUONChamber* iChamber;
422 AliMUONGeometrySegmentation* segmentation;
427 iChamber = &(pMUON->Chamber(chamber-1));
428 segmentation=iChamber->SegmentationModel2(cathode);
431 AliWarning("Segmentation not defined.");
435 for (istrip=0; istrip<16; istrip++) {
436 code=fXcode[0][istrip]; // decode current strip
437 idModule=Int_t(code/100); // corresponding module Id.
438 idDE = DetElemId(chamber, idModule);
439 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
440 idSector=segmentation->Sector(idDE, idModule, idStrip); // corresponding sector
441 width=segmentation->Dpy(idDE, idSector); // corresponding strip width
442 segmentation->GetPadC(idDE, idModule,idStrip,x,y,z); // get strip real position
445 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
451 iChamber = &(pMUON->Chamber(chamber-1));
452 segmentation=iChamber->SegmentationModel2(cathode);
454 for (istrip=0; istrip<32; istrip++) {
455 code=fXcode[2][istrip]; // decode current strip
456 idModule=Int_t(code/100); // corresponding module Id.
457 idDE = DetElemId(chamber, idModule);
458 if (idModule == 0) continue;
459 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
460 idSector=segmentation->Sector(idDE, idModule, idStrip); // corresponding sector
461 width=segmentation->Dpy(idDE, idSector); // corresponding strip width
462 segmentation->GetPadC(idDE, idModule,idStrip,x,y,z); // get strip real position
464 // using idModule!=0 prevents to fill garbage in case of circuits
465 // in the first and last rows
468 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
473 //----------------------------------------------------------------------
474 void AliMUONTriggerCircuit::LoadXPos2(){
475 // fill fXpos11 -> x position of Y strips for the first plane only
476 // fXpos11 contains the x position of Y strip for the current circuit
477 // taking into account whether or nor not part(s) of the circuit
478 // (middle, up or down) has(have) 16 strips
485 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
486 AliMUONChamber* iChamber;
487 AliMUONGeometrySegmentation* segmentation;
488 iChamber = &(pMUON->Chamber(chamber-1));
489 segmentation=iChamber->SegmentationModel2(cathode);
492 AliWarning("Segmentation not defined.");
496 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
497 // number of Y strips
498 idDE = DetElemId(chamber, idModule);
499 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
500 Int_t idSector=segmentation->Sector(idDE, idModule,0); // corresp. sector
501 Float_t width=segmentation->Dpx(idDE, idSector); // corresponding strip width
503 // first case : up middle and down parts have all 8 or 16 strip
504 if ((nStrY==16)||(nStrY==8&&fX2m==0&&fX2ud==0)) {
505 for (istrip=0; istrip<nStrY; istrip++) {
506 segmentation->GetPadC(idDE, idModule,istrip,x,y,z);
509 // second case : mixing 8 and 16 strips within same circuit
511 for (istrip=0; istrip<nStrY; istrip++) {
512 if (nStrY!=8) { printf(" bug in LoadXpos \n");}
513 segmentation->GetPadC(idDE, idModule, istrip, x, y, z);
514 fXpos11[2*istrip]=x-width/4.;
515 fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.;
520 //----------------------------------------------------------------------
521 //--- methods which return member data related info
522 //----------------------------------------------------------------------
523 Int_t AliMUONTriggerCircuit::GetIdCircuit() const {
524 // returns circuit Id
527 //----------------------------------------------------------------------
528 Int_t AliMUONTriggerCircuit::GetIdModule() const {
530 return Module(fIdCircuit);
532 //----------------------------------------------------------------------
533 Int_t AliMUONTriggerCircuit::GetNstripX() const {
534 // returns the number of X strips in the module where the circuit is sitting
535 return AliMUONTriggerConstants::NstripX(ModuleNumber(Module(fIdCircuit)));
537 //----------------------------------------------------------------------
538 Int_t AliMUONTriggerCircuit::GetNstripY() const {
539 // returns the number of Y strips in the module where the circuit is sitting
540 return AliMUONTriggerConstants::NstripY(ModuleNumber(Module(fIdCircuit)));
542 //----------------------------------------------------------------------
543 Int_t AliMUONTriggerCircuit::GetPosCircuit() const {
544 // returns the position of the circuit in its module
545 return Position(fIdCircuit);
547 //----------------------------------------------------------------------
548 Int_t AliMUONTriggerCircuit::GetIdCircuitD() const {
549 // returns the Id of the circuit down
550 Int_t idModule=Module(fIdCircuit);
551 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
552 return (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
554 //----------------------------------------------------------------------
555 Int_t AliMUONTriggerCircuit::GetICircuitD() const {
556 // returns the number of the circuit down
557 Int_t idModule=Module(fIdCircuit);
558 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
560 (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
561 return CircuitNumber(idCircuitD);
563 //----------------------------------------------------------------------
564 Int_t AliMUONTriggerCircuit::GetIdCircuitU() const {
565 // returns the Id of the circuit up
566 Int_t idModule=Module(fIdCircuit);
567 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
568 return (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
570 //----------------------------------------------------------------------
571 Int_t AliMUONTriggerCircuit::GetICircuitU() const {
572 // returns the number of the circuit up
573 Int_t idModule=Module(fIdCircuit);
574 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
576 (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
577 return CircuitNumber(idCircuitU);
579 //----------------------------------------------------------------------
580 Int_t AliMUONTriggerCircuit::GetX2m() const {
584 //----------------------------------------------------------------------
585 Int_t AliMUONTriggerCircuit::GetX2ud() const {
589 //----------------------------------------------------------------------
590 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]) const {
595 //----------------------------------------------------------------------
596 Int_t AliMUONTriggerCircuit::GetXcode(Int_t chamber, Int_t istrip) const {
597 // returns X code of circuit/chamber/istrip (warning : chamber in [0,3])
598 return fXcode[chamber][istrip];
600 //----------------------------------------------------------------------
601 Int_t AliMUONTriggerCircuit::GetYcode(Int_t chamber, Int_t istrip) const {
602 // returns Y code of circuit/chamber/istrip (warning : chamber in [0,3])
603 return fYcode[chamber][istrip];
605 //----------------------------------------------------------------------
606 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip) const {
607 // returns Y position of X strip istrip in MC11
608 return fYpos11[istrip];
610 //----------------------------------------------------------------------
611 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip) const {
612 // returns Y position of X strip istrip in MC21
613 return fYpos21[istrip];
615 //----------------------------------------------------------------------
616 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip) const {
617 // returns X position of Y strip istrip in MC11
618 return fXpos11[istrip];
620 //----------------------------------------------------------------------
621 //--- end of methods which return member data related info
622 //----------------------------------------------------------------------
625 Int_t AliMUONTriggerCircuit::DetElemId(Int_t ichamber, Int_t idModule)
627 // returns the detection element Id for given chamber and module
628 // ichamber (from 11 to 14), idModule (from 11 to 97)
629 Int_t itmp = (idModule > 0) ? 0 : 50; // right=0, left=50
630 return (ichamber*100)+itmp+(9-Int_t(TMath::Abs(idModule)/10));