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 **************************************************************************/
17 // $MpId: AliMpSectorSegmentation.cxx,v 1.15 2006/05/24 13:58:46 ivana Exp $
20 //-----------------------------------------------------------------------------
21 // Class AliMpSectorSegmentation
22 // -----------------------------
23 // Class describing the segmentation of the sector.
24 // Provides methods related to pads:
25 // conversion between pad indices, pad location, pad position;
26 // finding pad neighbour.
28 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
29 //-----------------------------------------------------------------------------
31 #include "AliMpSectorSegmentation.h"
32 #include "AliMpSector.h"
33 #include "AliMpZone.h"
34 #include "AliMpSubZone.h"
36 #include "AliMpVRowSegment.h"
37 #include "AliMpMotifMap.h"
38 #include "AliMpVMotif.h"
39 #include "AliMpMotifPosition.h"
40 #include "AliMpConnection.h"
41 #include "AliMpSectorAreaHPadIterator.h"
42 #include "AliMpSectorAreaVPadIterator.h"
43 #include "AliMpSectorPadIterator.h"
44 #include "AliMpArea.h"
45 #include "AliMpConstants.h"
46 #include "AliMpEncodePair.h"
50 #include <Riostream.h>
54 ClassImp(AliMpSectorSegmentation)
57 //______________________________________________________________________________
58 AliMpSectorSegmentation::AliMpSectorSegmentation(
59 const AliMpSector* sector, Bool_t own)
60 : AliMpVSegmentation(),
67 /// Standard constructor
69 AliDebugStream(1) << "this = " << this << endl;
71 fPadBuffer = new AliMpPad(AliMpPad::Invalid());
73 //FillPadDimensionsMap();
76 //______________________________________________________________________________
77 AliMpSectorSegmentation::AliMpSectorSegmentation()
78 : AliMpVSegmentation(),
85 /// Default constructor
87 AliDebugStream(1) << "this = " << this << endl;
90 //______________________________________________________________________________
91 AliMpSectorSegmentation::~AliMpSectorSegmentation()
95 AliDebugStream(1) << "this = " << this << endl;
97 if ( fIsOwner ) delete fkSector;
107 //______________________________________________________________________________
109 AliMpSectorSegmentation::FindMotifPosition(Int_t ix, Int_t iy) const
111 /// Find the motif position which contains the given pad indices
112 /// return 0 if not found
114 switch ( fkSector->GetDirection() ) {
116 // Case where all the pads have the same size along X direction
118 for ( Int_t irow=0; irow<fkSector->GetNofRows(); ++irow ) {
119 AliMpRow* row = fkSector->GetRow(irow);
120 if ( row->GetLowLimitIx() <= ix &&
121 row->GetHighLimitIx()>= ix ) {
123 for ( Int_t iseg=0;iseg<row->GetNofRowSegments();++iseg ) {
124 AliMpVRowSegment* seg = row->GetRowSegment(iseg);
125 if ( seg->GetLowLimitIx() <= ix &&
126 seg->GetHighLimitIx() >= ix ) {
128 AliMpMotifPosition* motifPos;
129 for ( Int_t imot=0;imot<seg->GetNofMotifs();++imot ) {
131 = fkSector->GetMotifMap()
132 ->FindMotifPosition(seg->GetMotifPositionId(imot));
133 if (motifPos && motifPos->HasPadByIndices(AliMp::Pair(ix,iy))) return motifPos;
142 ////////////////////////////////////////////////////////////////////////////////
144 // Case where all the pads have the same size along Y direction
145 // look for the row which contains the indices
148 for ( irow=0; irow<fkSector->GetNofRows(); ++irow ) {
149 row = fkSector->GetRow(irow);
150 AliMpVRowSegment* lastSeg = row->GetRowSegment(row->GetNofRowSegments()-1);
151 if ( lastSeg->GetLowLimitIy() <= iy &&
152 lastSeg->GetHighLimitIy() >= iy ) break;
153 // NOTE : We use the last row segment in order to ensure that
154 // we are not on a special motif
156 if ( irow==fkSector->GetNofRows() ) return 0;
157 // look for the row segment, in the found row, which contains the indices
158 AliMpVRowSegment* seg=0;
160 for ( iseg=0;iseg<row->GetNofRowSegments();++iseg ) {
161 seg = row->GetRowSegment(iseg);
162 if (seg->HasIndices(AliMp::Pair(ix, iy))) break;
164 if ( iseg==row->GetNofRowSegments() ) return 0;
166 // look for the motif position which contains the indices
167 AliMpMotifPosition* motifPos=0;
169 for ( imot=0;imot<seg->GetNofMotifs();++imot ) {
171 = fkSector->GetMotifMap()
172 ->FindMotifPosition(seg->GetMotifPositionId(imot));
173 if (motifPos && motifPos->HasPadByIndices(AliMp::Pair(ix, iy))) break;
175 if (imot==seg->GetNofMotifs()) return 0;
183 //______________________________________________________________________________
185 AliMpSectorSegmentation::PadByXDirection(Double_t startx, Double_t starty,
188 /// Find the first valid pad from starting position in the
189 /// direction of pad lines up to distance dx.
191 // Define step limits
192 Double_t stepX = fkSector->GetMinPadDimensionX();
194 // Search in X direction
196 Double_t posx = startx;
198 pad = PadByPosition(posx, starty, false);
201 while ( ! pad.IsValid() &&
202 posx - fkSector->GetMaxPadDimensionX() < maxX );
204 // Invalidate pad if it is outside limits
205 if ( ( pad.GetPositionX() - pad.GetDimensionX()) > maxX )
206 pad = AliMpPad::Invalid();
211 //______________________________________________________________________________
213 AliMpSectorSegmentation::PadByYDirection(Double_t startx, Double_t starty,
216 /// Find the first valid pad from starting position in the
217 /// direction of pad columns up to distance dx.
219 // Define step limits
220 Double_t stepY = fkSector->GetMinPadDimensionY();
222 // Search in Y direction
224 Double_t posy = starty;
226 pad = PadByPosition(startx, posy, false);
229 while ( ! pad.IsValid() &&
230 posy - fkSector->GetMaxPadDimensionY()< maxY );
232 // Invalidate pad if it is outside limits
233 if (( pad.GetPositionY() - pad.GetDimensionY()) > maxY )
234 pad = AliMpPad::Invalid();
243 //______________________________________________________________________________
245 AliMpSectorSegmentation::CreateIterator(const AliMpArea& area) const
247 /// Create the area iterator.
249 switch (fkSector->GetDirection()) {
251 case AliMp::kX: return new AliMpSectorAreaVPadIterator(this, area);
253 case AliMp::kY: return new AliMpSectorAreaHPadIterator(this, area);
257 Fatal("CreateIterator", "Incomplete switch on Sector direction");
261 //______________________________________________________________________________
263 AliMpSectorSegmentation::CreateIterator() const
265 /// Create the sector iterator
267 return new AliMpSectorPadIterator(fkSector);
270 //______________________________________________________________________________
272 AliMpSectorSegmentation::GetNeighbours(const AliMpPad& pad, TObjArray& neighbours,
274 Bool_t includeVoid) const
276 /// Uses default implementation
277 return AliMpVSegmentation::GetNeighbours(pad,neighbours,includeSelf,includeVoid);
280 //______________________________________________________________________________
282 AliMpSectorSegmentation::PadByLocation(Int_t manuId, Int_t manuChannel,
283 Bool_t warning) const
285 /// Find the pad which corresponds to the given location
287 if ( fPadBuffer->GetManuId() == manuId &&
288 fPadBuffer->GetManuChannel() == manuChannel ) return (*fPadBuffer);
290 AliMpMotifPosition* motifPos =
291 fkSector->GetMotifMap()->FindMotifPosition(manuId);
293 if (warning) Warning("PadByLocation","The pad motif position ID doesn't exists");
294 return AliMpPad::Invalid();
297 AliMpVMotif* motif = motifPos->GetMotif();
298 MpPair_t localIndices =
299 motif->GetMotifType()->FindLocalIndicesByGassiNum(manuChannel);
300 if ( localIndices < 0 ) {
301 if (warning) Warning("PadByLocation","The pad number doesn't exists");
302 return AliMpPad::Invalid();
306 motif->PadPositionLocal(localIndices, posx, posy);
307 posx += motifPos->GetPositionX();
308 posy += motifPos->GetPositionY();
311 motif->GetPadDimensionsByIndices(localIndices, dx, dy);
313 return (*fPadBuffer) = AliMpPad(manuId, manuChannel,
314 motifPos->GlobalIndices(localIndices),
317 //______________________________________________________________________________
319 AliMpSectorSegmentation::PadByIndices(Int_t ix, Int_t iy, Bool_t warning ) const
321 /// Find the pad which corresponds to the given indices
323 if ( fPadBuffer->GetIx() == ix &&
324 fPadBuffer->GetIy() == iy ) return (*fPadBuffer);
326 MpPair_t indices = AliMp::Pair(ix, iy);
327 AliMpMotifPosition* motifPos = FindMotifPosition(ix, iy);
330 Warning("PadByIndices","Pad indices not contained in any motif!");
331 return AliMpPad::Invalid();
334 // retrieve the local indices in the found motif
335 AliMpVMotif* motif = motifPos->GetMotif();
336 MpPair_t localIndices = indices - motifPos->GetLowIndicesLimit();
338 AliMpConnection* connection=
339 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
342 if (warning) Warning("PadByIndices","No connection with the given indices!");
343 return AliMpPad::Invalid();
347 motif->PadPositionLocal(localIndices, posx, posy);
348 posx += motifPos->GetPositionX();
349 posy += motifPos->GetPositionY();
352 motif->GetPadDimensionsByIndices(localIndices, dx, dy);
355 = AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
356 ix, iy, posx, posy, dx, dy);
359 //______________________________________________________________________________
361 AliMpSectorSegmentation::PadByPosition(Double_t x, Double_t y,
362 Bool_t warning) const
364 /// Find the pad which corresponds to the given position
366 if (fPadBuffer->GetPositionX()==x &&
367 fPadBuffer->GetPositionY()==y) return (*fPadBuffer);
369 Int_t motifPosID = fkSector->FindMotifPositionId(x,y);
370 AliMpMotifPosition* motifPos
371 = fkSector->GetMotifMap()
372 ->FindMotifPosition(motifPosID);
375 if (warning) Warning("PadByPosition","Position outside limits");
376 return AliMpPad::Invalid();
379 AliMpVMotif* motif = motifPos->GetMotif();
380 MpPair_t localIndices
381 = motif->PadIndicesLocal(x-motifPos->GetPositionX(),
382 y-motifPos->GetPositionY());
384 if ( localIndices < 0 ) {
385 if (warning) Warning("PadByPosition","Position outside motif limits");
386 return AliMpPad::Invalid();
389 AliMpConnection* connect =
390 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
393 if (warning) Warning("PadByPosition","Position outside motif limits");
394 return AliMpPad::Invalid();
398 motif->PadPositionLocal(localIndices, posx, posy);
399 posx += motifPos->GetPositionX();
400 posy += motifPos->GetPositionY();
403 motif->GetPadDimensionsByIndices(localIndices, dx, dy);
406 = AliMpPad(motifPosID, connect->GetManuChannel(),
407 motifPos->GlobalIndices(localIndices),
411 //______________________________________________________________________________
413 AliMpSectorSegmentation::PadByDirection(Double_t startx, Double_t starty,
414 Double_t distance) const
416 /// Find the first valid pad from starting position in the
417 /// direction of pad lines/columns up to the specified distance.
418 /// Pad lines are the lines of pads in the sector with constant pad y size,
419 /// pad columns are the columns of pads in the sector with constant pad x size.
421 switch (fkSector->GetDirection()) {
423 case AliMp::kX: return PadByYDirection(startx, starty, distance);
425 case AliMp::kY: return PadByXDirection(startx, starty, distance);
429 Fatal("PadByDirection", "Incomplete switch on Sector direction");
430 return AliMpPad::Invalid();
433 //_____________________________________________________________________________
435 AliMpSectorSegmentation::HasPadByIndices(Int_t ix, Int_t iy) const
437 /// Whether or not we have a pad at indices=(ix,iy)
439 MpPair_t indices = AliMp::Pair(ix, iy);
441 AliMpMotifPosition* motifPos = FindMotifPosition(ix, iy);
443 if (motifPos) return motifPos->HasPadByIndices(indices);
448 //_____________________________________________________________________________
450 AliMpSectorSegmentation::HasPadByLocation(Int_t manuId, Int_t manuChannel) const
452 /// Whether or not we have a pad at location=(manuId,manuChannel)
454 AliMpMotifPosition* motifPos
455 = fkSector->GetMotifMap()->FindMotifPosition(manuId);
457 if ( motifPos ) return motifPos->HasPadByManuChannel(manuChannel);
462 //______________________________________________________________________________
463 Int_t AliMpSectorSegmentation::MaxPadIndexX() const
465 /// Return maximum pad index in x
467 return AliMp::PairFirst(fkSector->GetMaxPadIndices());
470 //______________________________________________________________________________
471 Int_t AliMpSectorSegmentation::MaxPadIndexY() const
473 /// Return maximum pad index in y
475 return AliMp::PairSecond(fkSector->GetMaxPadIndices());
478 //______________________________________________________________________________
479 Int_t AliMpSectorSegmentation::NofPads() const
481 /// Return number of pads defined in the sector
483 return fkSector->GetNofPads();
486 //_____________________________________________________________________________
488 AliMpSectorSegmentation::GetAllElectronicCardIDs(TArrayI& ecn) const
490 /// Fill the array ecn with all manuIds
492 GetSector()->GetAllMotifPositionsIDs(ecn);
495 //_____________________________________________________________________________
497 AliMpSectorSegmentation::GetNofElectronicCards() const
499 /// Get the number of manus of this sector
501 return fkSector->GetNofMotifPositions();
504 //_____________________________________________________________________________
506 AliMpSectorSegmentation::HasMotifPosition(Int_t manuId) const
508 /// Whether we get a given manu. Uses default implementation
509 return (AliMpVSegmentation::HasMotifPosition(manuId) != 0x0);
512 //_____________________________________________________________________________
514 AliMpSectorSegmentation::MotifPosition(Int_t manuId) const
516 /// Return a given manu
517 return fkSector->GetMotifMap()->FindMotifPosition(manuId);
520 //______________________________________________________________________________
522 AliMpSectorSegmentation::PlaneType() const
524 return GetSector()->GetPlaneType();
527 //_____________________________________________________________________________
529 AliMpSectorSegmentation::GetDimensionX() const
531 /// Return sector x dimensions
532 return GetSector()->GetDimensionX();
535 //_____________________________________________________________________________
537 AliMpSectorSegmentation::GetDimensionY() const
539 /// Return sector y dimensions
540 return GetSector()->GetDimensionY();
543 //_____________________________________________________________________________
545 AliMpSectorSegmentation::GetPositionX() const
547 /// Return x position
551 //_____________________________________________________________________________
553 AliMpSectorSegmentation::GetPositionY() const
555 /// Return y position
559 //______________________________________________________________________________
561 AliMpSectorSegmentation::Print(Option_t* opt) const
565 fkSector->Print(opt);
568 //______________________________________________________________________________
569 Double_t AliMpSectorSegmentation::GetMinPadDimensionX() const
571 /// Return the x dimension of the smallest pad.
573 return fkSector->GetMinPadDimensionX();
577 //______________________________________________________________________________
578 Double_t AliMpSectorSegmentation::GetMinPadDimensionY() const
580 /// Return the y dimension of the smallest pad.
582 return fkSector->GetMinPadDimensionY();
586 //______________________________________________________________________________
587 Bool_t AliMpSectorSegmentation::CircleTest(Int_t ix, Int_t iy) const
589 /// Verify that all methods for retrieving pads are consistents between them.
590 /// Return true if the pad with specified indices was found and verified,
593 if ( ! HasPadByIndices(ix, iy) ) return false;
595 // Verify the indice->location->position->indice way
596 AliMpPad pad1 = PadByIndices(ix, iy);
597 AliMpPad pad2 = PadByLocation(pad1.GetManuId(), pad1.GetManuChannel());
598 AliMpPad pad3 = PadByPosition(pad2.GetPositionX(),pad2.GetPositionY());
600 MpPair_t retIndices = pad3.GetIndices();
602 if ( retIndices != AliMp::Pair(ix, iy) ) {
603 cout << "Pad (" << ix << ',' << iy << ") lead to inconsistency" << endl;
604 cout << "in indice->location->position->indice way..." << endl;
605 cout << "starting from indices " << pad1 << endl
606 << "--> location " << pad2 << endl
608 << '(' << pad3.GetPositionX() << ',' << pad3.GetPositionY() << ')'
612 // Verify the indice->position->location->indice way
613 AliMpPad pad2bis = PadByPosition(pad1.GetPositionX(),pad1.GetPositionY());
614 AliMpPad pad3bis = PadByLocation(pad2bis.GetManuId(), pad2bis.GetManuChannel());
616 retIndices = pad3bis.GetIndices();
618 if ( retIndices != AliMp::Pair(ix, iy) ) {
619 cout << "Pad (" << ix << ',' << iy << ") lead to inconsistency" << endl;
620 cout << "in indice->position->location->indice way..." << endl;
621 cout << "starting from indices " << pad1 << endl
623 << '(' << pad2bis.GetPositionX() << ',' << pad2bis.GetPositionY() << ')' << endl
624 << "--> location " << pad3bis