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 "AliMpNeighboursPadIterator.h"
42 #include "AliMpSectorAreaHPadIterator.h"
43 #include "AliMpSectorAreaVPadIterator.h"
44 #include "AliMpSectorPadIterator.h"
45 #include "AliMpIntPair.h"
46 #include "AliMpArea.h"
47 #include "AliMpConstants.h"
51 #include <Riostream.h>
55 ClassImp(AliMpSectorSegmentation)
59 const Double_t AliMpSectorSegmentation::fgkS1 = 100000.;
60 const Double_t AliMpSectorSegmentation::fgkS2 = 1000.;
63 //______________________________________________________________________________
64 AliMpSectorSegmentation::AliMpSectorSegmentation(
65 const AliMpSector* sector, Bool_t own)
66 : AliMpVSegmentation(),
74 /// Standard constructor
76 AliDebugStream(1) << "this = " << this << endl;
78 fPadBuffer = new AliMpPad(AliMpPad::Invalid());
80 FillPadDimensionsMap();
83 //______________________________________________________________________________
84 AliMpSectorSegmentation::AliMpSectorSegmentation()
85 : AliMpVSegmentation(),
93 /// Default constructor
95 AliDebugStream(1) << "this = " << this << endl;
98 //______________________________________________________________________________
99 AliMpSectorSegmentation::~AliMpSectorSegmentation()
103 AliDebugStream(1) << "this = " << this << endl;
105 if ( fIsOwner ) delete fkSector;
116 //______________________________________________________________________________
117 Long_t AliMpSectorSegmentation::GetIndex(const TVector2& vector2) const
119 /// Convert the two vector to long.
121 return Long_t(TMath::Floor((vector2.X()*fgkS1 + vector2.Y())*fgkS2));
124 //______________________________________________________________________________
125 TVector2 AliMpSectorSegmentation::GetVector(Long_t index) const
127 /// Convert the long index to twovector.
129 return TVector2( TMath::Floor(index/fgkS1)/fgkS2,
130 (index - TMath::Floor(index/fgkS1)*fgkS1)/fgkS2 );
134 //______________________________________________________________________________
135 void AliMpSectorSegmentation::FillPadDimensionsMap()
137 /// Fill the maps between zone ids and pad dimensions.
139 for (Int_t i=0; i<fkSector->GetNofZones(); i++) {
140 AliMpZone* zone = fkSector->GetZone(i+1);
141 Int_t zoneID = zone->GetID();
143 if (!AliMpConstants::IsEqual(zone->GetPadDimensions(), TVector2())) {
147 fPadDimensionsMap[zoneID*10] = zone->GetPadDimensions();
151 << "Filling fPadDimensions[" << zoneID*10 << "] = ("
152 << zone->GetPadDimensions().X() << ", "
153 << zone->GetPadDimensions().Y() << ")" << endl;
155 fPadDimensionsMap.Add((Long_t)(zoneID*10),
156 GetIndex(zone->GetPadDimensions()));
162 for (Int_t j=0; j<zone->GetNofSubZones(); j++) {
163 AliMpSubZone* subZone = zone->GetSubZone(j);
164 AliMpVMotif* motif = subZone->GetMotif();
166 for (Int_t k=0; k<motif->GetNofPadDimensions(); k++) {
167 Int_t index = zoneID*10 + subIndex++;
169 fPadDimensionsMap[index] = motif->GetPadDimensions(k);
173 << "Filling fPadDimensions[" << index << "] = ("
174 << motif->GetPadDimensions(k).X() << ", "
175 << motif->GetPadDimensions(k).Y() << ") motif "
176 << motif->GetID().Data() << "-" << k << endl;
178 fPadDimensionsMap.Add((Long_t)(index),
179 GetIndex(motif->GetPadDimensions(k)));
187 //______________________________________________________________________________
189 AliMpSectorSegmentation::FindMotifPosition(const AliMpIntPair& indices) const
191 /// Find the motif position which contains the given pad indices
192 /// return 0 if not found
194 switch (fkSector->GetDirection()) {
196 // Case where all the pads have the same size along X direction
198 for (Int_t irow=0; irow<fkSector->GetNofRows(); ++irow) {
199 AliMpRow* row = fkSector->GetRow(irow);
200 if (row->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
201 row->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
203 for (Int_t iseg=0;iseg<row->GetNofRowSegments();++iseg){
204 AliMpVRowSegment* seg = row->GetRowSegment(iseg);
205 if (seg->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
206 seg->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
208 AliMpMotifPosition* motifPos;
209 for (Int_t imot=0;imot<seg->GetNofMotifs();++imot) {
211 = fkSector->GetMotifMap()
212 ->FindMotifPosition(seg->GetMotifPositionId(imot));
213 if (motifPos && motifPos->HasPadByIndices(indices)) return motifPos;
222 ////////////////////////////////////////////////////////////////////////////////
224 // Case where all the pads have the same size along Y direction
225 // look for the row which contains the indices
228 for (irow=0; irow<fkSector->GetNofRows(); ++irow) {
229 row = fkSector->GetRow(irow);
230 AliMpVRowSegment* lastSeg = row->GetRowSegment(row->GetNofRowSegments()-1);
231 if (lastSeg->GetLowIndicesLimit().GetSecond()<=indices.GetSecond() &&
232 lastSeg->GetHighIndicesLimit().GetSecond()>=indices.GetSecond()) break;
233 // NOTE : We use the last row segment in order to ensure that
234 // we are not on a special motif
236 if (irow==fkSector->GetNofRows()) return 0;
237 // look for the row segment, in the found row, which contains the indices
238 AliMpVRowSegment* seg=0;
240 for (iseg=0;iseg<row->GetNofRowSegments();++iseg){
241 seg = row->GetRowSegment(iseg);
242 if (seg->HasIndices(indices)) break;
244 if (iseg==row->GetNofRowSegments()) return 0;
246 // look for the motif position which contains the indices
247 AliMpMotifPosition* motifPos=0;
249 for (imot=0;imot<seg->GetNofMotifs();++imot) {
251 = fkSector->GetMotifMap()
252 ->FindMotifPosition(seg->GetMotifPositionId(imot));
253 if (motifPos && motifPos->HasPadByIndices(indices)) break;
255 if (imot==seg->GetNofMotifs()) return 0;
263 //______________________________________________________________________________
265 AliMpSectorSegmentation::PadByXDirection(const TVector2& startPosition,
268 /// Find the first valid pad from starting position in the
269 /// direction of pad lines up to distance dx.
271 // Define step limits
272 Double_t stepX = fkSector->GetMinPadDimensions().X();
274 // Search in X direction
276 TVector2 position(startPosition);
278 pad = PadByPosition(position, false);
279 position += TVector2(stepX, 0.);
281 while ( !pad.IsValid() &&
282 position.X() - fkSector->GetMaxPadDimensions().X() < maxX );
284 // Invalidate pad if it is outside limits
285 if ( (pad.Position().X() - pad.Dimensions().X()) > maxX )
286 pad = AliMpPad::Invalid();
291 //______________________________________________________________________________
293 AliMpSectorSegmentation::PadByYDirection(const TVector2& startPosition,
296 /// Find the first valid pad from starting position in the
297 /// direction of pad columns up to distance dx.
299 // Define step limits
300 Double_t stepY = fkSector->GetMinPadDimensions().Y();
302 // Search in Y direction
304 TVector2 position(startPosition);
306 pad = PadByPosition(position, false);
307 position += TVector2(0., stepY);
309 while ( !pad.IsValid() &&
310 position.Y() - fkSector->GetMaxPadDimensions().Y()< maxY );
312 // Invalidate pad if it is outside limits
313 if ((pad.Position().Y() - pad.Dimensions().Y()) > maxY)
314 pad = AliMpPad::Invalid();
323 //______________________________________________________________________________
325 AliMpSectorSegmentation::CreateIterator(const AliMpArea& area) const
327 /// Create the area iterator.
329 switch (fkSector->GetDirection()) {
331 case AliMp::kX: return new AliMpSectorAreaVPadIterator(this, area);
333 case AliMp::kY: return new AliMpSectorAreaHPadIterator(this, area);
337 Fatal("CreateIterator", "Incomplete switch on Sector direction");
341 //______________________________________________________________________________
343 AliMpSectorSegmentation::CreateIterator() const
345 /// Create the sector iterator
347 return new AliMpSectorPadIterator(fkSector);
350 //______________________________________________________________________________
352 AliMpSectorSegmentation::CreateIterator(const AliMpPad& centerPad,
353 Bool_t includeCenter) const
355 /// Create the neighbours pad iterator.
357 return new AliMpNeighboursPadIterator(this, centerPad, includeCenter);
360 //______________________________________________________________________________
362 AliMpSectorSegmentation::GetNeighbours(const AliMpPad& pad, TObjArray& neighbours,
364 Bool_t includeVoid) const
366 /// Uses default implementation
367 return AliMpVSegmentation::GetNeighbours(pad,neighbours,includeSelf,includeVoid);
370 //______________________________________________________________________________
372 AliMpSectorSegmentation::PadByLocation(const AliMpIntPair& location,
373 Bool_t warning) const
375 /// Find the pad which corresponds to the given location
377 if ((*fPadBuffer).GetLocation()==location) return (*fPadBuffer);
379 AliMpMotifPosition* motifPos =
380 fkSector->GetMotifMap()->FindMotifPosition(location.GetFirst());
382 if (warning) Warning("PadByLocation","The pad motif position ID doesn't exists");
383 return AliMpPad::Invalid();
386 AliMpVMotif* motif = motifPos->GetMotif();
387 AliMpIntPair localIndices =
388 motif->GetMotifType()->FindLocalIndicesByGassiNum(location.GetSecond());
389 if (! localIndices.IsValid()) {
390 if (warning) Warning("PadByLocation","The pad number doesn't exists");
391 return AliMpPad::Invalid();
393 TVector2 delta = motif->PadPositionLocal(localIndices);
394 return (*fPadBuffer) = AliMpPad(location,
395 motifPos->GlobalIndices(localIndices),
396 motifPos->Position()+delta,
397 motif->GetPadDimensions(localIndices));
400 //______________________________________________________________________________
402 AliMpSectorSegmentation::PadByIndices(const AliMpIntPair& indices,
403 Bool_t warning ) const
405 /// Find the pad which corresponds to the given indices
407 if ((*fPadBuffer).GetIndices()==indices) return (*fPadBuffer);
409 AliMpMotifPosition* motifPos = FindMotifPosition(indices);
412 Warning("PadByIndices","Pad indices not contained in any motif!");
413 return AliMpPad::Invalid();
416 // retrieve the local indices in the found motif
417 AliMpVMotif* motif = motifPos->GetMotif();
418 AliMpIntPair localIndices = indices - motifPos->GetLowIndicesLimit();
420 AliMpConnection* connection=
421 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
424 if (warning) Warning("PadByIndices","No connection with the given indices!");
425 return AliMpPad::Invalid();
428 TVector2 localPos = motif->PadPositionLocal(localIndices);
431 = AliMpPad(AliMpIntPair(motifPos->GetID(),connection->GetManuChannel()),
433 motifPos->Position()+localPos,
434 motif->GetPadDimensions(localIndices));
437 //______________________________________________________________________________
439 AliMpSectorSegmentation::PadByPosition(const TVector2& position,
440 Bool_t warning) const
442 /// Find the pad which corresponds to the given position
444 if ((*fPadBuffer).Position().X()==position.X() &&
445 (*fPadBuffer).Position().Y()==position.Y()) return (*fPadBuffer);
447 Int_t motifPosID = fkSector->FindMotifPositionId(position);
448 AliMpMotifPosition* motifPos
449 = fkSector->GetMotifMap()
450 ->FindMotifPosition(motifPosID);
453 if (warning) Warning("PadByPosition","Position outside limits");
454 return AliMpPad::Invalid();
457 AliMpVMotif* motif = motifPos->GetMotif();
458 AliMpIntPair localIndices
459 = motif->PadIndicesLocal(position-motifPos->Position());
461 AliMpConnection* connect =
462 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
465 if (warning) Warning("PadByPosition","Position outside motif limits");
466 return AliMpPad::Invalid();
470 = AliMpPad(AliMpIntPair(motifPosID,connect->GetManuChannel()),
471 motifPos->GlobalIndices(localIndices),
472 motifPos->Position()+motif->PadPositionLocal(localIndices),
473 motif->GetPadDimensions(localIndices));
477 //______________________________________________________________________________
479 AliMpSectorSegmentation::PadByDirection(const TVector2& startPosition,
480 Double_t distance) const
482 /// Find the first valid pad from starting position in the
483 /// direction of pad lines/columns up to the specified distance.
484 /// Pad lines are the lines of pads in the sector with constant pad y size,
485 /// pad columns are the columns of pads in the sector with constant pad x size.
487 switch (fkSector->GetDirection()) {
489 case AliMp::kX: return PadByYDirection(startPosition, distance);
491 case AliMp::kY: return PadByXDirection(startPosition, distance);
495 Fatal("PadByDirection", "Incomplete switch on Sector direction");
496 return AliMpPad::Invalid();
499 //_____________________________________________________________________________
501 AliMpSectorSegmentation::HasPadByIndices(const AliMpIntPair& indices) const
503 /// Whether or not we have a pad at indices=(ix,iy)
505 AliMpMotifPosition* motifPos = FindMotifPosition(indices);
507 if (motifPos) return motifPos->HasPadByIndices(indices);
512 //_____________________________________________________________________________
514 AliMpSectorSegmentation::HasPadByLocation(const AliMpIntPair& location) const
516 /// Whether or not we have a pad at location=(manuId,manuChannel)
518 AliMpMotifPosition* motifPos =
519 fkSector->GetMotifMap()->FindMotifPosition(location.GetFirst());
521 if ( motifPos ) return motifPos->HasPadByManuChannel(location.GetSecond());
526 //______________________________________________________________________________
527 Bool_t AliMpSectorSegmentation::HasPad(const AliMpIntPair& indices) const
529 /// Does the pad specified by \a indices exist ?
531 return PadByIndices(indices,kFALSE) != AliMpPad::Invalid();
534 //______________________________________________________________________________
535 Int_t AliMpSectorSegmentation::MaxPadIndexX() const
537 /// Return maximum pad index in x
539 return fkSector->GetMaxPadIndices().GetFirst();
542 //______________________________________________________________________________
543 Int_t AliMpSectorSegmentation::MaxPadIndexY() const
545 /// Return maximum pad index in y
547 return fkSector->GetMaxPadIndices().GetSecond();
550 //______________________________________________________________________________
551 Int_t AliMpSectorSegmentation::NofPads() const
553 /// Return number of pads defined in the sector
555 return fkSector->GetNofPads();
558 //_____________________________________________________________________________
560 AliMpSectorSegmentation::GetAllElectronicCardIDs(TArrayI& ecn) const
562 /// Fill the array ecn with all manuIds
564 GetSector()->GetAllMotifPositionsIDs(ecn);
567 //_____________________________________________________________________________
569 AliMpSectorSegmentation::GetNofElectronicCards() const
571 /// Get the number of manus of this sector
573 return fkSector->GetNofMotifPositions();
576 //_____________________________________________________________________________
578 AliMpSectorSegmentation::HasMotifPosition(Int_t manuId) const
580 /// Whether we get a given manu. Uses default implementation
581 return (AliMpVSegmentation::HasMotifPosition(manuId) != 0x0);
584 //_____________________________________________________________________________
586 AliMpSectorSegmentation::MotifPosition(Int_t manuId) const
588 /// Return a given manu
589 return fkSector->GetMotifMap()->FindMotifPosition(manuId);
592 //______________________________________________________________________________
594 AliMpSectorSegmentation::PlaneType() const
596 return GetSector()->GetPlaneType();
599 //______________________________________________________________________________
601 AliMpSectorSegmentation::Dimensions() const
603 /// Return sector dimensions
605 return GetSector()->Dimensions();
608 //______________________________________________________________________________
610 AliMpSectorSegmentation::Position() const
612 /// Return sector position
614 // return GetSector()->Position();
615 return TVector2(0.,0.);
618 //______________________________________________________________________________
620 AliMpSectorSegmentation::Print(Option_t* opt) const
624 fkSector->Print(opt);
627 //______________________________________________________________________________
628 Int_t AliMpSectorSegmentation::Zone(const AliMpPad& pad, Bool_t warning) const
630 /// Return the zone index of the zone containing the specified pad.
631 /// This zone index is different from the zone ID,
632 /// as it is unique for each pad dimensions.
633 /// It is composed in this way:
634 /// zoneID*10 + specific index
635 /// Specific index is present only for zones containing special motifs.
637 if (!pad.IsValid()) {
638 if (warning) Warning("Zone(AliMpPad)", "Invalid pad");
643 PadDimensionsMapCIterator it;
644 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
645 if (AliMpConstants::IsEqual(it->second, pad.Dimensions()))
651 PadDimensionsMapCIterator it(&fPadDimensionsMap);
653 while ( it.Next(key, value) ) {
654 TVector2 dimensions = GetVector(value);
655 if (AliMpConstants::IsEqual(dimensions, pad.Dimensions()))
659 AliError(Form("fPadDimensionsMap size is %d",fPadDimensionsMap.GetSize()));
663 // Should never happen
665 << "Zone(AliMpPad pad) not found, where pad is: " << pad << endl;
669 //______________________________________________________________________________
671 AliMpSectorSegmentation::PadDimensions(Int_t zone, Bool_t warning) const
673 /// Return the pad dimensions for the zone with the specified zone index.
676 PadDimensionsMapCIterator it = fPadDimensionsMap.find(zone);
677 if (it != fPadDimensionsMap.end()) return it->second;
681 Long_t value = fPadDimensionsMap.GetValue(zone);
682 if (value) return GetVector(value);
685 if (warning) Warning("PadDimensions(zone)", "not found");
689 //______________________________________________________________________________
690 TVector2 AliMpSectorSegmentation::GetMinPadDimensions() const
692 /// Returne the dimensions of the smallest pad.
694 return fkSector->GetMinPadDimensions();
697 //______________________________________________________________________________
698 Bool_t AliMpSectorSegmentation::CircleTest(const AliMpIntPair& indices) const
700 /// Verify that all methods for retrieving pads are consistents between them.
701 /// Return true if the pad with specified indices was found and verified,
704 if (!HasPad(indices)) return false;
706 // Verify the indice->location->position->indice way
707 AliMpIntPair location = PadByIndices(indices).GetLocation();
708 TVector2 position = PadByLocation(location).Position();
709 AliMpIntPair retIndices = PadByPosition(position).GetIndices();
711 if (retIndices != indices) {
712 cout << "Pad " << indices << " lead to inconsistency" << endl;
713 cout << "in indice->location->position->indice way..." << endl;
714 cout << "starting from " << indices << "-->" << location << "-->"
715 << '(' << position.X() << ',' << position.Y() << ')'
716 << " and retIndices: " << retIndices << endl;
720 // Verify the indice->position->location->indice way
721 position = PadByIndices(indices).Position();
722 location = PadByPosition(position).GetLocation();
723 retIndices = PadByLocation(location).GetIndices();
725 if (retIndices != indices) {
726 cout << "Pad " << indices << " lead to inconsistency" << endl;
727 cout << "in indice->position->location->indice way..." <<endl;
728 cout << "starting from " << indices
729 << " and retIndices: " << retIndices << endl;
735 //______________________________________________________________________________
736 void AliMpSectorSegmentation::PrintZones() const
738 /// Print all zones and pads dimensions from the map.
740 cout << "Zones: " << endl;
743 PadDimensionsMapCIterator it;
744 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
745 cout << " zone: " << setw(4) << it->first;
746 cout << " pad dimensions: ( "
747 << it->second.X() << ", " << it->second.Y() << ")" << endl;
752 PadDimensionsMapCIterator it(&fPadDimensionsMap);
754 while ( it.Next(key, value) ) {
755 //cout << "Iterating over: " << key << ", " << value << endl;
756 TVector2 dimensions = GetVector(value);
758 cout << " zone: " << setw(4) << key;
759 cout << " pad dimensions: ( "
760 << dimensions.X() << ", " << dimensions.Y() << ")" << endl;