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
25 #include <Riostream.h>
27 #include <TObjArray.h>
31 #include <AliMpPlane.h>
32 #include <AliMpPlaneType.h>
33 #include <AliMpPlaneSegmentation.h>
34 #include <AliMpPlaneAreaPadIterator.h>
36 #include "AliMUONSt1Segmentation.h"
39 #include "AliMUONChamber.h"
41 ClassImp(AliMUONSt1Segmentation)
43 const Float_t AliMUONSt1Segmentation::fgkWireD = 0.20;
44 const Float_t AliMUONSt1Segmentation::fgkLengthUnit = 0.1;
46 //______________________________________________________________________________
47 AliMUONSt1Segmentation::AliMUONSt1Segmentation(const AliMpPlaneType planeType)
50 fPlaneSegmentation(0),
73 fPlane = AliMpPlane::Create(kStation1, planeType);
74 fPlaneSegmentation = new AliMpPlaneSegmentation(fPlane);
76 fCorrA = new TObjArray(3);
82 //______________________________________________________________________________
83 AliMUONSt1Segmentation::AliMUONSt1Segmentation()
86 fPlaneSegmentation(0),
107 // Default Constructor
110 //______________________________________________________________________________
111 AliMUONSt1Segmentation::AliMUONSt1Segmentation(const AliMUONSt1Segmentation& rhs) :AliSegmentation(rhs)
114 Fatal("Copy constructor",
115 "Copy constructor is not implemented.");
118 //______________________________________________________________________________
119 AliMUONSt1Segmentation::~AliMUONSt1Segmentation() {
123 delete fPlaneSegmentation;
124 delete fPlaneIterator;
131 //______________________________________________________________________________
132 AliMUONSt1Segmentation&
133 AliMUONSt1Segmentation::operator=(const AliMUONSt1Segmentation& rhs)
137 // check assignement to self
138 if (this == &rhs) return *this;
141 "Assignment operator is not implemented.");
150 //______________________________________________________________________________
151 void AliMUONSt1Segmentation::UpdateCurrentPadValues(const AliMpPad& pad)
153 // Updates current pad values.
156 fIx = pad.GetIndices().GetFirst();
157 fIy = pad.GetIndices().GetSecond();
158 fX = pad.Position().X() * fgkLengthUnit;
159 fY = pad.Position().Y() * fgkLengthUnit;
160 fSector = fPlaneSegmentation->Zone(pad);
167 //______________________________________________________________________________
168 void AliMUONSt1Segmentation::SetPadSize(Float_t /*p1*/, Float_t /*p2*/)
170 // Set pad size Dx*Dy
173 Fatal("SetPadSize", "Not uniform pad size.");
176 //______________________________________________________________________________
177 void AliMUONSt1Segmentation::SetDAnod(Float_t d)
185 //______________________________________________________________________________
186 Float_t AliMUONSt1Segmentation::GetAnod(Float_t xhit) const
188 // Anod wire coordinate closest to xhit
189 // Returns for a hit position xhit the position of the nearest anode wire
190 // From AliMUONSegmentationV01.
193 Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5
194 : Int_t(xhit/fWireD) - 0.5;
199 //______________________________________________________________________________
200 void AliMUONSt1Segmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
201 Int_t& ix, Int_t& iy)
203 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
206 GetPadI(x, y, ix, iy);
209 //______________________________________________________________________________
210 void AliMUONSt1Segmentation::GetPadI(Float_t x, Float_t y,
211 Int_t& ix, Int_t& iy)
213 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
214 // If there is no pad, ix = 0, iy = 0 are returned.
217 AliMpPad pad = fPlaneSegmentation
218 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), false);
220 ix = pad.GetIndices().GetFirst();
221 iy = pad.GetIndices().GetSecond();
224 //______________________________________________________________________________
225 void AliMUONSt1Segmentation::GetPadC(Int_t ix, Int_t iy,
226 Float_t& x, Float_t& y, Float_t& z)
228 // Transform from pad to real coordinates
232 GetPadC(ix, iy, x , y);
235 //______________________________________________________________________________
236 void AliMUONSt1Segmentation::GetPadC(Int_t ix, Int_t iy,
237 Float_t& x, Float_t& y)
239 // Transform from pad to real coordinates
240 // If there is no pad, x = 0., y = 0. are returned.
243 AliMpPad pad = fPlaneSegmentation->PadByIndices(AliMpIntPair(ix,iy));
245 x = pad.Position().X() * fgkLengthUnit;
246 y = pad.Position().Y() * fgkLengthUnit;
250 //______________________________________________________________________________
251 void AliMUONSt1Segmentation::Init(Int_t chamber)
253 // Initialize segmentation
256 // find Npx, Npy and save this info
258 // reference to chamber
259 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
260 fChamber = &(pMUON->Chamber(chamber));
261 fRmin=fChamber->RInner();
262 fRmax=fChamber->ROuter();
267 //______________________________________________________________________________
268 Float_t AliMUONSt1Segmentation::Dpx() const
273 Fatal("Dpx", "Not uniform pad size.");
277 //______________________________________________________________________________
278 Float_t AliMUONSt1Segmentation::Dpy() const
283 Fatal("Dpy", "Not uniform pad size.");
287 //______________________________________________________________________________
288 Float_t AliMUONSt1Segmentation::Dpx(Int_t isector) const
290 // Pad size in x by sector
293 return fPlaneSegmentation->PadDimensions(isector).X()*2.*fgkLengthUnit;
296 //______________________________________________________________________________
297 Float_t AliMUONSt1Segmentation::Dpy(Int_t isector) const
299 // Pad size in x, y by Sector
302 return fPlaneSegmentation->PadDimensions(isector).Y()*2.*fgkLengthUnit;
305 //______________________________________________________________________________
306 Int_t AliMUONSt1Segmentation::Npx() const
308 // Maximum number of Pads in x
311 //Fatal("Npx", "Not yet implemented.");
312 return 142; //hard coded for the time being
315 //______________________________________________________________________________
316 Int_t AliMUONSt1Segmentation::Npy() const
318 // Maximum number of Pads in y
321 //Fatal("Npy", "Not yet implemented.");
322 return 213; //hard coded for the time being
325 //______________________________________________________________________________
326 void AliMUONSt1Segmentation::SetPad(Int_t ix, Int_t iy)
329 // Sets virtual pad coordinates, needed for evaluating pad response
330 // outside the tracking program.
331 // From AliMUONSegmentationV01.
334 GetPadC(ix, iy, fX, fY);
335 fSector = Sector(ix, iy);
338 //______________________________________________________________________________
339 void AliMUONSt1Segmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
342 // Sets virtual hit position, needed for evaluating pad response
343 // outside the tracking program
344 // From AliMUONSegmentationV01.
350 //______________________________________________________________________________
351 void AliMUONSt1Segmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/,
352 Float_t dx, Float_t dy)
354 // Iterate over pads - initialiser
357 // Sets the current pad to that located in the hit position
359 SetHit(GetAnod(xhit), yhit, 0.);
361 // Enable iterating in one dimension
362 if (dx == 0.) dx = 0.01;
363 if (dy == 0.) dy = 0.01;
367 ->CreateIterator(AliMpArea(TVector2(fXhit/fgkLengthUnit, fYhit/fgkLengthUnit),
368 TVector2(dx/fgkLengthUnit, dy/fgkLengthUnit)));
370 fPlaneIterator->First();
372 if (! fPlaneIterator->IsDone())
373 UpdateCurrentPadValues(fPlaneIterator->CurrentItem());
376 //______________________________________________________________________________
377 void AliMUONSt1Segmentation::NextPad()
379 // Iterate over pads - stepper
382 fPlaneIterator->Next();
384 if (! fPlaneIterator->IsDone())
385 UpdateCurrentPadValues(fPlaneIterator->CurrentItem());
388 //______________________________________________________________________________
389 Int_t AliMUONSt1Segmentation::MorePads()
391 // Iterate over pads - condition
394 if (fPlaneIterator->IsDone())
400 //______________________________________________________________________________
401 Float_t AliMUONSt1Segmentation::Distance2AndOffset(Int_t iX, Int_t iY,
402 Float_t x, Float_t y, Int_t* /*dummy*/)
404 // Returns the square of the distance between 1 pad
405 // labelled by its channel numbers and a coordinate
408 AliMpPad pad = fPlaneSegmentation->PadByIndices(AliMpIntPair(iX, iY));
411 Fatal("Distance2AndOffset", "Cannot locate pad.");
413 return (pad.Position()*fgkLengthUnit - TVector2(x, y)).Mod2();
416 //______________________________________________________________________________
417 void AliMUONSt1Segmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
418 Int_t* /*Nparallel*/, Int_t* /*Offset*/)
420 // Number of pads read in parallel and offset to add to x
421 // (specific to LYON, but mandatory for display)
424 Fatal("GetNParallelAndOffset", "Not yet implemented.");
428 //______________________________________________________________________________
429 void AliMUONSt1Segmentation::Neighbours(Int_t iX, Int_t iY,
431 Int_t Xlist[10], Int_t Ylist[10])
433 // Get next neighbours
436 AliMpPad pad = fPlaneSegmentation->PadByIndices(AliMpIntPair(iX,iY));
439 AliMpVPadIterator* iter
441 ->CreateIterator(AliMpArea(pad.Position(),2.*pad.Dimensions()*1.1));
443 for( iter->First(); !iter->IsDone() && i<10; iter->Next()) {
444 Xlist[i] = iter->CurrentItem().GetIndices().GetFirst();
445 Ylist[i] = iter->CurrentItem().GetIndices().GetSecond();
452 //______________________________________________________________________________
453 Int_t AliMUONSt1Segmentation::Ix()
455 // Current pad cursor during disintegration
459 return fPlaneIterator->CurrentItem().GetIndices().GetFirst();
462 //______________________________________________________________________________
463 Int_t AliMUONSt1Segmentation::Iy()
465 // Current pad cursor during disintegration
469 return fPlaneIterator->CurrentItem().GetIndices().GetSecond();
472 //______________________________________________________________________________
473 Int_t AliMUONSt1Segmentation::ISector()
481 //______________________________________________________________________________
482 Int_t AliMUONSt1Segmentation::Sector(Int_t ix, Int_t iy)
484 // Calculate sector from pad coordinates
487 return fPlaneSegmentation
488 ->Zone(fPlaneSegmentation->PadByIndices(AliMpIntPair(ix, iy)));
491 //______________________________________________________________________________
492 Int_t AliMUONSt1Segmentation::Sector(Float_t x, Float_t y)
494 // Calculate sector from pad coordinates
497 return fPlaneSegmentation
498 ->Zone(fPlaneSegmentation
499 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit)));
502 //______________________________________________________________________________
503 void AliMUONSt1Segmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
504 Float_t& y1, Float_t& y2)
506 // Current integration limits
509 x1 = fXhit - fX - Dpx(fSector)/2.;
510 x2 = x1 + Dpx(fSector);
512 y1 = fYhit - fY - Dpy(fSector)/2.;
513 y2 = y1 + Dpy(fSector);
516 //______________________________________________________________________________
517 Int_t AliMUONSt1Segmentation::SigGenCond(Float_t x, Float_t y, Float_t /*z*/)
519 // Signal Generation Condition during Stepping
520 // 0: don't generate signal
521 // 1: generate signal
524 // Crossing of pad boundary and mid plane between neighbouring wires is checked.
525 // To correctly simulate the dependence of the spatial resolution on the angle
526 // of incidence signal must be generated for constant steps on
527 // the projection of the trajectory along the anode wire.
529 // Signal will be generated if particle crosses pad boundary or
530 // boundary between two wires.
532 // From AliMUONSegmentationV01
536 GetPadI(x, y, ixt, iyt);
537 Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1;
539 if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
548 //______________________________________________________________________________
549 void AliMUONSt1Segmentation::SigGenInit(Float_t x, Float_t y, Float_t /*z*/)
551 // Initialise signal generation at coord (x,y,z)
552 // Initialises pad and wire position during stepping.
553 // From AliMUONSegmentationV01
558 GetPadI(x, y, fIxt, fIyt);
559 fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ;
562 //______________________________________________________________________________
563 void AliMUONSt1Segmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const
565 // Test points for auto calibration
566 // Returns test point on the pad plane.
567 // Used during determination of the segmoid correction of the COG-method
568 // From AliMUONSegmentationV01
572 x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.);
576 //______________________________________________________________________________
577 void AliMUONSt1Segmentation::Draw(const char * /*opt*/) const
579 // Draw the segmentation zones.
580 // (Called from AliMUON::BuildGeometry)
583 Warning("Draw", "Not yet implemented.");
586 //______________________________________________________________________________
587 void AliMUONSt1Segmentation::SetCorrFunc(Int_t isec, TF1* func)
589 // Set the correction function.
590 // From AliMUONSegmentationV01
593 fCorrA->AddAt(func, isec);
596 //______________________________________________________________________________
597 TF1* AliMUONSt1Segmentation::CorrFunc(Int_t isec) const
599 // Get the correction Function.
600 // From AliMUONSegmentationV01
603 return (TF1*) fCorrA->At(isec);