4 // Class AliMpSectorSegmentation
5 // -----------------------------
6 // Class describing the segmentation of the sector.
7 // Provides methods related to pads:
8 // conversion between pad indices, pad location, pad position;
9 // finding pad neighbour.
11 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
13 #include <Riostream.h>
17 #include "AliMpSectorSegmentation.h"
18 #include "AliMpSector.h"
19 #include "AliMpZone.h"
20 #include "AliMpSubZone.h"
22 #include "AliMpVRowSegment.h"
23 #include "AliMpMotifMap.h"
24 #include "AliMpVMotif.h"
25 #include "AliMpMotifPosition.h"
26 #include "AliMpConnection.h"
27 #include "AliMpNeighboursPadIterator.h"
28 #include "AliMpSectorAreaHPadIterator.h"
29 #include "AliMpSectorAreaVPadIterator.h"
30 #include "AliMpIntPair.h"
31 #include "AliMpArea.h"
32 #include "AliMpConstants.h"
34 ClassImp(AliMpSectorSegmentation)
37 const Double_t AliMpSectorSegmentation::fgkSeparator = 10000.;
40 //______________________________________________________________________________
41 AliMpSectorSegmentation::AliMpSectorSegmentation(const AliMpSector* sector)
42 : AliMpVSegmentation(),
46 fPadBuffer = new AliMpPad(AliMpPad::Invalid());
48 FillPadDimensionsMap();
51 //______________________________________________________________________________
52 AliMpSectorSegmentation::AliMpSectorSegmentation()
53 : AliMpVSegmentation(),
61 //_____________________________________________________________________________
62 AliMpSectorSegmentation::AliMpSectorSegmentation(
63 const AliMpSectorSegmentation& right)
64 : AliMpVSegmentation(right) {
66 Fatal("AliMpSectorSegmentation", "Copy constructor not provided.");
69 //______________________________________________________________________________
70 AliMpSectorSegmentation::~AliMpSectorSegmentation() {
79 //_____________________________________________________________________________
80 AliMpSectorSegmentation&
81 AliMpSectorSegmentation::operator=(const AliMpSectorSegmentation& right)
83 // check assignement to self
84 if (this == &right) return *this;
86 Fatal("operator =", "Assignement operator not provided.");
96 //______________________________________________________________________________
97 Long_t AliMpSectorSegmentation::GetIndex(const TVector2& vector2) const
99 // Converts the twovector to long.
102 if (vector2.X() >= fgkSeparator || vector2.Y() >= fgkSeparator)
103 Fatal("GetIndex", "Index out of limit.");
105 return Long_t(vector2.X()*fgkSeparator + vector2.Y() + 1.);
108 //______________________________________________________________________________
109 TVector2 AliMpSectorSegmentation::GetVector(Long_t index) const
111 // Converts the long index to twovector.
114 return TVector2(TMath::Floor((index-1.)/fgkSeparator),
115 (index-1.) - TMath::Floor((index-1.)/fgkSeparator)*fgkSeparator);
119 //______________________________________________________________________________
120 void AliMpSectorSegmentation::FillPadDimensionsMap()
122 // Fills the maps between zone ids and pad dimensions.
125 for (Int_t i=0; i<fkSector->GetNofZones(); i++) {
126 AliMpZone* zone = fkSector->GetZone(i+1);
127 Int_t zoneID = zone->GetID();
129 if (!AliMpConstants::IsEqual(zone->GetPadDimensions(), TVector2())) {
133 fPadDimensionsMap[zoneID*10] = zone->GetPadDimensions();
136 fPadDimensionsMap.Add((Long_t)(zoneID*10),
137 GetIndex(zone->GetPadDimensions()));
143 for (Int_t j=0; j<zone->GetNofSubZones(); j++) {
144 AliMpSubZone* subZone = zone->GetSubZone(j);
145 AliMpVMotif* motif = subZone->GetMotif();
147 for (Int_t k=0; k<motif->GetNofPadDimensions(); k++) {
148 Int_t index = zoneID*10 + subIndex++;
150 fPadDimensionsMap[index] = motif->GetPadDimensions(k);
153 fPadDimensionsMap.Add((Long_t)(index),
154 GetIndex(motif->GetPadDimensions(k)));
162 //______________________________________________________________________________
164 AliMpSectorSegmentation::FindMotifPosition(const AliMpIntPair& indices) const
166 // Find the motif position which contains the given pad indices
167 // return 0 if not found
170 switch (fkSector->GetDirection()) {
172 // Case where all the pads have the same size along X direction
174 for (Int_t irow=0; irow<fkSector->GetNofRows(); ++irow) {
175 AliMpRow* row = fkSector->GetRow(irow);
176 if (row->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
177 row->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
179 for (Int_t iseg=0;iseg<row->GetNofRowSegments();++iseg){
180 AliMpVRowSegment* seg = row->GetRowSegment(iseg);
181 if (seg->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
182 seg->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
184 AliMpMotifPosition* motifPos;
185 for (Int_t imot=0;imot<seg->GetNofMotifs();++imot) {
187 = fkSector->GetMotifMap()
188 ->FindMotifPosition(seg->GetMotifPositionId(imot));
189 if (motifPos && motifPos->HasPad(indices)) return motifPos;
198 ////////////////////////////////////////////////////////////////////////////////
200 // Case where all the pads have the same size along Y direction
201 // look for the row which contains the indices
204 for (irow=0; irow<fkSector->GetNofRows(); ++irow) {
205 row = fkSector->GetRow(irow);
206 AliMpVRowSegment* lastSeg = row->GetRowSegment(row->GetNofRowSegments()-1);
207 if (lastSeg->GetLowIndicesLimit().GetSecond()<=indices.GetSecond() &&
208 lastSeg->GetHighIndicesLimit().GetSecond()>=indices.GetSecond()) break;
209 // NOTE : We use the last row segment in order to ensure that
210 // we are not on a special motif
212 if (irow==fkSector->GetNofRows()) return 0;
213 // look for the row segment, in the found row, which contains the indices
214 AliMpVRowSegment* seg=0;
216 for (iseg=0;iseg<row->GetNofRowSegments();++iseg){
217 seg = row->GetRowSegment(iseg);
218 if (seg->HasIndices(indices)) break;
220 if (iseg==row->GetNofRowSegments()) return 0;
222 // look for the motif position which contains the indices
223 AliMpMotifPosition* motifPos=0;
225 for (imot=0;imot<seg->GetNofMotifs();++imot) {
227 = fkSector->GetMotifMap()
228 ->FindMotifPosition(seg->GetMotifPositionId(imot));
229 if (motifPos && motifPos->HasPad(indices)) break;
231 if (imot==seg->GetNofMotifs()) return 0;
239 //______________________________________________________________________________
241 AliMpSectorSegmentation::PadByXDirection(const TVector2& startPosition,
244 // Find the first valid pad from starting position in the
245 // direction of pad lines up to distance dx.
248 // Define step limits
249 Double_t stepX = fkSector->GetMinPadDimensions().X();
251 // Search in X direction
253 TVector2 position(startPosition);
255 pad = PadByPosition(position, false);
256 position += TVector2(stepX, 0.);
258 while ( !pad.IsValid() && position.X() < maxX );
260 // Invalidate pad if it is outside limits
261 if ((pad.Position().X() - pad.Dimensions().X()) > maxX)
262 pad = AliMpPad::Invalid();
267 //______________________________________________________________________________
269 AliMpSectorSegmentation::PadByYDirection(const TVector2& startPosition,
272 // Find the first valid pad from starting position in the
273 // direction of pad columns up to distance dx.
276 // Define step limits
277 Double_t stepY = fkSector->GetMinPadDimensions().Y();
279 // Search in Y direction
281 TVector2 position(startPosition);
283 pad = PadByPosition(position, false);
284 position += TVector2(0., stepY);
286 while ( !pad.IsValid() && position.Y() < maxY );
288 // Invalidate pad if it is outside limits
289 if ((pad.Position().Y() - pad.Dimensions().Y()) > maxY)
290 pad = AliMpPad::Invalid();
295 //______________________________________________________________________________
296 AliMpVPadIterator* AliMpSectorSegmentation::CreateIterator() const
298 // The inherited method cannot be used
300 Fatal("CreateIterator", "Center pad has to be specified.");
309 //______________________________________________________________________________
311 AliMpSectorSegmentation::CreateIterator(const AliMpArea& area) const
313 // Creates the are iterator.
314 // (The inherited method cannot be used)
317 switch (fkSector->GetDirection()) {
319 case kX: return new AliMpSectorAreaVPadIterator(this, area);
321 case kY: return new AliMpSectorAreaHPadIterator(this, area);
325 Fatal("CreateIterator", "Incomplete switch on Sector direction");
329 //______________________________________________________________________________
331 AliMpSectorSegmentation::CreateIterator(const AliMpPad& centerPad,
332 Bool_t includeCenter) const
334 // Creates the neighbours pad iterator.
335 // (The inherited method cannot be used)
337 return new AliMpNeighboursPadIterator(this, centerPad, includeCenter);
340 //______________________________________________________________________________
342 AliMpSectorSegmentation::PadByLocation(const AliMpIntPair& location,
343 Bool_t warning) const
345 // Find the pad which corresponds to the given location
347 if ((*fPadBuffer).GetLocation()==location) return (*fPadBuffer);
349 AliMpMotifPosition* motifPos =
350 fkSector->GetMotifMap()->FindMotifPosition(location.GetFirst());
352 if (warning) Warning("PadByLocation","The pad motif position ID doesn't exists");
353 return AliMpPad::Invalid();
356 AliMpVMotif* motif = motifPos->GetMotif();
357 AliMpIntPair localIndices =
358 motif->GetMotifType()->FindLocalIndicesByGassiNum(location.GetSecond());
359 if (! localIndices.IsValid()) {
360 if (warning) Warning("PadByLocation","The pad number doesn't exists");
361 return AliMpPad::Invalid();
363 TVector2 delta = motif->PadPositionLocal(localIndices);
364 return (*fPadBuffer) = AliMpPad(location,
365 motifPos->GlobalIndices(localIndices),
366 motifPos->Position()+delta,
367 motif->GetPadDimensions(localIndices));
370 //______________________________________________________________________________
372 AliMpSectorSegmentation::PadByIndices(const AliMpIntPair& indices,
373 Bool_t warning ) const
375 // Find the pad which corresponds to the given indices
377 if ((*fPadBuffer).GetIndices()==indices) return (*fPadBuffer);
379 AliMpMotifPosition* motifPos = FindMotifPosition(indices);
381 if (warning) Warning("PadByIndices","Pad indices not contained in any motif!");
382 return AliMpPad::Invalid();
385 // retrieve the local indices in the found motif
386 AliMpVMotif* motif = motifPos->GetMotif();
387 AliMpIntPair localIndices = indices - motifPos->GetLowIndicesLimit();
389 AliMpConnection* connection=
390 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
393 if (warning) Warning("PadByIndices","No connection with the given indices!");
394 return AliMpPad::Invalid();
397 TVector2 localPos = motif->PadPositionLocal(localIndices);
400 = AliMpPad(AliMpIntPair(motifPos->GetID(),connection->GetGassiNum()),
402 motifPos->Position()+localPos,
403 motif->GetPadDimensions(localIndices));
406 //______________________________________________________________________________
408 AliMpSectorSegmentation::PadByPosition(const TVector2& position,
409 Bool_t warning) const
411 // Find the pad which corresponds to the given position
413 if ((*fPadBuffer).Position().X()==position.X() &&
414 (*fPadBuffer).Position().Y()==position.Y()) return (*fPadBuffer);
416 Int_t motifPosID = fkSector->FindMotifPositionId(position);
417 AliMpMotifPosition* motifPos
418 = fkSector->GetMotifMap()
419 ->FindMotifPosition(motifPosID);
422 if (warning) Warning("PadByPosition","Position outside limits");
423 return AliMpPad::Invalid();
426 AliMpVMotif* motif = motifPos->GetMotif();
427 AliMpIntPair localIndices
428 = motif->PadIndicesLocal(position-motifPos->Position());
430 AliMpConnection* connect =
431 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
434 if (warning) Warning("PadByPosition","Position outside motif limits");
435 return AliMpPad::Invalid();
439 = AliMpPad(AliMpIntPair(motifPosID,connect->GetGassiNum()),
440 motifPos->GlobalIndices(localIndices),
441 motifPos->Position()+motif->PadPositionLocal(localIndices),
442 motif->GetPadDimensions(localIndices));
446 //______________________________________________________________________________
448 AliMpSectorSegmentation::PadByDirection(const TVector2& startPosition,
449 Double_t distance) const
451 // Find the first valid pad from starting position in the
452 // direction of pad lines/columns up to the specified distance.
453 // Pad lines are the lines of pads in the sector with constant pad y size,
454 // pad columns are the columns of pads in the sector with constant pad x size.
457 switch (fkSector->GetDirection()) {
459 case kX: return PadByYDirection(startPosition, distance);
461 case kY: return PadByXDirection(startPosition, distance);
465 Fatal("PadByDirection", "Incomplete switch on Sector direction");
466 return AliMpPad::Invalid();
469 //______________________________________________________________________________
470 Bool_t AliMpSectorSegmentation::HasPad(const AliMpIntPair& indices) const
472 // Does the pad specified by <indices> exist ?
475 return PadByIndices(indices,kFALSE) != AliMpPad::Invalid();
478 //______________________________________________________________________________
479 Bool_t AliMpSectorSegmentation::HasMotifPosition(Int_t motifPositionID) const
481 // Does the motif position specified by motifPositionID exist ?
484 return (fkSector->GetMotifMap()->FindMotifPosition(motifPositionID) != 0);
487 //______________________________________________________________________________
488 TVector2 AliMpSectorSegmentation::GetMinPadDimensions() const
490 // Returnes the dimensions of the smallest pad.
493 return fkSector->GetMinPadDimensions();
496 //______________________________________________________________________________
497 Int_t AliMpSectorSegmentation::Zone(const AliMpPad& pad, Bool_t warning) const
499 // Returns the zone index of the zone containing the specified pad.
500 // This zone index is different from the zone ID,
501 // as it is unique for each pad dimensions.
502 // It is composed in this way:
503 // zoneID*10 + specific index
504 // Specific index is present only for zones containing special motifs.
507 if (!pad.IsValid()) {
508 if (warning) Warning("Zone(AliMpPad)", "Invalid pad");
513 PadDimensionsMapCIterator it;
514 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
515 if (AliMpConstants::IsEqual(it->second, pad.Dimensions()))
521 PadDimensionsMapCIterator it(&fPadDimensionsMap);
523 while ( it.Next(key, value) ) {
524 TVector2 dimensions = GetVector(value);
525 if (AliMpConstants::IsEqual(dimensions, pad.Dimensions()))
532 // Should never happen
533 Fatal("Zone(AliMpPad)", "not found");
537 //______________________________________________________________________________
539 AliMpSectorSegmentation::PadDimensions(Int_t zone, Bool_t warning) const
541 // Returns the pad dimensions for the zone with the specified zone index.
545 PadDimensionsMapCIterator it = fPadDimensionsMap.find(zone);
546 if (it != fPadDimensionsMap.end()) return it->second;
550 Long_t value = fPadDimensionsMap.GetValue(zone);
551 if (value) return GetVector(value);
554 if (warning) Warning("PadDimensions(zone)", "not found");
558 //______________________________________________________________________________
559 Bool_t AliMpSectorSegmentation::CircleTest(const AliMpIntPair& indices) const
561 // Verifies that all methods for retrieving pads are consistents between them.
562 // Returns true if the pad with specified indices was found and verified,
566 if (!HasPad(indices)) return false;
568 // Verify the indice->location->position->indice way
569 AliMpIntPair location = PadByIndices(indices).GetLocation();
570 TVector2 position = PadByLocation(location).Position();
571 AliMpIntPair retIndices = PadByPosition(position).GetIndices();
573 if (retIndices != indices) {
574 cout << "Pad " << indices << " lead to inconsistency" << endl;
575 cout << "in indice->location->position->indice way..." << endl;
576 cout << "starting from " << indices << "-->" << location << "-->"
577 << '(' << position.X() << ',' << position.Y() << ')'
578 << " and retIndices: " << retIndices << endl;
582 // Verify the indice->position->location->indice way
583 position = PadByIndices(indices).Position();
584 location = PadByPosition(position).GetLocation();
585 retIndices = PadByLocation(location).GetIndices();
587 if (retIndices != indices) {
588 cout << "Pad " << indices << " lead to inconsistency" << endl;
589 cout << "in indice->position->location->indice way..." <<endl;
590 cout << "starting from " << indices
591 << " and retIndices: " << retIndices << endl;