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 **************************************************************************/
17 Revision 1.8 2001/03/20 13:32:37 egangler
20 Revision 1.7 2000/10/02 16:58:29 egangler
21 Cleaning of the code :
24 -> some useless includes removed or replaced by "class" statement
26 Revision 1.6 2000/07/13 16:19:44 fca
27 Mainly coding conventions + some small bug fixes
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.
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).
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
47 #include "AliMUONTriggerCircuit.h"
48 #include "AliMUONTriggerConstants.h"
49 #include "AliSegmentation.h"
50 #include "AliMUONResponse.h"
51 #include "AliMUONChamber.h"
53 #include "Riostream.h"
55 ClassImp(AliMUONTriggerCircuit)
57 //----------------------------------------------------------------------
58 AliMUONTriggerCircuit::AliMUONTriggerCircuit()
65 fOrMud[0]=fOrMud[1]=0;
68 for (Int_t j=0; j<32; j++) {
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.; }
78 //----------------------------------------------------------------------
79 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit)
81 // Dummy copy constructor
84 //----------------------------------------------------------------------
85 AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit)
87 // Dummy assignment operator
91 //----------------------------------------------------------------------
92 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
93 // initialize circuit characteristics
94 fIdCircuit=AliMUONTriggerConstants::CircuitId(iCircuit);
102 //----------------------------------------------------------------------
103 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){
104 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
106 for (Int_t i=0; i<234; i++) {
107 if (AliMUONTriggerConstants::CircuitId(i)==idCircuit) {
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);
119 for (Int_t i=0; i<63; i++) {
120 if (AliMUONTriggerConstants::ModuleId(i)==absidModule) {
128 //----------------------------------------------------------------------
129 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) {
130 // returns ModuleId where Circuit idCircuit is sitting
131 return Int_t(idCircuit/10);
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;
139 //----------------------------------------------------------------------
140 void AliMUONTriggerCircuit::LoadX2() {
141 // initialize fX2m, fX2ud and fOrMud
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
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) {
154 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
155 Int_t nStrD=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleD));
158 &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {
159 if (nStrY==8) fX2m=1;
160 if (nStrD==8) fX2ud=1;
164 } else { // lower strips within same module
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) {
173 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
174 Int_t nStrU=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleU));
177 &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {
178 if (nStrY==8) fX2m=1;
179 if (nStrU==8) fX2ud=1;
183 } else { // upper strips within same module
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)
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
202 for (istrip=(iPosCircuit-1)*16;
203 istrip<(iPosCircuit-1)*16+16; istrip++) {
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);
214 // XMC21 XMC22 strips 0 to 7 and 24 to 31
215 Int_t idModuleD, idModuleU;
218 idModule=Module(fIdCircuit); // corresponding module Id.
219 // number of X strips
220 nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
221 sign=TMath::Abs(idModule)/idModule;
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));
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);
238 } else { // lower strips within same module
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);
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));
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);
265 } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)||
266 (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod.
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);
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)
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
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);
298 //----------------------------------------------------------------------
299 void AliMUONTriggerCircuit::LoadYPos(){
300 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
302 Int_t chamber, cathode;
303 Int_t code, idModule, idStrip, idSector;
304 Float_t x, y, z, width;
307 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
308 AliMUONChamber* iChamber;
309 AliSegmentation* segmentation;
314 iChamber = &(pMUON->Chamber(chamber-1));
315 segmentation=iChamber->SegmentationModel(cathode);
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
326 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
332 iChamber = &(pMUON->Chamber(chamber-1));
333 segmentation=iChamber->SegmentationModel(cathode);
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
343 // using idModule!=0 prevents to fill garbage in case of circuits
344 // in the first and last rows
347 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
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
364 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
365 AliMUONChamber* iChamber;
366 AliSegmentation* segmentation;
367 iChamber = &(pMUON->Chamber(chamber-1));
368 segmentation=iChamber->SegmentationModel(cathode);
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
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);
382 // second case : mixing 8 and 16 strips within same circuit
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.;
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]
398 // Int_t jdev = idev - 15; // jdev in [-15+15]
399 Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
401 Float_t yPosX1=fYpos11[istripX];
402 Float_t yPosX2=fYpos21[istripX2];
403 Float_t xPosY1=fXpos11[istripY];
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;
412 //----------------------------------------------------------------------
413 //--- methods which return member data related info
414 //----------------------------------------------------------------------
415 Int_t AliMUONTriggerCircuit::GetIdCircuit(){
416 // returns circuit Id
419 //----------------------------------------------------------------------
420 Int_t AliMUONTriggerCircuit::GetIdModule(){
422 return Module(fIdCircuit);
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)));
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)));
434 //----------------------------------------------------------------------
435 Int_t AliMUONTriggerCircuit::GetPosCircuit() {
436 // returns the position of the circuit in its module
437 return Position(fIdCircuit);
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);
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);
452 (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
453 return CircuitNumber(idCircuitD);
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);
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);
468 (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
469 return CircuitNumber(idCircuitU);
471 //----------------------------------------------------------------------
472 Int_t AliMUONTriggerCircuit::GetX2m(){
476 //----------------------------------------------------------------------
477 Int_t AliMUONTriggerCircuit::GetX2ud(){
481 //----------------------------------------------------------------------
482 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){
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];
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];
497 //----------------------------------------------------------------------
498 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){
499 // returns Y position of X strip istrip in MC11
500 return fYpos11[istrip];
502 //----------------------------------------------------------------------
503 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){
504 // returns Y position of X strip istrip in MC21
505 return fYpos21[istrip];
507 //----------------------------------------------------------------------
508 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){
509 // returns X position of Y strip istrip in MC11
510 return fXpos11[istrip];
512 //----------------------------------------------------------------------
513 //--- end of methods which return member data related info
514 //----------------------------------------------------------------------