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.6 2000/07/13 16:19:44 fca
18 Mainly coding conventions + some small bug fixes
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.
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).
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
38 #include "AliMUONPoints.h"
39 #include "AliMUONTriggerCircuit.h"
40 #include "AliMUONTriggerConstants.h"
41 #include "AliSegmentation.h"
42 #include "AliMUONResponse.h"
43 #include "AliMUONChamber.h"
47 ClassImp(AliMUONTriggerCircuit)
49 //----------------------------------------------------------------------
50 AliMUONTriggerCircuit::AliMUONTriggerCircuit()
57 fOrMud[0]=fOrMud[1]=0;
60 for (Int_t j=0; j<32; j++) {
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.; }
70 //----------------------------------------------------------------------
71 AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit)
73 // Dummy copy constructor
76 //----------------------------------------------------------------------
77 AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit)
79 // Dummy assignment operator
83 //----------------------------------------------------------------------
84 void AliMUONTriggerCircuit::Init(Int_t iCircuit) {
85 // initialize circuit characteristics
86 fIdCircuit=AliMUONTriggerConstants::CircuitId(iCircuit);
94 //----------------------------------------------------------------------
95 Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){
96 // returns circuit number iCircuit (0-234) corresponding to circuit idCircuit
98 for (Int_t i=0; i<234; i++) {
99 if (AliMUONTriggerConstants::CircuitId(i)==idCircuit) {
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);
111 for (Int_t i=0; i<63; i++) {
112 if (AliMUONTriggerConstants::ModuleId(i)==absidModule) {
120 //----------------------------------------------------------------------
121 Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) {
122 // returns ModuleId where Circuit idCircuit is sitting
123 return Int_t(idCircuit/10);
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;
131 //----------------------------------------------------------------------
132 void AliMUONTriggerCircuit::LoadX2() {
133 // initialize fX2m, fX2ud and fOrMud
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
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) {
146 Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule);
147 Int_t nStrD=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleD));
150 &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) {
151 if (nStrY==8) fX2m=1;
152 if (nStrD==8) fX2ud=1;
156 } else { // lower strips within same module
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) {
165 Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule);
166 Int_t nStrU=AliMUONTriggerConstants::NstripY(ModuleNumber(idModuleU));
169 &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) {
170 if (nStrY==8) fX2m=1;
171 if (nStrU==8) fX2ud=1;
175 } else { // upper strips within same module
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)
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
194 for (istrip=(iPosCircuit-1)*16;
195 istrip<(iPosCircuit-1)*16+16; istrip++) {
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);
206 // XMC21 XMC22 strips 0 to 7 and 24 to 31
207 Int_t idModuleD, idModuleU;
210 idModule=Module(fIdCircuit); // corresponding module Id.
211 // number of X strips
212 nStrX=AliMUONTriggerConstants::NstripX(ModuleNumber(idModule));
213 sign=TMath::Abs(idModule)/idModule;
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));
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);
230 } else { // lower strips within same module
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);
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));
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);
257 } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)||
258 (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod.
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);
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)
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
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);
290 //----------------------------------------------------------------------
291 void AliMUONTriggerCircuit::LoadYPos(){
292 // fill fYpos11 and fYpos21 -> y position of X declusterized strips
294 Int_t chamber, cathode;
295 Int_t code, idModule, idStrip, idSector;
296 Float_t x, y, z, width;
299 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
300 AliMUONChamber* iChamber;
301 AliSegmentation* segmentation;
306 iChamber = &(pMUON->Chamber(chamber-1));
307 segmentation=iChamber->SegmentationModel(cathode);
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
318 if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.;
324 iChamber = &(pMUON->Chamber(chamber-1));
325 segmentation=iChamber->SegmentationModel(cathode);
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
335 // using idModule!=0 prevents to fill garbage in case of circuits
336 // in the first and last rows
339 if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.;
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
356 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
357 AliMUONChamber* iChamber;
358 AliSegmentation* segmentation;
359 iChamber = &(pMUON->Chamber(chamber-1));
360 segmentation=iChamber->SegmentationModel(cathode);
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
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);
374 // second case : mixing 8 and 16 strips within same circuit
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.;
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]
390 // Int_t jdev = idev - 15; // jdev in [-15+15]
391 Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev
393 Float_t yPosX1=fYpos11[istripX];
394 Float_t yPosX2=fYpos21[istripX2];
395 Float_t xPosY1=fXpos11[istripY];
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;
404 //----------------------------------------------------------------------
405 //--- methods which return member data related info
406 //----------------------------------------------------------------------
407 Int_t AliMUONTriggerCircuit::GetIdCircuit(){
408 // returns circuit Id
411 //----------------------------------------------------------------------
412 Int_t AliMUONTriggerCircuit::GetIdModule(){
414 return Module(fIdCircuit);
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)));
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)));
426 //----------------------------------------------------------------------
427 Int_t AliMUONTriggerCircuit::GetPosCircuit() {
428 // returns the position of the circuit in its module
429 return Position(fIdCircuit);
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);
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);
444 (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule);
445 return CircuitNumber(idCircuitD);
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);
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);
460 (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule);
461 return CircuitNumber(idCircuitU);
463 //----------------------------------------------------------------------
464 Int_t AliMUONTriggerCircuit::GetX2m(){
468 //----------------------------------------------------------------------
469 Int_t AliMUONTriggerCircuit::GetX2ud(){
473 //----------------------------------------------------------------------
474 void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){
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];
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];
489 //----------------------------------------------------------------------
490 Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){
491 // returns Y position of X strip istrip in MC11
492 return fYpos11[istrip];
494 //----------------------------------------------------------------------
495 Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){
496 // returns Y position of X strip istrip in MC21
497 return fYpos21[istrip];
499 //----------------------------------------------------------------------
500 Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){
501 // returns X position of Y strip istrip in MC11
502 return fXpos11[istrip];
504 //----------------------------------------------------------------------
505 //--- end of methods which return member data related info
506 //----------------------------------------------------------------------