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.10 2005/10/28 15:22:02 ivana Exp $
20 // Class AliMpSectorSegmentation
21 // -----------------------------
22 // Class describing the segmentation of the sector.
23 // Provides methods related to pads:
24 // conversion between pad indices, pad location, pad position;
25 // finding pad neighbour.
27 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
29 #include <Riostream.h>
35 #include "AliMpSectorSegmentation.h"
36 #include "AliMpSector.h"
37 #include "AliMpZone.h"
38 #include "AliMpSubZone.h"
40 #include "AliMpVRowSegment.h"
41 #include "AliMpMotifMap.h"
42 #include "AliMpVMotif.h"
43 #include "AliMpMotifPosition.h"
44 #include "AliMpConnection.h"
45 #include "AliMpNeighboursPadIterator.h"
46 #include "AliMpSectorAreaHPadIterator.h"
47 #include "AliMpSectorAreaVPadIterator.h"
48 #include "AliMpIntPair.h"
49 #include "AliMpArea.h"
50 #include "AliMpConstants.h"
52 ClassImp(AliMpSectorSegmentation)
55 const Double_t AliMpSectorSegmentation::fgkS1 = 100000.;
56 const Double_t AliMpSectorSegmentation::fgkS2 = 1000.;
59 //______________________________________________________________________________
60 AliMpSectorSegmentation::AliMpSectorSegmentation(const AliMpSector* sector)
61 : AliMpVSegmentation(),
66 /// Standard constructor
68 fPadBuffer = new AliMpPad(AliMpPad::Invalid());
70 FillPadDimensionsMap();
73 //______________________________________________________________________________
74 AliMpSectorSegmentation::AliMpSectorSegmentation()
75 : AliMpVSegmentation(),
82 /// Default constructor
85 //_____________________________________________________________________________
86 AliMpSectorSegmentation::AliMpSectorSegmentation(
87 const AliMpSectorSegmentation& right)
88 : AliMpVSegmentation(right)
90 /// Protected copy constructor (not provided)
92 Fatal("AliMpSectorSegmentation", "Copy constructor not provided.");
95 //______________________________________________________________________________
96 AliMpSectorSegmentation::~AliMpSectorSegmentation()
107 //_____________________________________________________________________________
108 AliMpSectorSegmentation&
109 AliMpSectorSegmentation::operator=(const AliMpSectorSegmentation& right)
111 /// Protected assignment operator (not provided)
113 // check assignment to self
114 if (this == &right) return *this;
116 Fatal("operator =", "Assignment operator not provided.");
126 //______________________________________________________________________________
127 Long_t AliMpSectorSegmentation::GetIndex(const TVector2& vector2) const
129 /// Convert the two vector to long.
131 return Long_t(TMath::Floor((vector2.X()*fgkS1 + vector2.Y())*fgkS2));
134 //______________________________________________________________________________
135 TVector2 AliMpSectorSegmentation::GetVector(Long_t index) const
137 /// Convert the long index to twovector.
139 return TVector2( TMath::Floor(index/fgkS1)/fgkS2,
140 (index - TMath::Floor(index/fgkS1)*fgkS1)/fgkS2 );
144 //______________________________________________________________________________
145 void AliMpSectorSegmentation::FillPadDimensionsMap()
147 /// Fill the maps between zone ids and pad dimensions.
149 for (Int_t i=0; i<fkSector->GetNofZones(); i++) {
150 AliMpZone* zone = fkSector->GetZone(i+1);
151 Int_t zoneID = zone->GetID();
153 if (!AliMpConstants::IsEqual(zone->GetPadDimensions(), TVector2())) {
157 fPadDimensionsMap[zoneID*10] = zone->GetPadDimensions();
160 AliDebug(1,Form("Filling fPadDimensions[%d]=(%e,%e)",
161 zoneID*10,zone->GetPadDimensions().X(),
162 zone->GetPadDimensions().Y()));
163 fPadDimensionsMap.Add((Long_t)(zoneID*10),
164 GetIndex(zone->GetPadDimensions()));
170 for (Int_t j=0; j<zone->GetNofSubZones(); j++) {
171 AliMpSubZone* subZone = zone->GetSubZone(j);
172 AliMpVMotif* motif = subZone->GetMotif();
174 for (Int_t k=0; k<motif->GetNofPadDimensions(); k++) {
175 Int_t index = zoneID*10 + subIndex++;
177 fPadDimensionsMap[index] = motif->GetPadDimensions(k);
180 AliDebug(1,Form("Filling fPadDimensions[%d]=(%e,%e) motif %s-%d",
182 motif->GetPadDimensions(k).X(),
183 motif->GetPadDimensions(k).Y(),
184 motif->GetID().Data(),k));
186 fPadDimensionsMap.Add((Long_t)(index),
187 GetIndex(motif->GetPadDimensions(k)));
195 //______________________________________________________________________________
197 AliMpSectorSegmentation::FindMotifPosition(const AliMpIntPair& indices) const
199 /// Find the motif position which contains the given pad indices
200 /// return 0 if not found
202 switch (fkSector->GetDirection()) {
204 // Case where all the pads have the same size along X direction
206 for (Int_t irow=0; irow<fkSector->GetNofRows(); ++irow) {
207 AliMpRow* row = fkSector->GetRow(irow);
208 if (row->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
209 row->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
211 for (Int_t iseg=0;iseg<row->GetNofRowSegments();++iseg){
212 AliMpVRowSegment* seg = row->GetRowSegment(iseg);
213 if (seg->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
214 seg->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
216 AliMpMotifPosition* motifPos;
217 for (Int_t imot=0;imot<seg->GetNofMotifs();++imot) {
219 = fkSector->GetMotifMap()
220 ->FindMotifPosition(seg->GetMotifPositionId(imot));
221 if (motifPos && motifPos->HasPad(indices)) return motifPos;
230 ////////////////////////////////////////////////////////////////////////////////
232 // Case where all the pads have the same size along Y direction
233 // look for the row which contains the indices
236 for (irow=0; irow<fkSector->GetNofRows(); ++irow) {
237 row = fkSector->GetRow(irow);
238 AliMpVRowSegment* lastSeg = row->GetRowSegment(row->GetNofRowSegments()-1);
239 if (lastSeg->GetLowIndicesLimit().GetSecond()<=indices.GetSecond() &&
240 lastSeg->GetHighIndicesLimit().GetSecond()>=indices.GetSecond()) break;
241 // NOTE : We use the last row segment in order to ensure that
242 // we are not on a special motif
244 if (irow==fkSector->GetNofRows()) return 0;
245 // look for the row segment, in the found row, which contains the indices
246 AliMpVRowSegment* seg=0;
248 for (iseg=0;iseg<row->GetNofRowSegments();++iseg){
249 seg = row->GetRowSegment(iseg);
250 if (seg->HasIndices(indices)) break;
252 if (iseg==row->GetNofRowSegments()) return 0;
254 // look for the motif position which contains the indices
255 AliMpMotifPosition* motifPos=0;
257 for (imot=0;imot<seg->GetNofMotifs();++imot) {
259 = fkSector->GetMotifMap()
260 ->FindMotifPosition(seg->GetMotifPositionId(imot));
261 if (motifPos && motifPos->HasPad(indices)) break;
263 if (imot==seg->GetNofMotifs()) return 0;
271 //______________________________________________________________________________
273 AliMpSectorSegmentation::PadByXDirection(const TVector2& startPosition,
276 /// Find the first valid pad from starting position in the
277 /// direction of pad lines up to distance dx.
279 // Define step limits
280 Double_t stepX = fkSector->GetMinPadDimensions().X();
282 // Search in X direction
284 TVector2 position(startPosition);
286 pad = PadByPosition(position, false);
287 position += TVector2(stepX, 0.);
289 while ( !pad.IsValid() && position.X() < maxX );
291 // Invalidate pad if it is outside limits
292 if ((pad.Position().X() - pad.Dimensions().X()) > maxX)
293 pad = AliMpPad::Invalid();
298 //______________________________________________________________________________
300 AliMpSectorSegmentation::PadByYDirection(const TVector2& startPosition,
303 /// Find the first valid pad from starting position in the
304 /// direction of pad columns up to distance dx.
306 // Define step limits
307 Double_t stepY = fkSector->GetMinPadDimensions().Y();
309 // Search in Y direction
311 TVector2 position(startPosition);
313 pad = PadByPosition(position, false);
314 position += TVector2(0., stepY);
316 while ( !pad.IsValid() && position.Y() < maxY );
318 // Invalidate pad if it is outside limits
319 if ((pad.Position().Y() - pad.Dimensions().Y()) > maxY)
320 pad = AliMpPad::Invalid();
329 //______________________________________________________________________________
331 AliMpSectorSegmentation::CreateIterator(const AliMpArea& area) const
333 /// Create the area iterator.
335 switch (fkSector->GetDirection()) {
337 case kX: return new AliMpSectorAreaVPadIterator(this, area);
339 case kY: return new AliMpSectorAreaHPadIterator(this, area);
343 Fatal("CreateIterator", "Incomplete switch on Sector direction");
347 //______________________________________________________________________________
349 AliMpSectorSegmentation::CreateIterator(const AliMpPad& centerPad,
350 Bool_t includeCenter) const
352 /// Create the neighbours pad iterator.
354 return new AliMpNeighboursPadIterator(this, centerPad, includeCenter);
357 //______________________________________________________________________________
359 AliMpSectorSegmentation::PadByLocation(const AliMpIntPair& location,
360 Bool_t warning) const
362 /// Find the pad which corresponds to the given location
364 if ((*fPadBuffer).GetLocation()==location) return (*fPadBuffer);
366 AliMpMotifPosition* motifPos =
367 fkSector->GetMotifMap()->FindMotifPosition(location.GetFirst());
369 if (warning) Warning("PadByLocation","The pad motif position ID doesn't exists");
370 return AliMpPad::Invalid();
373 AliMpVMotif* motif = motifPos->GetMotif();
374 AliMpIntPair localIndices =
375 motif->GetMotifType()->FindLocalIndicesByGassiNum(location.GetSecond());
376 if (! localIndices.IsValid()) {
377 if (warning) Warning("PadByLocation","The pad number doesn't exists");
378 return AliMpPad::Invalid();
380 TVector2 delta = motif->PadPositionLocal(localIndices);
381 return (*fPadBuffer) = AliMpPad(location,
382 motifPos->GlobalIndices(localIndices),
383 motifPos->Position()+delta,
384 motif->GetPadDimensions(localIndices));
387 //______________________________________________________________________________
389 AliMpSectorSegmentation::PadByIndices(const AliMpIntPair& indices,
390 Bool_t warning ) const
392 /// Find the pad which corresponds to the given indices
394 if ((*fPadBuffer).GetIndices()==indices) return (*fPadBuffer);
396 AliMpMotifPosition* motifPos = FindMotifPosition(indices);
399 cout << "indices " << indices << endl;
400 Warning("PadByIndices","Pad indices not contained in any motif!");
402 return AliMpPad::Invalid();
405 // retrieve the local indices in the found motif
406 AliMpVMotif* motif = motifPos->GetMotif();
407 AliMpIntPair localIndices = indices - motifPos->GetLowIndicesLimit();
409 AliMpConnection* connection=
410 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
413 if (warning) Warning("PadByIndices","No connection with the given indices!");
414 return AliMpPad::Invalid();
417 TVector2 localPos = motif->PadPositionLocal(localIndices);
420 = AliMpPad(AliMpIntPair(motifPos->GetID(),connection->GetGassiNum()),
422 motifPos->Position()+localPos,
423 motif->GetPadDimensions(localIndices));
426 //______________________________________________________________________________
428 AliMpSectorSegmentation::PadByPosition(const TVector2& position,
429 Bool_t warning) const
431 /// Find the pad which corresponds to the given position
433 if ((*fPadBuffer).Position().X()==position.X() &&
434 (*fPadBuffer).Position().Y()==position.Y()) return (*fPadBuffer);
436 Int_t motifPosID = fkSector->FindMotifPositionId(position);
437 AliMpMotifPosition* motifPos
438 = fkSector->GetMotifMap()
439 ->FindMotifPosition(motifPosID);
442 if (warning) Warning("PadByPosition","Position outside limits");
443 return AliMpPad::Invalid();
446 AliMpVMotif* motif = motifPos->GetMotif();
447 AliMpIntPair localIndices
448 = motif->PadIndicesLocal(position-motifPos->Position());
450 AliMpConnection* connect =
451 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
454 if (warning) Warning("PadByPosition","Position outside motif limits");
455 return AliMpPad::Invalid();
459 = AliMpPad(AliMpIntPair(motifPosID,connect->GetGassiNum()),
460 motifPos->GlobalIndices(localIndices),
461 motifPos->Position()+motif->PadPositionLocal(localIndices),
462 motif->GetPadDimensions(localIndices));
466 //______________________________________________________________________________
468 AliMpSectorSegmentation::PadByDirection(const TVector2& startPosition,
469 Double_t distance) const
471 /// Find the first valid pad from starting position in the
472 /// direction of pad lines/columns up to the specified distance.
473 /// Pad lines are the lines of pads in the sector with constant pad y size,
474 /// pad columns are the columns of pads in the sector with constant pad x size.
476 switch (fkSector->GetDirection()) {
478 case kX: return PadByYDirection(startPosition, distance);
480 case kY: return PadByXDirection(startPosition, distance);
484 Fatal("PadByDirection", "Incomplete switch on Sector direction");
485 return AliMpPad::Invalid();
488 //______________________________________________________________________________
489 Int_t AliMpSectorSegmentation::MaxPadIndexX()
491 /// Return maximum pad index in x
493 if (fMaxIndexInX) return fMaxIndexInX;
495 for (Int_t i=0; i<fkSector->GetNofRows(); i++) {
496 Int_t ixh = fkSector->GetRow(i)->GetHighIndicesLimit().GetFirst();
497 if ( ixh > fMaxIndexInX ) fMaxIndexInX = ixh;
502 //______________________________________________________________________________
503 Int_t AliMpSectorSegmentation::MaxPadIndexY()
505 /// Return maximum pad index in y
507 if (fMaxIndexInY) return fMaxIndexInY;
509 for (Int_t i=0; i<fkSector->GetNofRows(); i++) {
510 Int_t iyh = fkSector->GetRow(i)->GetHighIndicesLimit().GetSecond();
511 if ( iyh > fMaxIndexInY ) fMaxIndexInY = iyh;
516 //______________________________________________________________________________
517 Bool_t AliMpSectorSegmentation::HasPad(const AliMpIntPair& indices) const
519 /// Does the pad specified by <indices> exist ?
521 return PadByIndices(indices,kFALSE) != AliMpPad::Invalid();
524 //______________________________________________________________________________
525 Bool_t AliMpSectorSegmentation::HasMotifPosition(Int_t motifPositionID) const
527 /// Does the motif position specified by motifPositionID exist ?
529 return (fkSector->GetMotifMap()->FindMotifPosition(motifPositionID) != 0);
532 //______________________________________________________________________________
533 TVector2 AliMpSectorSegmentation::GetMinPadDimensions() const
535 /// Returne the dimensions of the smallest pad.
537 return fkSector->GetMinPadDimensions();
540 //______________________________________________________________________________
541 Int_t AliMpSectorSegmentation::Zone(const AliMpPad& pad, Bool_t warning) const
543 /// Return the zone index of the zone containing the specified pad.
544 /// This zone index is different from the zone ID,
545 /// as it is unique for each pad dimensions.
546 /// It is composed in this way:
547 /// zoneID*10 + specific index
548 /// Specific index is present only for zones containing special motifs.
550 if (!pad.IsValid()) {
551 if (warning) Warning("Zone(AliMpPad)", "Invalid pad");
556 PadDimensionsMapCIterator it;
557 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
558 if (AliMpConstants::IsEqual(it->second, pad.Dimensions()))
564 PadDimensionsMapCIterator it(&fPadDimensionsMap);
566 while ( it.Next(key, value) ) {
567 TVector2 dimensions = GetVector(value);
568 if (AliMpConstants::IsEqual(dimensions, pad.Dimensions()))
572 AliError(Form("fPadDimensionsMap size is %d",fPadDimensionsMap.GetSize()));
576 // Should never happen
577 AliError("Zone(AliMpPad pad) not found, where pad is :");
578 StderrToAliError(cerr << pad << endl;);
582 //______________________________________________________________________________
584 AliMpSectorSegmentation::PadDimensions(Int_t zone, Bool_t warning) const
586 /// Return the pad dimensions for the zone with the specified zone index.
589 PadDimensionsMapCIterator it = fPadDimensionsMap.find(zone);
590 if (it != fPadDimensionsMap.end()) return it->second;
594 Long_t value = fPadDimensionsMap.GetValue(zone);
595 if (value) return GetVector(value);
598 if (warning) Warning("PadDimensions(zone)", "not found");
602 //______________________________________________________________________________
603 Bool_t AliMpSectorSegmentation::CircleTest(const AliMpIntPair& indices) const
605 /// Verify that all methods for retrieving pads are consistents between them.
606 /// Return true if the pad with specified indices was found and verified,
609 if (!HasPad(indices)) return false;
611 // Verify the indice->location->position->indice way
612 AliMpIntPair location = PadByIndices(indices).GetLocation();
613 TVector2 position = PadByLocation(location).Position();
614 AliMpIntPair retIndices = PadByPosition(position).GetIndices();
616 if (retIndices != indices) {
617 cout << "Pad " << indices << " lead to inconsistency" << endl;
618 cout << "in indice->location->position->indice way..." << endl;
619 cout << "starting from " << indices << "-->" << location << "-->"
620 << '(' << position.X() << ',' << position.Y() << ')'
621 << " and retIndices: " << retIndices << endl;
625 // Verify the indice->position->location->indice way
626 position = PadByIndices(indices).Position();
627 location = PadByPosition(position).GetLocation();
628 retIndices = PadByLocation(location).GetIndices();
630 if (retIndices != indices) {
631 cout << "Pad " << indices << " lead to inconsistency" << endl;
632 cout << "in indice->position->location->indice way..." <<endl;
633 cout << "starting from " << indices
634 << " and retIndices: " << retIndices << endl;
640 //______________________________________________________________________________
641 void AliMpSectorSegmentation::PrintZones() const
643 /// Print all zones and pads dimensions from the map.
645 cout << "Zones: " << endl;
648 PadDimensionsMapCIterator it;
649 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
650 cout << " zone: " << setw(4) << it->first;
651 cout << " pad dimensions: ( "
652 << it->second.X() << ", " << it->second.Y() << ")" << endl;
657 PadDimensionsMapCIterator it(&fPadDimensionsMap);
659 while ( it.Next(key, value) ) {
660 //cout << "Iterating over: " << key << ", " << value << endl;
661 TVector2 dimensions = GetVector(value);
663 cout << " zone: " << setw(4) << key;
664 cout << " pad dimensions: ( "
665 << dimensions.X() << ", " << dimensions.Y() << ")" << endl;