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 // Authors: David Guez, Ivana Hrivnacova, Marion MacCormick; IPN Orsay
20 // Class AliMUONSt1Segmentation
21 // ------------------------------
22 // Segmentation for MUON station 1 using the external
26 #include <TObjArray.h>
30 #include "AliMpPlane.h"
31 #include "AliMpPlaneSegmentation.h"
32 #include "AliMpPlaneAreaPadIterator.h"
35 #include "AliMUONSt1Segmentation.h"
38 #include "AliMUONChamber.h"
40 ClassImp(AliMUONSt1Segmentation)
42 const Float_t AliMUONSt1Segmentation::fgkWireD = 0.20;
43 const Float_t AliMUONSt1Segmentation::fgkLengthUnit = 0.1;
45 //______________________________________________________________________________
46 AliMUONSt1Segmentation::AliMUONSt1Segmentation(const AliMpPlaneType planeType)
49 fPlaneSegmentation(0),
72 fPlane = AliMpPlane::Create(kStation1, planeType);
73 fPlaneSegmentation = new AliMpPlaneSegmentation(fPlane);
75 fCorrA = new TObjArray(3);
81 //______________________________________________________________________________
82 AliMUONSt1Segmentation::AliMUONSt1Segmentation()
85 fPlaneSegmentation(0),
106 // Default Constructor
109 //______________________________________________________________________________
110 AliMUONSt1Segmentation::AliMUONSt1Segmentation(const AliMUONSt1Segmentation& rhs) :AliSegmentation(rhs)
113 Fatal("Copy constructor",
114 "Copy constructor is not implemented.");
117 //______________________________________________________________________________
118 AliMUONSt1Segmentation::~AliMUONSt1Segmentation() {
122 delete fPlaneSegmentation;
123 delete fPlaneIterator;
130 //______________________________________________________________________________
131 AliMUONSt1Segmentation&
132 AliMUONSt1Segmentation::operator=(const AliMUONSt1Segmentation& rhs)
136 // check assignement to self
137 if (this == &rhs) return *this;
140 "Assignment operator is not implemented.");
149 //______________________________________________________________________________
150 void AliMUONSt1Segmentation::UpdateCurrentPadValues(const AliMpPad& pad)
152 // Updates current pad values.
155 fIx = pad.GetIndices().GetFirst();
156 fIy = pad.GetIndices().GetSecond();
157 fX = pad.Position().X() * fgkLengthUnit;
158 fY = pad.Position().Y() * fgkLengthUnit;
159 fSector = fPlaneSegmentation->Zone(pad);
166 //______________________________________________________________________________
167 void AliMUONSt1Segmentation::SetPadSize(Float_t /*p1*/, Float_t /*p2*/)
169 // Set pad size Dx*Dy
172 Fatal("SetPadSize", "Not uniform pad size.");
175 //______________________________________________________________________________
176 void AliMUONSt1Segmentation::SetDAnod(Float_t d)
184 //______________________________________________________________________________
185 Float_t AliMUONSt1Segmentation::GetAnod(Float_t xhit) const
187 // Anod wire coordinate closest to xhit
188 // Returns for a hit position xhit the position of the nearest anode wire
189 // From AliMUONSegmentationV01.
192 Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5
193 : Int_t(xhit/fWireD) - 0.5;
198 //______________________________________________________________________________
199 void AliMUONSt1Segmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
200 Int_t& ix, Int_t& iy)
202 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
205 GetPadI(x, y, ix, iy);
208 //______________________________________________________________________________
209 void AliMUONSt1Segmentation::GetPadI(Float_t x, Float_t y,
210 Int_t& ix, Int_t& iy)
212 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
213 // If there is no pad, ix = 0, iy = 0 are returned.
216 AliMpPad pad = fPlaneSegmentation
217 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), false);
219 ix = pad.GetIndices().GetFirst();
220 iy = pad.GetIndices().GetSecond();
223 //______________________________________________________________________________
224 void AliMUONSt1Segmentation::GetPadC(Int_t ix, Int_t iy,
225 Float_t& x, Float_t& y, Float_t& z)
227 // Transform from pad to real coordinates
231 GetPadC(ix, iy, x , y);
234 //______________________________________________________________________________
235 void AliMUONSt1Segmentation::GetPadC(Int_t ix, Int_t iy,
236 Float_t& x, Float_t& y)
238 // Transform from pad to real coordinates
239 // If there is no pad, x = 0., y = 0. are returned.
242 AliMpPad pad = fPlaneSegmentation->PadByIndices(AliMpIntPair(ix,iy));
244 x = pad.Position().X() * fgkLengthUnit;
245 y = pad.Position().Y() * fgkLengthUnit;
249 //______________________________________________________________________________
250 void AliMUONSt1Segmentation::Init(Int_t chamber)
252 // Initialize segmentation
255 // find Npx, Npy and save this info
257 // reference to chamber
258 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
259 fChamber = &(pMUON->Chamber(chamber));
260 fRmin=fChamber->RInner();
261 fRmax=fChamber->ROuter();
266 //______________________________________________________________________________
267 Float_t AliMUONSt1Segmentation::Dpx() const
272 Fatal("Dpx", "Not uniform pad size.");
276 //______________________________________________________________________________
277 Float_t AliMUONSt1Segmentation::Dpy() const
282 Fatal("Dpy", "Not uniform pad size.");
286 //______________________________________________________________________________
287 Float_t AliMUONSt1Segmentation::Dpx(Int_t isector) const
289 // Pad size in x by sector
292 return fPlaneSegmentation->PadDimensions(isector).X()*2.*fgkLengthUnit;
295 //______________________________________________________________________________
296 Float_t AliMUONSt1Segmentation::Dpy(Int_t isector) const
298 // Pad size in x, y by Sector
301 return fPlaneSegmentation->PadDimensions(isector).Y()*2.*fgkLengthUnit;
304 //______________________________________________________________________________
305 Int_t AliMUONSt1Segmentation::Npx() const
307 // Maximum number of Pads in x
310 //Fatal("Npx", "Not yet implemented.");
311 return 142; //hard coded for the time being
314 //______________________________________________________________________________
315 Int_t AliMUONSt1Segmentation::Npy() const
317 // Maximum number of Pads in y
320 //Fatal("Npy", "Not yet implemented.");
321 return 213; //hard coded for the time being
324 //______________________________________________________________________________
325 void AliMUONSt1Segmentation::SetPad(Int_t ix, Int_t iy)
328 // Sets virtual pad coordinates, needed for evaluating pad response
329 // outside the tracking program.
330 // From AliMUONSegmentationV01.
333 GetPadC(ix, iy, fX, fY);
334 fSector = Sector(ix, iy);
337 //______________________________________________________________________________
338 void AliMUONSt1Segmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
341 // Sets virtual hit position, needed for evaluating pad response
342 // outside the tracking program
343 // From AliMUONSegmentationV01.
349 //______________________________________________________________________________
350 void AliMUONSt1Segmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/,
351 Float_t dx, Float_t dy)
353 // Iterate over pads - initialiser
356 // Sets the current pad to that located in the hit position
358 SetHit(GetAnod(xhit), yhit, 0.);
360 // Enable iterating in one dimension
361 if (dx == 0.) dx = 0.01;
362 if (dy == 0.) dy = 0.01;
366 ->CreateIterator(AliMpArea(TVector2(fXhit/fgkLengthUnit, fYhit/fgkLengthUnit),
367 TVector2(dx/fgkLengthUnit, dy/fgkLengthUnit)));
369 fPlaneIterator->First();
371 if (! fPlaneIterator->IsDone())
372 UpdateCurrentPadValues(fPlaneIterator->CurrentItem());
375 //______________________________________________________________________________
376 void AliMUONSt1Segmentation::NextPad()
378 // Iterate over pads - stepper
381 fPlaneIterator->Next();
383 if (! fPlaneIterator->IsDone())
384 UpdateCurrentPadValues(fPlaneIterator->CurrentItem());
387 //______________________________________________________________________________
388 Int_t AliMUONSt1Segmentation::MorePads()
390 // Iterate over pads - condition
393 if (fPlaneIterator->IsDone())
399 //______________________________________________________________________________
400 Float_t AliMUONSt1Segmentation::Distance2AndOffset(Int_t iX, Int_t iY,
401 Float_t x, Float_t y, Int_t* /*dummy*/)
403 // Returns the square of the distance between 1 pad
404 // labelled by its channel numbers and a coordinate
407 AliMpPad pad = fPlaneSegmentation->PadByIndices(AliMpIntPair(iX, iY));
410 Fatal("Distance2AndOffset", "Cannot locate pad.");
412 return (pad.Position()*fgkLengthUnit - TVector2(x, y)).Mod2();
415 //______________________________________________________________________________
416 void AliMUONSt1Segmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
417 Int_t* /*Nparallel*/, Int_t* /*Offset*/)
419 // Number of pads read in parallel and offset to add to x
420 // (specific to LYON, but mandatory for display)
423 Fatal("GetNParallelAndOffset", "Not yet implemented.");
427 //______________________________________________________________________________
428 void AliMUONSt1Segmentation::Neighbours(Int_t iX, Int_t iY,
430 Int_t Xlist[10], Int_t Ylist[10])
432 // Get next neighbours
435 AliMpPad pad = fPlaneSegmentation->PadByIndices(AliMpIntPair(iX,iY));
438 AliMpVPadIterator* iter
440 ->CreateIterator(AliMpArea(pad.Position(),2.*pad.Dimensions()*1.1));
442 for( iter->First(); !iter->IsDone() && i<10; iter->Next()) {
443 Xlist[i] = iter->CurrentItem().GetIndices().GetFirst();
444 Ylist[i] = iter->CurrentItem().GetIndices().GetSecond();
451 //______________________________________________________________________________
452 Int_t AliMUONSt1Segmentation::Ix()
454 // Current pad cursor during disintegration
458 return fPlaneIterator->CurrentItem().GetIndices().GetFirst();
461 //______________________________________________________________________________
462 Int_t AliMUONSt1Segmentation::Iy()
464 // Current pad cursor during disintegration
468 return fPlaneIterator->CurrentItem().GetIndices().GetSecond();
471 //______________________________________________________________________________
472 Int_t AliMUONSt1Segmentation::ISector()
480 //______________________________________________________________________________
481 Int_t AliMUONSt1Segmentation::Sector(Int_t ix, Int_t iy)
483 // Calculate sector from pad coordinates
486 return fPlaneSegmentation
487 ->Zone(fPlaneSegmentation->PadByIndices(AliMpIntPair(ix, iy)));
490 //______________________________________________________________________________
491 Int_t AliMUONSt1Segmentation::Sector(Float_t x, Float_t y)
493 // Calculate sector from pad coordinates
496 return fPlaneSegmentation
497 ->Zone(fPlaneSegmentation
498 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit)));
501 //______________________________________________________________________________
502 void AliMUONSt1Segmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
503 Float_t& y1, Float_t& y2)
505 // Current integration limits
508 x1 = fXhit - fX - Dpx(fSector)/2.;
509 x2 = x1 + Dpx(fSector);
511 y1 = fYhit - fY - Dpy(fSector)/2.;
512 y2 = y1 + Dpy(fSector);
515 //______________________________________________________________________________
516 Int_t AliMUONSt1Segmentation::SigGenCond(Float_t x, Float_t y, Float_t /*z*/)
518 // Signal Generation Condition during Stepping
519 // 0: don't generate signal
520 // 1: generate signal
523 // Crossing of pad boundary and mid plane between neighbouring wires is checked.
524 // To correctly simulate the dependence of the spatial resolution on the angle
525 // of incidence signal must be generated for constant steps on
526 // the projection of the trajectory along the anode wire.
528 // Signal will be generated if particle crosses pad boundary or
529 // boundary between two wires.
531 // From AliMUONSegmentationV01
535 GetPadI(x, y, ixt, iyt);
536 Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1;
538 if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
547 //______________________________________________________________________________
548 void AliMUONSt1Segmentation::SigGenInit(Float_t x, Float_t y, Float_t /*z*/)
550 // Initialise signal generation at coord (x,y,z)
551 // Initialises pad and wire position during stepping.
552 // From AliMUONSegmentationV01
557 GetPadI(x, y, fIxt, fIyt);
558 fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ;
561 //______________________________________________________________________________
562 void AliMUONSt1Segmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const
564 // Test points for auto calibration
565 // Returns test point on the pad plane.
566 // Used during determination of the segmoid correction of the COG-method
567 // From AliMUONSegmentationV01
571 x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.);
575 //______________________________________________________________________________
576 void AliMUONSt1Segmentation::Draw(const char * /*opt*/) const
578 // Draw the segmentation zones.
579 // (Called from AliMUON::BuildGeometry)
582 Warning("Draw", "Not yet implemented.");
585 //______________________________________________________________________________
586 void AliMUONSt1Segmentation::SetCorrFunc(Int_t isec, TF1* func)
588 // Set the correction function.
589 // From AliMUONSegmentationV01
592 fCorrA->AddAt(func, isec);
595 //______________________________________________________________________________
596 TF1* AliMUONSt1Segmentation::CorrFunc(Int_t isec) const
598 // Get the correction Function.
599 // From AliMUONSegmentationV01
602 return (TF1*) fCorrA->At(isec);