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.7 2000/10/02 16:58:29 egangler
18 Cleaning of the code :
21 -> some useless includes removed or replaced by "class" statement
23 Revision 1.6 2000/07/13 16:19:44 fca
24 Mainly coding conventions + some small bug fixes
26 Revision 1.5 2000/07/03 11:54:57 morsch
27 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
28 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
30 Revision 1.4 2000/06/28 15:16:35 morsch
31 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
32 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
33 framework. The changes should have no side effects (mostly dummy arguments).
34 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
35 of chambers with overlapping modules (MakePadHits, Disintegration).
37 Revision 1.3 2000/06/26 10:04:49 pcrochet
38 problem with HP compiler solved (PH), static variables removed : now defined in AliMUONTriggerConstants
44 #include "AliMUONTriggerCircuit.h"
45 #include "AliMUONTriggerConstants.h"
46 #include "AliSegmentation.h"
47 #include "AliMUONResponse.h"
48 #include "AliMUONChamber.h"
52 ClassImp(AliMUONTriggerCircuit)
54 //----------------------------------------------------------------------
55 AliMUONTriggerCircuit::AliMUONTriggerCircuit()
62 fOrMud[0]=fOrMud[1]=0;
65 for (Int_t j=0; j<32; j++) {
70 for (i=0; i<16; i++) { fXpos11[i]=0.; }
71 for (i=0; i<31; i++) { fYpos11[i]=0.; }
72 for (i=0; i<63; i++) { fYpos21[i]=0.; }
75 //----------------------------------------------------------------------
76 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit)
78 // Dummy copy constructor
81 //----------------------------------------------------------------------
82 AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit)
84 // Dummy assignment operator
88 //----------------------------------------------------------------------
89 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
90 // initialize circuit characteristics
91 fIdCircuit=AliMUONTriggerConstants::CircuitId(iCircuit);
99 //----------------------------------------------------------------------
100 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){
101 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
103 for (Int_t i=0; i<234; i++) {
104 if (AliMUONTriggerConstants::CircuitId(i)==idCircuit) {
111 //----------------------------------------------------------------------
112 Int_t AliMUONTriggerCircuit::ModuleNumber(Int_t idModule){
113 // returns module number imod (from 0 to 63) corresponding to module idmodule
114 Int_t absidModule=TMath::Abs(idModule);
116 for (Int_t i=0; i<63; i++) {
117 if (AliMUONTriggerConstants::ModuleId(i)==absidModule) {
125 //----------------------------------------------------------------------
126 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) {
127 // returns ModuleId where Circuit idCircuit is sitting
128 return Int_t(idCircuit/10);
130 //----------------------------------------------------------------------
131 Int_t AliMUONTriggerCircuit::Position(Int_t idCircuit) {
132 // returns position of idCircuit in correcponding Module
133 return TMath::Abs(idCircuit)-TMath::Abs(Module(idCircuit))*10;
136 //----------------------------------------------------------------------
137 void AliMUONTriggerCircuit::LoadX2() {
138 // initialize fX2m, fX2ud and fOrMud
140 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
141 // and its number of X strips
142 Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
143 // and its number of Y strips
144 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
145 Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
147 // first step : look at lower part
148 if (iPosCircuit==1) { // need to scan lower module
149 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) {
151 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
152 Int_t nStrD=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleD));
155 &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {
156 if (nStrY==8) fX2m=1;
157 if (nStrD==8) fX2ud=1;
161 } else { // lower strips within same module
165 // second step : look at upper part
166 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
167 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
168 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
170 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
171 Int_t nStrU=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleU));
174 &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {
175 if (nStrY==8) fX2m=1;
176 if (nStrU==8) fX2ud=1;
180 } else { // upper strips within same module
185 //----------------------------------------------------------------------
186 void AliMUONTriggerCircuit::LoadXCode(){
187 // assign a Id. number to each X strip of current circuit
188 // Id.=(corresponding module Id.)*100+(Id. strip of module)
190 // first part : fill XMC11 XMC12 and strips 8 to 24 (middle) XMC21 XMC22
191 Int_t iStripCircMT1=0, iStripCircMT2=8;
192 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
193 // and its number of strips
194 Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
195 Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
196 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
199 for (istrip=(iPosCircuit-1)*16;
200 istrip<(iPosCircuit-1)*16+16; istrip++) {
202 fXcode[0][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
203 fXcode[1][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
204 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
205 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
211 // XMC21 XMC22 strips 0 to 7 and 24 to 31
212 Int_t idModuleD, idModuleU;
215 idModule=Module(fIdCircuit); // corresponding module Id.
216 // number of X strips
217 nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
218 sign=TMath::Abs(idModule)/idModule;
220 // fill lower part (0 to 7)
221 if (iPosCircuit==1) { // need to scan lower module
222 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { // non-existing
223 idModuleD=sign*(TMath::Abs(idModule)+10); // lower module Id
224 // and its number of strips
225 nStrD=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleD));
228 for (istrip=nStrD-8; istrip<nStrD; istrip++) {
229 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
230 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
235 } else { // lower strips within same module
238 for (istrip=(iPosCircuit-1)*16-8;
239 istrip<(iPosCircuit-1)*16; istrip++) {
240 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
241 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
246 // fill upper part (24 to 31)
247 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
248 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
249 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
250 idModuleU=sign*(TMath::Abs(idModule)-10); // upper module Id
251 // and its number of strips
252 nStrU=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleU));
255 for (istrip=0; istrip<8; istrip++) {
256 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
257 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
262 } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)||
263 (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod.
266 for (istrip=(iPosCircuit-1)*16+16;
267 istrip<(iPosCircuit-1)*16+24; istrip++) {
268 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
269 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
275 //----------------------------------------------------------------------
276 void AliMUONTriggerCircuit::LoadYCode(){
277 // assign a Id. number to each Y strip of current circuit
278 // Id.=(corresponding module Id.)*100+(Id. strip of module)
279 // note : for Y plane fill only "central part" of circuit
280 // (upper and lower parts are filled in PreHandlingY of AliMUONTriggerDecision)
282 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
283 // and its number of Y strips
284 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
285 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
287 for (Int_t istrip=0; istrip<nStrY; istrip++) {
288 fYcode[0][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
289 fYcode[1][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
290 fYcode[2][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
291 fYcode[3][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
295 //----------------------------------------------------------------------
296 void AliMUONTriggerCircuit::LoadYPos(){
297 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
299 Int_t chamber, cathode;
300 Int_t code, idModule, idStrip, idSector;
301 Float_t x, y, z, width;
304 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
305 AliMUONChamber* iChamber;
306 AliSegmentation* segmentation;
311 iChamber = &(pMUON->Chamber(chamber-1));
312 segmentation=iChamber->SegmentationModel(cathode);
314 for (istrip=0; istrip<16; istrip++) {
315 code=fXcode[0][istrip]; // decode current strip
316 idModule=Int_t(code/100); // corresponding module Id.
317 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
318 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
319 width=segmentation->Dpy(idSector); // corresponding strip width
320 segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
323 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
329 iChamber = &(pMUON->Chamber(chamber-1));
330 segmentation=iChamber->SegmentationModel(cathode);
332 for (istrip=0; istrip<32; istrip++) {
333 code=fXcode[2][istrip]; // decode current strip
334 idModule=Int_t(code/100); // corresponding module Id.
335 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
336 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
337 width=segmentation->Dpy(idSector); // corresponding strip width
338 segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
340 // using idModule!=0 prevents to fill garbage in case of circuits
341 // in the first and last rows
344 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
349 //----------------------------------------------------------------------
350 void AliMUONTriggerCircuit::LoadXPos(){
351 // fill fXpos11 -> x position of Y strips for the first plane only
352 // fXpos11 contains the x position of Y strip for the current circuit
353 // taking into account whether or nor not part(s) of the circuit
354 // (middle, up or down) has(have) 16 strips
361 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
362 AliMUONChamber* iChamber;
363 AliSegmentation* segmentation;
364 iChamber = &(pMUON->Chamber(chamber-1));
365 segmentation=iChamber->SegmentationModel(cathode);
367 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
368 // number of Y strips
369 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
370 Int_t idSector=segmentation->Sector(idModule,0); // corresp. sector
371 Float_t width=segmentation->Dpx(idSector); // corresponding strip width
373 // first case : up middle and down parts have all 8 or 16 strip
374 if ((nStrY==16)||(nStrY==8&&fX2m==0&&fX2ud==0)) {
375 for (istrip=0; istrip<nStrY; istrip++) {
376 segmentation->GetPadC(idModule,istrip,x,y,z);
379 // second case : mixing 8 and 16 strips within same circuit
381 for (istrip=0; istrip<nStrY; istrip++) {
382 if (nStrY!=8) { cout << " bug in LoadXpos " << "\n";}
383 segmentation->GetPadC(idModule,istrip,x,y,z);
384 fXpos11[2*istrip]=x-width/4.;
385 fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.;
390 //----------------------------------------------------------------------
391 Float_t AliMUONTriggerCircuit::PtCal(Int_t istripX, Int_t idev, Int_t istripY){
392 // returns calculated pt for circuit/istripX/idev/istripY according
393 // to the formula of the TRD. Note : idev (input) is in [0+30]
395 // Int_t jdev = idev - 15; // jdev in [-15+15]
396 Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
398 Float_t yPosX1=fYpos11[istripX];
399 Float_t yPosX2=fYpos21[istripX2];
400 Float_t xPosY1=fXpos11[istripY];
402 Float_t zf=975., z1=1603.5, z2=1703.5;
403 Float_t thetaDev=(1./zf)*(yPosX1*z2-yPosX2*z1)/(z2-z1);
404 Float_t xf=xPosY1*zf/z1;
405 Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1);
406 return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/zf;
409 //----------------------------------------------------------------------
410 //--- methods which return member data related info
411 //----------------------------------------------------------------------
412 Int_t AliMUONTriggerCircuit::GetIdCircuit(){
413 // returns circuit Id
416 //----------------------------------------------------------------------
417 Int_t AliMUONTriggerCircuit::GetIdModule(){
419 return Module(fIdCircuit);
421 //----------------------------------------------------------------------
422 Int_t AliMUONTriggerCircuit::GetNstripX() {
423 // returns the number of X strips in the module where the circuit is sitting
424 return AliMUONTriggerConstants::NstripX(ModuleNumber(Module(fIdCircuit)));
426 //----------------------------------------------------------------------
427 Int_t AliMUONTriggerCircuit::GetNstripY() {
428 // returns the number of Y strips in the module where the circuit is sitting
429 return AliMUONTriggerConstants::NstripY(ModuleNumber(Module(fIdCircuit)));
431 //----------------------------------------------------------------------
432 Int_t AliMUONTriggerCircuit::GetPosCircuit() {
433 // returns the position of the circuit in its module
434 return Position(fIdCircuit);
436 //----------------------------------------------------------------------
437 Int_t AliMUONTriggerCircuit::GetIdCircuitD(){
438 // returns the Id of the circuit down
439 Int_t idModule=Module(fIdCircuit);
440 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
441 return (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
443 //----------------------------------------------------------------------
444 Int_t AliMUONTriggerCircuit::GetICircuitD(){
445 // returns the number of the circuit down
446 Int_t idModule=Module(fIdCircuit);
447 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
449 (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
450 return CircuitNumber(idCircuitD);
452 //----------------------------------------------------------------------
453 Int_t AliMUONTriggerCircuit::GetIdCircuitU(){
454 // returns the Id of the circuit up
455 Int_t idModule=Module(fIdCircuit);
456 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
457 return (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
459 //----------------------------------------------------------------------
460 Int_t AliMUONTriggerCircuit::GetICircuitU(){
461 // returns the number of the circuit up
462 Int_t idModule=Module(fIdCircuit);
463 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
465 (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
466 return CircuitNumber(idCircuitU);
468 //----------------------------------------------------------------------
469 Int_t AliMUONTriggerCircuit::GetX2m(){
473 //----------------------------------------------------------------------
474 Int_t AliMUONTriggerCircuit::GetX2ud(){
478 //----------------------------------------------------------------------
479 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){
484 //----------------------------------------------------------------------
485 Int_t AliMUONTriggerCircuit::GetXcode(Int_t chamber, Int_t istrip){
486 // returns X code of circuit/chamber/istrip (warning : chamber in [0,3])
487 return fXcode[chamber][istrip];
489 //----------------------------------------------------------------------
490 Int_t AliMUONTriggerCircuit::GetYcode(Int_t chamber, Int_t istrip){
491 // returns Y code of circuit/chamber/istrip (warning : chamber in [0,3])
492 return fYcode[chamber][istrip];
494 //----------------------------------------------------------------------
495 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){
496 // returns Y position of X strip istrip in MC11
497 return fYpos11[istrip];
499 //----------------------------------------------------------------------
500 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){
501 // returns Y position of X strip istrip in MC21
502 return fYpos21[istrip];
504 //----------------------------------------------------------------------
505 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){
506 // returns X position of Y strip istrip in MC11
507 return fXpos11[istrip];
509 //----------------------------------------------------------------------
510 //--- end of methods which return member data related info
511 //----------------------------------------------------------------------