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.9 2002/10/23 07:24:56 alibrary
18 Introducing Riostream.h
20 Revision 1.8 2001/03/20 13:32:37 egangler
23 Revision 1.7 2000/10/02 16:58:29 egangler
24 Cleaning of the code :
27 -> some useless includes removed or replaced by "class" statement
29 Revision 1.6 2000/07/13 16:19:44 fca
30 Mainly coding conventions + some small bug fixes
32 Revision 1.5 2000/07/03 11:54:57 morsch
33 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
34 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
36 Revision 1.4 2000/06/28 15:16:35 morsch
37 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
38 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
39 framework. The changes should have no side effects (mostly dummy arguments).
40 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
41 of chambers with overlapping modules (MakePadHits, Disintegration).
43 Revision 1.3 2000/06/26 10:04:49 pcrochet
44 problem with HP compiler solved (PH), static variables removed : now defined in AliMUONTriggerConstants
50 #include "AliMUONTriggerCircuit.h"
51 #include "AliMUONTriggerConstants.h"
52 #include "AliSegmentation.h"
53 #include "AliMUONResponse.h"
54 #include "AliMUONChamber.h"
56 #include "Riostream.h"
58 ClassImp(AliMUONTriggerCircuit)
60 //----------------------------------------------------------------------
61 AliMUONTriggerCircuit::AliMUONTriggerCircuit()
68 fOrMud[0]=fOrMud[1]=0;
71 for (Int_t j=0; j<32; j++) {
76 for (i=0; i<16; i++) { fXpos11[i]=0.; }
77 for (i=0; i<31; i++) { fYpos11[i]=0.; }
78 for (i=0; i<63; i++) { fYpos21[i]=0.; }
81 //----------------------------------------------------------------------
82 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit)
84 // Dummy copy constructor
87 //----------------------------------------------------------------------
88 AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit)
90 // Dummy assignment operator
94 //----------------------------------------------------------------------
95 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
96 // initialize circuit characteristics
97 fIdCircuit=AliMUONTriggerConstants::CircuitId(iCircuit);
105 //----------------------------------------------------------------------
106 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){
107 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
109 for (Int_t i=0; i<234; i++) {
110 if (AliMUONTriggerConstants::CircuitId(i)==idCircuit) {
117 //----------------------------------------------------------------------
118 Int_t AliMUONTriggerCircuit::ModuleNumber(Int_t idModule){
119 // returns module number imod (from 0 to 63) corresponding to module idmodule
120 Int_t absidModule=TMath::Abs(idModule);
122 for (Int_t i=0; i<63; i++) {
123 if (AliMUONTriggerConstants::ModuleId(i)==absidModule) {
131 //----------------------------------------------------------------------
132 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) {
133 // returns ModuleId where Circuit idCircuit is sitting
134 return Int_t(idCircuit/10);
136 //----------------------------------------------------------------------
137 Int_t AliMUONTriggerCircuit::Position(Int_t idCircuit) {
138 // returns position of idCircuit in correcponding Module
139 return TMath::Abs(idCircuit)-TMath::Abs(Module(idCircuit))*10;
142 //----------------------------------------------------------------------
143 void AliMUONTriggerCircuit::LoadX2() {
144 // initialize fX2m, fX2ud and fOrMud
146 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
147 // and its number of X strips
148 Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
149 // and its number of Y strips
150 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
151 Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
153 // first step : look at lower part
154 if (iPosCircuit==1) { // need to scan lower module
155 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) {
157 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
158 Int_t nStrD=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleD));
161 &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {
162 if (nStrY==8) fX2m=1;
163 if (nStrD==8) fX2ud=1;
167 } else { // lower strips within same module
171 // second step : look at upper part
172 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
173 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
174 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
176 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
177 Int_t nStrU=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleU));
180 &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {
181 if (nStrY==8) fX2m=1;
182 if (nStrU==8) fX2ud=1;
186 } else { // upper strips within same module
191 //----------------------------------------------------------------------
192 void AliMUONTriggerCircuit::LoadXCode(){
193 // assign a Id. number to each X strip of current circuit
194 // Id.=(corresponding module Id.)*100+(Id. strip of module)
196 // first part : fill XMC11 XMC12 and strips 8 to 24 (middle) XMC21 XMC22
197 Int_t iStripCircMT1=0, iStripCircMT2=8;
198 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
199 // and its number of strips
200 Int_t nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
201 Int_t iPosCircuit=Position(fIdCircuit); // position of circuit in module
202 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
205 for (istrip=(iPosCircuit-1)*16;
206 istrip<(iPosCircuit-1)*16+16; istrip++) {
208 fXcode[0][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
209 fXcode[1][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip);
210 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
211 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
217 // XMC21 XMC22 strips 0 to 7 and 24 to 31
218 Int_t idModuleD, idModuleU;
221 idModule=Module(fIdCircuit); // corresponding module Id.
222 // number of X strips
223 nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
224 sign=TMath::Abs(idModule)/idModule;
226 // fill lower part (0 to 7)
227 if (iPosCircuit==1) { // need to scan lower module
228 if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { // non-existing
229 idModuleD=sign*(TMath::Abs(idModule)+10); // lower module Id
230 // and its number of strips
231 nStrD=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleD));
234 for (istrip=nStrD-8; istrip<nStrD; istrip++) {
235 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
236 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleD)*100+istrip);
241 } else { // lower strips within same module
244 for (istrip=(iPosCircuit-1)*16-8;
245 istrip<(iPosCircuit-1)*16; istrip++) {
246 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
247 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
252 // fill upper part (24 to 31)
253 if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)||
254 (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) {
255 if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) {
256 idModuleU=sign*(TMath::Abs(idModule)-10); // upper module Id
257 // and its number of strips
258 nStrU=AliMUONTriggerConstants::NstripX(ModuleNumber(idModuleU));
261 for (istrip=0; istrip<8; istrip++) {
262 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
263 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip);
268 } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)||
269 (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod.
272 for (istrip=(iPosCircuit-1)*16+16;
273 istrip<(iPosCircuit-1)*16+24; istrip++) {
274 fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
275 fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip);
281 //----------------------------------------------------------------------
282 void AliMUONTriggerCircuit::LoadYCode(){
283 // assign a Id. number to each Y strip of current circuit
284 // Id.=(corresponding module Id.)*100+(Id. strip of module)
285 // note : for Y plane fill only "central part" of circuit
286 // (upper and lower parts are filled in PreHandlingY of AliMUONTriggerDecision)
288 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
289 // and its number of Y strips
290 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
291 Int_t sign=TMath::Abs(idModule)/idModule; // left or right
293 for (Int_t istrip=0; istrip<nStrY; istrip++) {
294 fYcode[0][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
295 fYcode[1][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
296 fYcode[2][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
297 fYcode[3][istrip]=sign*(TMath::Abs(idModule)*100+istrip);
301 //----------------------------------------------------------------------
302 void AliMUONTriggerCircuit::LoadYPos(){
303 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
305 Int_t chamber, cathode;
306 Int_t code, idModule, idStrip, idSector;
307 Float_t x, y, z, width;
310 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
311 AliMUONChamber* iChamber;
312 AliSegmentation* segmentation;
317 iChamber = &(pMUON->Chamber(chamber-1));
318 segmentation=iChamber->SegmentationModel(cathode);
320 for (istrip=0; istrip<16; istrip++) {
321 code=fXcode[0][istrip]; // decode current strip
322 idModule=Int_t(code/100); // corresponding module Id.
323 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
324 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
325 width=segmentation->Dpy(idSector); // corresponding strip width
326 segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
329 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
335 iChamber = &(pMUON->Chamber(chamber-1));
336 segmentation=iChamber->SegmentationModel(cathode);
338 for (istrip=0; istrip<32; istrip++) {
339 code=fXcode[2][istrip]; // decode current strip
340 idModule=Int_t(code/100); // corresponding module Id.
341 idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module
342 idSector=segmentation->Sector(idModule,idStrip); // corresponding sector
343 width=segmentation->Dpy(idSector); // corresponding strip width
344 segmentation->GetPadC(idModule,idStrip,x,y,z); // get strip real position
346 // using idModule!=0 prevents to fill garbage in case of circuits
347 // in the first and last rows
350 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
355 //----------------------------------------------------------------------
356 void AliMUONTriggerCircuit::LoadXPos(){
357 // fill fXpos11 -> x position of Y strips for the first plane only
358 // fXpos11 contains the x position of Y strip for the current circuit
359 // taking into account whether or nor not part(s) of the circuit
360 // (middle, up or down) has(have) 16 strips
367 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
368 AliMUONChamber* iChamber;
369 AliSegmentation* segmentation;
370 iChamber = &(pMUON->Chamber(chamber-1));
371 segmentation=iChamber->SegmentationModel(cathode);
373 Int_t idModule=Module(fIdCircuit); // corresponding module Id.
374 // number of Y strips
375 Int_t nStrY=AliMUONTriggerConstants::NstripY(ModuleNumber(idModule));
376 Int_t idSector=segmentation->Sector(idModule,0); // corresp. sector
377 Float_t width=segmentation->Dpx(idSector); // corresponding strip width
379 // first case : up middle and down parts have all 8 or 16 strip
380 if ((nStrY==16)||(nStrY==8&&fX2m==0&&fX2ud==0)) {
381 for (istrip=0; istrip<nStrY; istrip++) {
382 segmentation->GetPadC(idModule,istrip,x,y,z);
385 // second case : mixing 8 and 16 strips within same circuit
387 for (istrip=0; istrip<nStrY; istrip++) {
388 if (nStrY!=8) { printf(" bug in LoadXpos \n");}
389 segmentation->GetPadC(idModule,istrip,x,y,z);
390 fXpos11[2*istrip]=x-width/4.;
391 fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.;
396 //----------------------------------------------------------------------
397 Float_t AliMUONTriggerCircuit::PtCal(Int_t istripX, Int_t idev, Int_t istripY){
398 // returns calculated pt for circuit/istripX/idev/istripY according
399 // to the formula of the TRD. Note : idev (input) is in [0+30]
401 // Int_t jdev = idev - 15; // jdev in [-15+15]
402 Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
404 Float_t yPosX1=fYpos11[istripX];
405 Float_t yPosX2=fYpos21[istripX2];
406 Float_t xPosY1=fXpos11[istripY];
408 Float_t zf=975., z1=1603.5, z2=1703.5;
409 Float_t thetaDev=(1./zf)*(yPosX1*z2-yPosX2*z1)/(z2-z1);
410 Float_t xf=xPosY1*zf/z1;
411 Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1);
412 return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/zf;
415 //----------------------------------------------------------------------
416 //--- methods which return member data related info
417 //----------------------------------------------------------------------
418 Int_t AliMUONTriggerCircuit::GetIdCircuit(){
419 // returns circuit Id
422 //----------------------------------------------------------------------
423 Int_t AliMUONTriggerCircuit::GetIdModule(){
425 return Module(fIdCircuit);
427 //----------------------------------------------------------------------
428 Int_t AliMUONTriggerCircuit::GetNstripX() {
429 // returns the number of X strips in the module where the circuit is sitting
430 return AliMUONTriggerConstants::NstripX(ModuleNumber(Module(fIdCircuit)));
432 //----------------------------------------------------------------------
433 Int_t AliMUONTriggerCircuit::GetNstripY() {
434 // returns the number of Y strips in the module where the circuit is sitting
435 return AliMUONTriggerConstants::NstripY(ModuleNumber(Module(fIdCircuit)));
437 //----------------------------------------------------------------------
438 Int_t AliMUONTriggerCircuit::GetPosCircuit() {
439 // returns the position of the circuit in its module
440 return Position(fIdCircuit);
442 //----------------------------------------------------------------------
443 Int_t AliMUONTriggerCircuit::GetIdCircuitD(){
444 // returns the Id of the circuit down
445 Int_t idModule=Module(fIdCircuit);
446 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
447 return (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
449 //----------------------------------------------------------------------
450 Int_t AliMUONTriggerCircuit::GetICircuitD(){
451 // returns the number of the circuit down
452 Int_t idModule=Module(fIdCircuit);
453 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
455 (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
456 return CircuitNumber(idCircuitD);
458 //----------------------------------------------------------------------
459 Int_t AliMUONTriggerCircuit::GetIdCircuitU(){
460 // returns the Id of the circuit up
461 Int_t idModule=Module(fIdCircuit);
462 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
463 return (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
465 //----------------------------------------------------------------------
466 Int_t AliMUONTriggerCircuit::GetICircuitU(){
467 // returns the number of the circuit up
468 Int_t idModule=Module(fIdCircuit);
469 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
471 (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
472 return CircuitNumber(idCircuitU);
474 //----------------------------------------------------------------------
475 Int_t AliMUONTriggerCircuit::GetX2m(){
479 //----------------------------------------------------------------------
480 Int_t AliMUONTriggerCircuit::GetX2ud(){
484 //----------------------------------------------------------------------
485 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){
490 //----------------------------------------------------------------------
491 Int_t AliMUONTriggerCircuit::GetXcode(Int_t chamber, Int_t istrip){
492 // returns X code of circuit/chamber/istrip (warning : chamber in [0,3])
493 return fXcode[chamber][istrip];
495 //----------------------------------------------------------------------
496 Int_t AliMUONTriggerCircuit::GetYcode(Int_t chamber, Int_t istrip){
497 // returns Y code of circuit/chamber/istrip (warning : chamber in [0,3])
498 return fYcode[chamber][istrip];
500 //----------------------------------------------------------------------
501 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){
502 // returns Y position of X strip istrip in MC11
503 return fYpos11[istrip];
505 //----------------------------------------------------------------------
506 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){
507 // returns Y position of X strip istrip in MC21
508 return fYpos21[istrip];
510 //----------------------------------------------------------------------
511 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){
512 // returns X position of Y strip istrip in MC11
513 return fXpos11[istrip];
515 //----------------------------------------------------------------------
516 //--- end of methods which return member data related info
517 //----------------------------------------------------------------------