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