05f15c0f7dbab907516ed6d62af95ef4cc0d74b2
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerCircuit.cxx
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 /*
16 $Log$
17 Revision 1.8  2001/03/20 13:32:37  egangler
18 includes cleanup
19
20 Revision 1.7  2000/10/02 16:58:29  egangler
21 Cleaning of the code :
22 -> coding conventions
23 -> void Streamers
24 -> some useless includes removed or replaced by "class" statement
25
26 Revision 1.6  2000/07/13 16:19:44  fca
27 Mainly coding conventions + some small bug fixes
28
29 Revision 1.5  2000/07/03 11:54:57  morsch
30 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
31 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
32
33 Revision 1.4  2000/06/28 15:16:35  morsch
34 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
35 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
36 framework. The changes should have no side effects (mostly dummy arguments).
37 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
38 of chambers with overlapping modules (MakePadHits, Disintegration).
39
40 Revision 1.3  2000/06/26 10:04:49  pcrochet
41 problem with HP compiler solved (PH), static variables removed : now defined in AliMUONTriggerConstants
42
43 */
44
45 #include "AliRun.h"
46 #include "AliMUON.h"
47 #include "AliMUONTriggerCircuit.h"
48 #include "AliMUONTriggerConstants.h"
49 #include "AliSegmentation.h"
50 #include "AliMUONResponse.h"
51 #include "AliMUONChamber.h"
52 #include "TMath.h"
53 #include "Riostream.h"
54
55 ClassImp(AliMUONTriggerCircuit)
56
57 //----------------------------------------------------------------------
58 AliMUONTriggerCircuit::AliMUONTriggerCircuit() 
59 {
60 // Constructor
61   fSegmentation=0;
62   fIdCircuit=0;
63   fX2m=0;
64   fX2ud=0;
65   fOrMud[0]=fOrMud[1]=0;
66   Int_t i;  
67   for (i=0; i<4; i++) {
68     for (Int_t j=0; j<32; j++) {      
69       fXcode[i][j]=0;
70       fYcode[i][j]=0;
71     }
72   }
73   for (i=0; i<16; i++) { fXpos11[i]=0.; }
74   for (i=0; i<31; i++) { fYpos11[i]=0.; }
75   for (i=0; i<63; i++) { fYpos21[i]=0.; }
76 }
77
78 //----------------------------------------------------------------------
79 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit)
80 {
81 // Dummy copy constructor
82 }
83
84 //----------------------------------------------------------------------
85 AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit)
86 {
87 // Dummy assignment operator
88     return *this;
89 }
90
91 //----------------------------------------------------------------------
92 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
93 // initialize circuit characteristics
94   fIdCircuit=AliMUONTriggerConstants::CircuitId(iCircuit);
95   LoadX2();
96   LoadXCode();
97   LoadYCode();
98   LoadXPos();
99   LoadYPos();
100 }
101
102 //----------------------------------------------------------------------
103 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){
104 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
105   Int_t iCircuit=0;
106   for (Int_t i=0; i<234; i++) {
107     if (AliMUONTriggerConstants::CircuitId(i)==idCircuit) {
108       iCircuit=i;
109       break;
110     }
111   }
112   return iCircuit;
113 }
114 //----------------------------------------------------------------------
115 Int_t AliMUONTriggerCircuit::ModuleNumber(Int_t idModule){
116 // returns module number imod (from 0 to 63) corresponding to module idmodule
117   Int_t absidModule=TMath::Abs(idModule);
118   Int_t iModule=0;
119   for (Int_t i=0; i<63; i++) {
120     if (AliMUONTriggerConstants::ModuleId(i)==absidModule) { 
121       iModule=i;
122       break;
123     }
124   }
125   return iModule;
126 }
127
128 //----------------------------------------------------------------------
129 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) {
130 // returns ModuleId where Circuit idCircuit is sitting
131   return Int_t(idCircuit/10);
132 }
133 //----------------------------------------------------------------------
134 Int_t AliMUONTriggerCircuit::Position(Int_t idCircuit) {
135 // returns position of idCircuit in correcponding Module
136   return TMath::Abs(idCircuit)-TMath::Abs(Module(idCircuit))*10;
137 }
138
139 //----------------------------------------------------------------------
140 void AliMUONTriggerCircuit::LoadX2() {
141 // initialize fX2m, fX2ud and fOrMud
142   
143   Int_t idModule=Module(fIdCircuit);        // corresponding module Id.
144 // and its number of X strips
145   Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule)); 
146 // and its number of Y strips
147   Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule)); 
148   Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
149   
150 // first step : look at lower part 
151   if (iPosCircuit==1) {               // need to scan lower module       
152     if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { 
153       fOrMud[0]=1;
154       Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule); 
155       Int_t nStrD=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleD));
156       
157       if (nStrY!=nStrD    
158           &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {   
159         if (nStrY==8) fX2m=1; 
160         if (nStrD==8) fX2ud=1; 
161       }      
162     }      
163
164   } else {                         // lower strips within same module       
165     fOrMud[0]=0;
166   }    
167   
168 // second step : look at upper part
169   if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)|| 
170       (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {   
171     if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {  
172       fOrMud[1]=1;
173       Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule); 
174       Int_t nStrU=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleU)); 
175
176       if (nStrY!=nStrU    
177           &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {   
178         if (nStrY==8) fX2m=1; 
179         if (nStrU==8) fX2ud=1;
180       }      
181     }     
182     
183   } else {                       // upper strips within same module       
184     fOrMud[1]=0;
185   }
186 }  
187
188 //----------------------------------------------------------------------
189 void AliMUONTriggerCircuit::LoadXCode(){
190 // assign a Id. number to each X strip of current circuit 
191 // Id.=(corresponding module Id.)*100+(Id. strip of module)
192
193 // first part : fill XMC11 XMC12 and strips 8 to 24 (middle) XMC21 XMC22
194   Int_t iStripCircMT1=0, iStripCircMT2=8;
195   Int_t idModule=Module(fIdCircuit);        // corresponding module Id.
196 // and its number of strips
197   Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule)); 
198   Int_t iPosCircuit=Position(fIdCircuit);   // position of circuit in module  
199   Int_t sign=TMath::Abs(idModule)/idModule; // left or right 
200   Int_t istrip;
201
202   for (istrip=(iPosCircuit-1)*16; 
203        istrip<(iPosCircuit-1)*16+16; istrip++) {
204         
205     fXcode[0][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip); 
206     fXcode[1][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip); 
207     fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); 
208     fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);     
209     iStripCircMT1++;
210     iStripCircMT2++;
211   }
212
213 // second part 
214 // XMC21 XMC22 strips 0 to 7 and 24 to 31 
215   Int_t idModuleD, idModuleU;
216   Int_t nStrD, nStrU;
217
218   idModule=Module(fIdCircuit); // corresponding module Id.
219 // number of X strips
220   nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));  
221   sign=TMath::Abs(idModule)/idModule;
222
223 // fill lower part (0 to 7)
224   if (iPosCircuit==1) {                 // need to scan lower module 
225     if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { // non-existing
226       idModuleD=sign*(TMath::Abs(idModule)+10);  // lower module Id
227 // and its number of strips
228       nStrD=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleD)); 
229       
230       iStripCircMT2=0;
231       for (istrip=nStrD-8; istrip<nStrD; istrip++) {  
232         fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip); 
233         fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip); 
234         iStripCircMT2++;
235       }
236     }
237      
238   } else {                       // lower strips within same module 
239     
240     iStripCircMT2=0;
241     for (istrip=(iPosCircuit-1)*16-8; 
242          istrip<(iPosCircuit-1)*16; istrip++) {  
243       fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); 
244       fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); 
245       iStripCircMT2++;
246     }
247   }
248   
249 // fill upper part (24 to 31)
250   if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)|| 
251       (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {   
252     if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {  
253       idModuleU=sign*(TMath::Abs(idModule)-10);  // upper module Id
254 // and its number of strips
255       nStrU=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleU)); 
256       
257       iStripCircMT2=24;
258       for (istrip=0; istrip<8; istrip++) {        
259         fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip); 
260         fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip); 
261         iStripCircMT2++;
262       }
263     }
264     
265   } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)|| 
266              (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod. 
267     
268     iStripCircMT2=24;
269     for (istrip=(iPosCircuit-1)*16+16; 
270          istrip<(iPosCircuit-1)*16+24; istrip++) {  
271       fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); 
272       fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); 
273       iStripCircMT2++;
274     }   
275   }
276 }
277
278 //----------------------------------------------------------------------
279 void AliMUONTriggerCircuit::LoadYCode(){
280 // assign a Id. number to each Y strip of current circuit 
281 // Id.=(corresponding module Id.)*100+(Id. strip of module)
282 // note : for Y plane fill only "central part" of circuit
283 // (upper and lower parts are filled in PreHandlingY of AliMUONTriggerDecision)
284     
285   Int_t idModule=Module(fIdCircuit);        // corresponding module Id.
286 // and its number of Y strips
287   Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule)); 
288   Int_t sign=TMath::Abs(idModule)/idModule; // left or right 
289
290   for (Int_t istrip=0; istrip<nStrY; istrip++) {
291     fYcode[0][istrip]=sign*(TMath::Abs(idModule)*100+istrip); 
292     fYcode[1][istrip]=sign*(TMath::Abs(idModule)*100+istrip); 
293     fYcode[2][istrip]=sign*(TMath::Abs(idModule)*100+istrip); 
294     fYcode[3][istrip]=sign*(TMath::Abs(idModule)*100+istrip); 
295   }
296 }
297
298 //----------------------------------------------------------------------
299 void AliMUONTriggerCircuit::LoadYPos(){
300 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
301
302   Int_t chamber, cathode;
303   Int_t code, idModule, idStrip, idSector;
304   Float_t x, y, z, width;
305   Int_t istrip;
306
307   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");  
308   AliMUONChamber*  iChamber;
309   AliSegmentation*  segmentation;    
310
311 // first plane (11)
312   chamber=11;
313   cathode=1;
314   iChamber = &(pMUON->Chamber(chamber-1));
315   segmentation=iChamber->SegmentationModel(cathode);
316   
317   for (istrip=0; istrip<16; istrip++) {
318     code=fXcode[0][istrip];           // decode current strip
319     idModule=Int_t(code/100);           // corresponding module Id.
320     idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
321     idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
322     width=segmentation->Dpy(idSector);      // corresponding strip width
323     segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
324     
325     fYpos11[2*istrip]=y;
326     if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
327   }   
328    
329 // second plane (21)
330   chamber=13;
331   cathode=1;
332   iChamber = &(pMUON->Chamber(chamber-1));
333   segmentation=iChamber->SegmentationModel(cathode);
334   
335   for (istrip=0; istrip<32; istrip++) {
336     code=fXcode[2][istrip];    // decode current strip
337     idModule=Int_t(code/100);           // corresponding module Id.
338     idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
339     idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
340     width=segmentation->Dpy(idSector);      // corresponding strip width
341     segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
342     
343 // using idModule!=0 prevents to fill garbage in case of circuits 
344 // in the first and last rows 
345     if (idModule!=0) { 
346       fYpos21[2*istrip]=y;
347       if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
348     }
349   }   
350 }
351
352 //----------------------------------------------------------------------
353 void AliMUONTriggerCircuit::LoadXPos(){
354 // fill fXpos11 -> x position of Y strips for the first plane only
355 // fXpos11 contains the x position of Y strip for the current circuit
356 // taking into account whether or nor not part(s) of the circuit
357 // (middle, up or down) has(have) 16 strips
358   
359   Float_t x, y, z;
360   Int_t istrip;  
361
362   Int_t chamber=11;
363   Int_t cathode=2;
364   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");  
365   AliMUONChamber*  iChamber;
366   AliSegmentation*  segmentation; 
367   iChamber = &(pMUON->Chamber(chamber-1));
368   segmentation=iChamber->SegmentationModel(cathode);
369   
370   Int_t idModule=Module(fIdCircuit);        // corresponding module Id.  
371 // number of Y strips
372   Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule)); 
373   Int_t idSector=segmentation->Sector(idModule,0); // corresp. sector
374   Float_t width=segmentation->Dpx(idSector);      // corresponding strip width
375   
376 // first case : up middle and down parts have all 8 or 16 strip 
377   if ((nStrY==16)||(nStrY==8&&fX2m==0&&fX2ud==0)) { 
378     for (istrip=0; istrip<nStrY; istrip++) {
379       segmentation->GetPadC(idModule,istrip,x,y,z); 
380       fXpos11[istrip]=x;
381     }
382 // second case : mixing 8 and 16 strips within same circuit      
383   } else {
384     for (istrip=0; istrip<nStrY; istrip++) {
385       if (nStrY!=8) { cout << " bug in LoadXpos " << "\n";}
386       segmentation->GetPadC(idModule,istrip,x,y,z); 
387       fXpos11[2*istrip]=x-width/4.;
388       fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.;
389     }
390   }   
391 }
392
393 //----------------------------------------------------------------------
394 Float_t AliMUONTriggerCircuit::PtCal(Int_t istripX, Int_t idev, Int_t istripY){
395 // returns calculated pt for circuit/istripX/idev/istripY according 
396 // to the formula of the TRD. Note : idev (input) is in [0+30]
397
398   //  Int_t jdev = idev - 15;        // jdev in [-15+15]
399   Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
400
401   Float_t yPosX1=fYpos11[istripX];
402   Float_t yPosX2=fYpos21[istripX2];
403   Float_t xPosY1=fXpos11[istripY];
404   
405   Float_t zf=975., z1=1603.5, z2=1703.5;
406   Float_t thetaDev=(1./zf)*(yPosX1*z2-yPosX2*z1)/(z2-z1);
407   Float_t xf=xPosY1*zf/z1; 
408   Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1);
409   return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/zf;
410 }
411
412 //----------------------------------------------------------------------
413 //--- methods which return member data related info
414 //----------------------------------------------------------------------
415 Int_t AliMUONTriggerCircuit::GetIdCircuit(){ 
416 // returns circuit Id
417   return fIdCircuit;
418 }
419 //----------------------------------------------------------------------
420 Int_t AliMUONTriggerCircuit::GetIdModule(){ 
421 // returns module Id
422   return Module(fIdCircuit);
423 }
424 //----------------------------------------------------------------------
425 Int_t AliMUONTriggerCircuit::GetNstripX() { 
426 // returns the number of X strips in the module where the circuit is sitting
427   return AliMUONTriggerConstants::NstripX(ModuleNumber(Module(fIdCircuit)));
428 }
429 //----------------------------------------------------------------------
430 Int_t AliMUONTriggerCircuit::GetNstripY() { 
431 // returns the number of Y strips in the module where the circuit is sitting
432   return AliMUONTriggerConstants::NstripY(ModuleNumber(Module(fIdCircuit)));
433 }
434 //----------------------------------------------------------------------
435 Int_t AliMUONTriggerCircuit::GetPosCircuit() { 
436 // returns the position of the circuit in its module
437   return Position(fIdCircuit);
438 }
439 //----------------------------------------------------------------------
440 Int_t AliMUONTriggerCircuit::GetIdCircuitD(){
441 // returns the Id of the circuit down 
442   Int_t idModule=Module(fIdCircuit);
443   Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule); 
444   return (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
445 }
446 //----------------------------------------------------------------------
447 Int_t AliMUONTriggerCircuit::GetICircuitD(){
448 // returns the number of the circuit down 
449   Int_t idModule=Module(fIdCircuit);
450   Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule); 
451   Int_t idCircuitD=
452     (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
453   return CircuitNumber(idCircuitD);
454 }
455 //----------------------------------------------------------------------
456 Int_t AliMUONTriggerCircuit::GetIdCircuitU(){
457 // returns the Id of the circuit up 
458   Int_t idModule=Module(fIdCircuit);
459   Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule); 
460   return (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
461 }
462 //----------------------------------------------------------------------
463 Int_t AliMUONTriggerCircuit::GetICircuitU(){
464 // returns the number of the circuit up 
465   Int_t idModule=Module(fIdCircuit);
466   Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule); 
467   Int_t idCircuitU=
468     (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
469   return CircuitNumber(idCircuitU);
470 }
471 //----------------------------------------------------------------------
472 Int_t AliMUONTriggerCircuit::GetX2m(){ 
473 // returns fX2m
474   return fX2m;
475 }
476 //----------------------------------------------------------------------
477 Int_t AliMUONTriggerCircuit::GetX2ud(){ 
478 // returns fX2ud
479   return fX2ud;
480 }
481 //----------------------------------------------------------------------
482 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){
483 // returns fOrMud 
484   orMud[0]=fOrMud[0];
485   orMud[1]=fOrMud[1];
486 }
487 //----------------------------------------------------------------------
488 Int_t AliMUONTriggerCircuit::GetXcode(Int_t chamber, Int_t istrip){
489 // returns X code of circuit/chamber/istrip (warning : chamber in [0,3])
490   return fXcode[chamber][istrip];
491 }
492 //----------------------------------------------------------------------
493 Int_t AliMUONTriggerCircuit::GetYcode(Int_t chamber, Int_t istrip){
494 // returns Y code of circuit/chamber/istrip (warning : chamber in [0,3])
495   return fYcode[chamber][istrip];
496 }
497 //----------------------------------------------------------------------
498 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){
499 // returns Y position of X strip istrip in MC11
500   return fYpos11[istrip];
501 }
502 //----------------------------------------------------------------------
503 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){
504 // returns Y position of X strip istrip in MC21
505   return fYpos21[istrip];
506 }
507 //----------------------------------------------------------------------
508 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){
509 // returns X position of Y strip istrip in MC11
510   return fXpos11[istrip];
511 }
512 //----------------------------------------------------------------------
513 //--- end of methods which return member data related info
514 //----------------------------------------------------------------------
515
516
517
518
519
520
521