]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONPainterContourMaker.cxx
AliHLTTPCCAMerger.cxx added to compilation
[u/mrichter/AliRoot.git] / MUON / AliMUONPainterContourMaker.cxx
CommitLineData
0145e89a 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
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**************************************************************************/
15
16// $Id$
17
18#include "AliMUONPainterContourMaker.h"
19
20#include "AliMUONPainterContour.h"
21#include "AliMUONPainterHelper.h"
22#include "AliMUONVCalibParam.h"
23#include "AliMUONVDigit.h"
24#include "AliMpConnection.h"
25#include "AliMpConstants.h"
26#include "AliMpDEManager.h"
27#include "AliMpExMap.h"
28#include "AliMpMotifMap.h"
29#include "AliMpMotifPosition.h"
30#include "AliMpMotifType.h"
31#include "AliMpSector.h"
0145e89a 32#include "AliMpSegmentation.h"
33#include "AliMpSlat.h"
0145e89a 34#include "AliMpStationType.h"
35#include "AliMpVMotif.h"
36#include "AliCodeTimer.h"
37#include "AliLog.h"
38#include <Riostream.h>
39#include <TArrayI.h>
40#include <TGeoMatrix.h>
41#include <TLine.h>
42#include <TMap.h>
43#include <TMath.h>
44#include <TMathBase.h>
45#include <TObjArray.h>
46#include <TPolyLine.h>
47#include <cassert>
48#include <float.h>
49
cec5da80 50/// \class AliMUONPainterContourMaker
0145e89a 51///
52/// A class to build painter contours.
53///
54/// The basics are to build one manu contour, and then to merge contours
55/// to build higher order objects, like PCBS, DEs, etc...
56///
cec5da80 57/// \author Laurent Aphecetche, Subatech
0145e89a 58
59///\cond CLASSIMP
60ClassImp(AliMUONPainterContourMaker)
61ClassImp(AliMUONPainterContourMaker::AliMUONNeighbour)
62///\endcond
63
64//_____________________________________________________________________________
65Int_t
66AliMUONPainterContourMaker::AliMUONNeighbour::Compare(const TObject* obj) const
67{
68 /// Compare two neighbours objects
69
70 const AliMUONNeighbour* n = static_cast<const AliMUONNeighbour*>(obj);
71
72 if ( Position().X() < n->Position().X() )
73 {
74 return -1;
75 }
76 else if ( Position().X() > n->Position().X() )
77 {
78 return 1;
79 }
80 else
81 {
82 // same X
83 if ( Position().Y() < n->Position().Y() )
84 {
85 return -1;
86 }
87 else if ( Position().Y() > n->Position().Y() )
88 {
89 return 1;
90 }
91 }
92 return 0;
93}
94
95//_____________________________________________________________________________
96void
97AliMUONPainterContourMaker::AliMUONNeighbour::Print(Option_t*) const
98{
99 /// Printout
100 cout << Form("ID %10d DE %4d Manu %4d Channel %2d "
101 "(X,Y)=(%7.3f,%7.3f) L,R,T,B=%1d,%1d,%1d,%1d",
102 ID(),
103 AliMUONVDigit::DetElemId(ID()),
104 AliMUONVDigit::ManuId(ID()),
105 AliMUONVDigit::ManuChannel(ID()),
106 Position().X(),Position().Y(),
107 HasLeftNeighbour(),HasRightNeighbour(),
108 HasTopNeighbour(),HasBottomNeighbour())
109 << endl;
110}
111
112//_____________________________________________________________________________
113AliMUONPainterContourMaker::AliMUONPainterContourMaker(AliMpExMap* globalTransformations)
114: TObject(),
115 fGlobalTransformations(globalTransformations),
116 fLocalManuContours(new TMap),
117 fContours(new TMap)
118{
119 /// ctor
120 fContours->SetOwner(kTRUE);
121}
122
123//_____________________________________________________________________________
124AliMUONPainterContourMaker::~AliMUONPainterContourMaker()
125{
126 /// dtor
127 fLocalManuContours->DeleteAll();
128 delete fLocalManuContours;
129 fContours->DeleteAll();
130 delete fContours;
131}
132
133//_____________________________________________________________________________
134void
135AliMUONPainterContourMaker::Add(AliMUONPainterContour* contour)
136{
137 /// Add a contour to our store of contours
138 fContours->Add(new TObjString(contour->GetName()),contour);
139}
140
141//_____________________________________________________________________________
142void
143AliMUONPainterContourMaker::AddSegment(TObjArray& segments, Double_t x1, Double_t y1,
144 Double_t x2, Double_t y2, Int_t id) const
145{
146 /// Add one segment defined by (x1,y1,x2,y2) to the array of segments
147 AliCodeTimerAuto("")
148 AliDebug(1,Form("AddSegment %7.3f,%7.3f -> %7.3f,%7.3f",x1,y1,x2,y2));
149 TLine* line = new TLine(x1,y1,x2,y2);
150 line->SetUniqueID(id);
151 segments.Add(line);
152}
153
154//_____________________________________________________________________________
155Bool_t
156AliMUONPainterContourMaker::HasLine(const TObjArray& segments,
157 const TLine& line) const
158{
159 /// Check whether line is already part of segments array
160
161 TIter next(&segments);
162 TLine* l;
163
164 while ( ( l = static_cast<TLine*>(next()) ) )
165 {
166 if ( IsEqual(line,*l) ) return kTRUE;
167 }
168
169 return kFALSE;
170}
171
172//_____________________________________________________________________________
173void
174AliMUONPainterContourMaker::AddSegments(TObjArray& segments,
175 const AliMUONPainterContour& contour) const
176
177{
178 /// Add all the segments (that are not already there)
179 /// of contour to the segments array
180
181 AliCodeTimerAuto("")
182
183 const TObjArray* pl = contour.AsPolyLines();
184
185 TIter next(pl);
186
187 Int_t n(0);
188
189 TPolyLine* line;
190
191 while ( ( line = static_cast<TPolyLine*>(next()) ) )
192 {
193 n += line->GetLastPoint();
194 }
195
196 AliDebug(1,Form("Adding %d groups (%d lines) from contour %s ",pl->GetLast()+1,n,contour.GetName()));
197
198 next.Reset();
199
200 while ( ( line = static_cast<TPolyLine*>(next()) ) )
201 {
202 AliDebug(1,"line=");
203// StdoutToAliDebug(1,line->Print(););
204 for ( Int_t i = 0; i < line->GetLastPoint(); ++i )
205 {
206 Double_t x1 = line->GetX()[i];
207 Double_t y1 = line->GetY()[i];
208 Double_t x2 = line->GetX()[i+1];
209 Double_t y2 = line->GetY()[i+1];
210
bf0d3528 211 TLine* l = new TLine(x1,y1,x2,y2);
0145e89a 212
bf0d3528 213 if ( !HasLine(segments,*l) )
0145e89a 214 {
bf0d3528 215 segments.Add(l);
216 AliDebug(1,Form("Adding line %s",LineAsString(*l).Data()));
0145e89a 217 }
218 else
219 {
bf0d3528 220 AliDebug(1,Form("Line %s is already there",LineAsString(*l).Data()));
0145e89a 221 }
222 }
223 }
224}
225
226//_____________________________________________________________________________
227AliMUONPainterContour*
228AliMUONPainterContourMaker::ConvertEdgePadsToContour(TObjArray& ePads,
229 const char* name) const
230{
231 /// Convert an array of edge pads into a contour of a given name
232
233 AliCodeTimerAuto("")
234
235 ePads.Sort();
236
237 AliDebug(1,Form("%d pads to convert:",ePads.GetEntries()));
238// StdoutToAliDebug(1,ePads.Print();)
239
240 TObjArray segments;
241 segments.SetOwner(kTRUE);
242
243 TIter nextPad(&ePads);
244 AliMUONNeighbour* ne;
245
246 while ( ( ne = static_cast<AliMUONNeighbour*>(nextPad()) ) )
247 {
248 Int_t id = ne->ID();
249
250 if ( ! ne->HasLeftNeighbour() )
251 {
252 AddSegment(segments,ne->LowerLeft().X(),ne->LowerLeft().Y(),
253 ne->LowerLeft().X(),ne->UpperRight().Y(),id);
254 }
255 if ( ! ne->HasRightNeighbour() )
256 {
257 AddSegment(segments,ne->UpperRight().X(),ne->LowerLeft().Y(),
258 ne->UpperRight().X(),ne->UpperRight().Y(),id);
259 }
260 if ( ! ne->HasTopNeighbour() )
261 {
262 AddSegment(segments,ne->LowerLeft().X(),ne->UpperRight().Y(),
263 ne->UpperRight().X(),ne->UpperRight().Y(),id);
264 }
265 if ( ! ne->HasBottomNeighbour() )
266 {
267 AddSegment(segments,ne->LowerLeft().X(),ne->LowerLeft().Y(),
268 ne->UpperRight().X(),ne->LowerLeft().Y(),id);
269 }
270 }
271
272 return ConvertSegmentsToContour(segments,name);
273}
274
275//_____________________________________________________________________________
276void
277AliMUONPainterContourMaker::PrintLine(const TLine& line, const char* msg) const
278{
279 /// Printout of a line
280 cout << Form("%10s %s",
281 msg,LineAsString(line).Data()) << endl;
282}
283
284//_____________________________________________________________________________
285TString
286AliMUONPainterContourMaker::LineAsString(const TLine& line, Bool_t slope) const
287{
288 /// Return a string representation of the line
289
290 TString rv(Form("%7.3f,%7.3f -> %7.3f,%7.3f",
291 line.GetX1(),line.GetY1(),
292 line.GetX2(),line.GetY2()));
293
294 if ( slope )
295 {
296 if ( IsHorizontal(line) ) rv += " H";
297 else if ( IsVertical(line) ) rv += " V";
298 else rv += Form(" (slope %e)",Slope(line));
299 }
300
301 return rv;
302}
303
304//_____________________________________________________________________________
305void
306AliMUONPainterContourMaker::PrintSegments(const TObjArray& segments) const
307{
308 /// Printout of segment arrays (debug)
309
310 for ( Int_t i = 0; i <= segments.GetLast(); ++i )
311 {
312 TLine* l = static_cast<TLine*>(segments.UncheckedAt(i));
313
314 cout << Form("***--- i %4d",i);
315 if ( l )
316 {
317 PrintLine(*l);
318 }
319 else
320 {
321 cout << " line is null ?" << endl;
322 }
323 }
324}
325
326//_____________________________________________________________________________
327TLine*
328AliMUONPainterContourMaker::AddToLine(TPolyLine& line, TObjArray& segments, Int_t i) const
329{
330 /// Add one segment (taken from position i in array) into polyline
331
332 AliDebug(1,Form("i=%d",i));
333 TLine* l = static_cast<TLine*>(segments.UncheckedAt(i));
334 if (l)
335 {
336 line.SetNextPoint(l->GetX1(),l->GetY1());
337 line.SetNextPoint(l->GetX2(),l->GetY2());
338 }
339 else
340 {
341 AliError(Form("Did not find the line at i=%d",i));
342 PrintSegments(segments);
343 }
344 return l;
345}
346
347//_____________________________________________________________________________
348Int_t
349AliMUONPainterContourMaker::FindPoint(Double_t x, Double_t y,
350 TObjArray& segments) const
351{
352 /// Find if point (x,y) is in segments array, and return
353 /// its index (=position within array)
354
355 TIter next(&segments);
356 TLine* l;
357
358 while ( ( l = static_cast<TLine*>(next()) ) )
359 {
360 if ( IsEqual(l->GetX1(),x) && IsEqual(l->GetY1(),y) )
361 {
362 return segments.IndexOf(l);
363 }
364 }
365 AliError(Form("Did not find point %7.3f %7.3f in those segments:",x,y));
366// StdoutToAliDebug(1,PrintSegments(segments););
367 return -1;
368}
369
370//_____________________________________________________________________________
371AliMUONPainterContour*
372AliMUONPainterContourMaker::ConvertSegmentsToContour(TObjArray& segments,
373 const char* name) const
374{
375 /// Convert an array of segments into a contour
376
377 AliDebug(1,"");
378 AliCodeTimerAuto("");
379
380 AliMUONPainterContour* contour = new AliMUONPainterContour(name);
381
382 Int_t n(0); // this is a protection against infinite loop (used for debug only)
383
384 while ( segments.GetLast() >= 0 && n < 100 )
385 {
386 TPolyLine lines;
387 TIter next(&segments);
388 TLine* l;
389
390 while ( ( l = static_cast<TLine*>(next() ) ) )
391 {
392 TLine* inserted = InsertSegment(lines,*l);
393 if ( inserted )
394 {
395 segments.Remove(inserted);
396 next.Reset();
397 }
398
399 // check for closure
400 if ( IsLineClosed(lines) )
401 {
402 AliDebug(1,"Line closed. Starting a new one");
403 break;
404 }
405 }
406
407 TPolyLine* sl = Simplify(lines);
408
409 contour->AdoptPolyLine(sl);
410 ++n;
411 }
412
413 if ( segments.GetLast() >= 0 )
414 {
415 AliError("segment should be empty by now");
416// StdoutToAliError(PrintSegments(segments););
417 }
418
419 return contour;
420}
421
422//_____________________________________________________________________________
423Int_t
424AliMUONPainterContourMaker::FindPoint(const TPolyLine& lines, Double_t x, Double_t y) const
425{
426 /// Return position of (x,y) within the polyline
427
428 AliCodeTimerAuto("")
429
430 for ( Int_t i = 0; i < lines.Size(); ++i )
431 {
432 if ( IsEqual(lines.GetX()[i],x) && IsEqual(lines.GetY()[i],y) )
433 {
434 return i;
435 }
436 }
437 return -1;
438}
439
440//_____________________________________________________________________________
441void
442AliMUONPainterContourMaker::CleanSegments(TObjArray& segments,
443 const TArrayI& toBeRemoved) const
444{
445 /// Remove segments at indices stored in toBeRemoved array
446 for ( Int_t i = 0; i < toBeRemoved.GetSize(); ++i )
447 {
448 if ( toBeRemoved[i] )
449 {
450 segments.RemoveAt(i);
451 }
452 }
453 segments.Compress();
454}
455
456//_____________________________________________________________________________
457Int_t
458AliMUONPainterContourMaker::SplitSegments(TObjArray& segments) const
459{
460 /// Split segments that have partial overlap
461
462 AliCodeTimerAuto("")
463
464 TArrayI toBeRemoved(segments.GetLast()+1);
465 toBeRemoved.Reset(0);
466 Bool_t added(kFALSE);
467
468 for ( Int_t i = 0; i <= segments.GetLast() && !added; ++i )
469 {
470 if ( toBeRemoved[i] ) continue;
471
472 TLine* li = static_cast<TLine*>(segments.UncheckedAt(i));
473
474 for ( Int_t j = i+1; j <= segments.GetLast() && !added; ++j )
475 {
476 if ( toBeRemoved[j] ) continue;
477
478 TLine* lj = static_cast<TLine*>(segments.UncheckedAt(j));
479
480 Int_t o = Overlap(*li,*lj);
481
482 if ( o )
483 {
484 toBeRemoved[i] = toBeRemoved[j] = 1;
485
486 Double_t x[] = { li->GetX1(), lj->GetX1(), li->GetX2(), lj->GetX2() };
487 Double_t y[] = { li->GetY1(), lj->GetY1(), li->GetY2(), lj->GetY2() };
488
489 Double_t xmin(FLT_MAX), ymin(FLT_MAX);
490 Double_t xmax(-FLT_MAX), ymax(-FLT_MAX);
491
bf0d3528 492 for ( Int_t k = 0; k < 4; ++k )
0145e89a 493 {
bf0d3528 494 xmin = TMath::Min(x[k],xmin);
495 ymin = TMath::Min(y[k],ymin);
496 xmax = TMath::Max(x[k],xmax);
497 ymax = TMath::Max(y[k],ymax);
0145e89a 498 }
499
500 TLine fullLine(xmin,ymin,xmax,ymax);
501
bf0d3528 502 for ( Int_t i1 = 0; i1 < 4; ++i1 )
0145e89a 503 {
bf0d3528 504 for ( Int_t j1 = i1+1; j1 < 4; ++j1 )
0145e89a 505 {
bf0d3528 506 if ( TMath::Abs(i1-j1) != 2 )
0145e89a 507 {
bf0d3528 508 TLine test(x[i1],y[i1],x[j1],y[j1]);
0145e89a 509
510 Bool_t isFullLine = IsEqual(test,fullLine);
511
512 if ( !IsPoint(test) && !isFullLine )
513 {
514 segments.Add(new TLine(test));
515 added = kTRUE;
516 }
517 }
518 }
519 }
520 }
521 }
522 }
523
524 CleanSegments(segments,toBeRemoved);
525
526 return added;
527}
528
529//_____________________________________________________________________________
530Bool_t
531AliMUONPainterContourMaker::ShouldBeRemoved(const TObjArray& contours,
532 Double_t x, Double_t y) const
533{
534 /// Tells whether or not a point can be removed, because it lies
535 /// inside the global contour
536
537 const Double_t kPrecision(AliMpConstants::LengthTolerance());
538 const Double_t kShiftX[] = { kPrecision,kPrecision,-kPrecision,-kPrecision };
539 const Double_t kShiftY[] = { kPrecision,-kPrecision,kPrecision,-kPrecision };
540
541 TIter next(&contours);
542 AliMUONPainterContour* contour;
543
544 Int_t n(0);
545
546 while ( ( contour = static_cast<AliMUONPainterContour*>(next()) ) )
547 {
548 for ( Int_t i = 0; i < 4; ++i )
549 {
550 if ( contour->IsInside( x + kShiftX[i], y + kShiftY[i]) )
551 {
552 ++n;
553 }
554 }
555 }
556
557 return (n>=4);
558}
559
560//_____________________________________________________________________________
561Int_t
562AliMUONPainterContourMaker::RemoveInsideSegments(const TObjArray& contours,
563 TObjArray& segments) const
564{
565 /// Remove segments that have 2 triple points
566
567 AliCodeTimerAuto("")
568
569 TArrayI toBeRemoved(segments.GetLast()+1);
570 toBeRemoved.Reset(0);
571
572 for ( Int_t i = 0; i <= segments.GetLast(); ++i )
573 {
574 TLine* line = static_cast<TLine*>(segments.UncheckedAt(i));
575
576 Double_t x = (line->GetX1() + line->GetX2())/2.0;
577 Double_t y = (line->GetY1() + line->GetY2())/2.0;
578
579 if ( ShouldBeRemoved(contours,x,y) )
580 {
581 toBeRemoved[i] = 1;
582 }
583 }
584
585 Int_t before = segments.GetLast()+1;
586
587 CleanSegments(segments,toBeRemoved);
588
589 Int_t after = segments.GetLast()+1;
590
591 AliDebug(1,Form("# of segments before = %d after = %d",before,after));
592
593 return after-before;
594}
595
596//_____________________________________________________________________________
597AliMUONPainterContour*
598AliMUONPainterContourMaker::MergeContours(const TObjArray& contours,
599 const char* contourName) const
600{
601 /// Merge an array of contours into a single contour, with a given name
602
603 AliCodeTimerAuto("");
604
605 AliDebug(1,Form("Merging %d contours into %s",contours.GetLast()+1,contourName));
606
607 if ( contours.GetSize() == 0 ) return 0x0;
608
609 TIter next(&contours);
610 AliMUONPainterContour* contour;
611
612 TObjArray segments;
613 segments.SetOwner(kTRUE);
614
615 while ( ( contour = static_cast<AliMUONPainterContour*>(next()) ) )
616 {
617 AddSegments(segments,*contour);
618 }
619
620// AliDebug(1,"After AddSegments");
621// StdoutToAliDebug(1,PrintSegments(segments));
622
94bf739c 623 while (SplitSegments(segments)) {}
0145e89a 624
625// AliDebug(1,"After SplitSegments");
626// StdoutToAliDebug(1,PrintSegments(segments));
627
628// if (!SanityCheck(contours,segments))
629// {
630// return 0x0;
631// }
632
633 RemoveInsideSegments(contours,segments);
634
635// if (!SanityCheck(contours,segments))
636// {
637// return 0x0;
638// }
639
640// AliDebug(1,"After RemoveInsideSegments");
641// StdoutToAliDebug(1,PrintSegments(segments););
642
643// if (!SanityCheck(contours,segments))
644// {
645// return 0x0;
646// }
647
648 return ConvertSegmentsToContour(segments,contourName);
649}
650
651//_____________________________________________________________________________
652TString
653AliMUONPainterContourMaker::NameIt(const AliMpMotifPosition& motifPosition) const
654{
655 /// Get the name of an AliMpMotifPosition
656
657 AliMpVMotif* motif = motifPosition.GetMotif();
658 TString name(Form("%s",motif->GetID().Data()));
659
660 for ( Int_t i = 0; i < motif->GetNofPadDimensions(); ++i )
661 {
662 TVector2 padDim = motif->GetPadDimensions(i);
663 name += Form("/%7.3f-%7.3f:",padDim.X(),padDim.Y());
664 }
665 return name;
666}
667
668//_____________________________________________________________________________
669AliMUONPainterContour*
670AliMUONPainterContourMaker::FindLocalManuContour(Int_t detElemId, Int_t manuId) const
671{
672 /// Get a pre-computed manu contour (in local coordinates)
673 AliCodeTimerAuto("")
674
675 AliMpMotifPosition* motifPos = FindMotifPosition(detElemId,manuId);
676
677 TObject* o = fLocalManuContours->GetValue(NameIt(*motifPos));
678
679 if (o) return static_cast<AliMUONPainterContour*>(o);
680 return 0x0;
681}
682
683//_____________________________________________________________________________
684AliMpMotifPosition*
685AliMUONPainterContourMaker::FindMotifPosition(Int_t detElemId, Int_t manuId) const
686{
687 /// Find a given motifPosition object
688
689 AliCodeTimerAuto("")
690
0145e89a 691 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
692
693 if ( stationType == AliMp::kStation345 )
694 {
f3ed9a44 695 const AliMpSlat* kSlat
696 = AliMpSegmentation::Instance()->GetSlatByElectronics(detElemId,manuId);
697 if ( ! kSlat ) {
698 AliFatal(Form("Could not find motif for DE %d manu %d",detElemId,manuId));
699 }
700 return kSlat->FindMotifPosition(manuId);
0145e89a 701 }
702 else
703 {
f3ed9a44 704 const AliMpSector* kSector
705 = AliMpSegmentation::Instance()->GetSectorByElectronics(detElemId,manuId);
706 if ( ! kSector ) {
707 AliFatal(Form("Could not find motif for DE %d manu %d",detElemId,manuId));
708 }
709 return kSector->GetMotifMap()->FindMotifPosition(manuId);
0145e89a 710 }
711 return 0x0;
712}
713
714//_____________________________________________________________________________
715AliMUONPainterContour*
716AliMUONPainterContourMaker::GenerateManuContour(const char* name,
717 Int_t detElemId, Int_t manuId,
718 AliMUONAttPainter viewType) const
719{
720 /// Generate the contour for a given manu
721
722 AliDebug(3,Form("DE %04d ManuID %04d Name %s",detElemId,manuId,name));
723
724 AliCodeTimerAuto("")
725
726 AliMpMotifPosition* motifPosition = FindMotifPosition(detElemId,manuId);
727 AliMpVMotif* motif = motifPosition->GetMotif();
728
729 AliMUONPainterContour* contour = FindLocalManuContour(detElemId,manuId);
730 // do we already have the local contour for that manu ?
731
732 // no : build it
733 if (!contour)
734 {
735 AliCodeTimerAuto("Generation of local contour");
736 TObjArray ePads;
737 ePads.SetOwner(kTRUE);
738 AliMpMotifType* motifType = motif->GetMotifType();
739 AliDebug(3,Form("motifType %s",motifType->GetID().Data()));
740
741// for ( Int_t i = 0; i <= motifType->GetNofPads(); ++i )
742 for ( Int_t i = 0; i <= AliMpConstants::ManuNofChannels(); ++i )
743 {
744// AliMpConnection* connection = motifType->FindConnectionByPadNum(i);
745 AliMpConnection* connection = motifType->FindConnectionByGassiNum(i);
746
747 AliDebug(3,Form("connection i =%d",i));
748
749 if ( connection )
750 {
168e9c4d 751 Int_t ix = connection->GetLocalIx();
752 Int_t iy = connection->GetLocalIy();
0145e89a 753 Bool_t left(kTRUE);
754 Bool_t right(kTRUE);
755 Bool_t top(kTRUE);
756 Bool_t bottom(kTRUE);
757
168e9c4d 758 if ( ! motifType->FindConnectionByLocalIndices(ix+1, iy) )
0145e89a 759 {
760 right = kFALSE;
761 }
168e9c4d 762 if ( ! motifType->FindConnectionByLocalIndices(ix-1, iy) )
0145e89a 763 {
764 left = kFALSE;
765 }
168e9c4d 766 if ( ! motifType->FindConnectionByLocalIndices(ix, iy+1) )
0145e89a 767 {
768 top = kFALSE;
769 }
168e9c4d 770 if ( ! motifType->FindConnectionByLocalIndices(ix, iy-1) )
0145e89a 771 {
772 bottom = kFALSE;
773 }
774
775 AliDebug(3,Form("indices=(%3d,%3d) L %d R %d T %d B %d",
168e9c4d 776 ix,iy, left,right,top,bottom));
0145e89a 777
168e9c4d 778 TVector2 position = motif->PadPositionLocal(ix,iy);
779 TVector2 dimensions = motif->GetPadDimensionsByIndices(ix, iy);
0145e89a 780
781 if ( !left || !right || !top || !bottom )
782 {
783 // the pad is on the edge
784 Int_t id = AliMUONVDigit::BuildUniqueID(detElemId,manuId,
34ee05d7 785 connection->GetManuChannel(),0);
0145e89a 786 ePads.AddLast(new AliMUONNeighbour(id,position,dimensions,left,right,top,bottom));
787 }
788 }
789 }
790
791 contour = ConvertEdgePadsToContour(ePads,NameIt(*motifPosition));
792
793 AliDebug(1,Form("localContour:"));
794// StdoutToAliDebug(1,contour->Print("full"));
795 // register the local contour
796 fLocalManuContours->Add(new TObjString(contour->GetName()),contour);
797 }
798
799 AliMUONPainterContour* globalContour = static_cast<AliMUONPainterContour*>(contour->Clone(name));
800
801 // once we have the local contour, convert it to global
802
803 TVector2 pos(motifPosition->Position());
804
805 if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
806 {
807 const AliMpSlat* slat = AliMUONPainterHelper::Instance()->GetSlat(detElemId,manuId);
808 pos -= slat->Position();
809 }
810 globalContour->Offset(pos);
811 TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(fGlobalTransformations->GetValue(detElemId));
812 globalContour->Transform(*matrix);
813
814 if ( viewType.IsBackView() )
815 {
816 AliWarning("Got a back view : will rotate ! This has not been really tested. Please do so now !");
817 TGeoRotation rot;
818 rot.RotateZ(180);
819 globalContour->Transform(rot);
820 }
821
822 return globalContour;
823}
824
825//_____________________________________________________________________________
826AliMUONPainterContour*
827AliMUONPainterContourMaker::GetContour(const char* name) const
828{
829 /// Get contour by name
830
831 TObject* o = fContours->GetValue(name);
832 return static_cast<AliMUONPainterContour*>(o);
833}
834
835//_____________________________________________________________________________
836Bool_t
837AliMUONPainterContourMaker::HasContour(const char* name) const
838{
839 /// Whether contour named "name" exists
840 TObject* o = fContours->GetValue(name);
841 if (o) return kTRUE;
842 return kFALSE;
843}
844
845//_____________________________________________________________________________
846TLine*
847AliMUONPainterContourMaker::InsertSegment(TPolyLine& lines, TLine& l) const
848{
849 /// Insert line into polyline, at the correct position
850
851 AliCodeTimerAuto("")
852// AliDebug(2,Form("Trying to insert %7.3f,%7.3f -> %7.3f,%7.3f from "
853// "(DE,manu,ch)=(%d,%d,%d) into",
854// l.GetX1(),l.GetY1(),l.GetX2(),l.GetY2(),
855// AliMUONVDigit::DetElemId(l.GetUniqueID()),
856// AliMUONVDigit::ManuId(l.GetUniqueID()),
857// AliMUONVDigit::ManuChannel(l.GetUniqueID())));
858
859 if ( lines.Size()==0 )
860 {
861// AliDebug(2,"Starting line");
862//
863 lines.SetNextPoint(l.GetX1(),l.GetY1());
864 lines.SetNextPoint(l.GetX2(),l.GetY2());
865 return &l;
866 }
867
868 Int_t i1 = FindPoint(lines,l.GetX1(),l.GetY1());
869 Int_t i2 = FindPoint(lines,l.GetX2(),l.GetY2());
870
871 if ( i1 < 0 && i2 < 0 )
872 {
873// AliDebug(2,"Not yet");
874 return 0x0;
875 }
876
877 if ( i1 >= 0 && i2 >= 0 )
878 {
879 if ( i1==0 )
880 {
881 lines.SetNextPoint(l.GetX1(),l.GetY1());
882 }
883 else if ( i2==0 )
884 {
885 lines.SetNextPoint(l.GetX2(),l.GetY2());
886 }
887 else
888 {
889 AliError("Segment already there but does not correspond to ending the polyline !");
890 AliError(Form("Segment is %7.3f,%7.3f -> %7.3f,%7.3f and existing points are : ",
891 l.GetX1(),l.GetY1(),l.GetX2(),l.GetY2()));
892
893 for ( Int_t i = 0; i < lines.Size(); ++i )
894 {
895 AliError(Form("Point %2d X %7.3f Y %7.3f",i,lines.GetX()[i],lines.GetY()[i]));
896 }
897// TObject* o(0x0);
898// o->Print(); // to crash and throw gdb...
899 }
900 return &l;
901 }
902
903 Double_t x = (i1>=0) ? l.GetX2() : l.GetX1();
904 Double_t y = (i1>=0) ? l.GetY2() : l.GetY1();
905
906 Int_t iref = ( i1 >= 0 ? i1 : i2 ) ;
907
908 Bool_t firstPoint = ( iref == 0 );
909
910 if ( firstPoint )
911 {
912 // must insert segment before
913 lines.SetPolyLine(lines.Size()+1);
914// AliDebug(2,Form("Inserting %7.3f,%7.3f",x,y));
915 for ( Int_t i = lines.Size()-1; i > 0; --i )
916 {
917 lines.SetPoint(i,lines.GetX()[i-1],lines.GetY()[i-1]);
918 }
919 lines.SetPoint(0,x,y);
920 }
921 else
922 {
923// AliDebug(2,Form("Appending %7.3f,%7.3f",x,y));
924 lines.SetNextPoint(x,y);
925 }
926
927 return &l;
928}
929
930//_____________________________________________________________________________
931Bool_t
932AliMUONPainterContourMaker::IsEqual(Double_t x, Double_t y) const
933{
934 /// Whether x==y
935
936 if ( TMath::Abs(x-y) < AliMpConstants::LengthTolerance() ) return kTRUE;
937 else return kFALSE;
938}
939
940//_____________________________________________________________________________
941Bool_t
942AliMUONPainterContourMaker::IsEqual(const TLine& line1,
943 const TLine& line2) const
944{
945 /// Whether line1 == line2
946
947 Bool_t check1 =
948 IsEqual(line1.GetX1(),line2.GetX1()) &&
949 IsEqual(line1.GetY1(),line2.GetY1()) &&
950 IsEqual(line1.GetX2(),line2.GetX2()) &&
951 IsEqual(line1.GetY2(),line2.GetY2());
952
953 Bool_t check2 =
954 IsEqual(line1.GetX1(),line2.GetX2()) &&
955 IsEqual(line1.GetY1(),line2.GetY2()) &&
956 IsEqual(line1.GetX2(),line2.GetX1()) &&
957 IsEqual(line1.GetY2(),line2.GetY1());
958
959 return (check1 || check2);
960}
961
962//_____________________________________________________________________________
963Double_t
964AliMUONPainterContourMaker::Slope(const TLine& line) const
965{
966 /// Get the slope of line
967
968 Double_t x = TMath::Abs(line.GetX2() - line.GetX1());
969
970 if ( x < AliMpConstants::LengthTolerance() ) return FLT_MAX;
971
972 return TMath::Abs(line.GetY2() - line.GetY1())/x;
973}
974
975//_____________________________________________________________________________
976Bool_t
977AliMUONPainterContourMaker::IsPoint(const TLine& line) const
978{
979 /// Whether the line is a point (sic ;-) )
980 return
981 IsEqual(line.GetX1(),line.GetX2()) &&
982 IsEqual(line.GetY1(),line.GetY2());
983}
984
985//_____________________________________________________________________________
986TLine
987AliMUONPainterContourMaker::Shift(const TLine& line, Double_t x, Double_t y) const
988{
989 /// Shift the line by a given offset
990
991 return TLine(line.GetX1()-x,line.GetY1()-y,line.GetX2()-x,line.GetY2()-y);
992}
993
994//_____________________________________________________________________________
995Bool_t
996AliMUONPainterContourMaker::SameDirection(const TLine& line1, const TLine& line2) const
997{
998 /// Whether both lines have the same direction.
999
1000 TLine l1 = Shift(line1,line1.GetX1(),line1.GetY1());
1001 TLine l2 = Shift(line2,line2.GetX1(),line2.GetY1());
1002
1003 Double_t v = l1.GetX2()*l2.GetX2() + l1.GetY2()*l2.GetY2();
1004
1005 return v > 0 ;
1006}
1007
1008//_____________________________________________________________________________
1009void
1010AliMUONPainterContourMaker::Swap(TLine& line) const
1011{
1012 /// Swap both points of the line
1013
1014 Double_t x = line.GetX1();
1015 Double_t y = line.GetY1();
1016
1017 line.SetX1(line.GetX2());
1018 line.SetY1(line.GetY2());
1019 line.SetX2(x);
1020 line.SetY2(y);
1021}
1022
1023//_____________________________________________________________________________
1024Int_t
1025AliMUONPainterContourMaker::IsInRange(Double_t x, Double_t a, Double_t b,
1026 Bool_t strict) const
1027{
1028 /// Whether w is in [a,b] (if strict=kFALSE) or in ]a,b[ (if strict=kTRUE)
1029
1030 if ( a > b )
1031 {
1032 Double_t tmp(b);
1033 b = a;
1034 a = tmp;
1035 }
1036
1037 Bool_t rv(kFALSE);
1038
1039 if ( strict )
1040 {
1041 rv = ( x > a && x < b );
1042 }
1043 else
1044 {
1045 rv = ( x >= a && x <= b);
1046 }
1047
1048 AliDebug(4,Form("x = %7.3f a = %7.3f b = %7.3f strict = %d IsInRange = %d",x,a,b,strict,rv));
1049
1050 return rv;
1051}
1052
1053//_____________________________________________________________________________
1054Int_t
1055AliMUONPainterContourMaker::IsInLine(const TLine& line,
1056 Double_t x,
1057 Double_t y,
1058 Bool_t strict) const
1059{
1060 /// Check whether point (x,y) is belonging to the line segment
1061 /// by computing the distance point to line
1062 /// line1 must not be a single point.
1063 /// Returns the number of *coordinates* that matches, for a point
1064 /// that lies on line (if point is not on the line, returns 0 always).
1065 /// For instance, if (x,y) is on the line (and strict=kFALSE),
1066 /// it will return 1 if x *or* y corresponds to line.GetX1() or X2 or Y1 or Y2,
1067 /// and 2 if the pair (x,y) corresponds to one of the line points.
1068
1069 Double_t x1 = line.GetX1();
1070 Double_t x2 = line.GetX2();
1071 Double_t y1 = line.GetY1();
1072 Double_t y2 = line.GetY2();
1073
1074 Double_t distance = TMath::Abs( (x2-x1)*(y1-y) - (x1-x)*(y2-y1) );
1075
1076 distance /= TMath::Sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
1077
1078 Bool_t online = ( distance < AliMpConstants::LengthTolerance() ) ;
1079
1080 Int_t rv(0);
1081
1082 if (online)
1083 {
1084 // point is on the line,
1085 // check in addition that it's within the segment
1086
1087 rv = IsInRange(x,x1,x2,strict) + IsInRange(y,y1,y2,strict);
1088 }
1089 else
1090 {
1091 rv = 0;
1092 }
1093
1094 AliDebug(4,Form("Point (%7.3f,%7.3f) isinline=%d in line %s",
1095 x,y,rv,LineAsString(line).Data()));
1096
1097 return rv;
1098}
1099
1100//_____________________________________________________________________________
1101Int_t
1102AliMUONPainterContourMaker::IsInside(const TLine& line1,
1103 const TLine& line2,
1104 Bool_t useEndPoints) const
1105{
1106 /// Check whether one or both points of line2 are within line1.
1107 /// Both line1 and line2 must have the same slope
1108 /// and the same direction
1109
1110 if (!IsEqual(Slope(line1),Slope(line2))) return 0;
1111
1112 TLine l2(line2);
1113
1114 if (!SameDirection(line1,line2))
1115 {
1116 Swap(l2);
1117 }
1118
1119 Int_t rv =
1120 IsInLine(line1,l2.GetX1(),l2.GetY1(),!useEndPoints) +
1121 IsInLine(line1,l2.GetX2(),l2.GetY2(),!useEndPoints);
1122
1123 assert(rv<=4);
1124
1125 return rv;
1126}
1127
1128//_____________________________________________________________________________
1129Bool_t
1130AliMUONPainterContourMaker::IsInside(const TObjArray& segments,
1131 const TLine& line) const
1132{
1133 /// Whether the segment (line) is contained inside the contour defined
1134 /// by all the segments (i.e. is it on the boundary or not)
1135 /// Basic (and dirty) implementation only working with horizontal and vertical lines.
1136 /// I know there must be a better way to do it, but it took me way too long
1137 /// to get this stuff working, so I'm giving up on the optimisation/cleaning,
1138 /// at least for now...
1139 /// If you'd like to clean this (while keeping it working in all cases), be
1140 /// my guest and do it ;-) )
1141
1142 Int_t p1 = CountPoint(segments,line.GetX1(),line.GetY1());
1143 Int_t p2 = CountPoint(segments,line.GetX2(),line.GetY2());
1144
1145 Bool_t triplet = ( p1 >= 3 || p2 >= 3 );
1146
1147 AliDebug(4,Form("IsInside(segments,%s) triplet=%d",
1148 LineAsString(line).Data(),triplet));
1149
1150 if (!triplet) return kFALSE;
1151
1152 Bool_t top(kFALSE), bottom(kFALSE), left(kFALSE), right(kFALSE);
1153
1154 Bool_t vertical(IsVertical(line));
1155 Bool_t horizontal(IsHorizontal(line));
1156
1157 if (!vertical && !horizontal )
1158 {
1159 AliFatal("Only working with horizontal and vertical lines");
1160 }
1161
1162 for ( Int_t i = 0; i <= segments.GetLast(); ++i )
1163 {
1164 TLine* l = static_cast<TLine*>(segments.UncheckedAt(i));
1165
1166 if ( IsEqual(*l,line) ) continue;
1167
1168 if ( vertical && IsVertical(*l) )
1169 {
1170 TLine tmpLine(l->GetX1(),line.GetY1(),
1171 l->GetX1(),line.GetY2());
1172
1173 AliDebug(4,Form("i=%2d VV\nIsInside(l=%s,%s)=%d\nIsInside(%s,l=%s)=%d",
1174 i,
1175 LineAsString(*l).Data(),LineAsString(tmpLine).Data(),
1176 IsInside(*l,tmpLine,kTRUE),
1177 LineAsString(tmpLine).Data(),LineAsString(*l).Data(),
1178 IsInside(tmpLine,*l,kTRUE)));
1179
1180 if ( IsInside(*l,tmpLine,kTRUE) == 4 || IsInside(tmpLine,*l,kTRUE) == 4 )
1181 {
1182 if ( l->GetX1() > line.GetX1() )
1183 {
1184 right = kTRUE;
1185 }
1186 else
1187 {
1188 left = kTRUE;
1189 }
1190 }
1191 }
1192
1193 if ( vertical && IsHorizontal(*l) )
1194 {
1195 if ( !IsEqual(l->GetY1(),line.GetX1()) &&
1196 !IsEqual(l->GetY1(),line.GetY2()) &&
1197 IsInLine(*l,line.GetX1(),l->GetY1(),kFALSE)==2 )
1198 {
1199 if ( line.GetY2() < l->GetY1() )
1200 {
1201 top = kTRUE;
1202 }
1203 else if ( line.GetY2() > l->GetY1() )
1204 {
1205 bottom = kTRUE;
1206 }
1207 }
1208 }
1209
1210 if ( horizontal && IsHorizontal(*l) )
1211 {
1212 TLine tmpLine(line.GetX1(),l->GetY1(),
1213 line.GetX2(),l->GetY1());
1214
1215 AliDebug(4,Form("i=%2d HH\nIsInside(%s,%s)=%d\nIsInside(%s,%s)=%d",
1216 i,
1217 LineAsString(*l).Data(),LineAsString(tmpLine).Data(),
1218 IsInside(*l,tmpLine),
1219 LineAsString(tmpLine).Data(),LineAsString(*l).Data(),
1220 IsInside(tmpLine,*l)));
1221
1222 if ( IsInside(*l,tmpLine) == 4 || IsInside(tmpLine,*l) == 4 )
1223 {
1224 if ( l->GetY1() > line.GetY1() )
1225 {
1226 top = kTRUE;
1227 }
1228 else
1229 {
1230 bottom = kTRUE;
1231 }
1232 }
1233 }
1234
1235 if ( horizontal && IsVertical(*l) )
1236 {
1237 if ( !IsEqual(l->GetX1(),line.GetX1()) &&
1238 !IsEqual(l->GetX1(),line.GetX2()) &&
1239 IsInLine(*l,l->GetX1(),line.GetY1(),kFALSE)==2 )
1240 {
1241 if ( line.GetX2() < l->GetX1() )
1242 {
1243 right = kTRUE;
1244 }
1245 else if ( line.GetX2() > l->GetX1() )
1246 {
1247 left = kTRUE;
1248 }
1249 }
1250 }
1251
1252 }
1253
1254 Bool_t rv(kFALSE);
1255
1256 AliDebug(3,Form("%s %s R %d L %d T %d B% d IsInside %d",
1257 IsVertical(line) ?
1258 "Vertical " :
1259 "Horizontal",
1260 LineAsString(line,kFALSE).Data(),right,left,top,bottom,rv));
1261
1262 if ( vertical )
1263 {
1264 rv = (right && left) && ( top || bottom );
1265 }
1266
1267 if ( horizontal )
1268 {
1269 rv = (top && bottom) && ( right || left );
1270 }
1271
1272 return rv;
1273}
1274
1275//_____________________________________________________________________________
1276Bool_t
1277AliMUONPainterContourMaker::IsHorizontal(const TLine& line) const
1278{
1279 /// whether line is horizontal
1280
1281 static Double_t l2 = AliMpConstants::LengthTolerance()*AliMpConstants::LengthTolerance();
1282
1283 return ( Slope(line) < l2 );
1284}
1285
1286//_____________________________________________________________________________
1287Bool_t
1288AliMUONPainterContourMaker::IsVertical(const TLine& line) const
1289{
1290 /// whether line is vertical
1291
1292 return ( TMath::Abs(Slope(line)) == FLT_MAX );
1293}
1294
1295//_____________________________________________________________________________
1296Int_t
1297AliMUONPainterContourMaker::Overlap(const TLine& line1,
1298 const TLine& line2) const
1299{
1300 /// Whether line1 and line2 overlap
1301
1302 Int_t rv(0);
1303
1304 if ( IsEqual(line1,line2) )
1305 {
1306 // First things first. If both lines are the same one,
1307 // they for sure overlap ;-)
1308 rv = 4;
1309 }
1310 else
1311 {
1312 rv = IsInside(line1,line2) + IsInside(line2,line1);
1313 }
1314
1315 AliDebug(3,Form("%s and %s : overlap=%d",
1316 LineAsString(line1).Data(),
1317 LineAsString(line2).Data(),
1318 rv));
1319
1320 return rv;
1321}
1322
1323//_____________________________________________________________________________
1324Bool_t
1325AliMUONPainterContourMaker::IsLineClosed(const TPolyLine& line) const
1326{
1327 /// check if polyline is already closed (i.e. last point = first point)
1328
1329 Double_t* x = line.GetX();
1330 Double_t* y = line.GetY();
1331
1332 if ( IsEqual(x[line.GetLastPoint()],x[0]) &&
1333 IsEqual(y[line.GetLastPoint()],y[0]) )
1334 {
1335 return kTRUE;
1336 }
1337 else
1338 {
1339 return kFALSE;
1340 }
1341}
1342
1343//_____________________________________________________________________________
1344void
1345AliMUONPainterContourMaker::Local2Global(Int_t detElemId,
1346 Double_t xl, Double_t yl, Double_t zl,
1347 Double_t& xg, Double_t& yg, Double_t& zg) const
1348{
1349 /// Convert local coordinates to global ones
1350 TGeoHMatrix* matrix = static_cast<TGeoHMatrix*>(fGlobalTransformations->GetValue(detElemId));
1351 Double_t pl[3] = { xl, yl, zl };
1352 Double_t pg[3] = { 0., 0., 0. };
1353 matrix->LocalToMaster(pl, pg);
1354 xg = pg[0];
1355 yg = pg[1];
1356 zg = pg[2];
1357}
1358
1359//_____________________________________________________________________________
1360void
1361AliMUONPainterContourMaker::Print(Option_t* opt) const
1362{
1363 /// Printout
1364
1365 cout << "Local Contours" << endl;
1366
1367 TIter next(fLocalManuContours);
1368 TObjString* key;
1369
1370 while ( ( key = static_cast<TObjString*>(next()) ) )
1371 {
1372 cout << key->String().Data() << endl;
1373 AliMUONPainterContour* contour = static_cast<AliMUONPainterContour*>(fLocalManuContours->GetValue(key));
1374 contour->Print(opt);
1375 }
1376
1377 cout << "Global Contours" << endl;
1378
1379 TIter nextC(fContours);
1380
1381 while ( ( key = static_cast<TObjString*>(nextC()) ) )
1382 {
1383 AliMUONPainterContour* contour = static_cast<AliMUONPainterContour*>(fContours->GetValue(key));
1384 contour->Print(opt);
1385 }
1386}
1387
1388//_____________________________________________________________________________
1389Int_t
1390AliMUONPainterContourMaker::CountPoint(const TObjArray& segments,
1391 Double_t x, Double_t y) const
1392{
1393 /// Count the number of times the point (x,y) appears in the segment array
1394
1395 Int_t n(0);
1396
1397 for ( Int_t i = 0; i <= segments.GetLast(); ++i )
1398 {
1399 TLine* line = static_cast<TLine*>(segments.UncheckedAt(i));
1400
1401 if ( IsEqual(x,line->GetX1()) &&
1402 IsEqual(y,line->GetY1()) )
1403 {
1404 ++n;
1405 }
1406
1407 if ( IsEqual(x,line->GetX2()) &&
1408 IsEqual(y,line->GetY2()) )
1409 {
1410 ++n;
1411 }
1412 }
1413
1414 return n;
1415}
1416
1417//_____________________________________________________________________________
1418Bool_t
1419AliMUONPainterContourMaker::SanityCheck(const TObjArray& contours,
1420 const TObjArray& segments, Bool_t check) const
1421{
1422 /// (debug) check
1423
1424 Bool_t ok(kTRUE);
1425
1426 // cross-check that we have no more complete duplicates
1427 // and that we have no orphan point
1428
1429 Double_t xmin(FLT_MAX), xmax(-FLT_MAX);
1430 Double_t ymin(FLT_MAX), ymax(-FLT_MAX);
1431
1432 for ( Int_t i = 0; i <= segments.GetLast(); ++i )
1433 {
1434 TLine* li = static_cast<TLine*>(segments.UncheckedAt(i));
1435
1436 if (!IsHorizontal(*li) && !IsVertical(*li))
1437 {
1438 AliError("Got an oblique line !");
1439 return kFALSE;
1440 }
1441
1442 xmin = TMath::Min(xmin,li->GetX1());
1443 xmin = TMath::Min(xmin,li->GetX2());
1444
1445 xmax = TMath::Max(xmax,li->GetX1());
1446 xmax = TMath::Max(xmax,li->GetX2());
1447
1448 ymin = TMath::Min(ymin,li->GetY1());
1449 ymin = TMath::Min(ymin,li->GetY2());
1450
1451 ymax = TMath::Max(ymax,li->GetY1());
1452 ymax = TMath::Max(ymax,li->GetY2());
1453
1454 }
1455
1456 AliDebug(1,Form("xmin=%7.3f ymin=%7.3f xmax=%7.3f ymax=%7.3f",
1457 xmin,ymin,xmax,ymax));
1458
1459 for ( Int_t i = 0; i <= segments.GetLast(); ++i )
1460 {
1461 TLine* li = static_cast<TLine*>(segments.UncheckedAt(i));
1462
1463 if (!check)
1464 {
1465 for ( Int_t j = 0; j <= segments.GetLast(); ++j )
1466 {
1467 TLine* lj = static_cast<TLine*>(segments.UncheckedAt(j));
1468
1469 if ( i != j && IsEqual(*li,*lj) )
1470 {
1471 ok = kFALSE;
1472 PrintLine(*li);
1473 PrintLine(*lj);
1474 AliFatal("");
1475 }
1476 }
1477 }
1478
1479
1480 Int_t rv(0);
1481
1482 Double_t x = (li->GetX1()+li->GetX2())/2.0;
1483 Double_t y = (li->GetY1()+li->GetY2())/2.0;
1484
1485 if ( ShouldBeRemoved(contours,x,y) ) rv = 1;
1486
1487 AliDebug(1,Form("Line %4d %7.3f,%7.3f -> %7.3f,%7.3f [ %d ]",
1488 i,
1489 li->GetX1(),li->GetY1(),
1490 li->GetX2(),li->GetY2(),
1491 rv));
1492 }
1493
1494 return kTRUE;
1495}
1496
1497//_____________________________________________________________________________
1498TPolyLine*
1499AliMUONPainterContourMaker::Simplify(const TPolyLine& lines) const
1500{
1501 /// try to simplify the polyline, by minimizing the number of points
1502
1503 if ( lines.Size() < 3 )
1504 {
1505 AliError("Cannot simplify lines with less that 3 points !");
1506 return 0x0;
1507 }
1508
1509 AliCodeTimerAuto("")
1510
1511// cout << "Before simplify" << endl;
1512//
1513// for ( Int_t i = 0; i < lines.Size(); ++i )
1514// {
1515// cout << Form("Point %3d %7.3f %7.3f",i,lines.GetX()[i],lines.GetY()[i]) << endl;
1516// }
1517
1518 TPolyLine* l = new TPolyLine;
1519
1520 Double_t* x = lines.GetX();
1521 Double_t* y = lines.GetY();
1522
1523 l->SetNextPoint(x[0],y[0]);
1524
1525 Bool_t verticalCurrent = IsEqual(x[1],x[0]);
1526 Bool_t horizontalCurrent = IsEqual(y[1],y[0]);
1527
1528 Int_t i(2);
1529
1530 while ( i < lines.Size() )
1531 {
1532 Bool_t vertical = IsEqual(x[i],x[i-1]);
1533 Bool_t horizontal = IsEqual(y[i],y[i-1]);
1534
1535// cout << Form("i %3d %7.3f %7.3f vert %d horiz %d (current vert %d horiz %d)",
1536// i,x[i],y[i],vertical,horizontal,verticalCurrent,horizontalCurrent)
1537// << endl;
1538
1539 if ( ( vertical != verticalCurrent ) ||
1540 ( horizontal != horizontalCurrent ) )
1541 {
1542// cout << Form("Changing direction : adding point %7.3f %7.3f",x[i-1],y[i-1]) << endl;
1543 l->SetNextPoint(x[i-1],y[i-1]);
1544 verticalCurrent = vertical;
1545 horizontalCurrent = horizontal;
1546 }
1547 ++i;
1548 }
1549
1550 l->SetNextPoint(l->GetX()[0],l->GetY()[0]);
1551
1552// cout << "After simplify" << endl;
1553//
1554// for ( Int_t i = 0; i < l->Size(); ++i )
1555// {
1556// cout << Form("Point %3d %7.3f %7.3f",i,l->GetX()[i],l->GetY()[i]) << endl;
1557// }
1558
1559 return l;
1560}
1561
1562//_____________________________________________________________________________
1563Int_t
1564AliMUONPainterContourMaker::Size() const
1565{
1566 /// Number of contours we have already
1567
1568 return fContours->GetSize();
1569}
1570