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 // Class AliMUONSt12QuadrantSegmentation
19 // -------------------------------------
20 // Segmentation for MUON quadrants of stations 1 and 2 using
21 // the mapping package
23 // Author: Ivana Hrivnacova, IPN Orsay
27 #include <TObjArray.h>
31 #include "AliMpArea.h"
32 #include "AliMpReader.h"
33 #include "AliMpSector.h"
34 #include "AliMpVPadIterator.h"
35 #include "AliMpSectorSegmentation.h"
37 #include "AliMUONSt12QuadrantSegmentation.h"
40 #include "AliMUONChamber.h"
43 ClassImp(AliMUONSt12QuadrantSegmentation)
45 const Float_t AliMUONSt12QuadrantSegmentation::fgkWireD = 0.20;
46 const Float_t AliMUONSt12QuadrantSegmentation::fgkLengthUnit = 0.1;
48 //______________________________________________________________________________
49 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation(
50 AliMpStationType stationType,
51 AliMpPlaneType planeType)
52 : AliMUONVGeometryDESegmentation(),
54 fSectorSegmentation(0),
78 AliMpReader r(stationType, planeType);
79 fSector = r.BuildSector();
80 fSectorSegmentation = new AliMpSectorSegmentation(fSector);
82 fCorrA = new TObjArray(3);
88 //______________________________________________________________________________
89 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation()
90 : AliMUONVGeometryDESegmentation(),
92 fSectorSegmentation(0),
113 // Default Constructor
116 //______________________________________________________________________________
117 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation(const AliMUONSt12QuadrantSegmentation& rhs)
118 : AliMUONVGeometryDESegmentation(rhs)
121 AliFatal("Copy constructor is not implemented.");
124 //______________________________________________________________________________
125 AliMUONSt12QuadrantSegmentation::~AliMUONSt12QuadrantSegmentation() {
129 delete fSectorSegmentation;
130 delete fSectorIterator;
137 //______________________________________________________________________________
138 AliMUONSt12QuadrantSegmentation&
139 AliMUONSt12QuadrantSegmentation::operator=(const AliMUONSt12QuadrantSegmentation& rhs)
143 // check assignement to self
144 if (this == &rhs) return *this;
146 AliFatal("Assignment operator is not implemented.");
155 //______________________________________________________________________________
156 void AliMUONSt12QuadrantSegmentation::UpdateCurrentPadValues(const AliMpPad& pad)
158 // Updates current pad values.
161 fIx = pad.GetIndices().GetFirst();
162 fIy = pad.GetIndices().GetSecond();
163 fX = pad.Position().X() * fgkLengthUnit;
164 fY = pad.Position().Y() * fgkLengthUnit;
165 fZone = fSectorSegmentation->Zone(pad);
172 //______________________________________________________________________________
173 void AliMUONSt12QuadrantSegmentation::SetPadSize(Float_t /*p1*/, Float_t /*p2*/)
175 // Set pad size Dx*Dy
178 AliFatal("Not uniform pad size.");
181 //______________________________________________________________________________
182 void AliMUONSt12QuadrantSegmentation::SetDAnod(Float_t d)
190 //______________________________________________________________________________
191 Bool_t AliMUONSt12QuadrantSegmentation::HasPad(Float_t x, Float_t y, Float_t /*z*/)
193 // Returns true if a pad exists in the given position
195 AliMpPad pad = fSectorSegmentation
196 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), false);
198 return pad.IsValid();
202 //______________________________________________________________________________
203 Bool_t AliMUONSt12QuadrantSegmentation::HasPad(Int_t ix, Int_t iy)
205 // Returns true if a pad with given indices exists
207 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), false);
209 return pad.IsValid();
213 //______________________________________________________________________________
214 AliMUONGeometryDirection AliMUONSt12QuadrantSegmentation::GetDirection()
216 // Returns the direction with a constant pad size
217 // (Direction or coordinate where the resolution is the best)
219 switch ( fSector->GetDirection() ) {
220 case kX: return kDirX;
221 case kY: return kDirY;
222 default: return kDirUndefined;
226 //______________________________________________________________________________
227 Float_t AliMUONSt12QuadrantSegmentation::GetAnod(Float_t xhit) const
229 // Anod wire coordinate closest to xhit
230 // Returns for a hit position xhit the position of the nearest anode wire
231 // From AliMUONSegmentationV01.
234 Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5
235 : Int_t(xhit/fWireD) - 0.5;
240 //______________________________________________________________________________
241 void AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
242 Int_t& ix, Int_t& iy)
244 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
247 GetPadI(x, y, ix, iy);
250 //______________________________________________________________________________
251 void AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y,
252 Int_t& ix, Int_t& iy)
254 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
255 // If there is no pad, ix = 0, iy = 0 are returned.
258 AliMpPad pad = fSectorSegmentation
259 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), true);
261 ix = pad.GetIndices().GetFirst();
262 iy = pad.GetIndices().GetSecond();
265 //______________________________________________________________________________
266 void AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy,
267 Float_t& x, Float_t& y, Float_t& z)
269 // Transform from pad to real coordinates
273 GetPadC(ix, iy, x , y);
276 //______________________________________________________________________________
277 void AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy,
278 Float_t& x, Float_t& y)
280 // Transform from pad to real coordinates
281 // If there is no pad, x = 0., y = 0. are returned.
284 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), true);
286 x = pad.Position().X() * fgkLengthUnit;
287 y = pad.Position().Y() * fgkLengthUnit;
291 //______________________________________________________________________________
292 void AliMUONSt12QuadrantSegmentation::Init(Int_t chamber)
294 // Initialize segmentation
297 // find Npx, Npy and save this info
299 // reference to chamber
300 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
301 fChamber = &(pMUON->Chamber(chamber));
302 fRmin=fChamber->RInner();
303 fRmax=fChamber->ROuter();
308 //______________________________________________________________________________
309 Float_t AliMUONSt12QuadrantSegmentation::Dpx() const
314 AliFatal( "Not uniform pad size.");
318 //______________________________________________________________________________
319 Float_t AliMUONSt12QuadrantSegmentation::Dpy() const
324 AliFatal("Not uniform pad size.");
328 //______________________________________________________________________________
329 Float_t AliMUONSt12QuadrantSegmentation::Dpx(Int_t isector) const
331 // Pad size in x by sector
334 return fSectorSegmentation->PadDimensions(isector).X()*2.*fgkLengthUnit;
337 //______________________________________________________________________________
338 Float_t AliMUONSt12QuadrantSegmentation::Dpy(Int_t isector) const
340 // Pad size in x, y by Sector
343 return fSectorSegmentation->PadDimensions(isector).Y()*2.*fgkLengthUnit;
346 //______________________________________________________________________________
347 Int_t AliMUONSt12QuadrantSegmentation::Npx() const
349 // Maximum number of Pads in x
350 // hard coded for the time being
353 //Fatal("Npx", "Not yet implemented.");
354 switch (fSector->GetDirection()) {
360 AliError("Unknown sector direction");
365 //______________________________________________________________________________
366 Int_t AliMUONSt12QuadrantSegmentation::Npy() const
368 // Maximum number of Pads in y
369 // hard coded for the time being
372 //Fatal("Npy", "Not yet implemented.");
373 switch (fSector->GetDirection()) {
379 AliError("Unknown sector direction");
384 //______________________________________________________________________________
385 void AliMUONSt12QuadrantSegmentation::SetPad(Int_t ix, Int_t iy)
388 // Sets virtual pad coordinates, needed for evaluating pad response
389 // outside the tracking program.
390 // From AliMUONSegmentationV01.
393 GetPadC(ix, iy, fX, fY);
394 fZone = Sector(ix, iy);
397 //______________________________________________________________________________
398 void AliMUONSt12QuadrantSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
401 // Sets virtual hit position, needed for evaluating pad response
402 // outside the tracking program
403 // From AliMUONSegmentationV01.
409 //______________________________________________________________________________
410 void AliMUONSt12QuadrantSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/,
411 Float_t dx, Float_t dy)
413 // Iterate over pads - initialiser
416 // Sets the current pad to that located in the hit position
418 SetHit(GetAnod(xhit), yhit, 0.);
420 // Enable iterating in one dimension
421 if (dx == 0.) dx = 0.01;
422 if (dy == 0.) dy = 0.01;
425 = fSectorSegmentation
426 ->CreateIterator(AliMpArea(TVector2(fXhit/fgkLengthUnit, fYhit/fgkLengthUnit),
427 TVector2(dx/fgkLengthUnit, dy/fgkLengthUnit)));
429 fSectorIterator->First();
431 if (! fSectorIterator->IsDone())
432 UpdateCurrentPadValues(fSectorIterator->CurrentItem());
435 //______________________________________________________________________________
436 void AliMUONSt12QuadrantSegmentation::NextPad()
438 // Iterate over pads - stepper
441 fSectorIterator->Next();
443 if (! fSectorIterator->IsDone())
444 UpdateCurrentPadValues(fSectorIterator->CurrentItem());
447 //______________________________________________________________________________
448 Int_t AliMUONSt12QuadrantSegmentation::MorePads()
450 // Iterate over pads - condition
453 if (fSectorIterator->IsDone())
459 //______________________________________________________________________________
460 Float_t AliMUONSt12QuadrantSegmentation::Distance2AndOffset(Int_t iX, Int_t iY,
461 Float_t x, Float_t y, Int_t* /*dummy*/)
463 // Returns the square of the distance between 1 pad
464 // labelled by its channel numbers and a coordinate
467 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX, iY));
470 AliFatal("Cannot locate pad.");
472 return (pad.Position()*fgkLengthUnit - TVector2(x, y)).Mod2();
475 //______________________________________________________________________________
476 void AliMUONSt12QuadrantSegmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
477 Int_t* /*Nparallel*/, Int_t* /*Offset*/)
479 // Number of pads read in parallel and offset to add to x
480 // (specific to LYON, but mandatory for display)
483 AliFatal( "Not yet implemented.");
487 //______________________________________________________________________________
488 void AliMUONSt12QuadrantSegmentation::Neighbours(Int_t iX, Int_t iY,
490 Int_t Xlist[10], Int_t Ylist[10])
492 // Get next neighbours
495 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX,iY));
498 AliMpVPadIterator* iter
499 = fSectorSegmentation
500 ->CreateIterator(AliMpArea(pad.Position(),2.*pad.Dimensions()*1.1));
502 for( iter->First(); !iter->IsDone() && i<10; iter->Next()) {
503 Xlist[i] = iter->CurrentItem().GetIndices().GetFirst();
504 Ylist[i] = iter->CurrentItem().GetIndices().GetSecond();
511 //______________________________________________________________________________
512 Int_t AliMUONSt12QuadrantSegmentation::Ix()
514 // Current pad cursor during disintegration
518 return fSectorIterator->CurrentItem().GetIndices().GetFirst();
521 //______________________________________________________________________________
522 Int_t AliMUONSt12QuadrantSegmentation::Iy()
524 // Current pad cursor during disintegration
528 return fSectorIterator->CurrentItem().GetIndices().GetSecond();
531 //______________________________________________________________________________
532 Int_t AliMUONSt12QuadrantSegmentation::ISector()
540 //______________________________________________________________________________
541 Int_t AliMUONSt12QuadrantSegmentation::Sector(Int_t ix, Int_t iy)
543 // Calculate sector from pad coordinates
546 return fSectorSegmentation
547 ->Zone(fSectorSegmentation->PadByIndices(AliMpIntPair(ix, iy)));
550 //______________________________________________________________________________
551 Int_t AliMUONSt12QuadrantSegmentation::Sector(Float_t x, Float_t y)
553 // Calculate sector from pad coordinates
556 return fSectorSegmentation
557 ->Zone(fSectorSegmentation
558 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit)));
561 //______________________________________________________________________________
562 void AliMUONSt12QuadrantSegmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
563 Float_t& y1, Float_t& y2)
565 // Current integration limits
568 x1 = fXhit - fX - Dpx(fZone)/2.;
569 x2 = x1 + Dpx(fZone);
571 y1 = fYhit - fY - Dpy(fZone)/2.;
572 y2 = y1 + Dpy(fZone);
575 //______________________________________________________________________________
576 Int_t AliMUONSt12QuadrantSegmentation::SigGenCond(Float_t x, Float_t y, Float_t /*z*/)
578 // Signal Generation Condition during Stepping
579 // 0: don't generate signal
580 // 1: generate signal
583 // Crossing of pad boundary and mid plane between neighbouring wires is checked.
584 // To correctly simulate the dependence of the spatial resolution on the angle
585 // of incidence signal must be generated for constant steps on
586 // the projection of the trajectory along the anode wire.
588 // Signal will be generated if particle crosses pad boundary or
589 // boundary between two wires.
591 // From AliMUONSegmentationV01
595 GetPadI(x, y, ixt, iyt);
596 Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1;
598 if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
607 //______________________________________________________________________________
608 void AliMUONSt12QuadrantSegmentation::SigGenInit(Float_t x, Float_t y, Float_t /*z*/)
610 // Initialise signal generation at coord (x,y,z)
611 // Initialises pad and wire position during stepping.
612 // From AliMUONSegmentationV01
617 GetPadI(x, y, fIxt, fIyt);
618 fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ;
621 //______________________________________________________________________________
622 void AliMUONSt12QuadrantSegmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const
624 // Test points for auto calibration
625 // Returns test point on the pad plane.
626 // Used during determination of the segmoid correction of the COG-method
627 // From AliMUONSegmentationV01
631 x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.);
635 //______________________________________________________________________________
636 void AliMUONSt12QuadrantSegmentation::Draw(const char * /*opt*/)
638 // Draw the segmentation zones.
639 // (Called from AliMUON::BuildGeometry)
642 AliWarning("Not yet implemented.");
645 //______________________________________________________________________________
646 void AliMUONSt12QuadrantSegmentation::SetCorrFunc(Int_t isec, TF1* func)
648 // Set the correction function.
649 // From AliMUONSegmentationV01
652 fCorrA->AddAt(func, isec);
655 //______________________________________________________________________________
656 TF1* AliMUONSt12QuadrantSegmentation::CorrFunc(Int_t isec) const
658 // Get the correction Function.
659 // From AliMUONSegmentationV01
662 return (TF1*) fCorrA->At(isec);