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 **************************************************************************/
21 #include "AliMUONPoints.h"
22 #include "AliMUONTriggerCircuit.h"
23 #include "AliMUONSegmentation.h"
24 #include "AliMUONResponse.h"
25 #include "AliMUONChamber.h"
29 ClassImp(AliMUONTriggerCircuit)
31 static Int_t circuitId[234]=
32 {111, 121, 131, 141, 151, 161, 171,
33 211, 212, 221, 222, 231, 232, 241, 242, 251, 252, 261, 262, 271,
34 311, 312, 321, 322, 331, 332, 341, 342, 351, 352, 361, 362, 371,
35 411, 412, 413, 421, 422, 423, 424, 431, 432, 433, 434, 441, 442,
36 451, 452, 461, 462, 471,
37 521, 522, 523, 524, 531, 532, 533, 534, 541, 542, 551, 552, 561, 562, 571,
38 611, 612, 613, 621, 622, 623, 624, 631, 632, 633, 634, 641, 642,
39 651, 652, 661, 662, 671,
40 711, 712, 721, 722, 731, 732, 741, 742, 751, 752, 761, 762, 771,
41 811, 812, 821, 822, 831, 832, 841, 842, 851, 852, 861, 862, 871,
42 911, 921, 931, 941, 951, 961, 971,
43 -111, -121, -131, -141, -151, -161, -171,
44 -211, -212, -221, -222, -231, -232, -241, -242, -251, -252, -261, -262, -271,
45 -311, -312, -321, -322, -331, -332, -341, -342, -351, -352, -361, -362, -371,
46 -411, -412, -413, -421, -422, -423, -424, -431, -432, -433, -434, -441, -442,
47 -451, -452, -461, -462, -471,
48 -521, -522, -523, -524, -531, -532, -533, -534, -541, -542, -551, -552, -561, -562, -571,
49 -611, -612, -613, -621, -622, -623, -624, -631, -632, -633, -634, -641, -642,
50 -651, -652, -661, -662, -671,
51 -711, -712, -721, -722, -731, -732, -741, -742, -751, -752, -761, -762, -771,
52 -811, -812, -821, -822, -831, -832, -841, -842, -851, -852, -861, -862, -871,
53 -911, -921, -931, -941, -951, -961, -971};
55 static Int_t moduleId[63]=
56 {11,12,13,14,15,16,17,
64 91,92,93,94,95,96,97};
66 static Int_t nStripX[63]=
67 {16,16,16,16,16,16,16,
75 16,16,16,16,16,16,16};
77 static Int_t nStripY[63]=
88 //----------------------------------------------------------------------
89 AliMUONTriggerCircuit::AliMUONTriggerCircuit()
95 fOrMud[0]=fOrMud[1]=0;
96 for (Int_t i=0; i<4; i++) {
97 for (Int_t j=0; j<32; j++) {
102 for (Int_t i=0; i<16; i++) { fXpos11[i]=0.; }
103 for (Int_t i=0; i<31; i++) { fYpos11[i]=0.; }
104 for (Int_t i=0; i<63; i++) { fYpos21[i]=0.; }
107 //----------------------------------------------------------------------
108 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit)
110 // Dummy copy constructor
113 //----------------------------------------------------------------------
114 AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit)
116 // Dummy assignment operator
120 //----------------------------------------------------------------------
121 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
122 // initialize circuit characteristics
123 fidCircuit=circuitId[iCircuit];
131 //----------------------------------------------------------------------
132 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){
133 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
135 for (Int_t i=0; i<234; i++) {
136 if (circuitId[i]==idCircuit) {
143 //----------------------------------------------------------------------
144 Int_t AliMUONTriggerCircuit::ModuleNumber(Int_t idModule){
145 // returns module number imod (from 0 to 63) corresponding to module idmodule
146 Int_t absidModule=TMath::Abs(idModule);
148 for (Int_t i=0; i<63; i++) {
149 if (moduleId[i]==absidModule) {
157 //----------------------------------------------------------------------
158 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) {
159 // returns ModuleId where Circuit idCircuit is sitting
160 return Int_t(idCircuit/10);
162 //----------------------------------------------------------------------
163 Int_t AliMUONTriggerCircuit::Position(Int_t idCircuit) {
164 // returns position of idCircuit in correcponding Module
165 return TMath::Abs(idCircuit)-TMath::Abs(Module(idCircuit))*10;
168 //----------------------------------------------------------------------
169 void AliMUONTriggerCircuit::LoadX2() {
170 // initialize fx2m, fx2ud and fOrMud
172 Int_t idModule=Module(fidCircuit); // corresponding module Id.
173 Int_t nStrX=nStripX[ModuleNumber(idModule)]; // and its number of X strips
174 Int_t nStrY=nStripY[ModuleNumber(idModule)]; // and its number of Y strips
175 Int_t iPosCircuit=Position(fidCircuit); // position of circuit in module
177 // first step : look at lower part
178 if (iPosCircuit==1) { // need to scan lower module
179 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) {
181 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
182 Int_t nStrD=nStripY[ModuleNumber(idModuleD)];
185 &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {
186 if (nStrY==8) fx2m=1;
187 if (nStrD==8) fx2ud=1;
191 } else { // lower strips within same module
195 // second step : look at upper part
196 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
197 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
198 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
200 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
201 Int_t nStrU=nStripY[ModuleNumber(idModuleU)];
204 &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {
205 if (nStrY==8) fx2m=1;
206 if (nStrU==8) fx2ud=1;
210 } else { // upper strips within same module
215 //----------------------------------------------------------------------
216 void AliMUONTriggerCircuit::LoadXCode(){
217 // assign a Id. number to each X strip of current circuit
218 // Id.=(corresponding module Id.)*100+(Id. strip of module)
220 // first part : fill XMC11 XMC12 and strips 8 to 24 (middle) XMC21 XMC22
221 Int_t iStripCircMT1=0, iStripCircMT2=8;
222 Int_t idModule=Module(fidCircuit); // corresponding module Id.
223 Int_t nStrX=nStripX[ModuleNumber(idModule)]; // and its number of strips
224 Int_t iPosCircuit=Position(fidCircuit); // position of circuit in module
225 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
227 for (Int_t istrip=(iPosCircuit-1)*16;
228 istrip<(iPosCircuit-1)*16+16; istrip++) {
230 fXcode[0][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
231 fXcode[1][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
232 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
233 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
239 // XMC21 XMC22 strips 0 to 7 and 24 to 31
240 Int_t idModuleD, idModuleU;
243 idModule=Module(fidCircuit); // corresponding module Id.
244 nStrX=nStripX[ModuleNumber(idModule)]; // number of X strips
245 sign=TMath::Abs(idModule)/idModule;
247 // fill lower part (0 to 7)
248 if (iPosCircuit==1) { // need to scan lower module
249 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { // non-existing
250 idModuleD=sign*(TMath::Abs(idModule)+10); // lower module Id
251 nStrD=nStripX[ModuleNumber(idModuleD)]; // and its number of strips
254 for (Int_t istrip=nStrD-8; istrip<nStrD; istrip++) {
255 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
256 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
261 } else { // lower strips within same module
264 for (Int_t istrip=(iPosCircuit-1)*16-8;
265 istrip<(iPosCircuit-1)*16; istrip++) {
266 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
267 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
272 // fill upper part (24 to 31)
273 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
274 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
275 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
276 idModuleU=sign*(TMath::Abs(idModule)-10); // upper module Id
277 nStrU=nStripX[ModuleNumber(idModuleU)]; // and its number of strips
280 for (Int_t istrip=0; istrip<8; istrip++) {
281 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
282 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
287 } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)||
288 (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod.
291 for (Int_t istrip=(iPosCircuit-1)*16+16;
292 istrip<(iPosCircuit-1)*16+24; istrip++) {
293 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
294 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
300 //----------------------------------------------------------------------
301 void AliMUONTriggerCircuit::LoadYCode(){
302 // assign a Id. number to each Y strip of current circuit
303 // Id.=(corresponding module Id.)*100+(Id. strip of module)
304 // note : for Y plane fill only "central part" of circuit
305 // (upper and lower parts are filled in PreHandlingY of AliMUONTriggerDecision)
307 Int_t idModule=Module(fidCircuit); // corresponding module Id.
308 Int_t nStrY=nStripY[ModuleNumber(idModule)]; // its number of Y strips
309 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
311 for (Int_t istrip=0; istrip<nStrY; istrip++) {
312 fYcode[0][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
313 fYcode[1][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
314 fYcode[2][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
315 fYcode[3][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
319 //----------------------------------------------------------------------
320 void AliMUONTriggerCircuit::LoadYPos(){
321 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
323 Int_t chamber, cathode;
324 Int_t code, idModule, idStrip, idSector;
327 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
328 AliMUONChamber* iChamber;
329 AliMUONSegmentation* segmentation;
334 iChamber = &(pMUON->Chamber(chamber-1));
335 segmentation=iChamber->SegmentationModel(cathode);
337 for (Int_t istrip=0; istrip<16; istrip++) {
338 code=fXcode[0][istrip]; // decode current strip
339 idModule=Int_t(code/100); // corresponding module Id.
340 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
341 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
342 width=segmentation->Dpy(idSector); // corresponding strip width
343 segmentation->GetPadCxy(idModule,idStrip,x,y); // get strip real position
346 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
352 iChamber = &(pMUON->Chamber(chamber-1));
353 segmentation=iChamber->SegmentationModel(cathode);
355 for (Int_t istrip=0; istrip<32; istrip++) {
356 code=fXcode[2][istrip]; // decode current strip
357 idModule=Int_t(code/100); // corresponding module Id.
358 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
359 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
360 width=segmentation->Dpy(idSector); // corresponding strip width
361 segmentation->GetPadCxy(idModule,idStrip,x,y); // get strip real position
363 // using idModule!=0 prevents to fill garbage in case of circuits
364 // in the first and last rows
367 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
372 //----------------------------------------------------------------------
373 void AliMUONTriggerCircuit::LoadXPos(){
374 // fill fXpos11 -> x position of Y strips for the first plane only
375 // fXpos11 contains the x position of Y strip for the current circuit
376 // taking into account whether or nor not part(s) of the circuit
377 // (middle, up or down) has(have) 16 strips
383 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
384 AliMUONChamber* iChamber;
385 AliMUONSegmentation* segmentation;
386 iChamber = &(pMUON->Chamber(chamber-1));
387 segmentation=iChamber->SegmentationModel(cathode);
389 Int_t idModule=Module(fidCircuit); // corresponding module Id.
390 Int_t nStrY=nStripY[ModuleNumber(idModule)]; // number of Y strips
391 Int_t idSector=segmentation->Sector(idModule,0); // corresp. sector
392 Float_t width=segmentation->Dpx(idSector); // corresponding strip width
394 // first case : up middle and down parts have all 8 or 16 strip
395 if ((nStrY==16)||(nStrY==8&&fx2m==0&&fx2ud==0)) {
396 for (Int_t istrip=0; istrip<nStrY; istrip++) {
397 segmentation->GetPadCxy(idModule,istrip,x,y);
400 // second case : mixing 8 and 16 strips within same circuit
402 for (Int_t istrip=0; istrip<nStrY; istrip++) {
403 if (nStrY!=8) { cout << " bug in LoadXpos " << "\n";}
404 segmentation->GetPadCxy(idModule,istrip,x,y);
405 fXpos11[2*istrip]=x-width/4.;
406 fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.;
411 //----------------------------------------------------------------------
412 Float_t AliMUONTriggerCircuit::PtCal(Int_t istripX, Int_t idev, Int_t istripY){
413 // returns calculated pt for circuit/istripX/idev/istripY according
414 // to the formula of the TRD. Note : idev (input) is in [0+30]
416 // Int_t jdev = idev - 15; // jdev in [-15+15]
417 Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
419 Float_t yPosX1=fYpos11[istripX];
420 Float_t yPosX2=fYpos21[istripX2];
421 Float_t xPosY1=fXpos11[istripY];
423 Float_t zf=975., z1=1603.5, z2=1703.5;
424 Float_t thetaDev=(1./zf)*(yPosX1*z2-yPosX2*z1)/(z2-z1);
425 Float_t xf=xPosY1*zf/z1;
426 Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1);
427 return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/zf;
430 //----------------------------------------------------------------------
431 //--- methods which return member data related info
432 //----------------------------------------------------------------------
433 Int_t AliMUONTriggerCircuit::GetIdCircuit(){
434 // returns circuit Id
437 //----------------------------------------------------------------------
438 Int_t AliMUONTriggerCircuit::GetIdModule(){
440 return Module(fidCircuit);
442 //----------------------------------------------------------------------
443 Int_t AliMUONTriggerCircuit::GetNstripX() {
444 // returns the number of X strips in the module where the circuit is sitting
445 return nStripX[ModuleNumber(Module(fidCircuit))];
447 //----------------------------------------------------------------------
448 Int_t AliMUONTriggerCircuit::GetNstripY() {
449 // returns the number of Y strips in the module where the circuit is sitting
450 return nStripY[ModuleNumber(Module(fidCircuit))];
452 //----------------------------------------------------------------------
453 Int_t AliMUONTriggerCircuit::GetPosCircuit() {
454 // returns the position of the circuit in its module
455 return Position(fidCircuit);
457 //----------------------------------------------------------------------
458 Int_t AliMUONTriggerCircuit::GetIdCircuitD(){
459 // returns the Id of the circuit down
460 Int_t idModule=Module(fidCircuit);
461 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
462 return (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
464 //----------------------------------------------------------------------
465 Int_t AliMUONTriggerCircuit::GetICircuitD(){
466 // returns the number of the circuit down
467 Int_t idModule=Module(fidCircuit);
468 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
470 (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
471 return CircuitNumber(idCircuitD);
473 //----------------------------------------------------------------------
474 Int_t AliMUONTriggerCircuit::GetIdCircuitU(){
475 // returns the Id of the circuit up
476 Int_t idModule=Module(fidCircuit);
477 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
478 return (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
480 //----------------------------------------------------------------------
481 Int_t AliMUONTriggerCircuit::GetICircuitU(){
482 // returns the number of the circuit up
483 Int_t idModule=Module(fidCircuit);
484 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
486 (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
487 return CircuitNumber(idCircuitU);
489 //----------------------------------------------------------------------
490 Int_t AliMUONTriggerCircuit::GetX2m(){
494 //----------------------------------------------------------------------
495 Int_t AliMUONTriggerCircuit::GetX2ud(){
499 //----------------------------------------------------------------------
500 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){
505 //----------------------------------------------------------------------
506 Int_t AliMUONTriggerCircuit::GetXcode(Int_t chamber, Int_t istrip){
507 // returns X code of circuit/chamber/istrip (warning : chamber in [0,3])
508 return fXcode[chamber][istrip];
510 //----------------------------------------------------------------------
511 Int_t AliMUONTriggerCircuit::GetYcode(Int_t chamber, Int_t istrip){
512 // returns Y code of circuit/chamber/istrip (warning : chamber in [0,3])
513 return fYcode[chamber][istrip];
515 //----------------------------------------------------------------------
516 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){
517 // returns Y position of X strip istrip in MC11
518 return fYpos11[istrip];
520 //----------------------------------------------------------------------
521 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){
522 // returns Y position of X strip istrip in MC21
523 return fYpos21[istrip];
525 //----------------------------------------------------------------------
526 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){
527 // returns X position of Y strip istrip in MC11
528 return fXpos11[istrip];
530 //----------------------------------------------------------------------
531 //--- end of methods which return member data related info
532 //----------------------------------------------------------------------