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