]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/mapping/AliMpSectorSegmentation.cxx
Warning suppression
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpSectorSegmentation.cxx
CommitLineData
5f91c9e8 1// $Id$
2// Category: sector
3//
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.
10//
11// Authors: David Guez, Ivana Hrivnacova; IPN Orsay
12
13#include <Riostream.h>
14#include <TMath.h>
fb1bf5c0 15#include <TError.h>
5f91c9e8 16
17#include "AliMpSectorSegmentation.h"
18#include "AliMpSector.h"
19#include "AliMpZone.h"
2998a151 20#include "AliMpSubZone.h"
5f91c9e8 21#include "AliMpRow.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"
2998a151 30#include "AliMpIntPair.h"
31#include "AliMpArea.h"
5f91c9e8 32#include "AliMpConstants.h"
33
34ClassImp(AliMpSectorSegmentation)
35
f79c58a5 36#ifdef WITH_ROOT
bcf37928 37const Double_t AliMpSectorSegmentation::fgkS1 = 10000.;
38const Double_t AliMpSectorSegmentation::fgkS2 = 100.;
f79c58a5 39#endif
40
5f91c9e8 41//______________________________________________________________________________
42AliMpSectorSegmentation::AliMpSectorSegmentation(const AliMpSector* sector)
43 : AliMpVSegmentation(),
44 fkSector(sector)
45{
46//
47 fPadBuffer = new AliMpPad(AliMpPad::Invalid());
48
49 FillPadDimensionsMap();
50}
51
52//______________________________________________________________________________
53AliMpSectorSegmentation::AliMpSectorSegmentation()
54 : AliMpVSegmentation(),
55 fkSector(0),
56 fPadBuffer(0),
57 fPadDimensionsMap()
58{
59//
60}
61
fb1bf5c0 62//_____________________________________________________________________________
63AliMpSectorSegmentation::AliMpSectorSegmentation(
64 const AliMpSectorSegmentation& right)
65 : AliMpVSegmentation(right) {
66//
67 Fatal("AliMpSectorSegmentation", "Copy constructor not provided.");
68}
69
5f91c9e8 70//______________________________________________________________________________
71AliMpSectorSegmentation::~AliMpSectorSegmentation() {
72//
73 delete fPadBuffer;
74}
75
fb1bf5c0 76//
77// operators
78//
79
80//_____________________________________________________________________________
81AliMpSectorSegmentation&
82AliMpSectorSegmentation::operator=(const AliMpSectorSegmentation& right)
83{
84 // check assignement to self
85 if (this == &right) return *this;
86
87 Fatal("operator =", "Assignement operator not provided.");
88
89 return *this;
90}
91
5f91c9e8 92//
93// private methods
94//
95
f79c58a5 96#ifdef WITH_ROOT
97//______________________________________________________________________________
98Long_t AliMpSectorSegmentation::GetIndex(const TVector2& vector2) const
99{
bcf37928 100// Converts the two vector to long.
f79c58a5 101// ---
102
bcf37928 103 return Long_t(TMath::Floor((vector2.X()*fgkS1 + vector2.Y())*fgkS2));
f79c58a5 104}
105
106//______________________________________________________________________________
107TVector2 AliMpSectorSegmentation::GetVector(Long_t index) const
108{
109// Converts the long index to twovector.
110// ---
111
bcf37928 112 return TVector2( TMath::Floor(index/fgkS1)/fgkS2,
113 (index - TMath::Floor(index/fgkS1)*fgkS1)/fgkS2 );
f79c58a5 114}
115#endif
116
5f91c9e8 117//______________________________________________________________________________
118void AliMpSectorSegmentation::FillPadDimensionsMap()
119{
120// Fills the maps between zone ids and pad dimensions.
121// ---
122
123 for (Int_t i=0; i<fkSector->GetNofZones(); i++) {
124 AliMpZone* zone = fkSector->GetZone(i+1);
125 Int_t zoneID = zone->GetID();
126
127 if (!AliMpConstants::IsEqual(zone->GetPadDimensions(), TVector2())) {
f79c58a5 128
5f91c9e8 129 // regular zone
f79c58a5 130#ifdef WITH_STL
5f91c9e8 131 fPadDimensionsMap[zoneID*10] = zone->GetPadDimensions();
f79c58a5 132#endif
133#ifdef WITH_ROOT
bcf37928 134 fPadDimensionsMap.Add((Long_t)(zoneID*10),
f79c58a5 135 GetIndex(zone->GetPadDimensions()));
136#endif
5f91c9e8 137 }
138 else {
139 // special zone
140 Int_t subIndex = 0;
141 for (Int_t j=0; j<zone->GetNofSubZones(); j++) {
142 AliMpSubZone* subZone = zone->GetSubZone(j);
143 AliMpVMotif* motif = subZone->GetMotif();
144
145 for (Int_t k=0; k<motif->GetNofPadDimensions(); k++) {
146 Int_t index = zoneID*10 + subIndex++;
f79c58a5 147#ifdef WITH_STL
5f91c9e8 148 fPadDimensionsMap[index] = motif->GetPadDimensions(k);
f79c58a5 149#endif
150#ifdef WITH_ROOT
151 fPadDimensionsMap.Add((Long_t)(index),
152 GetIndex(motif->GetPadDimensions(k)));
153#endif
5f91c9e8 154 }
155 }
156 }
157 }
158}
159
160//______________________________________________________________________________
161AliMpMotifPosition*
162AliMpSectorSegmentation::FindMotifPosition(const AliMpIntPair& indices) const
163{
164// Find the motif position which contains the given pad indices
165// return 0 if not found
166// ---
167
168 switch (fkSector->GetDirection()) {
169 case kX : {
170 // Case where all the pads have the same size along X direction
171
172 for (Int_t irow=0; irow<fkSector->GetNofRows(); ++irow) {
173 AliMpRow* row = fkSector->GetRow(irow);
174 if (row->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
175 row->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
176
177 for (Int_t iseg=0;iseg<row->GetNofRowSegments();++iseg){
178 AliMpVRowSegment* seg = row->GetRowSegment(iseg);
179 if (seg->GetLowIndicesLimit().GetFirst()<=indices.GetFirst() &&
180 seg->GetHighIndicesLimit().GetFirst()>=indices.GetFirst()) {
181
182 AliMpMotifPosition* motifPos;
183 for (Int_t imot=0;imot<seg->GetNofMotifs();++imot) {
184 motifPos
185 = fkSector->GetMotifMap()
186 ->FindMotifPosition(seg->GetMotifPositionId(imot));
187 if (motifPos && motifPos->HasPad(indices)) return motifPos;
188 }
189 }
190 }
191 }
192 }
193 return 0;
194 }
195 break;
196 ////////////////////////////////////////////////////////////////////////////////
197 case kY : {
198 // Case where all the pads have the same size along Y direction
199 // look for the row which contains the indices
200 AliMpRow* row=0;
201 Int_t irow;
202 for (irow=0; irow<fkSector->GetNofRows(); ++irow) {
203 row = fkSector->GetRow(irow);
204 AliMpVRowSegment* lastSeg = row->GetRowSegment(row->GetNofRowSegments()-1);
205 if (lastSeg->GetLowIndicesLimit().GetSecond()<=indices.GetSecond() &&
206 lastSeg->GetHighIndicesLimit().GetSecond()>=indices.GetSecond()) break;
207 // NOTE : We use the last row segment in order to ensure that
208 // we are not on a special motif
209 }
210 if (irow==fkSector->GetNofRows()) return 0;
211 // look for the row segment, in the found row, which contains the indices
212 AliMpVRowSegment* seg=0;
213 Int_t iseg;
214 for (iseg=0;iseg<row->GetNofRowSegments();++iseg){
215 seg = row->GetRowSegment(iseg);
216 if (seg->HasIndices(indices)) break;
217 }
218 if (iseg==row->GetNofRowSegments()) return 0;
219
220 // look for the motif position which contains the indices
221 AliMpMotifPosition* motifPos=0;
222 Int_t imot=0;
223 for (imot=0;imot<seg->GetNofMotifs();++imot) {
224 motifPos
225 = fkSector->GetMotifMap()
226 ->FindMotifPosition(seg->GetMotifPositionId(imot));
227 if (motifPos && motifPos->HasPad(indices)) break;
228 }
229 if (imot==seg->GetNofMotifs()) return 0;
230
231 return motifPos;
232 }
233 default: return 0;
234 }
235}
236
237//______________________________________________________________________________
238AliMpPad
239AliMpSectorSegmentation::PadByXDirection(const TVector2& startPosition,
240 Double_t maxX) const
241{
242// Find the first valid pad from starting position in the
243// direction of pad lines up to distance dx.
244// ---
245
246 // Define step limits
247 Double_t stepX = fkSector->GetMinPadDimensions().X();
248
249 // Search in X direction
250 AliMpPad pad;
251 TVector2 position(startPosition);
252 do {
253 pad = PadByPosition(position, false);
254 position += TVector2(stepX, 0.);
255 }
256 while ( !pad.IsValid() && position.X() < maxX );
257
258 // Invalidate pad if it is outside limits
259 if ((pad.Position().X() - pad.Dimensions().X()) > maxX)
260 pad = AliMpPad::Invalid();
261
262 return pad;
263}
264
265//______________________________________________________________________________
266AliMpPad
267AliMpSectorSegmentation::PadByYDirection(const TVector2& startPosition,
268 Double_t maxY) const
269{
270// Find the first valid pad from starting position in the
271// direction of pad columns up to distance dx.
272// ---
273
274 // Define step limits
275 Double_t stepY = fkSector->GetMinPadDimensions().Y();
276
277 // Search in Y direction
278 AliMpPad pad;
279 TVector2 position(startPosition);
280 do {
281 pad = PadByPosition(position, false);
282 position += TVector2(0., stepY);
283 }
284 while ( !pad.IsValid() && position.Y() < maxY );
285
286 // Invalidate pad if it is outside limits
287 if ((pad.Position().Y() - pad.Dimensions().Y()) > maxY)
288 pad = AliMpPad::Invalid();
289
290 return pad;
291}
292
293//______________________________________________________________________________
294AliMpVPadIterator* AliMpSectorSegmentation::CreateIterator() const
295{
296// The inherited method cannot be used
297
298 Fatal("CreateIterator", "Center pad has to be specified.");
299 return 0;
300}
301
302
303//
304// public methods
305//
306
307//______________________________________________________________________________
308AliMpVPadIterator*
309AliMpSectorSegmentation::CreateIterator(const AliMpArea& area) const
310{
311// Creates the are iterator.
312// (The inherited method cannot be used)
313// ---
314
315 switch (fkSector->GetDirection()) {
316
317 case kX: return new AliMpSectorAreaVPadIterator(this, area);
318 ;;
319 case kY: return new AliMpSectorAreaHPadIterator(this, area);
320 ;;
321 }
322
323 Fatal("CreateIterator", "Incomplete switch on Sector direction");
324 return 0;
325}
326
327//______________________________________________________________________________
328AliMpVPadIterator*
329AliMpSectorSegmentation::CreateIterator(const AliMpPad& centerPad,
330 Bool_t includeCenter) const
331{
332// Creates the neighbours pad iterator.
333// (The inherited method cannot be used)
334
335 return new AliMpNeighboursPadIterator(this, centerPad, includeCenter);
336}
337
338//______________________________________________________________________________
339AliMpPad
340AliMpSectorSegmentation::PadByLocation(const AliMpIntPair& location,
341 Bool_t warning) const
342{
343// Find the pad which corresponds to the given location
344
345 if ((*fPadBuffer).GetLocation()==location) return (*fPadBuffer);
346
347 AliMpMotifPosition* motifPos =
348 fkSector->GetMotifMap()->FindMotifPosition(location.GetFirst());
349 if (!motifPos){
350 if (warning) Warning("PadByLocation","The pad motif position ID doesn't exists");
351 return AliMpPad::Invalid();
352 }
353
354 AliMpVMotif* motif = motifPos->GetMotif();
355 AliMpIntPair localIndices =
356 motif->GetMotifType()->FindLocalIndicesByGassiNum(location.GetSecond());
357 if (! localIndices.IsValid()) {
358 if (warning) Warning("PadByLocation","The pad number doesn't exists");
359 return AliMpPad::Invalid();
360 }
361 TVector2 delta = motif->PadPositionLocal(localIndices);
362 return (*fPadBuffer) = AliMpPad(location,
363 motifPos->GlobalIndices(localIndices),
364 motifPos->Position()+delta,
365 motif->GetPadDimensions(localIndices));
366
367}
368//______________________________________________________________________________
369AliMpPad
370AliMpSectorSegmentation::PadByIndices(const AliMpIntPair& indices,
371 Bool_t warning ) const
372{
373// Find the pad which corresponds to the given indices
374
375 if ((*fPadBuffer).GetIndices()==indices) return (*fPadBuffer);
376
377 AliMpMotifPosition* motifPos = FindMotifPosition(indices);
378 if (!motifPos) {
379 if (warning) Warning("PadByIndices","Pad indices not contained in any motif!");
380 return AliMpPad::Invalid();
381 }
382
383 // retrieve the local indices in the found motif
384 AliMpVMotif* motif = motifPos->GetMotif();
385 AliMpIntPair localIndices = indices - motifPos->GetLowIndicesLimit();
386
387 AliMpConnection* connection=
388 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
389
390 if (!connection){
391 if (warning) Warning("PadByIndices","No connection with the given indices!");
392 return AliMpPad::Invalid();
393 }
394
395 TVector2 localPos = motif->PadPositionLocal(localIndices);
396
397 return (*fPadBuffer)
398 = AliMpPad(AliMpIntPair(motifPos->GetID(),connection->GetGassiNum()),
399 indices,
400 motifPos->Position()+localPos,
401 motif->GetPadDimensions(localIndices));
402
403}
404//______________________________________________________________________________
405AliMpPad
406AliMpSectorSegmentation::PadByPosition(const TVector2& position,
407 Bool_t warning) const
408{
409// Find the pad which corresponds to the given position
410
411 if ((*fPadBuffer).Position().X()==position.X() &&
412 (*fPadBuffer).Position().Y()==position.Y()) return (*fPadBuffer);
413
414 Int_t motifPosID = fkSector->FindMotifPositionId(position);
415 AliMpMotifPosition* motifPos
416 = fkSector->GetMotifMap()
417 ->FindMotifPosition(motifPosID);
418
419 if (!motifPos){
420 if (warning) Warning("PadByPosition","Position outside limits");
421 return AliMpPad::Invalid();
422 }
423
424 AliMpVMotif* motif = motifPos->GetMotif();
425 AliMpIntPair localIndices
426 = motif->PadIndicesLocal(position-motifPos->Position());
427
428 AliMpConnection* connect =
429 motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
430
431 if (!connect){
432 if (warning) Warning("PadByPosition","Position outside motif limits");
433 return AliMpPad::Invalid();
434 }
435
436 return (*fPadBuffer)
437 = AliMpPad(AliMpIntPair(motifPosID,connect->GetGassiNum()),
438 motifPos->GlobalIndices(localIndices),
439 motifPos->Position()+motif->PadPositionLocal(localIndices),
440 motif->GetPadDimensions(localIndices));
441
442}
443
444//______________________________________________________________________________
445AliMpPad
446AliMpSectorSegmentation::PadByDirection(const TVector2& startPosition,
447 Double_t distance) const
448{
449// Find the first valid pad from starting position in the
450// direction of pad lines/columns up to the specified distance.
451// Pad lines are the lines of pads in the sector with constant pad y size,
452// pad columns are the columns of pads in the sector with constant pad x size.
453// ---
454
455 switch (fkSector->GetDirection()) {
456
457 case kX: return PadByYDirection(startPosition, distance);
458 ;;
459 case kY: return PadByXDirection(startPosition, distance);
460 ;;
461 }
462
463 Fatal("PadByDirection", "Incomplete switch on Sector direction");
464 return AliMpPad::Invalid();
465}
466
467//______________________________________________________________________________
468Bool_t AliMpSectorSegmentation::HasPad(const AliMpIntPair& indices) const
469{
470// Does the pad specified by <indices> exist ?
471// ---
472
473 return PadByIndices(indices,kFALSE) != AliMpPad::Invalid();
474}
475
476//______________________________________________________________________________
477Bool_t AliMpSectorSegmentation::HasMotifPosition(Int_t motifPositionID) const
478{
479// Does the motif position specified by motifPositionID exist ?
480// ---
481
482 return (fkSector->GetMotifMap()->FindMotifPosition(motifPositionID) != 0);
483}
484
485//______________________________________________________________________________
486TVector2 AliMpSectorSegmentation::GetMinPadDimensions() const
487{
488// Returnes the dimensions of the smallest pad.
489// ---
490
491 return fkSector->GetMinPadDimensions();
492}
493
494//______________________________________________________________________________
495Int_t AliMpSectorSegmentation::Zone(const AliMpPad& pad, Bool_t warning) const
496{
497// Returns the zone index of the zone containing the specified pad.
498// This zone index is different from the zone ID,
499// as it is unique for each pad dimensions.
500// It is composed in this way:
501// zoneID*10 + specific index
502// Specific index is present only for zones containing special motifs.
503// ---
504
505 if (!pad.IsValid()) {
506 if (warning) Warning("Zone(AliMpPad)", "Invalid pad");
507 return 0;
508 }
509
f79c58a5 510#ifdef WITH_STL
2998a151 511 PadDimensionsMapCIterator it;
5f91c9e8 512 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
513 if (AliMpConstants::IsEqual(it->second, pad.Dimensions()))
514 return it->first;
515 }
f79c58a5 516#endif
517
518#ifdef WITH_ROOT
519 PadDimensionsMapCIterator it(&fPadDimensionsMap);
520 Long_t key, value;
521 while ( it.Next(key, value) ) {
522 TVector2 dimensions = GetVector(value);
523 if (AliMpConstants::IsEqual(dimensions, pad.Dimensions()))
524 return (Int_t)key;
bcf37928 525 }
f79c58a5 526#endif
5f91c9e8 527
528 // Should never happen
bcf37928 529 Error("Zone(AliMpPad)", "not found");
530 cerr << pad << endl;
5f91c9e8 531 return 0;
532}
533
534//______________________________________________________________________________
535TVector2
536AliMpSectorSegmentation::PadDimensions(Int_t zone, Bool_t warning) const
537{
538// Returns the pad dimensions for the zone with the specified zone index.
539// ---
540
f79c58a5 541#ifdef WITH_STL
2998a151 542 PadDimensionsMapCIterator it = fPadDimensionsMap.find(zone);
5f91c9e8 543 if (it != fPadDimensionsMap.end()) return it->second;
f79c58a5 544#endif
545
546#ifdef WITH_ROOT
547 Long_t value = fPadDimensionsMap.GetValue(zone);
548 if (value) return GetVector(value);
549#endif
5f91c9e8 550
551 if (warning) Warning("PadDimensions(zone)", "not found");
552 return TVector2();
553}
554
555//______________________________________________________________________________
556Bool_t AliMpSectorSegmentation::CircleTest(const AliMpIntPair& indices) const
557{
558// Verifies that all methods for retrieving pads are consistents between them.
559// Returns true if the pad with specified indices was found and verified,
560// false otherwise.
561// ---
562
563 if (!HasPad(indices)) return false;
564
565 // Verify the indice->location->position->indice way
566 AliMpIntPair location = PadByIndices(indices).GetLocation();
567 TVector2 position = PadByLocation(location).Position();
568 AliMpIntPair retIndices = PadByPosition(position).GetIndices();
569
570 if (retIndices != indices) {
571 cout << "Pad " << indices << " lead to inconsistency" << endl;
572 cout << "in indice->location->position->indice way..." << endl;
573 cout << "starting from " << indices << "-->" << location << "-->"
574 << '(' << position.X() << ',' << position.Y() << ')'
575 << " and retIndices: " << retIndices << endl;
576 }
577
578
579 // Verify the indice->position->location->indice way
580 position = PadByIndices(indices).Position();
581 location = PadByPosition(position).GetLocation();
582 retIndices = PadByLocation(location).GetIndices();
583
584 if (retIndices != indices) {
585 cout << "Pad " << indices << " lead to inconsistency" << endl;
586 cout << "in indice->position->location->indice way..." <<endl;
587 cout << "starting from " << indices
588 << " and retIndices: " << retIndices << endl;
589 }
590
591 return true;
592}
bcf37928 593
594//______________________________________________________________________________
595void AliMpSectorSegmentation::PrintZones() const
596{
597// Prints all zones and pads dimensions from the map.
598// ---
599
600 cout << "Zones: " << endl;
601
602#ifdef WITH_STL
603 PadDimensionsMapCIterator it;
604 for (it = fPadDimensionsMap.begin(); it != fPadDimensionsMap.end(); ++it) {
605 cout << " zone: " << setw(4) << it->first;
606 cout << " pad dimensions: ( "
607 << it->second.X() << ", " << it->second.Y() << ")" << endl;
608 }
609#endif
610
611#ifdef WITH_ROOT
612 PadDimensionsMapCIterator it(&fPadDimensionsMap);
613 Long_t key, value;
614 while ( it.Next(key, value) ) {
615 //cout << "Iterating over: " << key << ", " << value << endl;
616 TVector2 dimensions = GetVector(value);
617
618 cout << " zone: " << setw(4) << key;
619 cout << " pad dimensions: ( "
620 << dimensions.X() << ", " << dimensions.Y() << ")" << endl;
621 }
622#endif
623}
624