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 **************************************************************************/
18 //*********************************************************
19 // Segmentation classes for slat modules
20 // This class works with local coordinates
21 // of the slats via the class AliMUONGeometrySegmentation
22 // This class contains the size of the slats and the
23 // and the differents PCB densities.
24 // (from old AliMUONSegmentationSlatModule)
25 // Gines, Subatech, Nov04
26 // Add electronics mapping
27 // Christian, Subatech, Mai 05
28 //*********************************************************
32 #include "AliMUONSt345SlatSegmentation.h"
33 #include "AliMUONSegmentationDetectionElement.h"
34 #include "AliMUONSegmentManuIndex.h"
35 #include "AliMUONSegmentIndex.h"
39 ClassImp(AliMUONSt345SlatSegmentation)
42 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation()
43 : AliMUONVGeometryDESegmentation(),
66 fSegmentationDetectionElement(0x0)
68 // default constructor
72 //___________________________________________
73 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending)
74 : AliMUONVGeometryDESegmentation(),
97 fSegmentationDetectionElement(0x0)
101 // Non default constructor
102 fNsec = 4; // 4 sector densities at most per slat
103 fNDiv = new TArrayI(fNsec);
104 fDpxD = new TArrayF(fNsec);
105 fDpyD = new TArrayF(fNsec);
106 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
107 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
108 (*fDpyD)[0]=(*fDpyD)[1]=(*fDpyD)[2]=(*fDpyD)[3]=0;
112 //----------------------------------------------------------------------
113 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs)
114 : AliMUONVGeometryDESegmentation(rhs),
132 fSegmentationDetectionElement(0x0)
134 // default constructor
136 //----------------------------------------------------------------------
137 AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation()
140 if (fNDiv) delete fNDiv;
141 if (fDpxD) delete fDpxD;
142 if (fDpyD) delete fDpyD;
143 // if (fSegmentationDetectionElement) fSegmentationDetectionElement->Delete();
145 //----------------------------------------------------------------------
146 AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
148 // Protected assignement operator
149 if (this == &rhs) return *this;
150 AliFatal("Not implemented.");
155 //------------------------------------------------------------------------
156 Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
158 // Returns the square of the distance between 1 pad
159 // labelled by its Channel numbers and a coordinate
162 return (x-X)*(x-X) + (y-Y)*(y-Y);
164 //____________________________________________________________________________
165 Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
167 // Return x-strip width
168 return (*fDpxD)[isec];
171 //____________________________________________________________________________
172 Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t isec) const
174 // Return y-strip width
175 return (*fDpyD)[isec];
177 //_____________________________________________________________________________
178 Float_t AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
180 // Returns for a hit position xhit the position of the nearest anode wire
181 Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
187 //--------------------------------------------------------------------------------
188 void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
190 if (ix < 1 || ix > Npx() || iy < 1 || iy > Npy() ){
191 AliWarning(Form("ix %d or iy %d out of boundaries: Npx=%d and Npy=%d",ix, iy, Npx(), Npy()));
192 x=-99999.; y=-99999.;
196 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
198 Int_t isec = Sector(ix,iy);
199 if (isec == -1) AliWarning(Form("isector = %d with ix %d, iy %d", isec, ix, iy));
200 if (iy > fNpyS[isec]) {
201 x=-99999.; y=-99999.;
205 x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
206 x = x-(*fDpxD)[isec]/2;
207 y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy; // !!!
215 //_____________________________________________________________________________
216 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
218 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
222 for (Int_t i=fNsec-1; i > 0; i--) {
225 if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
229 if (isec == -1) AliWarning(Form("isector equal to %d with xl %f, yl %f", isec, x, y));
231 ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
233 iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
234 } else if (isec == 0) {
235 ix= Int_t(x/(*fDpxD)[isec])+1;
236 iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
242 //-------------------------------------------------------------------------
243 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
245 GetPadI(x, y, ix, iy);
248 //-------------------------------------------------------------------------
249 void AliMUONSt345SlatSegmentation::GetPadE(Int_t &ix, Int_t &iy, AliMUONSegmentManuIndex* manuIndex)
252 // return Padx and Pady
253 // input value: electronic connection number
255 Int_t icathode = (fBending == 1) ? 0 : 1; // cathode 0 == bending
257 // Int_t busPatchId = manuIndex->GetBusPatchId(); //
258 Int_t manuId = manuIndex->GetManuId();
259 Int_t manuChannelId = manuIndex->GetManuChannelId();
260 // Int_t channelId = manuIndex->GetChannelId();
262 AliMUONSegmentIndex* index = fSegmentationDetectionElement->GetIndex(manuId, manuChannelId);
264 ix = index->GetPadX();
265 iy = index->GetPadY();
266 swap(ix,iy); // swap cos origin in segmentation and mapping file are different for iy (temporary solution)
268 if (index->GetCathode() != icathode)
269 AliWarning("Wrong cathode number !");
273 //-------------------------------------------------------------------------
274 AliMUONSegmentManuIndex* AliMUONSt345SlatSegmentation::GetMpConnection(Int_t ix, Int_t iy)
277 // return electronic connection number
278 // input value: Padx and Pady
280 Int_t icathode = (fBending == 1) ? 0 : 1; // cathode 0 == bending
282 return fSegmentationDetectionElement->GetManuIndex(ix, iy, icathode);
286 //_______________________________________________________________
287 void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
289 // Defines the pad size perp. to the anode wire (y) for different sectors.
290 // Pad sizes are defined as integral fractions ndiv of a basis pad size
293 for (Int_t i=0; i<4; i++) {
298 //____________________________________________________________________________
299 void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
305 //_______________________________________________________________
306 void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
309 // Set PcbBoard segmentation zones for each density
310 // n[0] slat type parameter
311 // n[1] PcbBoards for highest density sector fNDiv[1] etc ...
315 for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
318 //-------------------------------------------------------------------------
319 void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
322 // Sets virtual pad coordinates, needed for evaluating pad response
323 // outside the tracking program
324 GetPadC(ix,iy,fX,fY);
325 fSector=Sector(ix,iy);
327 //---------------------------------------------------------------------------
328 void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
335 if (x < fCx[0]) fXhit = fCx[0];
336 if (y < -fDyPCB/2.) fYhit = -fDyPCB/2.;
338 if (x > fCx[fNsec-1]) fXhit = fCx[fNsec-1];
339 if (y > fDyPCB/2.) fYhit = fDyPCB/2.;
342 //----------------------------------------------------------------------------
343 void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
348 //----------------------------------------------------------
349 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
351 // Initialises iteration over pads for charge distribution algorithm
354 // Find the wire position (center of charge distribution)
355 Float_t x0a = GetAnod(xhit);
359 // and take fNsigma*sigma around this center
360 Float_t x01 = x0a - dx ;
361 Float_t x02 = x0a + dx;
362 Float_t y01 = yhit - dy;
363 Float_t y02 = yhit + dy;
365 // check the limits after adding (fNsigma*sigma)
366 if (x01 < fCx[0]) x01 = fCx[0];
367 if (y01 < -fDyPCB/2) y01 = -fDyPCB/2;
369 if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1]; // still ok ? (CF)
373 for (Int_t i=fNsec-1; i > 0; i--) {
374 if (x02 >= fCx[i-1]) {
376 if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
381 y02 += Dpy(isec);// why ? (CF)
382 if (y02 >= fDyPCB/2.) y02 = fDyPCB/2;
385 // find the pads over which the charge distributes
386 GetPadI(x01,y01,fIxmin,fIymin);
387 GetPadI(x02,y02,fIxmax,fIymax);
389 if (fIxmax > fNpx) fIxmax=fNpx;
390 if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];
391 if (fIxmin < 1) fIxmin = 1; // patch for the moment (Ch. Finck)
392 if (fIymin < 1) fIymin = 1;
400 // Set current pad to lower left corner
401 if (fIxmax < fIxmin) fIxmax = fIxmin;
402 if (fIymax < fIymin) fIymax = fIymin;
406 GetPadC(fIx,fIy,fX,fY);
407 fSector = Sector(fIx,fIy);
409 printf("\n \n First Pad: %d %d %f %f %d %d %d %f" ,
410 fIxmin, fIxmax, fXmin, fXmax, fNpx, fId, isec, Dpy(isec));
411 printf("\n \n First Pad: %d %d %f %f %d %d %d %f",
412 fIymin, fIymax, fYmin, fYmax, fNpyS[isec], fId, isec, Dpy(isec));
418 //----------------------------------------------------------------------
419 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
421 FirstPad(xhit, yhit, dx, dy);
423 //----------------------------------------------------------------------
424 void AliMUONSt345SlatSegmentation::NextPad()
426 // Stepper for the iteration over pads
428 // Step to next pad in the integration region
429 // step from left to right
432 GetPadC(fIx,fIy,fX,fY);
433 fSector=Sector(fIx,fIy);
435 } else if (fIy != fIymax) {
438 GetPadC(fIx,fIy,fX,fY);
439 fSector=Sector(fIx,fIy);
446 //-------------------------------------------------------------------------
447 Int_t AliMUONSt345SlatSegmentation::MorePads()
449 // Stopping condition for the iterator over pads
451 // Are there more pads in the integration region
453 return (fIx != -999 || fIy != -999);
455 //--------------------------------------------------------------------------
456 Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy)
459 // Determine segmentation zone from pad coordinates
462 for (Int_t i = 0; i < fNsec; i++) {
463 if (ix <= fNpxS[i]) {
468 if (isec == -1) AliWarning(Form("Sector = %d with ix %d and iy %d, Npx %d",
469 isec, ix, iy, fNpx));
474 //-----------------------------------------------------------------------------
475 void AliMUONSt345SlatSegmentation::
476 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
478 // Returns integration limits for current pad
480 x1=fXhit-fX-Dpx(fSector)/2.;
482 y1=fYhit-fY-Dpy(fSector)/2.;
484 // printf("\n Integration Limits %f %f %f %f %d %f", x1, x2, y1, y2, fSector, Dpx(fSector));
487 //-----------------------------------------------------------------------------
488 void AliMUONSt345SlatSegmentation::
489 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
491 // Returns list of next neighbours for given Pad (iX, iY)
503 Int_t sector = Sector(iX,iY);
505 if (iY+1 <= fNpyS[sector]) {
517 //--------------------------------------------------------------------------
518 void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
521 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
522 // These arrays help in converting from real to pad co-ordinates and
525 // Segmentation is defined by rectangular modules approximating
526 // concentric circles as shown below
528 // PCB module size in cm
529 // printf("\n Initialise Segmentation SlatModule \n");
532 // printf(" fBending: %d \n",fBending);
534 if (fInitDone) return; // security if init is already done in AliMUONFactory
538 // Calculate padsize along x
539 (*fDpxD)[fNsec-1]=fDpx;
540 (*fDpyD)[fNsec-1]=fDpy;
542 for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
545 (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
547 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
553 // fill the arrays defining the pad segmentation boundaries
556 // Loop over sectors (isec=0 for secto close to the beam pipe)
557 Float_t totalLength = 0;
558 for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB; // !!!!
560 fNpy = 0; // maximum number of pads in y
561 for (Int_t isec=0; isec<4; isec++) {
565 fCx[0] = -totalLength/2;
567 fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]);
568 fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]);
569 if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec];
570 fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
574 fNpx = fNpxS[3]; // maximum number of pads in x
577 fId = detectionElementId;
582 // Int_t icathode = (fBending == 1) ? 0 : 1; // cathode 0 == bending
584 // GetMpFileName(name);
585 // fSegmentationDetectionElement = new AliMUONSegmentationDetectionElement();
586 // fSegmentationDetectionElement->Init(name, icathode);
590 //--------------------------------------------------------------------------
591 void AliMUONSt345SlatSegmentation::GetMpFileName(Char_t* name) const
594 // Get mapping file name
599 for (Int_t isec = 1; isec < 4; isec++) {
603 for (Int_t i = 0; i < fPcbBoards[isec]; i++)
607 for (Int_t i = 0; i < fPcbBoards[isec]; i++)
611 for (Int_t i = 0; i < fPcbBoards[isec]; i++)
617 while (strlen(name) < 10)
643 strcat(name, "SR3"); // should not exist
644 AliFatal("SR3 Slat type does not exist !!");
649 //--------------------------------------------------------------------------
650 void AliMUONSt345SlatSegmentation::Swap(Int_t padX, Int_t &padY)
653 // swap the numbering between segmentation (i.e. pady = [0,40])
654 // and mapping file (i.e. pady = [-20,20])
667 padY += fNpyS[Sector(padX, padY)] + 1;
669 padY += fNpyS[Sector(padX, padY)];