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"
42 #include "AliMpFiles.h"
45 ClassImp(AliMUONSt12QuadrantSegmentation)
47 const Float_t AliMUONSt12QuadrantSegmentation::fgkWireD = 0.20;
48 const Float_t AliMUONSt12QuadrantSegmentation::fgkLengthUnit = 0.1;
50 //______________________________________________________________________________
51 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation(
52 AliMpStationType stationType,
53 AliMpPlaneType planeType)
54 : AliMUONVGeometryDESegmentation(),
56 fSectorSegmentation(0),
80 // set path to mapping data files
81 if (!gSystem->Getenv("MINSTALL")) {
82 TString dirPath = gSystem->Getenv("ALICE_ROOT");
83 dirPath += "/MUON/mapping";
84 AliMpFiles::Instance()->SetTopPath(dirPath);
85 gSystem->Setenv("MINSTALL", dirPath.Data());
86 //cout << "AliMpFiles top path set to " << dirPath << endl;
89 AliMpReader r(stationType, planeType);
90 fSector = r.BuildSector();
91 fSectorSegmentation = new AliMpSectorSegmentation(fSector);
93 fCorrA = new TObjArray(3);
99 //______________________________________________________________________________
100 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation()
101 : AliMUONVGeometryDESegmentation(),
103 fSectorSegmentation(0),
124 // Default Constructor
127 //______________________________________________________________________________
128 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation(const AliMUONSt12QuadrantSegmentation& rhs)
129 : AliMUONVGeometryDESegmentation(rhs)
132 AliFatal("Copy constructor is not implemented.");
135 //______________________________________________________________________________
136 AliMUONSt12QuadrantSegmentation::~AliMUONSt12QuadrantSegmentation() {
140 delete fSectorSegmentation;
141 delete fSectorIterator;
148 //______________________________________________________________________________
149 AliMUONSt12QuadrantSegmentation&
150 AliMUONSt12QuadrantSegmentation::operator=(const AliMUONSt12QuadrantSegmentation& rhs)
154 // check assignement to self
155 if (this == &rhs) return *this;
157 AliFatal("Assignment operator is not implemented.");
166 //______________________________________________________________________________
167 void AliMUONSt12QuadrantSegmentation::UpdateCurrentPadValues(const AliMpPad& pad)
169 // Updates current pad values.
172 fIx = pad.GetIndices().GetFirst();
173 fIy = pad.GetIndices().GetSecond();
174 fX = pad.Position().X() * fgkLengthUnit;
175 fY = pad.Position().Y() * fgkLengthUnit;
176 fZone = fSectorSegmentation->Zone(pad);
183 //______________________________________________________________________________
184 void AliMUONSt12QuadrantSegmentation::SetPadSize(Float_t /*p1*/, Float_t /*p2*/)
186 // Set pad size Dx*Dy
189 AliFatal("Not uniform pad size.");
192 //______________________________________________________________________________
193 void AliMUONSt12QuadrantSegmentation::SetDAnod(Float_t d)
201 //______________________________________________________________________________
202 Bool_t AliMUONSt12QuadrantSegmentation::HasPad(Float_t x, Float_t y, Float_t /*z*/)
204 // Returns true if a pad exists in the given position
206 AliMpPad pad = fSectorSegmentation
207 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), false);
209 return pad.IsValid();
213 //______________________________________________________________________________
214 Bool_t AliMUONSt12QuadrantSegmentation::HasPad(Int_t ix, Int_t iy)
216 // Returns true if a pad with given indices exists
218 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), false);
220 return pad.IsValid();
224 //______________________________________________________________________________
225 AliMUONGeometryDirection AliMUONSt12QuadrantSegmentation::GetDirection()
227 // Returns the direction with a constant pad size
228 // (Direction or coordinate where the resolution is the best)
230 switch ( fSector->GetDirection() ) {
231 case kX: return kDirX;
232 case kY: return kDirY;
233 default: return kDirUndefined;
237 //______________________________________________________________________________
238 Float_t AliMUONSt12QuadrantSegmentation::GetAnod(Float_t xhit) const
240 // Anod wire coordinate closest to xhit
241 // Returns for a hit position xhit the position of the nearest anode wire
242 // From AliMUONSegmentationV01.
245 Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5
246 : Int_t(xhit/fWireD) - 0.5;
251 //______________________________________________________________________________
252 void AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
253 Int_t& ix, Int_t& iy)
255 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
258 GetPadI(x, y, ix, iy);
261 //______________________________________________________________________________
262 void AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y,
263 Int_t& ix, Int_t& iy)
265 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
266 // If there is no pad, ix = 0, iy = 0 are returned.
269 AliMpPad pad = fSectorSegmentation
270 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), true);
272 ix = pad.GetIndices().GetFirst();
273 iy = pad.GetIndices().GetSecond();
276 //______________________________________________________________________________
277 void AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy,
278 Float_t& x, Float_t& y, Float_t& z)
280 // Transform from pad to real coordinates
284 GetPadC(ix, iy, x , y);
287 //______________________________________________________________________________
288 void AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy,
289 Float_t& x, Float_t& y)
291 // Transform from pad to real coordinates
292 // If there is no pad, x = 0., y = 0. are returned.
295 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), true);
297 x = pad.Position().X() * fgkLengthUnit;
298 y = pad.Position().Y() * fgkLengthUnit;
302 //______________________________________________________________________________
303 void AliMUONSt12QuadrantSegmentation::Init(Int_t chamber)
305 // Initialize segmentation
308 // find Npx, Npy and save this info
310 // reference to chamber
311 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
312 fChamber = &(pMUON->Chamber(chamber));
313 fRmin=fChamber->RInner();
314 fRmax=fChamber->ROuter();
319 //______________________________________________________________________________
320 Float_t AliMUONSt12QuadrantSegmentation::Dpx() const
325 AliFatal( "Not uniform pad size.");
329 //______________________________________________________________________________
330 Float_t AliMUONSt12QuadrantSegmentation::Dpy() const
335 AliFatal("Not uniform pad size.");
339 //______________________________________________________________________________
340 Float_t AliMUONSt12QuadrantSegmentation::Dpx(Int_t isector) const
342 // Pad size in x by sector
345 return fSectorSegmentation->PadDimensions(isector).X()*2.*fgkLengthUnit;
348 //______________________________________________________________________________
349 Float_t AliMUONSt12QuadrantSegmentation::Dpy(Int_t isector) const
351 // Pad size in x, y by Sector
354 return fSectorSegmentation->PadDimensions(isector).Y()*2.*fgkLengthUnit;
357 //______________________________________________________________________________
358 Int_t AliMUONSt12QuadrantSegmentation::Npx() const
360 // Maximum number of Pads in x
361 // hard coded for the time being
364 //Fatal("Npx", "Not yet implemented.");
365 switch (fSector->GetDirection()) {
371 AliError("Unknown sector direction");
376 //______________________________________________________________________________
377 Int_t AliMUONSt12QuadrantSegmentation::Npy() const
379 // Maximum number of Pads in y
380 // hard coded for the time being
383 //Fatal("Npy", "Not yet implemented.");
384 switch (fSector->GetDirection()) {
390 AliError("Unknown sector direction");
395 //______________________________________________________________________________
396 void AliMUONSt12QuadrantSegmentation::SetPad(Int_t ix, Int_t iy)
399 // Sets virtual pad coordinates, needed for evaluating pad response
400 // outside the tracking program.
401 // From AliMUONSegmentationV01.
404 GetPadC(ix, iy, fX, fY);
405 fZone = Sector(ix, iy);
408 //______________________________________________________________________________
409 void AliMUONSt12QuadrantSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
412 // Sets virtual hit position, needed for evaluating pad response
413 // outside the tracking program
414 // From AliMUONSegmentationV01.
420 //______________________________________________________________________________
421 void AliMUONSt12QuadrantSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/,
422 Float_t dx, Float_t dy)
424 // Iterate over pads - initialiser
427 // Sets the current pad to that located in the hit position
429 SetHit(GetAnod(xhit), yhit, 0.);
431 // Enable iterating in one dimension
432 if (dx == 0.) dx = 0.01;
433 if (dy == 0.) dy = 0.01;
436 = fSectorSegmentation
437 ->CreateIterator(AliMpArea(TVector2(fXhit/fgkLengthUnit, fYhit/fgkLengthUnit),
438 TVector2(dx/fgkLengthUnit, dy/fgkLengthUnit)));
440 fSectorIterator->First();
442 if (! fSectorIterator->IsDone())
443 UpdateCurrentPadValues(fSectorIterator->CurrentItem());
446 //______________________________________________________________________________
447 void AliMUONSt12QuadrantSegmentation::NextPad()
449 // Iterate over pads - stepper
452 fSectorIterator->Next();
454 if (! fSectorIterator->IsDone())
455 UpdateCurrentPadValues(fSectorIterator->CurrentItem());
458 //______________________________________________________________________________
459 Int_t AliMUONSt12QuadrantSegmentation::MorePads()
461 // Iterate over pads - condition
464 if (fSectorIterator->IsDone())
470 //______________________________________________________________________________
471 Float_t AliMUONSt12QuadrantSegmentation::Distance2AndOffset(Int_t iX, Int_t iY,
472 Float_t x, Float_t y, Int_t* /*dummy*/)
474 // Returns the square of the distance between 1 pad
475 // labelled by its channel numbers and a coordinate
478 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX, iY));
481 AliFatal("Cannot locate pad.");
483 return (pad.Position()*fgkLengthUnit - TVector2(x, y)).Mod2();
486 //______________________________________________________________________________
487 void AliMUONSt12QuadrantSegmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
488 Int_t* /*Nparallel*/, Int_t* /*Offset*/)
490 // Number of pads read in parallel and offset to add to x
491 // (specific to LYON, but mandatory for display)
494 AliFatal( "Not yet implemented.");
498 //______________________________________________________________________________
499 void AliMUONSt12QuadrantSegmentation::Neighbours(Int_t iX, Int_t iY,
501 Int_t Xlist[10], Int_t Ylist[10])
503 // Get next neighbours
506 AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX,iY));
509 AliMpVPadIterator* iter
510 = fSectorSegmentation
511 ->CreateIterator(AliMpArea(pad.Position(),2.*pad.Dimensions()*1.1));
513 for( iter->First(); !iter->IsDone() && i<10; iter->Next()) {
514 Xlist[i] = iter->CurrentItem().GetIndices().GetFirst();
515 Ylist[i] = iter->CurrentItem().GetIndices().GetSecond();
522 //______________________________________________________________________________
523 Int_t AliMUONSt12QuadrantSegmentation::Ix()
525 // Current pad cursor during disintegration
529 return fSectorIterator->CurrentItem().GetIndices().GetFirst();
532 //______________________________________________________________________________
533 Int_t AliMUONSt12QuadrantSegmentation::Iy()
535 // Current pad cursor during disintegration
539 return fSectorIterator->CurrentItem().GetIndices().GetSecond();
542 //______________________________________________________________________________
543 Int_t AliMUONSt12QuadrantSegmentation::ISector()
551 //______________________________________________________________________________
552 Int_t AliMUONSt12QuadrantSegmentation::Sector(Int_t ix, Int_t iy)
554 // Calculate sector from pad coordinates
557 return fSectorSegmentation
558 ->Zone(fSectorSegmentation->PadByIndices(AliMpIntPair(ix, iy)));
561 //______________________________________________________________________________
562 Int_t AliMUONSt12QuadrantSegmentation::Sector(Float_t x, Float_t y)
564 // Calculate sector from pad coordinates
567 return fSectorSegmentation
568 ->Zone(fSectorSegmentation
569 ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit)));
572 //______________________________________________________________________________
573 void AliMUONSt12QuadrantSegmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
574 Float_t& y1, Float_t& y2)
576 // Current integration limits
579 x1 = fXhit - fX - Dpx(fZone)/2.;
580 x2 = x1 + Dpx(fZone);
582 y1 = fYhit - fY - Dpy(fZone)/2.;
583 y2 = y1 + Dpy(fZone);
586 //______________________________________________________________________________
587 Int_t AliMUONSt12QuadrantSegmentation::SigGenCond(Float_t x, Float_t y, Float_t /*z*/)
589 // Signal Generation Condition during Stepping
590 // 0: don't generate signal
591 // 1: generate signal
594 // Crossing of pad boundary and mid plane between neighbouring wires is checked.
595 // To correctly simulate the dependence of the spatial resolution on the angle
596 // of incidence signal must be generated for constant steps on
597 // the projection of the trajectory along the anode wire.
599 // Signal will be generated if particle crosses pad boundary or
600 // boundary between two wires.
602 // From AliMUONSegmentationV01
606 GetPadI(x, y, ixt, iyt);
607 Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1;
609 if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
618 //______________________________________________________________________________
619 void AliMUONSt12QuadrantSegmentation::SigGenInit(Float_t x, Float_t y, Float_t /*z*/)
621 // Initialise signal generation at coord (x,y,z)
622 // Initialises pad and wire position during stepping.
623 // From AliMUONSegmentationV01
628 GetPadI(x, y, fIxt, fIyt);
629 fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ;
632 //______________________________________________________________________________
633 void AliMUONSt12QuadrantSegmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const
635 // Test points for auto calibration
636 // Returns test point on the pad plane.
637 // Used during determination of the segmoid correction of the COG-method
638 // From AliMUONSegmentationV01
642 x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.);
646 //______________________________________________________________________________
647 void AliMUONSt12QuadrantSegmentation::Draw(const char * /*opt*/)
649 // Draw the segmentation zones.
650 // (Called from AliMUON::BuildGeometry)
653 AliWarning("Not yet implemented.");
656 //______________________________________________________________________________
657 void AliMUONSt12QuadrantSegmentation::SetCorrFunc(Int_t isec, TF1* func)
659 // Set the correction function.
660 // From AliMUONSegmentationV01
663 fCorrA->AddAt(func, isec);
666 //______________________________________________________________________________
667 TF1* AliMUONSt12QuadrantSegmentation::CorrFunc(Int_t isec) const
669 // Get the correction Function.
670 // From AliMUONSegmentationV01
673 return (TF1*) fCorrA->At(isec);