From 0b936dc01b2ff324e3256c1b5c63dd67f372e976 Mon Sep 17 00:00:00 2001 From: laphecet Date: Mon, 6 Apr 2009 20:33:28 +0000 Subject: [PATCH] Adding classes forgotten in previous commit --- MUON/AliMUONContour.cxx | 304 ++++++ MUON/AliMUONContour.h | 76 ++ MUON/AliMUONContourMaker.cxx | 462 ++++++++ MUON/AliMUONContourMaker.h | 54 + MUON/AliMUONContourMakerTest.cxx | 530 +++++++++ MUON/AliMUONContourMakerTest.h | 64 ++ MUON/AliMUONContourPainter.cxx | 101 ++ MUON/AliMUONContourPainter.h | 36 + MUON/AliMUONManuContourMaker.cxx | 288 +++++ MUON/AliMUONManuContourMaker.h | 56 + MUON/AliMUONNode.cxx | 224 ++++ MUON/AliMUONNode.h | 77 ++ MUON/AliMUONPainterContour.cxx | 317 ------ MUON/AliMUONPainterContour.h | 70 -- MUON/AliMUONPainterContourMaker.cxx | 1572 --------------------------- MUON/AliMUONPainterContourMaker.h | 234 ---- MUON/AliMUONPainterDataRegistry.cxx | 279 +++++ MUON/AliMUONPainterDataRegistry.h | 81 ++ MUON/AliMUONPointWithRef.cxx | 89 ++ MUON/AliMUONPointWithRef.h | 47 + MUON/AliMUONPolygon.cxx | 208 ++++ MUON/AliMUONPolygon.h | 61 ++ MUON/AliMUONSegment.cxx | 148 +++ MUON/AliMUONSegment.h | 91 ++ MUON/AliMUONSegmentTree.cxx | 118 ++ MUON/AliMUONSegmentTree.h | 60 + MUON/mapping/AliMpUID.cxx | 363 +++++++ MUON/mapping/AliMpUID.h | 80 ++ 28 files changed, 3897 insertions(+), 2193 deletions(-) create mode 100644 MUON/AliMUONContour.cxx create mode 100644 MUON/AliMUONContour.h create mode 100644 MUON/AliMUONContourMaker.cxx create mode 100644 MUON/AliMUONContourMaker.h create mode 100644 MUON/AliMUONContourMakerTest.cxx create mode 100644 MUON/AliMUONContourMakerTest.h create mode 100644 MUON/AliMUONContourPainter.cxx create mode 100644 MUON/AliMUONContourPainter.h create mode 100644 MUON/AliMUONManuContourMaker.cxx create mode 100644 MUON/AliMUONManuContourMaker.h create mode 100644 MUON/AliMUONNode.cxx create mode 100644 MUON/AliMUONNode.h delete mode 100644 MUON/AliMUONPainterContour.cxx delete mode 100644 MUON/AliMUONPainterContour.h delete mode 100644 MUON/AliMUONPainterContourMaker.cxx delete mode 100644 MUON/AliMUONPainterContourMaker.h create mode 100644 MUON/AliMUONPainterDataRegistry.cxx create mode 100644 MUON/AliMUONPainterDataRegistry.h create mode 100644 MUON/AliMUONPointWithRef.cxx create mode 100644 MUON/AliMUONPointWithRef.h create mode 100644 MUON/AliMUONPolygon.cxx create mode 100644 MUON/AliMUONPolygon.h create mode 100644 MUON/AliMUONSegment.cxx create mode 100644 MUON/AliMUONSegment.h create mode 100644 MUON/AliMUONSegmentTree.cxx create mode 100644 MUON/AliMUONSegmentTree.h create mode 100644 MUON/mapping/AliMpUID.cxx create mode 100644 MUON/mapping/AliMpUID.h diff --git a/MUON/AliMUONContour.cxx b/MUON/AliMUONContour.cxx new file mode 100644 index 00000000000..a5c4493e452 --- /dev/null +++ b/MUON/AliMUONContour.cxx @@ -0,0 +1,304 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +///\class AliMUONContour +/// +/// A contour is a set of (closed and counter-clockwise-oriented) polygons +/// +/// \author Laurent Aphecetche, Subatech + +#include "AliMUONContour.h" + +#include "AliLog.h" +#include "AliMUONPolygon.h" +#include "AliMpArea.h" +#include +#include +#include +#include +#include +#include +#include +#include + +///\cond CLASSIMP +ClassImp(AliMUONContour) +///\endcond + +//_____________________________________________________________________________ +AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""), +fPolygons(new TObjArray), +fXmin(FLT_MAX), +fXmax(-FLT_MAX), +fYmin(FLT_MAX), +fYmax(-FLT_MAX), +fNofVertices(0) +{ + /// ctor + fPolygons->SetOwner(kTRUE); +} + +//_____________________________________________________________________________ +AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area) +: TNamed(name,""), +fPolygons(new TObjArray), +fXmin(area.LeftBorder()), +fXmax(area.RightBorder()), +fYmin(area.DownBorder()), +fYmax(area.UpBorder()), +fNofVertices(0) +{ + /// ctor + fPolygons->SetOwner(kTRUE); + + AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(), + area.GetPositionY(), + area.GetDimensionX(), + area.GetDimensionY()); + + fPolygons->AddLast(pol); + + fNofVertices = pol->NumberOfVertices(); +} + +//______________________________________________________________________________ +AliMUONContour::AliMUONContour(const AliMUONContour& rhs) +: TNamed(rhs), +fPolygons(0x0), +fXmin(FLT_MAX), +fXmax(-FLT_MAX), +fYmin(FLT_MAX), +fYmax(-FLT_MAX), +fNofVertices(0) +{ + /// Copy constructor. + + ((AliMUONContour&)rhs).Copy(*this); +} + +//______________________________________________________________________________ +AliMUONContour& +AliMUONContour::operator=(const AliMUONContour& rhs) +{ + /// Assignment operator + if ( this != &rhs ) + { + delete fPolygons; + fPolygons = 0; + rhs.Copy(*this); + } + return *this; +} + +//_____________________________________________________________________________ +AliMUONContour::~AliMUONContour() +{ + /// dtor + delete fPolygons; +} + +//_____________________________________________________________________________ +void +AliMUONContour::Add(const AliMUONPolygon& polygon) +{ + /// Add points from the polygon + + for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i ) + { + Double_t x = polygon.X(i); + Double_t y = polygon.Y(i); + fXmin = TMath::Min(fXmin,x); + fXmax = TMath::Max(fXmax,x); + fYmin = TMath::Min(fYmin,y); + fYmax = TMath::Max(fYmax,y); + } + + fPolygons->AddLast(new AliMUONPolygon(polygon)); + + fNofVertices += polygon.NumberOfVertices(); +} + +//_____________________________________________________________________________ +AliMpArea +AliMUONContour::Area() const +{ + /// Return the area covered by this contour (i.e. the area that + /// contains all the poylines) + + return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 , + TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 ); +} + +//______________________________________________________________________________ +void +AliMUONContour::AssertOrientation(Bool_t autoCorrect) +{ + /// Insure that all our polygons are counter-clockwise oriented + /// If autoCorrect==kTRUE, we change the orientation if it is not + /// already correct. + /// If autoCorrect==kFALSE and the orientation is not correct, we + /// just issue an error message. + + for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i ) + { + AliMUONPolygon* pol = static_cast(fPolygons->UncheckedAt(i)); + if ( !pol->IsCounterClockwiseOriented() ) + { + if ( autoCorrect ) + { + pol->ReverseOrientation(); + } + else + { + AliError("Got a polygon oriented the wrong way"); + StdoutToAliError(Print();); + return; + } + } + } +} + +//______________________________________________________________________________ +void AliMUONContour::Copy(TObject& obj) const +{ + /// Copy this to obj + + AliMUONContour& rhs = static_cast(obj); + TNamed::Copy(rhs); + delete rhs.fPolygons; + rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1); + rhs.fPolygons->SetOwner(kTRUE); + TIter next(fPolygons); + AliMUONPolygon* pol; + while ( ( pol = static_cast(next()) ) ) + { + rhs.fPolygons->AddLast(pol->Clone()); + } + rhs.fXmin = fXmin; + rhs.fXmax = fXmax; + rhs.fYmin = fYmin; + rhs.fYmax = fYmax; + rhs.fNofVertices = fNofVertices; +} + +//_____________________________________________________________________________ +Bool_t +AliMUONContour::IsInside(Double_t x, Double_t y) const +{ + /// Whether the point (x,y) is inside one of ours polylines + + if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax ) + { + TIter next(fPolygons); + AliMUONPolygon* pol; + while ( ( pol = static_cast(next()) ) ) + { + if ( pol->Contains(x,y) ) + { + return kTRUE; + } + } + } + + return kFALSE; +} + +//_____________________________________________________________________________ +void +AliMUONContour::Offset(Double_t x, Double_t y) +{ + /// Offset all lines by a given offset + + TIter next(fPolygons); + AliMUONPolygon* pol; + + while ( ( pol = static_cast(next()) ) ) + { + for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i ) + { + pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y); + } + } + + fXmin += x; + fXmax += x; + fYmin += y; + fYmax += y; +} + +//_____________________________________________________________________________ +void +AliMUONContour::Print(Option_t* opt) const +{ + /// Printout + + cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl; + TString sopt(opt); + sopt.ToUpper(); + if (sopt.Contains("B")) + { + Area().Print("B"); + } + + TIter next(fPolygons); + AliMUONPolygon* pol; + while ( ( pol = static_cast(next()) ) ) + { + pol->Print(opt); + } + + + cout << endl; +} + +//_____________________________________________________________________________ +void +AliMUONContour::Transform(const TGeoHMatrix& matrix) +{ + /// Transform the polygons using the given transformation + + TIter next(fPolygons); + AliMUONPolygon* pol; + + fXmin = fYmin = FLT_MAX; + fXmax = fYmax = -FLT_MAX; + + while ( ( pol = static_cast(next()) ) ) + { + for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i ) + { + Double_t pl[3] = { pol->X(i), pol->Y(i), 0 }; + Double_t pg[3] = { 0., 0., 0. }; + matrix.LocalToMaster(pl, pg); + pol->SetVertex(i,pg[0],pg[1]); + fXmin = TMath::Min(fXmin,pg[0]); + fYmin = TMath::Min(fYmin,pg[1]); + fXmax = TMath::Max(fXmax,pg[0]); + fYmax = TMath::Max(fYmax,pg[1]); + } + } + + AssertOrientation(kTRUE); +} + +//_____________________________________________________________________________ +Bool_t +AliMUONContour::IsValid() const +{ + /// A valid contour is one with a valid area and at least 3 vertices. + return fNofVertices >= 3 && Area().IsValid(); +} diff --git a/MUON/AliMUONContour.h b/MUON/AliMUONContour.h new file mode 100644 index 00000000000..60922512d0a --- /dev/null +++ b/MUON/AliMUONContour.h @@ -0,0 +1,76 @@ +#ifndef ALIMUONCONTOUR_H +#define ALIMUONCONTOUR_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONContour +/// \brief 2D contour +/// +// Author Laurent Aphecetche, Subatech + +#ifndef ROOT_TNamed +# include "TNamed.h" +#endif + +#ifndef ALI_MP_AREA_H +# include "AliMpArea.h" +#endif + +class AliMUONPolygon; +class TGeoHMatrix; +class TObjArray; + +class AliMUONContour : public TNamed +{ +public: + AliMUONContour(const char* name=""); + AliMUONContour(const char* name, const AliMpArea& area); + AliMUONContour(const AliMUONContour& rhs); + AliMUONContour& operator=(const AliMUONContour& rhs); + virtual ~AliMUONContour(); + + AliMpArea Area() const; + + /// Get a full copy of this object. + virtual TObject* Clone(const char* /*newname*/="") const { return new AliMUONContour(*this); } + + /// Add an offset to all points + void Offset(Double_t x, Double_t y); + + /// Apply a global transformation to all points + void Transform(const TGeoHMatrix& matrix); + + void Add(const AliMUONPolygon& polygon); + + virtual void Copy(TObject& obj) const; + + Bool_t IsInside(Double_t x, Double_t y) const; + + virtual void Print(Option_t* opt="") const; + + /// Get the number of vertices of this contour + Int_t NumberOfVertices() const { return fNofVertices; } + + Bool_t IsValid() const; + + /// Get the list of polygons we have + const TObjArray* Polygons() const { return fPolygons; } + + void AssertOrientation(Bool_t autoCorrect=kFALSE); + +private: + TObjArray* fPolygons; ///< the polygons that this contour is made of + Double_t fXmin; ///< min x-value + Double_t fXmax; ///< max x-value + Double_t fYmin; ///< min y-value + Double_t fYmax; ///< max y-value + Int_t fNofVertices; ///< total number of vertices + + ClassDef(AliMUONContour,1) // 2D-contour of an object +}; + +#endif diff --git a/MUON/AliMUONContourMaker.cxx b/MUON/AliMUONContourMaker.cxx new file mode 100644 index 00000000000..73435cc2d07 --- /dev/null +++ b/MUON/AliMUONContourMaker.cxx @@ -0,0 +1,462 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// +/// Maker/merger of contours. Can create contour from a set polygons or +/// merger a set of contours into a single one. +/// +/// This is based on (one of the) algorithm found in +/// Diane L. Souvaine and Iliana Bjorling-Sachs, +/// Proceedings of the IEEE, Vol. 80, No. 9, September 1992, p. 1449 +/// +/// Note that besides the AliMUON prefix, nothing is really MUON specific +/// in this class... +/// +/// \author Laurent Aphecetche, Subatech +/// + +#include "AliMUONContourMaker.h" + +#include "AliCodeTimer.h" +#include "AliLog.h" +#include "AliMUONContour.h" +#include "AliMUONPointWithRef.h" +#include "AliMUONPolygon.h" +#include "AliMUONSegment.h" +#include "AliMUONSegmentTree.h" +#include "Riostream.h" +#include "TArrayD.h" +#include "TMath.h" +#include + +/// \cond CLASSIMP +ClassImp(AliMUONContourMaker) +/// \endcond + +namespace +{ + void PrintSegments(const TObjArray& array) + { + TIter next(&array); + AliMUONSegment* s; + Int_t i(0); + while ( ( s = static_cast(next()) ) ) + { + cout << Form("i=%d %s",i,s->AsString()) << endl; + ++i; + } + } +} + +//_____________________________________________________________________________ +AliMUONContourMaker::AliMUONContourMaker() +{ +} + +//_____________________________________________________________________________ +AliMUONContourMaker::~AliMUONContourMaker() +{ +} + +//_____________________________________________________________________________ +AliMUONContour* +AliMUONContourMaker::CreateContour(const TObjArray& polygons, const char* name) const +{ + /// Create the contour of the polygon array + /// and get back the intermediate verticals and horizontal segments + /// both arrays are arrays of AliMUONSegment objects. + + AliCodeTimerAuto(""); + + if ( polygons.IsEmpty() ) return 0x0; // protection against user error... + + // Sanity check : insure that all polygons are oriented counter-clockwise + TIter next(&polygons); + AliMUONPolygon* pol; + while ( ( pol = static_cast(next()) ) ) + { + if ( !pol->IsCounterClockwiseOriented() ) + { + AliError(Form("Got a clockwise oriented polygon in CreateContour(%s). That's not OK !",name)); + StdoutToAliError(polygons.Print()); + return 0x0; + } + } + + AliMUONContour* contour(0x0); + + if ( polygons.GetLast() == 0 ) + { + AliCodeTimerAuto("Trivial case"); + contour = new AliMUONContour(name); + pol = static_cast(polygons.First()); + contour->Add(*pol); + contour->AssertOrientation(); + return contour; + } + + TObjArray polygonVerticalEdges; // arrray of AliMUONSegment objects + polygonVerticalEdges.SetOwner(kTRUE); + // get vertical edges of input polygons + GetVerticalEdges(polygons,polygonVerticalEdges); + + // sort them in ascending x order + // if same x, insure that left edges are before right edges + // within same x, order by increasing bottommost y (see AliMUONSegment::Compare method) + polygonVerticalEdges.Sort(); + + if ( polygonVerticalEdges.GetLast()+1 < 2 ) + { + AliError(Form("Got too few edges here for createContour %s",name)); + polygons.Print(); + TObject* o(0x0); + o->Print(); + } + + // Find the vertical edges of the merged contour. This is the meat of the algorithm... + TObjArray contourVerticalEdges; + contourVerticalEdges.SetOwner(kTRUE); + Sweep(polygonVerticalEdges,contourVerticalEdges); + + TObjArray horizontals; + horizontals.SetOwner(kTRUE); + VerticalToHorizontal(contourVerticalEdges,horizontals); + + contour = FinalizeContour(contourVerticalEdges,horizontals); + + if ( contour && name ) contour->SetName(name); + + return contour; +} + +//_____________________________________________________________________________ +AliMUONContour* +AliMUONContourMaker::FinalizeContour(const TObjArray& verticals, + const TObjArray& horizontals) const +{ + /// For a list of vertical and horizontal edges, we build the final + /// contour object. + + AliCodeTimerAuto(""); + + TObjArray all; // array of AliMUONSegment + TObjArray inorder; // array of AliMUONSegment + + all.SetOwner(kFALSE); + inorder.SetOwner(kFALSE); + + for ( Int_t i = 0; i <= verticals.GetLast(); ++i ) + { + all.Add(verticals.UncheckedAt(i)); + all.Add(horizontals.UncheckedAt(i)); + } + + Int_t i(0); + + AliMUONContour* contour = new AliMUONContour; + + int total(0); + + while ( !all.IsEmpty() ) + { + total++; + + if ( total > 1000 ) + { + AliError("Total 1000 reached !!!!"); + return 0x0; + } + + AliMUONSegment* si = static_cast(all.UncheckedAt(i)); + inorder.Add(si); + const AliMUONSegment* all0 = static_cast(all.First()); + if ( i != 0 && AliMUONSegment::AreEqual(si->EndX(),all0->StartX()) && AliMUONSegment::AreEqual(si->EndY(),all0->StartY()) ) + { + Int_t n(-1); + + AliMUONPolygon polygon(inorder.GetLast()+2); + + // we got a cycle. Add it to the contour + for ( Int_t j = 0; j <= inorder.GetLast(); ++j ) + { + AliMUONSegment* s = static_cast(inorder.UncheckedAt(j)); + polygon.SetVertex(++n,s->StartX(),s->StartY()); + all.Remove(s); + } + + all.Compress(); + + polygon.Close(); + + contour->Add(polygon); + + if ( ! all.IsEmpty() ) + { + i = 0; + inorder.Clear(); + } + continue; + } + + for ( Int_t j = 0; j <= all.GetLast(); ++j) + { + if ( j != i ) + { + const AliMUONSegment* sj = static_cast(all.UncheckedAt(j)); + if ( AliMUONSegment::AreEqual(si->EndX(),sj->StartX()) && AliMUONSegment::AreEqual(si->EndY(),sj->StartY())) + { + i = j; + break; + } + } + } + } + + contour->AssertOrientation(kTRUE); + return contour; +} + + +//_____________________________________________________________________________ +void +AliMUONContourMaker::GetVerticalEdges(const TObjArray& polygons, TObjArray& polygonVerticalEdges) const +{ + /// From an array of polygons, extract the list of vertical edges. + /// Output array polygonVerticalEdges should be empty before calling. + + AliCodeTimerAuto(""); + + for ( Int_t i = 0; i <= polygons.GetLast(); ++i ) + { + const AliMUONPolygon* g = static_cast(polygons.UncheckedAt(i)); + for ( Int_t j = 0; j < g->NumberOfVertices()-1; ++j ) + { + if ( AliMUONSegment::AreEqual(g->X(j),g->X(j+1)) ) // segment is vertical + { + polygonVerticalEdges.Add(new AliMUONSegment(g->X(j),g->Y(j),g->X(j+1),g->Y(j+1))); + } + } + } +} + + +//_____________________________________________________________________________ +void +AliMUONContourMaker::GetYPositions(const TObjArray& polygonVerticalEdges, + TArrayD& yPositions) const +{ + /// Fill the array yPositions with the different y positions found in + /// polygonVerticalEdges + + AliCodeTimerAuto(""); + + Double_t* y = new Double_t[polygonVerticalEdges.GetSize()*2]; + Int_t n(0); + + for ( Int_t i = 0; i < polygonVerticalEdges.GetLast(); ++i ) + { + AliMUONSegment* s = static_cast(polygonVerticalEdges.UncheckedAt(i)); + y[n] = s->StartY(); + y[n+1] = s->EndY(); + n += 2; + } + Int_t* ix = new Int_t[n+1]; + + TMath::Sort(n,y,ix,kFALSE); + + yPositions.Set(n+1); + + Int_t u(0); + Double_t x(FLT_MAX); + + for ( Int_t i = 0; i < n; ++i ) + { + if ( y[ix[i]] != x ) + { + yPositions[u] = y[ix[i]]; + x = y[ix[i]]; + ++u; + } + } + + yPositions.Set(u); + + delete[] ix; + delete[] y; + +} + +//_____________________________________________________________________________ +AliMUONContour* +AliMUONContourMaker::MergeContour(const TObjArray& contours, const char* name) const +{ + /// Merge all the polygons of all contours into a single contour + + AliCodeTimerAuto(""); + + TObjArray polygons; + polygons.SetOwner(kTRUE); + + TIter next(&contours); + AliMUONContour* contour; + while ( ( contour = static_cast(next()) ) ) + { + const TObjArray* contourPolygons = contour->Polygons(); + TIter nextPol(contourPolygons); + AliMUONPolygon* pol; + while ( ( pol = static_cast(nextPol()) ) ) + { + polygons.Add(new AliMUONPolygon(*pol)); + } + } + + if ( polygons.IsEmpty() ) return 0x0; + + contour = CreateContour(polygons,name); + + return contour; +} + +//_____________________________________________________________________________ +void +AliMUONContourMaker::SortPoints(const TObjArray& polygonVerticalEdges, + TObjArray& sortedPoints) const +{ + /// Sort the point of the vertical edges in ascending order, first on ordinate, + /// then on abcissa, and put them in output vector sortedPoints. + /// Output array sortedPoints should be empty before calling this method. + + AliCodeTimerAuto(""); + + for ( Int_t i = 0; i <= polygonVerticalEdges.GetLast(); ++i ) + { + const AliMUONSegment* e = static_cast(polygonVerticalEdges.UncheckedAt(i)); + sortedPoints.Add(new AliMUONPointWithRef(e->StartX(),e->StartY(),i)); + sortedPoints.Add(new AliMUONPointWithRef(e->EndX(),e->EndY(),i)); + // note that we keep track of the original edge, which is used + // later on to deduce orientation of horizontal edges. + } + + sortedPoints.Sort(); +} + +//_____________________________________________________________________________ +void +AliMUONContourMaker::Sweep(const TObjArray& polygonVerticalEdges, + TObjArray& contourVerticalEdges) const +{ + /// This is the meat of the algorithm of the contour merging... + + AliCodeTimerAuto(""); + + TArrayD yPositions; + GetYPositions(polygonVerticalEdges,yPositions); + + AliMUONSegmentTree segmentTree(yPositions); + + for ( Int_t i = 0; i <= polygonVerticalEdges.GetLast(); ++i ) + { + const AliMUONSegment* edge = static_cast(polygonVerticalEdges.UncheckedAt(i)); + + assert(edge!=0x0); + + if ( edge->IsLeftEdge() ) + { + segmentTree.Contribution(edge->Bottom(),edge->Top()); + segmentTree.InsertInterval(edge->Bottom(),edge->Top()); + } + else + { + segmentTree.DeleteInterval(edge->Bottom(),edge->Top()); + segmentTree.Contribution(edge->Bottom(),edge->Top()); + } + + AliMUONSegment e1(*edge); + + if ( i < polygonVerticalEdges.GetLast() ) + { + const AliMUONSegment* next = static_cast(polygonVerticalEdges.UncheckedAt(i+1)); + e1 = *next; + } + + if ( ( edge->IsLeftEdge() != e1.IsLeftEdge() ) || + ( !AliMUONSegment::AreEqual(edge->StartX(),e1.StartX() ) ) || + ( i == polygonVerticalEdges.GetLast() ) ) + { + const TObjArray& stack = segmentTree.Stack(); + + double x = edge->StartX(); + + for ( Int_t j = 0; j <= stack.GetLast(); ++j ) + { + AliMUONSegment* sj = static_cast(stack.UncheckedAt(j)); + AliMUONSegment* s = new AliMUONSegment(x,sj->StartY(),x,sj->EndY()); + + if (s->IsAPoint()) + { + delete s; + continue; + } + + if ( edge->IsLeftEdge() != s->IsLeftEdge() ) + { + s->Set(x,sj->EndY(),x,sj->StartY()); + } + contourVerticalEdges.Add(s); + } + segmentTree.ResetStack(); + } + } +} + +//_____________________________________________________________________________ +void +AliMUONContourMaker::VerticalToHorizontal(const TObjArray& polygonVerticalEdges, + TObjArray& horizontalEdges) const +{ + /// Deduce the set of horizontal edges from the vertical edges + /// Output array horizontalEdges should be empty before calling this method + + AliCodeTimerAuto(""); + + TObjArray points; // array of AliMUONPointWithRef + points.SetOwner(kTRUE); + + SortPoints(polygonVerticalEdges,points); + + for ( Int_t k = 0; k < (points.GetLast()+1)/2; ++k ) + { + const AliMUONPointWithRef* p1 = static_cast(points.UncheckedAt(k*2)); + const AliMUONPointWithRef* p2 = static_cast(points.UncheckedAt(k*2+1)); + + const AliMUONSegment* refEdge = static_cast(polygonVerticalEdges.UncheckedAt(p1->Ref())); + + // (p1,p2) is the horizontal edge. + // refEdge is used to deduce the orientation of (p1,p2) + + if ( AliMUONSegment::AreEqual(p1->X(),refEdge->EndX()) && AliMUONSegment::AreEqual(p1->Y(),refEdge->EndY()) ) +// if ( AreEqual(p1,refEdge->End()) ) + { + horizontalEdges.Add(new AliMUONSegment(p1->X(),p1->Y(),p2->X(),p2->Y())); + } + else + { + horizontalEdges.Add(new AliMUONSegment(p2->X(),p2->Y(),p1->X(),p1->Y())); + } + } +} + diff --git a/MUON/AliMUONContourMaker.h b/MUON/AliMUONContourMaker.h new file mode 100644 index 00000000000..43869c9e6e7 --- /dev/null +++ b/MUON/AliMUONContourMaker.h @@ -0,0 +1,54 @@ +#ifndef ALIMUONCONTOURMAKER_H +#define ALIMUONCONTOURMAKER_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONContourMaker +/// \brief Creator/merger of AliMUONContour objects +/// +// Author Laurent Aphecetche, Subatech + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +#ifndef ROOT_TMap +#include "TMap.h" +#endif + +class AliMUONContour; +class TObjArray; +class TArrayD; + +class AliMUONContourMaker : public TObject +{ +public: + AliMUONContourMaker(); + virtual ~AliMUONContourMaker(); + + AliMUONContour* CreateContour(const TObjArray& polygons, const char* name=0x0) const; + + AliMUONContour* MergeContour(const TObjArray& contours, const char* name=0x0) const; + +private: + + AliMUONContour* FinalizeContour(const TObjArray& verticals, const TObjArray& horizontals) const; + + void GetYPositions(const TObjArray& polygonVerticalEdges, TArrayD& yPositions) const; + + void GetVerticalEdges(const TObjArray& polygons, TObjArray& polygonVerticalEdges) const; + + void SortPoints(const TObjArray& polygonVerticalEdges, TObjArray& sortedPoints) const; + + void Sweep(const TObjArray& polygonVerticalEdges, TObjArray& contourVerticalEdges) const; + + void VerticalToHorizontal(const TObjArray& verticalEdges, TObjArray& horizontalEdges) const; + + ClassDef(AliMUONContourMaker,1) // Maker/merger of AliMUONContour objects +}; + +#endif diff --git a/MUON/AliMUONContourMakerTest.cxx b/MUON/AliMUONContourMakerTest.cxx new file mode 100644 index 00000000000..298e7b76fc3 --- /dev/null +++ b/MUON/AliMUONContourMakerTest.cxx @@ -0,0 +1,530 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// +/// \class AliMUONContourMakerTest +/// +/// Class used to test (and in particular time) the contour creation +/// algorithms. +/// +/// \author Laurent Aphecetche, Subatech +/// + +#include "AliMUONContourMakerTest.h" + +#include "AliCodeTimer.h" +#include "AliLog.h" +#include "AliMUONContour.h" +#include "AliMUONContourMaker.h" +#include "AliMUONGeometryDetElement.h" +#include "AliMUONGeometryTransformer.h" +#include "AliMUONManuContourMaker.h" +#include "AliMUONPolygon.h" +#include "AliMUONSegment.h" +#include "AliMpArea.h" +#include "AliMpCDB.h" +#include "AliMpDDLStore.h" +#include "AliMpDEManager.h" +#include "AliMpExMap.h" +#include +#include "Riostream.h" +#include "TArrow.h" +#include "TCanvas.h" +#include "TFile.h" +#include "TGeoMatrix.h" +#include "TLine.h" +#include "TObjArray.h" +#include "TPolyLine.h" +#include "TSystem.h" + +///\cond CLASSIMP +ClassImp(AliMUONContourMakerTest) +///\endcond + +namespace +{ + //_____________________________________________________________________________ + void Plot(TPolyLine& line, Bool_t orientation) + { + if ( !orientation ) + { + line.Draw(); + } + else + { + Double_t* x = line.GetX(); + Double_t* y = line.GetY(); + + for ( Int_t i = 0; i < line.GetLastPoint(); ++i ) + { + Double_t x1 = x[i]; + Double_t y1 = y[i]; + Double_t x2 = x[i+1]; + Double_t y2 = y[i+1]; + + Bool_t horizontal = AliMUONSegment::AreEqual(y1,y2); + + TLine* a = new TArrow(x1,y1,x2,y2,0.03,"->-"); + if (horizontal) + { + a->SetLineStyle(3); + } + a->Draw(); + } + } + } +} + +//_____________________________________________________________________________ +AliMUONContourMakerTest::AliMUONContourMakerTest() +{ + /// ctor +} + +//_____________________________________________________________________________ +AliMUONContourMakerTest::~AliMUONContourMakerTest() +{ + /// dtor +} + + +//______________________________________________________________________________ +TObjArray* +AliMUONContourMakerTest::CreateContourList(const TObjArray& manuContours) +{ + /// Create an array of maps of contour names + /// + /// Assyming that key is something like station#/chamber#/de#/buspatch#/manu# + /// the idea here is to put one TMap for each level in mapArray : + /// + /// mapArray[0].key = station0 + /// mapArray[0].value = map of strings { station0/chamber0, station0/chamber1 } + /// + /// Then each entry in mapArray will be converted into a contour by + /// merging its children (e.g. station0 contour will be made from the merging + /// of station0/chamber0 and station0/chamber1 in the example above). + /// + + AliCodeTimerAuto(""); + + TIter next(&manuContours); + AliMUONContour* contour; + TObjArray* mapArray = new TObjArray; + + while ( ( contour = static_cast(next()) ) ) + { + // Key is something like station#/chamber#/de#/buspatch#/manu# + + TString key(contour->GetName()); + TObjArray* s = key.Tokenize("/"); + for ( Int_t i = 0; i < s->GetLast(); ++i ) + { + TMap* m = static_cast(mapArray->At(i)); + if (!m) + { + m = new TMap; + if ( i > mapArray->GetSize() ) mapArray->Expand(i); + mapArray->AddAt(m,i); + } + TString parent; + for ( Int_t k = 0; k <= i; ++k ) + { + TObjString* str = static_cast(s->At(k)); + parent += str->String(); + if ( k < i ) parent += "/"; + } + TString child(parent); + child += "/"; + child += static_cast(s->At(i+1))->String(); + + TObjArray* ma = static_cast(m->GetValue(parent.Data())); + if (!ma) + { + ma = new TObjArray; + m->Add(new TObjString(parent.Data()),ma); + } + TPair* p = static_cast(ma->FindObject(child.Data())); + if ( !p ) + { + ma->Add(new TObjString(child.Data())); + } + } + delete s; + } + + return mapArray; +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::Exec(const Option_t* opt) +{ + /// Main method + /// Generate the geometry transformations, then + /// contours for all manus, and then for all the elements + /// (bus patches, detection elements, etc...) + + AliInfo("Resetting all timers before I start..."); + + AliCodeTimer::Instance()->Reset(); + + AliMpCDB::LoadDDLStore2(); + + AliCodeTimer::Instance()->Print(); + + AliInfo("Resetting all timers after loading the mapping..."); + + AliCodeTimer::Instance()->Reset(); + + AliCodeTimerAuto(""); + + AliMpExMap* real(0x0); + AliMpExMap* exploded(0x0); + + GenerateTransformations(real,exploded); + + TObjArray* manus(0x0); + TObjArray* all(0x0); + + TString sopt(opt); + + if ( sopt.Contains("MANU") || sopt.Contains("ALL") ) + { + AliMUONManuContourMaker manuMaker(exploded); + manus = manuMaker.GenerateManuContours(kTRUE); + } + + if ( sopt.Contains("ALL") && manus ) + { + manus->SetOwner(kFALSE); + all = GenerateAllContours(*manus); + if ( sopt.Contains("SAVE") && all ) + { + TFile f("AliMUONContourMakerTest.all.root","RECREATE"); + all->Write("ALL",TObject::kSingleKey); + f.Close(); + } + + } + + AliCodeTimer::Instance()->Print(); + + delete manus; + delete all; +} + +//______________________________________________________________________________ +TObjArray* +AliMUONContourMakerTest::GenerateAllContours(const TObjArray& manuContours) +{ + /// From a map of manu contours, generate the compound contours (bp, de, etc...) + /// by merging them. + /// Note that manuContours should NOT be the owner of its contours, + /// as they are adopted by the array returned by this method. + + AliCodeTimerAuto(""); + + // Get the list of contours to create + TObjArray* mapArray = CreateContourList(manuContours); + + // Now loop over the mapArray to actually create the contours + TIter next2(mapArray,kIterBackward); + + TMap allContourMap; + allContourMap.SetOwnerKeyValue(kTRUE,kFALSE); // not owner of contours, as the returned array will be the owner + TObjArray* allContourArray = new TObjArray; + allContourArray->SetOwner(kTRUE); + + TIter nextContour(&manuContours); + AliMUONContour* contour(0x0); + + while ( ( contour = static_cast(nextContour()) ) ) + { + allContourMap.Add(new TObjString(contour->GetName()),contour); + allContourArray->Add(contour); + } + + AliMUONContourMaker maker; + + for ( Int_t i = mapArray->GetLast(); i >= 1; --i ) + // end at 1 to avoid merging different cathodes together, which + // would not work... + { + TMap* a = static_cast(mapArray->At(i)); + TIter next3(a); + TObjString* str; + while ( ( str = static_cast(next3()) ) ) + { + TObjArray* m = static_cast(a->GetValue(str->String().Data())); + TIter next4(m); + TObjString* k; + TObjArray subcontours; + subcontours.SetOwner(kFALSE); + while ( ( k = static_cast(next4()) ) ) + { + contour = static_cast(allContourMap.GetValue(k->String().Data())); + if ( contour ) + { + subcontours.Add(contour); + } + else + { + AliError(Form("Did not find contour %s",k->String().Data())) + return allContourArray; + } + } + + contour = maker.MergeContour(subcontours,str->String().Data()); + + bool error(kFALSE); + + if (!contour) + { + error=kTRUE; + AliError(Form("ERROR : could not merge into %s",str->String().Data())); + } + else + { + if ( contour->Area().IsValid() == kFALSE ) + { + error=kTRUE; + AliError(Form("ERROR : area of contour %s is invalid",str->String().Data())); + } + } + + if ( error ) + { + // do it again, but get intermediate results to plot them + PrintAsPNG(str->String().Data(),subcontours); + if (contour ) + { + StdoutToAliError(contour->Area().Print("B");); + } + AliError(Form("%d subcontours",subcontours.GetLast()+1)); + StdoutToAliError(subcontours.Print();); + // check whether one of the subcontour itself is already invalid ? + TIter next(&subcontours); + AliMUONContour* cont; + while ( ( cont = static_cast(next()) ) ) + { + if (!cont->IsValid()) + { + AliError(Form("subcontour %s is invalid",cont->GetName())); + } + } + TFile f("subcontour.root","recreate"); + subcontours.Write("fault",TObject::kSingleKey); + f.Close(); + + return allContourArray; + } + + allContourArray->Add(contour); + allContourMap.Add(new TObjString(str->String().Data()),contour); + } + } + + return allContourArray; +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::GenerateTransformations(AliMpExMap*& real, AliMpExMap*& exploded) +{ + /// Generate geometric transformations to be used to compute the contours + /// (real are, as the name implies, real ones, while the other ones are + /// a bit tweaked to look fine on screen). + + AliCodeTimerAuto(""); + + AliMUONGeometryTransformer transformer; + Bool_t ok = transformer.LoadGeometryData("transform.dat"); + // transformer.LoadGeometryData("geometry.root"); //FIXME: add a protection if geometry.root file does not exist + if (!ok) + { + cout << "ERROR : cannot get geometry !" << endl; + return; + } + real = new AliMpExMap; + exploded = new AliMpExMap; + AliMpDEIterator deIt; + deIt.First(); + while ( !deIt.IsDone() ) + { + Int_t detElemId = deIt.CurrentDEId(); + const AliMUONGeometryDetElement* de = transformer.GetDetElement(detElemId); + + real->Add(detElemId,de->GetGlobalTransformation()->Clone()); + + TGeoHMatrix* matrix = static_cast(de->GetGlobalTransformation()->Clone()); + Double_t* translation = matrix->GetTranslation(); + + if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 ) + { + translation[0] *= 1.0; + translation[1] *= 1.5; + } + else + { + Double_t shift = 5; // cm + Double_t xshift[] = { shift, -shift, -shift, shift }; + Double_t yshift[] = { shift, shift, -shift, -shift }; + Int_t ishift = detElemId % 100; + + translation[0] += xshift[ishift]; + translation[1] += yshift[ishift]; + } + matrix->SetTranslation(translation); + exploded->Add(detElemId,matrix); + deIt.Next(); + } +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::GetBoundingBox(const TObjArray& array, + Double_t& xmin, Double_t& ymin, + Double_t& xmax, Double_t& ymax, + Bool_t enlarge) const +{ + /// Get the bounding box of all the contours in array. + /// If enlarge = kTRUE, the bounding box is "enlarged" a bit + /// (e.g. to leave some blank around a plot in a canvas) + /// + + xmin=ymin=FLT_MAX; + xmax=ymax=-FLT_MAX; + TIter next(&array); + AliMUONContour* contour; + while ( ( contour = static_cast(next()) ) ) + { + AliMpArea area(contour->Area()); + xmin = TMath::Min(xmin,area.LeftBorder()); + xmax = TMath::Max(xmax,area.RightBorder()); + ymin = TMath::Min(ymin,area.DownBorder()); + ymax = TMath::Max(ymax,area.UpBorder()); + } + + if (enlarge) + { + Double_t xsize = (xmax-xmin); + Double_t ysize = (ymax-ymin); + Double_t xshift = xsize*0.1; + Double_t yshift = ysize*0.1; + xmin -= xshift; + ymin -= yshift; + xmax = xmin + xsize + xshift*2; + ymax = ymin + ysize + yshift*2; + } +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::PlotSegments(const TObjArray& segments, Int_t lineColor, Int_t lineWidth, Bool_t orientation) const +{ + /// Plot an array of segments + + TIter next(&segments); + AliMUONSegment* s; + while ( ( s = static_cast(next()) ) ) + { + TPolyLine* line = new TPolyLine(2); + line->SetPoint(0,s->StartX(),s->StartY()); + line->SetPoint(1,s->EndX(),s->EndY()); + line->SetLineColor(lineColor); + line->SetLineWidth(lineWidth); + ::Plot(*line,orientation); + } +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::Plot(const AliMUONPolygon& polygon, + Int_t lineColor, Int_t lineWidth, + Bool_t orientation) const +{ + /// Plot a polygon + TPolyLine* line = new TPolyLine(polygon.NumberOfVertices()); + for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i ) + { + line->SetPoint(i,polygon.X(i),polygon.Y(i)); + } + + line->SetLineColor(lineColor); + line->SetLineWidth(lineWidth); + ::Plot(*line,kFALSE); + if ( orientation ) ::Plot(*line,kTRUE); +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::Plot(const AliMUONContour& contour, Int_t lineColor, Int_t lineWidth, + Bool_t orientation) const +{ + /// Plot a contour (i.e. a set of polygons) + const TObjArray* polygons = contour.Polygons(); + TIter next(polygons); + AliMUONPolygon* pol; + while ( ( pol = static_cast(next()) ) ) + { + Plot(*pol,lineColor,lineWidth,orientation); + } +} + +//_____________________________________________________________________________ +void +AliMUONContourMakerTest::PlotContours(const TObjArray& array, Bool_t orientations) const +{ + /// Plot an array of contours + TIter next(&array); + AliMUONContour* contour; + while ( ( contour = static_cast(next()) ) ) + { + Plot(*contour,5,4,orientations); + } +} + +//______________________________________________________________________________ +void +AliMUONContourMakerTest::PrintAsPNG(const char* basename, const TObjArray& contourArray, + const TObjArray* verticals, const TObjArray* horizontals) const +{ + /// Output contours and segments into a PNG file. + TCanvas* c = new TCanvas(basename,basename,0,0,600,600); + double xmin,ymin,xmax,ymax; + GetBoundingBox(contourArray,xmin,ymin,xmax,ymax,kTRUE); + c->Range(xmin,ymin,xmax,ymax); + PlotContours(contourArray,kTRUE); + c->Modified(); + c->Update(); + TString name(Form("%s",basename)); + name.ReplaceAll("/","_"); + c->Print(Form("%s.png",name.Data())); + if ( verticals || horizontals ) + { + c->Clear(); + if ( verticals ) PlotSegments(*verticals,1); + if ( horizontals) PlotSegments(*horizontals,2); + c->Modified(); + c->Update(); + name = Form("%s",basename); + name.ReplaceAll("/","_"); + c->Print(Form("%s-segments.png",name.Data())); + } + delete c; +} + diff --git a/MUON/AliMUONContourMakerTest.h b/MUON/AliMUONContourMakerTest.h new file mode 100644 index 00000000000..1483de32043 --- /dev/null +++ b/MUON/AliMUONContourMakerTest.h @@ -0,0 +1,64 @@ +#ifndef ALIMUONCONTOURMAKERTEST_H +#define ALIMUONCONTOURMAKERTEST_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup evaluation +/// \class AliMUONContourMakerTest +/// \brief Test of ContourMaker classes +/// +// author Laurent Aphecetche, Subatech + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +class AliMpExMap; +class TObjArray; +class TString; +class AliMpMotifPosition; +class AliMUONContour; +class AliMUONPolygon; + +class AliMUONContourMakerTest : public TObject +{ +public: + AliMUONContourMakerTest(); + virtual ~AliMUONContourMakerTest(); + + void Exec(const Option_t* opt="ALL"); + + void GetBoundingBox(const TObjArray& array, + Double_t& xmin, Double_t& ymin, + Double_t& xmax, Double_t& ymax, + Bool_t enlarge=kFALSE) const; + + void Plot(const AliMUONContour& contour, Int_t lineColor=5, Int_t lineWidth=4, Bool_t orientation=kFALSE) const; + + void Plot(const AliMUONPolygon& polygon, Int_t lineColor=5, Int_t lineWidth=4, Bool_t orientation=kFALSE) const; + + void PlotContours(const TObjArray& array, Bool_t orientations=kFALSE) const; + + void PlotSegments(const TObjArray& segments, Int_t lineColor=1, Int_t lineWidth=2, Bool_t orientations=kFALSE) const; + + void PrintAsPNG(const char* basename, const TObjArray& contourArray, + const TObjArray* contourVerticalEdges=0x0, + const TObjArray* horizontals=0x0) const; + +private: + + TObjArray* CreateContourList(const TObjArray& manuContours); + + TObjArray* GenerateAllContours(const TObjArray& manuContours); + + void GenerateTransformations(AliMpExMap*& real, AliMpExMap*& exploded); + + TString NameIt(const AliMpMotifPosition& motifPosition) const; + + ClassDef(AliMUONContourMakerTest,1) // Test of AliMUONContourMaker +}; + +#endif diff --git a/MUON/AliMUONContourPainter.cxx b/MUON/AliMUONContourPainter.cxx new file mode 100644 index 00000000000..56797cea3e4 --- /dev/null +++ b/MUON/AliMUONContourPainter.cxx @@ -0,0 +1,101 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// \class AliMUONContourPainter +/// +/// Class to draw AliMUONContour objects (2D) +/// +/// \author Laurent Aphecetche, Subatech + +#include "AliMUONContourPainter.h" + +#include "TVirtualX.h" +#include "AliMUONPolygon.h" +#include "AliMUONContour.h" +#include "TObjArray.h" +#include "TVirtualPad.h" + +///\cond CLASSIMP +ClassImp(AliMUONContourPainter) +///\endcond + +//_____________________________________________________________________________ +AliMUONContourPainter::AliMUONContourPainter() +{ + /// Ctor +} + +//_____________________________________________________________________________ +AliMUONContourPainter::~AliMUONContourPainter() +{ + /// dtor +} + +//_____________________________________________________________________________ +void +AliMUONContourPainter::Paint(const AliMUONContour& contour, + Int_t lineColor, Int_t lineWidth, + Int_t fillColor, Int_t fillStyle) +{ + /// Paint the given contour. + /// If lineColor > 0 the outline is drawn + /// If fillColor > 0 the contour is filled. + + Bool_t outline(lineColor>0); + Bool_t fill(fillColor>0); + + Int_t fc = gVirtualX->GetFillColor(); + Int_t fs = gVirtualX->GetFillStyle(); + Int_t lc = gVirtualX->GetLineColor(); + Int_t lw = gVirtualX->GetLineWidth(); + + if ( lineColor > 0 ) gVirtualX->SetLineColor(lineColor); + if ( lineWidth > 0 ) gVirtualX->SetLineWidth(lineWidth); + if ( fillColor > 0 ) gVirtualX->SetFillColor(fillColor); + if ( fillStyle > 0 ) gVirtualX->SetFillStyle(fillStyle); + + TIter next(contour.Polygons()); + AliMUONPolygon* pol; + while ( ( pol = static_cast(next()) ) ) + { + Int_t n = pol->NumberOfVertices(); + Double_t* x = new Double_t[n]; + Double_t* y = new Double_t[n]; + for ( Int_t i = 0; i < n; ++i ) + { + x[i] = gPad->GetLogx() ? gPad->XtoPad(pol->X(i)) : pol->X(i); + y[i] = gPad->GetLogy() ? gPad->YtoPad(pol->Y(i)) : pol->Y(i); + } + if ( fill ) + { + gPad->PaintFillArea(n,x,y); + } + if (outline) + { + gPad->PaintPolyLine(n,x,y); + } + + delete[] x; + delete[] y; + } + + gVirtualX->SetFillColor(fc); + gVirtualX->SetFillStyle(fs); + gVirtualX->SetLineColor(lc); + gVirtualX->SetLineWidth(lw); + +} diff --git a/MUON/AliMUONContourPainter.h b/MUON/AliMUONContourPainter.h new file mode 100644 index 00000000000..c7ae4138795 --- /dev/null +++ b/MUON/AliMUONContourPainter.h @@ -0,0 +1,36 @@ +#ifndef ALIMUONCONTOURPAINTER_H +#define ALIMUONCONTOURPAINTER_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup graphics +/// \class AliMUONContourPainter +/// \brief Class to draw AliMUONContour objects +/// +// Author Laurent Aphecetche, Subatech + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +class AliMUONContour; + +class AliMUONContourPainter : public TObject +{ +public: + AliMUONContourPainter(); + virtual ~AliMUONContourPainter(); + + using TObject::Paint; + + static void Paint(const AliMUONContour& contour, + Int_t lineColor=1, Int_t lineStyle=1, + Int_t fillColor=-1, Int_t fillStyle=1001); + + ClassDef(AliMUONContourPainter,1) // +}; + +#endif diff --git a/MUON/AliMUONManuContourMaker.cxx b/MUON/AliMUONManuContourMaker.cxx new file mode 100644 index 00000000000..538172af4b0 --- /dev/null +++ b/MUON/AliMUONManuContourMaker.cxx @@ -0,0 +1,288 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// \class AliMUONManuContourMaker +/// +/// Maker of manu contours. +/// +/// Make use of the AliMUONContourMaker class, but this one contains +/// specific things for MUON (as the mapping, for instance), hence its +/// separation from AliMUONContourMaker. +/// +/// This class requires that the mapping is loaded before anything can be done. +/// +/// \author Laurent Aphecetche, Subatech + +#include "AliMUONManuContourMaker.h" + +#include "AliCodeTimer.h" +#include "AliLog.h" +#include "AliMUONContour.h" +#include "AliMUONContourMaker.h" +#include "AliMUONPolygon.h" +#include "AliMpCathodType.h" +#include "AliMpConnection.h" +#include "AliMpConstants.h" +#include "AliMpDDLStore.h" +#include "AliMpDEManager.h" +#include "AliMpIntPair.h" +#include "AliMpMotifPosition.h" +#include "AliMpMotifType.h" +#include "AliMpManuIterator.h" +#include "AliMpPlaneType.h" +#include "AliMpSegmentation.h" +#include "AliMpUID.h" +#include "AliMpVMotif.h" +#include "AliMpVSegmentation.h" +#include "TGeoMatrix.h" +#include "TObjArray.h" +#include "TObjString.h" +#include "TString.h" +#include "TVector2.h" + +///\cond CLASSIMP +ClassImp(AliMUONManuContourMaker) +///\endcond + +//_____________________________________________________________________________ +AliMUONManuContourMaker::AliMUONManuContourMaker(AliMpExMap* deTransformations) +: TObject(), fDETransformations(deTransformations), fLocalManuContours(222,1) +{ + fLocalManuContours.SetOwnerKeyValue(kTRUE,kTRUE); +} + +//_____________________________________________________________________________ +AliMUONManuContourMaker::~AliMUONManuContourMaker() +{ +} + +//_____________________________________________________________________________ +AliMUONContour* +AliMUONManuContourMaker::CreateManuContour(Int_t detElemId, Int_t manuId, const char* name) const +{ + /// Create the contour of a given manu (global coordinates) + + AliCodeTimerAuto(""); + + TString sname(name); + + if ( sname.Length()==0 ) + { + sname = ManuPathName(detElemId,manuId); + } + + const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId); + const AliMpMotifPosition* motifPos = seg->MotifPosition(manuId); + + AliMUONContour* contour = CreateMotifContour(*motifPos); + + if (!contour) + { + AliError(Form("Could not build contour %s",sname.Data())); + return 0x0; + } + + contour->SetName(sname.Data()); + + contour->Offset(motifPos->GetPositionX()-seg->GetPositionX(), + motifPos->GetPositionY()-seg->GetPositionY()); + + TGeoHMatrix* matrix = 0x0; + + if ( fDETransformations ) + { + matrix = static_cast(fDETransformations->GetValue(detElemId)); + if ( matrix ) contour->Transform(*matrix); + } + + return contour; +} + + +//_____________________________________________________________________________ +AliMUONContour* +AliMUONManuContourMaker::CreateMotifContour(const AliMpMotifPosition& motifPosition) const +{ + /// Create the contour of a given MOTIF (i.e. local coordinates only). + + AliCodeTimerAuto(""); + + TString mpName(NameIt(motifPosition)); + + AliMUONContour* contour = static_cast(fLocalManuContours.GetValue(mpName.Data())); + + if ( contour ) + { + // if we have already done the job, just have to clone it and we are done + return static_cast(contour->Clone()); + } + + TObjArray polygons(AliMpConstants::ManuNofChannels()); // array of AliMUONPolygon objects + polygons.SetOwner(kTRUE); + + AliMpVMotif* motif = motifPosition.GetMotif(); + + AliMpMotifType* motifType = motif->GetMotifType(); + + if ( motifType->IsFull() ) + { + // motif is a simple rectangle. No need to loop over pads, we can + // compute the contour right here and now. + polygons.Add(new AliMUONPolygon(0.0,0.0,motif->DimensionX(),motif->DimensionY())); + } + else + { + for ( Int_t i = 0; i <= AliMpConstants::ManuNofChannels(); ++i ) + { + AliMpConnection* connection = motifType->FindConnectionByGassiNum(i); + + if ( connection ) + { + Int_t ix = connection->GetLocalIx(); + Int_t iy = connection->GetLocalIy(); + + Double_t x,y,dx,dy; + + motif->GetPadDimensionsByIndices(ix,iy,dx,dy); + motif->PadPositionLocal(ix,iy,x,y); + + AliMUONPolygon* pol = new AliMUONPolygon(x,y,dx,dy); + polygons.Add(pol); + } + } + } + + AliMUONContourMaker maker; + + contour = maker.CreateContour(polygons); + + if (!contour || !contour->IsValid() ) + { + AliError(Form("Failed to properly create contour %s contour = %p",mpName.Data(),contour)); + if ( contour ) + { + AliError(Form("nofVertices=%d area.isvalid=%d",contour->NumberOfVertices(),contour->Area().IsValid())); + StdoutToAliError(contour->Area().Print();); + } + delete contour; + return 0x0; + } + + { + AliCodeTimerAuto("localmanucontour.add"); + fLocalManuContours.Add(new TObjString(mpName),contour); + } + + return static_cast(contour->Clone()); +} + +//_____________________________________________________________________________ +TObjArray* +AliMUONManuContourMaker::GenerateManuContours(Bool_t stopAtError) +{ + /// Generate the contours for all the manus, taking into account the given transformation + /// (to go from local to global). That transformation need not be the real one (i.e. + /// it can be an "exploded" one to ease visualization). + + AliCodeTimerAuto(""); + + TObjArray* manuContours = new TObjArray; + + manuContours->SetOwner(kTRUE); + + AliMpManuIterator it; + Int_t detElemId, manuId; + Int_t nmanus(0); + Int_t nok(0); + + while ( it.Next(detElemId,manuId) ) + { + ++nmanus; + AliMUONContour* contour = CreateManuContour(detElemId,manuId); + if (contour) + { + manuContours->Add(contour); + } + else + { + if ( stopAtError ) + { + break; + } + } + ++nok; + } + + AliInfo(Form("%d manus. %d contours successfully created",nmanus,nok)); + + return manuContours; +} + +//_____________________________________________________________________________ +TString +AliMUONManuContourMaker::NameIt(const AliMpMotifPosition& motifPosition) const +{ + /// Get the name of an AliMpMotifPosition + + AliMpVMotif* motif = motifPosition.GetMotif(); + TString name(Form("%s",motif->GetID().Data())); + + for ( Int_t i = 0; i < motif->GetNofPadDimensions(); ++i ) + { + name += Form("/%7.3f-%7.3f:",motif->GetPadDimensionX(i),motif->GetPadDimensionY(i)); + } + + return name; +} + +//_____________________________________________________________________________ +TString +AliMUONManuContourMaker::ManuPathName(Int_t detElemId, Int_t manuId, Bool_t withCathodeName) +{ + /// Get the name of a manu + + AliMp::PlaneType planeType; + if ( manuId & AliMpConstants::ManuMask(AliMp::kNonBendingPlane) ) + { + planeType = AliMp::kNonBendingPlane; + } + else + { + planeType = AliMp::kBendingPlane; + } + AliMp::CathodType cathodeType = AliMpDEManager::GetCathod(detElemId,planeType); + + Int_t chamberId = AliMpDEManager::GetChamberId(detElemId); + Int_t stationId = chamberId/2; + + Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId, manuId); + + AliMpUID id(cathodeType,stationId,chamberId,detElemId,busPatchId,manuId); + + if ( withCathodeName ) return id.PathName(); + + TString name(id.PathName()); + + name.ReplaceAll("Cathode0/",""); + name.ReplaceAll("Cathode1/",""); + + return name; +} + + + + diff --git a/MUON/AliMUONManuContourMaker.h b/MUON/AliMUONManuContourMaker.h new file mode 100644 index 00000000000..0dbea02a2b3 --- /dev/null +++ b/MUON/AliMUONManuContourMaker.h @@ -0,0 +1,56 @@ +#ifndef ALIMUONMANUCONTOURMAKER_H +#define ALIMUONMANUCONTOURMAKER_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONManuContourMaker +/// \brief Maker of AliMUONContour objects for all the tracker manus +/// +// Author Laurent Aphecetche, Subatech + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +#ifndef ROOT_TMap +# include "TMap.h" +#endif + +class AliMpExMap; +class AliMpMotifPosition; +class AliMUONContour; + +class AliMUONManuContourMaker : public TObject +{ +public: + AliMUONManuContourMaker(AliMpExMap* deTransformations); + virtual ~AliMUONManuContourMaker(); + + AliMUONContour* CreateManuContour(Int_t detElemId, Int_t manuId, const char* name="") const; + + AliMUONContour* CreateMotifContour(const AliMpMotifPosition& motifPosition) const; + + TObjArray* GenerateManuContours(Bool_t stopAtError=kFALSE); + + static TString ManuPathName(Int_t detElemId, Int_t manu, Bool_t withCathodeName=kTRUE); + +private: + /// not implemented + AliMUONManuContourMaker(const AliMUONManuContourMaker& rhs); + /// not implemented + AliMUONManuContourMaker& operator=(const AliMUONManuContourMaker& rhs); + + TString NameIt(const AliMpMotifPosition& motifPosition) const; + +private: + AliMpExMap* fDETransformations; //< map of detElemId to matrix + mutable TMap fLocalManuContours; //< map of local manu contours + + ClassDef(AliMUONManuContourMaker,1) // +}; + +#endif diff --git a/MUON/AliMUONNode.cxx b/MUON/AliMUONNode.cxx new file mode 100644 index 00000000000..ac98327c420 --- /dev/null +++ b/MUON/AliMUONNode.cxx @@ -0,0 +1,224 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// \class AliMUONNode +/// +/// A node of a segment tree +/// +/// For the details of the meaning of cardinality and potent data +/// members, please see Diane L. Souvaine and Iliana Bjorling-Sachs, +/// Proceedings of the IEEE, Vol. 80, No. 9, September 1992, p. 1449 +/// +/// +/// \Author Laurent Aphecetche, Subatech + +#include "AliMUONNode.h" + +#include "AliLog.h" +#include "AliMUONSegment.h" +#include "Riostream.h" +#include "TMath.h" +#include "TObjArray.h" +#include "TString.h" + +///\cond CLASSIMP +ClassImp(AliMUONNode) +///\endcond + +//_____________________________________________________________________________ +AliMUONNode::AliMUONNode(Double_t a, Double_t b, Double_t midpoint) +: fLeftNode(0x0), fRightNode(0x0), fMin(a), fMax(b), fMidPoint(midpoint), fC(0), fP(0) +{ + /// ctor +} + +//_____________________________________________________________________________ +AliMUONNode::~AliMUONNode() +{ + /// dtor + delete fLeftNode; + delete fRightNode; +} + +//_____________________________________________________________________________ +void +AliMUONNode::Print(const char* opt) const +{ + /// Printout + cout << opt << Form("[%7.2f,%7.2f]",fMin,fMax); + if ( !TMath::IsNaN(fMidPoint) ) cout << Form(" (%7.2f)",fMidPoint); + cout << endl; + + TString sopt(opt); + sopt += " "; + + if ( fLeftNode ) + { + fLeftNode->Print(sopt.Data()); + } + if ( fRightNode ) + { + fRightNode->Print(sopt.Data()); + } +} + +//_____________________________________________________________________________ +void +AliMUONNode::Contribution(Double_t b, Double_t e, TObjArray& stack) +{ + /// Contribution of an edge (b,e) to the final contour + if ( fMax < fMin ) + { + AliError(Form("fMax(%10.5f) < fMin(%10.5f",fMax,fMin)); + } + + if ( fC == 0 ) + { + if ( IsFullyContained(b,e) && fP == 0 ) + { + AliMUONSegment* back = static_cast(stack.Last()); + + if ( back && AliMUONSegment::AreEqual(back->EndY(),fMin) ) + { + // merge to existing segment + Double_t y(back->StartY()); + back->Set(0.0,y,0.0,fMax); + } + else + { + // add a new segment + stack.Add(new AliMUONSegment(0.0,fMin,0.0,fMax)); + } + } + else + { + if ( b < fMidPoint ) + { + fLeftNode->Contribution(b,e,stack); + } + if ( fMidPoint < e ) + { + fRightNode->Contribution(b,e,stack); + } + } + } +} + +//_____________________________________________________________________________ +Bool_t +AliMUONNode::IsFullyContained(Double_t b, Double_t e) const +{ + /// Whether this node's interval is fully contained into [b,e] + + return ( ( b < fMin || AliMUONSegment::AreEqual(b,fMin) ) && ( fMax < e || AliMUONSegment::AreEqual(e,fMax)) ); +} + +//_____________________________________________________________________________ +void +AliMUONNode::InsertInterval(Double_t b, Double_t e, TObjArray& stack) +{ + /// Insert an interval + if ( IsFullyContained(b,e) ) + { + C(1); + } + else + { + if ( b < fMidPoint ) + { + fLeftNode->InsertInterval(b,e,stack); + } + if ( fMidPoint < e ) + { + fRightNode->InsertInterval(b,e,stack); + } + } + Update(); +} + +//_____________________________________________________________________________ +void +AliMUONNode::DeleteInterval(Double_t b, Double_t e, TObjArray& stack) +{ + /// Delete an interval + if ( IsFullyContained(b,e) ) + { + C(-1); + } + else + { + if ( fC > 0 ) Demote(); + if ( b < fMidPoint ) + { + fLeftNode->DeleteInterval(b,e,stack); + } + + if ( fMidPoint < e ) + { + fRightNode->DeleteInterval(b,e,stack); + } + } + Update(); +} + +//_____________________________________________________________________________ +void +AliMUONNode::Update() +{ + /// Update internal values + if ( !fLeftNode ) + { + fP = 0; + } + else + { + if (fLeftNode->C() > 0 && fRightNode->C() > 0 ) + { + Promote(); + } + if (fLeftNode->C()==0 && fRightNode->C()==0 && fLeftNode->P()==0 && fRightNode->P()==0 ) + { + fP = 0; + } + else + { + fP = 1; + } + } +} + +//_____________________________________________________________________________ +void +AliMUONNode::Promote() +{ + /// Promote node + fLeftNode->C(-1); + fRightNode->C(-1); + C(+1); +} + +//_____________________________________________________________________________ +void +AliMUONNode::Demote() +{ + /// Demote node + fLeftNode->C(+1); + fRightNode->C(+1); + C(-1); + fP = 1; +} + diff --git a/MUON/AliMUONNode.h b/MUON/AliMUONNode.h new file mode 100644 index 00000000000..eac51b4707e --- /dev/null +++ b/MUON/AliMUONNode.h @@ -0,0 +1,77 @@ +#ifndef ALIMUONNODE_H +#define ALIMUONNODE_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONNode +/// \brief A node of a segment tree +/// +// author Laurent Aphecetche + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +class TObjArray; + +class AliMUONNode : public TObject +{ +public: + AliMUONNode(Double_t a, Double_t b, Double_t midpoInt_t); + virtual ~AliMUONNode(); + + void Print(const char* opt="") const; + + void Contribution(Double_t b, Double_t e, TObjArray& stack); + + void InsertInterval(Double_t b, Double_t e, TObjArray& stack); + + void DeleteInterval(Double_t b, Double_t e, TObjArray& stack); + + Bool_t IsFullyContained(Double_t b, Double_t e) const; + + void Update(); + + void Demote(); + + void Promote(); + + /// Get cardinality + Int_t C() const { return fC; } + + /// Increase cardinality + void C(Int_t v) { fC += v; } + + /// Get potent state + Int_t P() const { return fP; } + + /// Set left node + void LeftNode(AliMUONNode* n) { fLeftNode = n; } + + /// Set right node + void RightNode(AliMUONNode* n) { fRightNode = n; } + +private: + + /// not implemented + AliMUONNode(const AliMUONNode& node); + /// not implemented + AliMUONNode& operator=(const AliMUONNode& node); + AliMUONNode* fLeftNode; //< left node + AliMUONNode* fRightNode; //< right node + + Double_t fMin; //< Min + Double_t fMax; //< Max + Double_t fMidPoint; //< (Min+Max)/2 + + Int_t fC; //< cardinality + Int_t fP; //< potent state + + ClassDef(AliMUONNode,0); // A node of a segment tree +}; + +#endif diff --git a/MUON/AliMUONPainterContour.cxx b/MUON/AliMUONPainterContour.cxx deleted file mode 100644 index c0010d916e2..00000000000 --- a/MUON/AliMUONPainterContour.cxx +++ /dev/null @@ -1,317 +0,0 @@ -/************************************************************************** -* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * -* * -* Author: The ALICE Off-line Project. * -* Contributors are mentioned in the code where appropriate. * -* * -* Permission to use, copy, modify and distribute this software and its * -* documentation strictly for non-commercial purposes is hereby granted * -* without fee, provided that the above copyright notice appears in all * -* copies and that both the copyright notice and this permission notice * -* appear in the supporting documentation. The authors make no claims * -* about the suitability of this software for any purpose. It is * -* provided "as is" without express or implied warranty. * -**************************************************************************/ - -// $Id$ - -#include "AliMUONPainterContour.h" - -#include "AliMpArea.h" -#include "AliLog.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -///\class AliMUONPainterContour -/// -/// Contour for one painter. A contour is a set of TPolyLine (one polyline -/// per closed shape). -/// -///\author Laurent Aphecetche, Subatech - -///\cond CLASSIMP -ClassImp(AliMUONPainterContour) -///\endcond - -//_____________________________________________________________________________ -AliMUONPainterContour::AliMUONPainterContour(const char* name) : TNamed(name,""), -fPolyLines(new TObjArray), -fXmin(FLT_MAX), -fXmax(-FLT_MAX), -fYmin(FLT_MAX), -fYmax(-FLT_MAX) -{ - /// ctor - fPolyLines->SetOwner(kTRUE); -} - -//_____________________________________________________________________________ -AliMUONPainterContour::AliMUONPainterContour(const char* name, const AliMpArea& area) -: TNamed(name,""), -fPolyLines(new TObjArray), -fXmin(area.LeftBorder()), -fXmax(area.RightBorder()), -fYmin(area.DownBorder()), -fYmax(area.UpBorder()) -{ - /// ctor - fPolyLines->SetOwner(kTRUE); - TPolyLine* line = new TPolyLine(5); - Double_t x, y, dx, dy; - area.GetParameters(x, y, dx, dy); - line->SetPoint(0,x-dx,y-dy); - line->SetPoint(1,x-dx,y+dy); - line->SetPoint(2,x+dx,y+dy); - line->SetPoint(3,x+dx,y-dy); - line->SetPoint(4,x-dx,y-dy); - - fPolyLines->AddLast(line); -} - -//______________________________________________________________________________ -AliMUONPainterContour::AliMUONPainterContour(const AliMUONPainterContour& rhs) -: TNamed(rhs), -fPolyLines(0x0), -fXmin(FLT_MAX), -fXmax(-FLT_MAX), -fYmin(FLT_MAX), -fYmax(-FLT_MAX) -{ - /// Copy constructor. - - ((AliMUONPainterContour&)rhs).Copy(*this); -} - -//______________________________________________________________________________ -AliMUONPainterContour& -AliMUONPainterContour::operator=(const AliMUONPainterContour& rhs) -{ - /// Assignment operator - if ( this != &rhs ) - { - delete fPolyLines; - fPolyLines = 0; - rhs.Copy(*this); - } - return *this; -} - -//_____________________________________________________________________________ -AliMUONPainterContour::~AliMUONPainterContour() -{ - /// dtor - delete fPolyLines; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContour::AdoptPolyLine(TPolyLine* line) -{ - /// Adopt one polyline into our array of polylines - fPolyLines->AddLast(line); - for ( Int_t i = 0; i <= line->GetLastPoint(); ++i ) - { - Double_t x = line->GetX()[i]; - Double_t y = line->GetY()[i]; - fXmin = TMath::Min(fXmin,x); - fXmax = TMath::Max(fXmax,x); - fYmin = TMath::Min(fYmin,y); - fYmax = TMath::Max(fYmax,y); - } -} - -//_____________________________________________________________________________ -AliMpArea -AliMUONPainterContour::Area() const -{ - /// Return the area covered by this contour (i.e. the area that - /// contains all the poylines) - - return AliMpArea( ( fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 , - TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 ); -} - -//______________________________________________________________________________ -void AliMUONPainterContour::Copy(TObject& obj) const -{ - /// Copy this to obj - - AliMUONPainterContour& rhs = static_cast(obj); - TNamed::Copy(rhs); - rhs.fPolyLines = new TObjArray; - rhs.fPolyLines->SetOwner(kTRUE); - TIter next(fPolyLines); - TPolyLine* line; - while ( ( line = static_cast(next()) ) ) - { - rhs.fPolyLines->AddLast(line->Clone()); - } - rhs.fXmin = fXmin; - rhs.fXmax = fXmax; - rhs.fYmin = fYmin; - rhs.fYmax = fYmax; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContour::IsInside(Double_t x, Double_t y) const -{ - /// Whether the point (x,y) is inside one of ours polylines -// if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax ) - { - TIter next(fPolyLines); - TPolyLine* line; - while ( ( line = static_cast(next()) ) ) - { - if ( TMath::IsInside(x,y,line->Size(),line->GetX(),line->GetY() ) ) - { - return kTRUE; - } - } - } - return kFALSE; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContour::Offset(const TVector2& offset) -{ - /// Offset all lines by a given offset - - TIter next(fPolyLines); - TPolyLine* line; - - while ( ( line = static_cast(next()) ) ) - { - for ( Int_t i = 0; i <= line->GetLastPoint(); ++i ) - { - Double_t x = line->GetX()[i]; - Double_t y = line->GetY()[i]; - x += offset.X(); - y += offset.Y(); - line->SetPoint(i,x,y); - } - } - - fXmin += offset.X(); - fXmax += offset.X(); - fYmin += offset.Y(); - fYmax += offset.Y(); -} - -//_____________________________________________________________________________ -void -AliMUONPainterContour::PaintArea(Int_t fillColor, Int_t fillStyle) -{ - /// Paint a filled contour - - Int_t fc = gVirtualX->GetFillColor(); - Int_t fs = gVirtualX->GetFillStyle(); - - TIter next(fPolyLines); - TPolyLine* line; - - while ( ( line = static_cast(next()) ) ) - { - line->SetFillColor(fillColor); - line->SetFillStyle(fillStyle); - line->Paint("F"); - } - - gVirtualX->SetFillColor(fc); - gVirtualX->SetFillStyle(fs); -} - -//_____________________________________________________________________________ -void -AliMUONPainterContour::PaintOutline(Int_t lineColor, Int_t lineWidth) -{ - /// Paint the outline of this contour - - Int_t lc = gVirtualX->GetLineColor(); - Int_t lw = gVirtualX->GetLineWidth(); - - TIter next(fPolyLines); - TPolyLine* line; - - while ( ( line = static_cast(next()) ) ) - { - line->SetLineColor(lineColor); - line->SetLineWidth(lineWidth); - line->Paint(); - } - - gVirtualX->SetLineColor(lc); - gVirtualX->SetLineWidth(lw); -} - -//_____________________________________________________________________________ -void -AliMUONPainterContour::Print(Option_t* opt) const -{ - /// Printout - - cout << GetName() << " Ngroups=" << fPolyLines->GetLast()+1; - TString sopt(opt); - sopt.ToUpper(); - - TIter next(fPolyLines); - TPolyLine* line; - while ( ( line = static_cast(next()) ) ) - { - cout << " (" << line->Size() << ")"; - if ( sopt.Contains("FULL") ) - { - cout << endl; - for ( Int_t i = 0; i < line->Size(); ++i ) - { - Double_t x = line->GetX()[i]; - Double_t y = line->GetY()[i]; - cout << Form("Point %3d = %7.3f %7.3f",i,x,y) << endl; - } - } - } - cout << endl; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContour::Transform(const TGeoHMatrix& matrix) -{ - /// Transform the polylines using the given transformation - - TIter next(fPolyLines); - TPolyLine* line; - while ( ( line = static_cast(next()) ) ) - { - for ( Int_t i = 0; i < line->Size(); ++i ) - { - Double_t pl[3] = { line->GetX()[i], line->GetY()[i], 0 }; - Double_t pg[3] = { 0., 0., 0. }; - matrix.LocalToMaster(pl, pg); - line->SetPoint(i,pg[0],pg[1]); - } - } - - - Double_t pl[3] = { fXmin,fYmin, 0 }; - Double_t pg[3] = { 0., 0., 0. }; - matrix.LocalToMaster(pl, pg); - - fXmin = pg[0]; - fYmin = pg[1]; - - pl[0] = fXmax; - pl[1] = fYmax; - - matrix.LocalToMaster(pl, pg); - fXmax = pg[0]; - fYmax= pg[1]; -} diff --git a/MUON/AliMUONPainterContour.h b/MUON/AliMUONPainterContour.h deleted file mode 100644 index 6caec5df049..00000000000 --- a/MUON/AliMUONPainterContour.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef ALIMUONPAINTERCONTOUR_H -#define ALIMUONPAINTERCONTOUR_H - -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * -* See cxx source for full Copyright notice */ - -// $Id$ - -/// \ingroup graphics -/// \class AliMUONPainterContour -/// \brief Contour(s) of a painter -/// -// Author Laurent Aphecetche, Subatech - -#ifndef ROOT_TNamed -# include "TNamed.h" -#endif - -class AliMpArea; -class TObjArray; -class TPolyLine; -class TGeoHMatrix; -class TVector2; - -class AliMUONPainterContour : public TNamed -{ -public: - AliMUONPainterContour(const char* name=""); - AliMUONPainterContour(const char* name, const AliMpArea& area); - AliMUONPainterContour(const AliMUONPainterContour& rhs); - AliMUONPainterContour& operator=(const AliMUONPainterContour& rhs); - virtual ~AliMUONPainterContour(); - - AliMpArea Area() const; - - /// Add an offset to all points - void Offset(const TVector2& offset); - - /// Apply a global transformation to all points - void Transform(const TGeoHMatrix& matrix); - - void AdoptPolyLine(TPolyLine* line); - - virtual void Copy(TObject& obj) const; - - Bool_t IsInside(Double_t x, Double_t y) const; - - /// Paint the outline - void Paint(Option_t* ="") { PaintOutline(1,1); } - - void PaintOutline(Int_t lineColor, Int_t lineWidth); - - void PaintArea(Int_t fillColor, Int_t fillStyle=1001); - - virtual void Print(Option_t* opt="") const; - - /// Return as an array of polylines - const TObjArray* AsPolyLines() const { return fPolyLines; } - -private: - TObjArray* fPolyLines; ///< the polylines used to represent to contour - Double_t fXmin; ///< min x-value - Double_t fXmax; ///< max x-value - Double_t fYmin; ///< min y-value - Double_t fYmax; ///< max y-value - - ClassDef(AliMUONPainterContour,1) // Contour for one painter -}; - -#endif diff --git a/MUON/AliMUONPainterContourMaker.cxx b/MUON/AliMUONPainterContourMaker.cxx deleted file mode 100644 index f70f507e301..00000000000 --- a/MUON/AliMUONPainterContourMaker.cxx +++ /dev/null @@ -1,1572 +0,0 @@ -/************************************************************************** -* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * -* * -* Author: The ALICE Off-line Project. * -* Contributors are mentioned in the code where appropriate. * -* * -* Permission to use, copy, modify and distribute this software and its * -* documentation strictly for non-commercial purposes is hereby granted * -* without fee, provided that the above copyright notice appears in all * -* copies and that both the copyright notice and this permission notice * -* appear in the supporting documentation. The authors make no claims * -* about the suitability of this software for any purpose. It is * -* provided "as is" without express or implied warranty. * -**************************************************************************/ - -// $Id$ - -#include "AliMUONPainterContourMaker.h" - -#include "AliMUONPainterContour.h" -#include "AliMUONPainterHelper.h" -#include "AliMUONVCalibParam.h" -#include "AliMUONVDigit.h" -#include "AliMpConnection.h" -#include "AliMpConstants.h" -#include "AliMpDEManager.h" -#include "AliMpExMap.h" -#include "AliMpMotifMap.h" -#include "AliMpMotifPosition.h" -#include "AliMpMotifType.h" -#include "AliMpSector.h" -#include "AliMpSegmentation.h" -#include "AliMpSlat.h" -#include "AliMpStationType.h" -#include "AliMpVMotif.h" -#include "AliCodeTimer.h" -#include "AliLog.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/// \class AliMUONPainterContourMaker -/// -/// A class to build painter contours. -/// -/// The basics are to build one manu contour, and then to merge contours -/// to build higher order objects, like PCBS, DEs, etc... -/// -/// \author Laurent Aphecetche, Subatech - -///\cond CLASSIMP -ClassImp(AliMUONPainterContourMaker) -ClassImp(AliMUONPainterContourMaker::AliMUONNeighbour) -///\endcond - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::AliMUONNeighbour::Compare(const TObject* obj) const -{ - /// Compare two neighbours objects - - const AliMUONNeighbour* n = static_cast(obj); - - if ( Position().X() < n->Position().X() ) - { - return -1; - } - else if ( Position().X() > n->Position().X() ) - { - return 1; - } - else - { - // same X - if ( Position().Y() < n->Position().Y() ) - { - return -1; - } - else if ( Position().Y() > n->Position().Y() ) - { - return 1; - } - } - return 0; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::AliMUONNeighbour::Print(Option_t*) const -{ - /// Printout - cout << Form("ID %10d DE %4d Manu %4d Channel %2d " - "(X,Y)=(%7.3f,%7.3f) L,R,T,B=%1d,%1d,%1d,%1d", - ID(), - AliMUONVDigit::DetElemId(ID()), - AliMUONVDigit::ManuId(ID()), - AliMUONVDigit::ManuChannel(ID()), - Position().X(),Position().Y(), - HasLeftNeighbour(),HasRightNeighbour(), - HasTopNeighbour(),HasBottomNeighbour()) - << endl; -} - -//_____________________________________________________________________________ -AliMUONPainterContourMaker::AliMUONPainterContourMaker(AliMpExMap* globalTransformations) -: TObject(), - fGlobalTransformations(globalTransformations), - fLocalManuContours(new TMap), - fContours(new TMap) -{ - /// ctor - fContours->SetOwner(kTRUE); -} - -//_____________________________________________________________________________ -AliMUONPainterContourMaker::~AliMUONPainterContourMaker() -{ - /// dtor - fLocalManuContours->DeleteAll(); - delete fLocalManuContours; - fContours->DeleteAll(); - delete fContours; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::Add(AliMUONPainterContour* contour) -{ - /// Add a contour to our store of contours - fContours->Add(new TObjString(contour->GetName()),contour); -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::AddSegment(TObjArray& segments, Double_t x1, Double_t y1, - Double_t x2, Double_t y2, Int_t id) const -{ - /// Add one segment defined by (x1,y1,x2,y2) to the array of segments - AliCodeTimerAuto("") - AliDebug(1,Form("AddSegment %7.3f,%7.3f -> %7.3f,%7.3f",x1,y1,x2,y2)); - TLine* line = new TLine(x1,y1,x2,y2); - line->SetUniqueID(id); - segments.Add(line); -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::HasLine(const TObjArray& segments, - const TLine& line) const -{ - /// Check whether line is already part of segments array - - TIter next(&segments); - TLine* l; - - while ( ( l = static_cast(next()) ) ) - { - if ( IsEqual(line,*l) ) return kTRUE; - } - - return kFALSE; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::AddSegments(TObjArray& segments, - const AliMUONPainterContour& contour) const - -{ - /// Add all the segments (that are not already there) - /// of contour to the segments array - - AliCodeTimerAuto("") - - const TObjArray* pl = contour.AsPolyLines(); - - TIter next(pl); - - Int_t n(0); - - TPolyLine* line; - - while ( ( line = static_cast(next()) ) ) - { - n += line->GetLastPoint(); - } - - AliDebug(1,Form("Adding %d groups (%d lines) from contour %s ",pl->GetLast()+1,n,contour.GetName())); - - next.Reset(); - - while ( ( line = static_cast(next()) ) ) - { - AliDebug(1,"line="); -// StdoutToAliDebug(1,line->Print();); - for ( Int_t i = 0; i < line->GetLastPoint(); ++i ) - { - Double_t x1 = line->GetX()[i]; - Double_t y1 = line->GetY()[i]; - Double_t x2 = line->GetX()[i+1]; - Double_t y2 = line->GetY()[i+1]; - - TLine* l = new TLine(x1,y1,x2,y2); - - if ( !HasLine(segments,*l) ) - { - segments.Add(l); - AliDebug(1,Form("Adding line %s",LineAsString(*l).Data())); - } - else - { - AliDebug(1,Form("Line %s is already there",LineAsString(*l).Data())); - } - } - } -} - -//_____________________________________________________________________________ -AliMUONPainterContour* -AliMUONPainterContourMaker::ConvertEdgePadsToContour(TObjArray& ePads, - const char* name) const -{ - /// Convert an array of edge pads into a contour of a given name - - AliCodeTimerAuto("") - - ePads.Sort(); - - AliDebug(1,Form("%d pads to convert:",ePads.GetEntries())); -// StdoutToAliDebug(1,ePads.Print();) - - TObjArray segments; - segments.SetOwner(kTRUE); - - TIter nextPad(&ePads); - AliMUONNeighbour* ne; - - while ( ( ne = static_cast(nextPad()) ) ) - { - Int_t id = ne->ID(); - - if ( ! ne->HasLeftNeighbour() ) - { - AddSegment(segments,ne->LowerLeft().X(),ne->LowerLeft().Y(), - ne->LowerLeft().X(),ne->UpperRight().Y(),id); - } - if ( ! ne->HasRightNeighbour() ) - { - AddSegment(segments,ne->UpperRight().X(),ne->LowerLeft().Y(), - ne->UpperRight().X(),ne->UpperRight().Y(),id); - } - if ( ! ne->HasTopNeighbour() ) - { - AddSegment(segments,ne->LowerLeft().X(),ne->UpperRight().Y(), - ne->UpperRight().X(),ne->UpperRight().Y(),id); - } - if ( ! ne->HasBottomNeighbour() ) - { - AddSegment(segments,ne->LowerLeft().X(),ne->LowerLeft().Y(), - ne->UpperRight().X(),ne->LowerLeft().Y(),id); - } - } - - return ConvertSegmentsToContour(segments,name); -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::PrintLine(const TLine& line, const char* msg) const -{ - /// Printout of a line - cout << Form("%10s %s", - msg,LineAsString(line).Data()) << endl; -} - -//_____________________________________________________________________________ -TString -AliMUONPainterContourMaker::LineAsString(const TLine& line, Bool_t slope) const -{ - /// Return a string representation of the line - - TString rv(Form("%7.3f,%7.3f -> %7.3f,%7.3f", - line.GetX1(),line.GetY1(), - line.GetX2(),line.GetY2())); - - if ( slope ) - { - if ( IsHorizontal(line) ) rv += " H"; - else if ( IsVertical(line) ) rv += " V"; - else rv += Form(" (slope %e)",Slope(line)); - } - - return rv; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::PrintSegments(const TObjArray& segments) const -{ - /// Printout of segment arrays (debug) - - for ( Int_t i = 0; i <= segments.GetLast(); ++i ) - { - TLine* l = static_cast(segments.UncheckedAt(i)); - - cout << Form("***--- i %4d",i); - if ( l ) - { - PrintLine(*l); - } - else - { - cout << " line is null ?" << endl; - } - } -} - -//_____________________________________________________________________________ -TLine* -AliMUONPainterContourMaker::AddToLine(TPolyLine& line, TObjArray& segments, Int_t i) const -{ - /// Add one segment (taken from position i in array) into polyline - - AliDebug(1,Form("i=%d",i)); - TLine* l = static_cast(segments.UncheckedAt(i)); - if (l) - { - line.SetNextPoint(l->GetX1(),l->GetY1()); - line.SetNextPoint(l->GetX2(),l->GetY2()); - } - else - { - AliError(Form("Did not find the line at i=%d",i)); - PrintSegments(segments); - } - return l; -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::FindPoint(Double_t x, Double_t y, - TObjArray& segments) const -{ - /// Find if point (x,y) is in segments array, and return - /// its index (=position within array) - - TIter next(&segments); - TLine* l; - - while ( ( l = static_cast(next()) ) ) - { - if ( IsEqual(l->GetX1(),x) && IsEqual(l->GetY1(),y) ) - { - return segments.IndexOf(l); - } - } - AliError(Form("Did not find point %7.3f %7.3f in those segments:",x,y)); -// StdoutToAliDebug(1,PrintSegments(segments);); - return -1; -} - -//_____________________________________________________________________________ -AliMUONPainterContour* -AliMUONPainterContourMaker::ConvertSegmentsToContour(TObjArray& segments, - const char* name) const -{ - /// Convert an array of segments into a contour - - AliDebug(1,""); - AliCodeTimerAuto(""); - - AliMUONPainterContour* contour = new AliMUONPainterContour(name); - - Int_t n(0); // this is a protection against infinite loop (used for debug only) - - while ( segments.GetLast() >= 0 && n < 100 ) - { - TPolyLine lines; - TIter next(&segments); - TLine* l; - - while ( ( l = static_cast(next() ) ) ) - { - TLine* inserted = InsertSegment(lines,*l); - if ( inserted ) - { - segments.Remove(inserted); - next.Reset(); - } - - // check for closure - if ( IsLineClosed(lines) ) - { - AliDebug(1,"Line closed. Starting a new one"); - break; - } - } - - TPolyLine* sl = Simplify(lines); - - contour->AdoptPolyLine(sl); - ++n; - } - - if ( segments.GetLast() >= 0 ) - { - AliError("segment should be empty by now"); -// StdoutToAliError(PrintSegments(segments);); - } - - return contour; -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::FindPoint(const TPolyLine& lines, Double_t x, Double_t y) const -{ - /// Return position of (x,y) within the polyline - - AliCodeTimerAuto("") - - for ( Int_t i = 0; i < lines.Size(); ++i ) - { - if ( IsEqual(lines.GetX()[i],x) && IsEqual(lines.GetY()[i],y) ) - { - return i; - } - } - return -1; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::CleanSegments(TObjArray& segments, - const TArrayI& toBeRemoved) const -{ - /// Remove segments at indices stored in toBeRemoved array - for ( Int_t i = 0; i < toBeRemoved.GetSize(); ++i ) - { - if ( toBeRemoved[i] ) - { - segments.RemoveAt(i); - } - } - segments.Compress(); -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::SplitSegments(TObjArray& segments) const -{ - /// Split segments that have partial overlap - - AliCodeTimerAuto("") - - TArrayI toBeRemoved(segments.GetLast()+1); - toBeRemoved.Reset(0); - Bool_t added(kFALSE); - - for ( Int_t i = 0; i <= segments.GetLast() && !added; ++i ) - { - if ( toBeRemoved[i] ) continue; - - TLine* li = static_cast(segments.UncheckedAt(i)); - - for ( Int_t j = i+1; j <= segments.GetLast() && !added; ++j ) - { - if ( toBeRemoved[j] ) continue; - - TLine* lj = static_cast(segments.UncheckedAt(j)); - - Int_t o = Overlap(*li,*lj); - - if ( o ) - { - toBeRemoved[i] = toBeRemoved[j] = 1; - - Double_t x[] = { li->GetX1(), lj->GetX1(), li->GetX2(), lj->GetX2() }; - Double_t y[] = { li->GetY1(), lj->GetY1(), li->GetY2(), lj->GetY2() }; - - Double_t xmin(FLT_MAX), ymin(FLT_MAX); - Double_t xmax(-FLT_MAX), ymax(-FLT_MAX); - - for ( Int_t k = 0; k < 4; ++k ) - { - xmin = TMath::Min(x[k],xmin); - ymin = TMath::Min(y[k],ymin); - xmax = TMath::Max(x[k],xmax); - ymax = TMath::Max(y[k],ymax); - } - - TLine fullLine(xmin,ymin,xmax,ymax); - - for ( Int_t i1 = 0; i1 < 4; ++i1 ) - { - for ( Int_t j1 = i1+1; j1 < 4; ++j1 ) - { - if ( TMath::Abs(i1-j1) != 2 ) - { - TLine test(x[i1],y[i1],x[j1],y[j1]); - - Bool_t isFullLine = IsEqual(test,fullLine); - - if ( !IsPoint(test) && !isFullLine ) - { - segments.Add(new TLine(test)); - added = kTRUE; - } - } - } - } - } - } - } - - CleanSegments(segments,toBeRemoved); - - return added; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::ShouldBeRemoved(const TObjArray& contours, - Double_t x, Double_t y) const -{ - /// Tells whether or not a point can be removed, because it lies - /// inside the global contour - - const Double_t kPrecision(AliMpConstants::LengthTolerance()); - const Double_t kShiftX[] = { kPrecision,kPrecision,-kPrecision,-kPrecision }; - const Double_t kShiftY[] = { kPrecision,-kPrecision,kPrecision,-kPrecision }; - - TIter next(&contours); - AliMUONPainterContour* contour; - - Int_t n(0); - - while ( ( contour = static_cast(next()) ) ) - { - for ( Int_t i = 0; i < 4; ++i ) - { - if ( contour->IsInside( x + kShiftX[i], y + kShiftY[i]) ) - { - ++n; - } - } - } - - return (n>=4); -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::RemoveInsideSegments(const TObjArray& contours, - TObjArray& segments) const -{ - /// Remove segments that have 2 triple points - - AliCodeTimerAuto("") - - TArrayI toBeRemoved(segments.GetLast()+1); - toBeRemoved.Reset(0); - - for ( Int_t i = 0; i <= segments.GetLast(); ++i ) - { - TLine* line = static_cast(segments.UncheckedAt(i)); - - Double_t x = (line->GetX1() + line->GetX2())/2.0; - Double_t y = (line->GetY1() + line->GetY2())/2.0; - - if ( ShouldBeRemoved(contours,x,y) ) - { - toBeRemoved[i] = 1; - } - } - - Int_t before = segments.GetLast()+1; - - CleanSegments(segments,toBeRemoved); - - Int_t after = segments.GetLast()+1; - - AliDebug(1,Form("# of segments before = %d after = %d",before,after)); - - return after-before; -} - -//_____________________________________________________________________________ -AliMUONPainterContour* -AliMUONPainterContourMaker::MergeContours(const TObjArray& contours, - const char* contourName) const -{ - /// Merge an array of contours into a single contour, with a given name - - AliCodeTimerAuto(""); - - AliDebug(1,Form("Merging %d contours into %s",contours.GetLast()+1,contourName)); - - if ( contours.GetSize() == 0 ) return 0x0; - - TIter next(&contours); - AliMUONPainterContour* contour; - - TObjArray segments; - segments.SetOwner(kTRUE); - - while ( ( contour = static_cast(next()) ) ) - { - AddSegments(segments,*contour); - } - -// AliDebug(1,"After AddSegments"); -// StdoutToAliDebug(1,PrintSegments(segments)); - - while (SplitSegments(segments)) {} - -// AliDebug(1,"After SplitSegments"); -// StdoutToAliDebug(1,PrintSegments(segments)); - -// if (!SanityCheck(contours,segments)) -// { -// return 0x0; -// } - - RemoveInsideSegments(contours,segments); - -// if (!SanityCheck(contours,segments)) -// { -// return 0x0; -// } - -// AliDebug(1,"After RemoveInsideSegments"); -// StdoutToAliDebug(1,PrintSegments(segments);); - -// if (!SanityCheck(contours,segments)) -// { -// return 0x0; -// } - - return ConvertSegmentsToContour(segments,contourName); -} - -//_____________________________________________________________________________ -TString -AliMUONPainterContourMaker::NameIt(const AliMpMotifPosition& motifPosition) const -{ - /// Get the name of an AliMpMotifPosition - - AliMpVMotif* motif = motifPosition.GetMotif(); - TString name(Form("%s",motif->GetID().Data())); - - for ( Int_t i = 0; i < motif->GetNofPadDimensions(); ++i ) - { - name += Form("/%7.3f-%7.3f:",motif->GetPadDimensionX(i),motif->GetPadDimensionY(i)); - } - return name; -} - -//_____________________________________________________________________________ -AliMUONPainterContour* -AliMUONPainterContourMaker::FindLocalManuContour(Int_t detElemId, Int_t manuId) const -{ - /// Get a pre-computed manu contour (in local coordinates) - AliCodeTimerAuto("") - - AliMpMotifPosition* motifPos = FindMotifPosition(detElemId,manuId); - - TObject* o = fLocalManuContours->GetValue(NameIt(*motifPos)); - - if (o) return static_cast(o); - return 0x0; -} - -//_____________________________________________________________________________ -AliMpMotifPosition* -AliMUONPainterContourMaker::FindMotifPosition(Int_t detElemId, Int_t manuId) const -{ - /// Find a given motifPosition object - - AliCodeTimerAuto("") - - AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId); - - if ( stationType == AliMp::kStation345 ) - { - const AliMpSlat* kSlat - = AliMpSegmentation::Instance()->GetSlatByElectronics(detElemId,manuId); - if ( ! kSlat ) { - AliFatal(Form("Could not find motif for DE %d manu %d",detElemId,manuId)); - } - return kSlat->FindMotifPosition(manuId); - } - else - { - const AliMpSector* kSector - = AliMpSegmentation::Instance()->GetSectorByElectronics(detElemId,manuId); - if ( ! kSector ) { - AliFatal(Form("Could not find motif for DE %d manu %d",detElemId,manuId)); - } - return kSector->GetMotifMap()->FindMotifPosition(manuId); - } - return 0x0; -} - -//_____________________________________________________________________________ -AliMUONPainterContour* -AliMUONPainterContourMaker::GenerateManuContour(const char* name, - Int_t detElemId, Int_t manuId, - AliMUONAttPainter viewType) const -{ - /// Generate the contour for a given manu - - AliDebug(3,Form("DE %04d ManuID %04d Name %s",detElemId,manuId,name)); - - AliCodeTimerAuto("") - - AliMpMotifPosition* motifPosition = FindMotifPosition(detElemId,manuId); - AliMpVMotif* motif = motifPosition->GetMotif(); - - AliMUONPainterContour* contour = FindLocalManuContour(detElemId,manuId); - // do we already have the local contour for that manu ? - - // no : build it - if (!contour) - { - AliCodeTimerAuto("Generation of local contour"); - TObjArray ePads; - ePads.SetOwner(kTRUE); - AliMpMotifType* motifType = motif->GetMotifType(); - AliDebug(3,Form("motifType %s",motifType->GetID().Data())); - -// for ( Int_t i = 0; i <= motifType->GetNofPads(); ++i ) - for ( Int_t i = 0; i <= AliMpConstants::ManuNofChannels(); ++i ) - { -// AliMpConnection* connection = motifType->FindConnectionByPadNum(i); - AliMpConnection* connection = motifType->FindConnectionByGassiNum(i); - - AliDebug(3,Form("connection i =%d",i)); - - if ( connection ) - { - Int_t ix = connection->GetLocalIx(); - Int_t iy = connection->GetLocalIy(); - Bool_t left(kTRUE); - Bool_t right(kTRUE); - Bool_t top(kTRUE); - Bool_t bottom(kTRUE); - - if ( ! motifType->FindConnectionByLocalIndices(ix+1, iy) ) - { - right = kFALSE; - } - if ( ! motifType->FindConnectionByLocalIndices(ix-1, iy) ) - { - left = kFALSE; - } - if ( ! motifType->FindConnectionByLocalIndices(ix, iy+1) ) - { - top = kFALSE; - } - if ( ! motifType->FindConnectionByLocalIndices(ix, iy-1) ) - { - bottom = kFALSE; - } - - AliDebug(3,Form("indices=(%3d,%3d) L %d R %d T %d B %d", - ix,iy, left,right,top,bottom)); - - Double_t posx, posy; - motif->PadPositionLocal(ix, iy, posx, posy); - - Double_t dx, dy; - motif->GetPadDimensionsByIndices(ix, iy, dx, dy); - - if ( !left || !right || !top || !bottom ) - { - // the pad is on the edge - Int_t id = AliMUONVDigit::BuildUniqueID(detElemId,manuId, - connection->GetManuChannel(),0); - ePads.AddLast(new AliMUONNeighbour(id,TVector2(posx, posy),TVector2(dx, dy),left,right,top,bottom)); - } - } - } - - contour = ConvertEdgePadsToContour(ePads,NameIt(*motifPosition)); - - AliDebug(1,Form("localContour:")); -// StdoutToAliDebug(1,contour->Print("full")); - // register the local contour - fLocalManuContours->Add(new TObjString(contour->GetName()),contour); - } - - AliMUONPainterContour* globalContour = static_cast(contour->Clone(name)); - - // once we have the local contour, convert it to global - - TVector2 pos(motifPosition->GetPositionX(), motifPosition->GetPositionY()); - - if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 ) - { - const AliMpSlat* slat = AliMUONPainterHelper::Instance()->GetSlat(detElemId,manuId); - pos -= TVector2(slat->GetPositionX(),slat->GetPositionY()) ; - } - globalContour->Offset(pos); - TGeoHMatrix* matrix = static_cast(fGlobalTransformations->GetValue(detElemId)); - globalContour->Transform(*matrix); - - if ( viewType.IsBackView() ) - { - AliWarning("Got a back view : will rotate ! This has not been really tested. Please do so now !"); - TGeoRotation rot; - rot.RotateZ(180); - globalContour->Transform(rot); - } - - return globalContour; -} - -//_____________________________________________________________________________ -AliMUONPainterContour* -AliMUONPainterContourMaker::GetContour(const char* name) const -{ - /// Get contour by name - - TObject* o = fContours->GetValue(name); - return static_cast(o); -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::HasContour(const char* name) const -{ - /// Whether contour named "name" exists - TObject* o = fContours->GetValue(name); - if (o) return kTRUE; - return kFALSE; -} - -//_____________________________________________________________________________ -TLine* -AliMUONPainterContourMaker::InsertSegment(TPolyLine& lines, TLine& l) const -{ - /// Insert line into polyline, at the correct position - - AliCodeTimerAuto("") -// AliDebug(2,Form("Trying to insert %7.3f,%7.3f -> %7.3f,%7.3f from " -// "(DE,manu,ch)=(%d,%d,%d) into", -// l.GetX1(),l.GetY1(),l.GetX2(),l.GetY2(), -// AliMUONVDigit::DetElemId(l.GetUniqueID()), -// AliMUONVDigit::ManuId(l.GetUniqueID()), -// AliMUONVDigit::ManuChannel(l.GetUniqueID()))); - - if ( lines.Size()==0 ) - { -// AliDebug(2,"Starting line"); -// - lines.SetNextPoint(l.GetX1(),l.GetY1()); - lines.SetNextPoint(l.GetX2(),l.GetY2()); - return &l; - } - - Int_t i1 = FindPoint(lines,l.GetX1(),l.GetY1()); - Int_t i2 = FindPoint(lines,l.GetX2(),l.GetY2()); - - if ( i1 < 0 && i2 < 0 ) - { -// AliDebug(2,"Not yet"); - return 0x0; - } - - if ( i1 >= 0 && i2 >= 0 ) - { - if ( i1==0 ) - { - lines.SetNextPoint(l.GetX1(),l.GetY1()); - } - else if ( i2==0 ) - { - lines.SetNextPoint(l.GetX2(),l.GetY2()); - } - else - { - AliError("Segment already there but does not correspond to ending the polyline !"); - AliError(Form("Segment is %7.3f,%7.3f -> %7.3f,%7.3f and existing points are : ", - l.GetX1(),l.GetY1(),l.GetX2(),l.GetY2())); - - for ( Int_t i = 0; i < lines.Size(); ++i ) - { - AliError(Form("Point %2d X %7.3f Y %7.3f",i,lines.GetX()[i],lines.GetY()[i])); - } -// TObject* o(0x0); -// o->Print(); // to crash and throw gdb... - } - return &l; - } - - Double_t x = (i1>=0) ? l.GetX2() : l.GetX1(); - Double_t y = (i1>=0) ? l.GetY2() : l.GetY1(); - - Int_t iref = ( i1 >= 0 ? i1 : i2 ) ; - - Bool_t firstPoint = ( iref == 0 ); - - if ( firstPoint ) - { - // must insert segment before - lines.SetPolyLine(lines.Size()+1); -// AliDebug(2,Form("Inserting %7.3f,%7.3f",x,y)); - for ( Int_t i = lines.Size()-1; i > 0; --i ) - { - lines.SetPoint(i,lines.GetX()[i-1],lines.GetY()[i-1]); - } - lines.SetPoint(0,x,y); - } - else - { -// AliDebug(2,Form("Appending %7.3f,%7.3f",x,y)); - lines.SetNextPoint(x,y); - } - - return &l; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsEqual(Double_t x, Double_t y) const -{ - /// Whether x==y - - if ( TMath::Abs(x-y) < AliMpConstants::LengthTolerance() ) return kTRUE; - else return kFALSE; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsEqual(const TLine& line1, - const TLine& line2) const -{ - /// Whether line1 == line2 - - Bool_t check1 = - IsEqual(line1.GetX1(),line2.GetX1()) && - IsEqual(line1.GetY1(),line2.GetY1()) && - IsEqual(line1.GetX2(),line2.GetX2()) && - IsEqual(line1.GetY2(),line2.GetY2()); - - Bool_t check2 = - IsEqual(line1.GetX1(),line2.GetX2()) && - IsEqual(line1.GetY1(),line2.GetY2()) && - IsEqual(line1.GetX2(),line2.GetX1()) && - IsEqual(line1.GetY2(),line2.GetY1()); - - return (check1 || check2); -} - -//_____________________________________________________________________________ -Double_t -AliMUONPainterContourMaker::Slope(const TLine& line) const -{ - /// Get the slope of line - - Double_t x = TMath::Abs(line.GetX2() - line.GetX1()); - - if ( x < AliMpConstants::LengthTolerance() ) return FLT_MAX; - - return TMath::Abs(line.GetY2() - line.GetY1())/x; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsPoint(const TLine& line) const -{ - /// Whether the line is a point (sic ;-) ) - return - IsEqual(line.GetX1(),line.GetX2()) && - IsEqual(line.GetY1(),line.GetY2()); -} - -//_____________________________________________________________________________ -TLine -AliMUONPainterContourMaker::Shift(const TLine& line, Double_t x, Double_t y) const -{ - /// Shift the line by a given offset - - return TLine(line.GetX1()-x,line.GetY1()-y,line.GetX2()-x,line.GetY2()-y); -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::SameDirection(const TLine& line1, const TLine& line2) const -{ - /// Whether both lines have the same direction. - - TLine l1 = Shift(line1,line1.GetX1(),line1.GetY1()); - TLine l2 = Shift(line2,line2.GetX1(),line2.GetY1()); - - Double_t v = l1.GetX2()*l2.GetX2() + l1.GetY2()*l2.GetY2(); - - return v > 0 ; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::Swap(TLine& line) const -{ - /// Swap both points of the line - - Double_t x = line.GetX1(); - Double_t y = line.GetY1(); - - line.SetX1(line.GetX2()); - line.SetY1(line.GetY2()); - line.SetX2(x); - line.SetY2(y); -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::IsInRange(Double_t x, Double_t a, Double_t b, - Bool_t strict) const -{ - /// Whether w is in [a,b] (if strict=kFALSE) or in ]a,b[ (if strict=kTRUE) - - if ( a > b ) - { - Double_t tmp(b); - b = a; - a = tmp; - } - - Bool_t rv(kFALSE); - - if ( strict ) - { - rv = ( x > a && x < b ); - } - else - { - rv = ( x >= a && x <= b); - } - - AliDebug(4,Form("x = %7.3f a = %7.3f b = %7.3f strict = %d IsInRange = %d",x,a,b,strict,rv)); - - return rv; -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::IsInLine(const TLine& line, - Double_t x, - Double_t y, - Bool_t strict) const -{ - /// Check whether point (x,y) is belonging to the line segment - /// by computing the distance point to line - /// line1 must not be a single point. - /// Returns the number of *coordinates* that matches, for a point - /// that lies on line (if point is not on the line, returns 0 always). - /// For instance, if (x,y) is on the line (and strict=kFALSE), - /// it will return 1 if x *or* y corresponds to line.GetX1() or X2 or Y1 or Y2, - /// and 2 if the pair (x,y) corresponds to one of the line points. - - Double_t x1 = line.GetX1(); - Double_t x2 = line.GetX2(); - Double_t y1 = line.GetY1(); - Double_t y2 = line.GetY2(); - - Double_t distance = TMath::Abs( (x2-x1)*(y1-y) - (x1-x)*(y2-y1) ); - - distance /= TMath::Sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); - - Bool_t online = ( distance < AliMpConstants::LengthTolerance() ) ; - - Int_t rv(0); - - if (online) - { - // point is on the line, - // check in addition that it's within the segment - - rv = IsInRange(x,x1,x2,strict) + IsInRange(y,y1,y2,strict); - } - else - { - rv = 0; - } - - AliDebug(4,Form("Point (%7.3f,%7.3f) isinline=%d in line %s", - x,y,rv,LineAsString(line).Data())); - - return rv; -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::IsInside(const TLine& line1, - const TLine& line2, - Bool_t useEndPoints) const -{ - /// Check whether one or both points of line2 are within line1. - /// Both line1 and line2 must have the same slope - /// and the same direction - - if (!IsEqual(Slope(line1),Slope(line2))) return 0; - - TLine l2(line2); - - if (!SameDirection(line1,line2)) - { - Swap(l2); - } - - Int_t rv = - IsInLine(line1,l2.GetX1(),l2.GetY1(),!useEndPoints) + - IsInLine(line1,l2.GetX2(),l2.GetY2(),!useEndPoints); - - assert(rv<=4); - - return rv; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsInside(const TObjArray& segments, - const TLine& line) const -{ - /// Whether the segment (line) is contained inside the contour defined - /// by all the segments (i.e. is it on the boundary or not) - /// Basic (and dirty) implementation only working with horizontal and vertical lines. - /// I know there must be a better way to do it, but it took me way too long - /// to get this stuff working, so I'm giving up on the optimisation/cleaning, - /// at least for now... - /// If you'd like to clean this (while keeping it working in all cases), be - /// my guest and do it ;-) ) - - Int_t p1 = CountPoint(segments,line.GetX1(),line.GetY1()); - Int_t p2 = CountPoint(segments,line.GetX2(),line.GetY2()); - - Bool_t triplet = ( p1 >= 3 || p2 >= 3 ); - - AliDebug(4,Form("IsInside(segments,%s) triplet=%d", - LineAsString(line).Data(),triplet)); - - if (!triplet) return kFALSE; - - Bool_t top(kFALSE), bottom(kFALSE), left(kFALSE), right(kFALSE); - - Bool_t vertical(IsVertical(line)); - Bool_t horizontal(IsHorizontal(line)); - - if (!vertical && !horizontal ) - { - AliFatal("Only working with horizontal and vertical lines"); - } - - for ( Int_t i = 0; i <= segments.GetLast(); ++i ) - { - TLine* l = static_cast(segments.UncheckedAt(i)); - - if ( IsEqual(*l,line) ) continue; - - if ( vertical && IsVertical(*l) ) - { - TLine tmpLine(l->GetX1(),line.GetY1(), - l->GetX1(),line.GetY2()); - - AliDebug(4,Form("i=%2d VV\nIsInside(l=%s,%s)=%d\nIsInside(%s,l=%s)=%d", - i, - LineAsString(*l).Data(),LineAsString(tmpLine).Data(), - IsInside(*l,tmpLine,kTRUE), - LineAsString(tmpLine).Data(),LineAsString(*l).Data(), - IsInside(tmpLine,*l,kTRUE))); - - if ( IsInside(*l,tmpLine,kTRUE) == 4 || IsInside(tmpLine,*l,kTRUE) == 4 ) - { - if ( l->GetX1() > line.GetX1() ) - { - right = kTRUE; - } - else - { - left = kTRUE; - } - } - } - - if ( vertical && IsHorizontal(*l) ) - { - if ( !IsEqual(l->GetY1(),line.GetX1()) && - !IsEqual(l->GetY1(),line.GetY2()) && - IsInLine(*l,line.GetX1(),l->GetY1(),kFALSE)==2 ) - { - if ( line.GetY2() < l->GetY1() ) - { - top = kTRUE; - } - else if ( line.GetY2() > l->GetY1() ) - { - bottom = kTRUE; - } - } - } - - if ( horizontal && IsHorizontal(*l) ) - { - TLine tmpLine(line.GetX1(),l->GetY1(), - line.GetX2(),l->GetY1()); - - AliDebug(4,Form("i=%2d HH\nIsInside(%s,%s)=%d\nIsInside(%s,%s)=%d", - i, - LineAsString(*l).Data(),LineAsString(tmpLine).Data(), - IsInside(*l,tmpLine), - LineAsString(tmpLine).Data(),LineAsString(*l).Data(), - IsInside(tmpLine,*l))); - - if ( IsInside(*l,tmpLine) == 4 || IsInside(tmpLine,*l) == 4 ) - { - if ( l->GetY1() > line.GetY1() ) - { - top = kTRUE; - } - else - { - bottom = kTRUE; - } - } - } - - if ( horizontal && IsVertical(*l) ) - { - if ( !IsEqual(l->GetX1(),line.GetX1()) && - !IsEqual(l->GetX1(),line.GetX2()) && - IsInLine(*l,l->GetX1(),line.GetY1(),kFALSE)==2 ) - { - if ( line.GetX2() < l->GetX1() ) - { - right = kTRUE; - } - else if ( line.GetX2() > l->GetX1() ) - { - left = kTRUE; - } - } - } - - } - - Bool_t rv(kFALSE); - - AliDebug(3,Form("%s %s R %d L %d T %d B% d IsInside %d", - IsVertical(line) ? - "Vertical " : - "Horizontal", - LineAsString(line,kFALSE).Data(),right,left,top,bottom,rv)); - - if ( vertical ) - { - rv = (right && left) && ( top || bottom ); - } - - if ( horizontal ) - { - rv = (top && bottom) && ( right || left ); - } - - return rv; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsHorizontal(const TLine& line) const -{ - /// whether line is horizontal - - static Double_t l2 = AliMpConstants::LengthTolerance()*AliMpConstants::LengthTolerance(); - - return ( Slope(line) < l2 ); -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsVertical(const TLine& line) const -{ - /// whether line is vertical - - return ( TMath::Abs(Slope(line)) == FLT_MAX ); -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::Overlap(const TLine& line1, - const TLine& line2) const -{ - /// Whether line1 and line2 overlap - - Int_t rv(0); - - if ( IsEqual(line1,line2) ) - { - // First things first. If both lines are the same one, - // they for sure overlap ;-) - rv = 4; - } - else - { - rv = IsInside(line1,line2) + IsInside(line2,line1); - } - - AliDebug(3,Form("%s and %s : overlap=%d", - LineAsString(line1).Data(), - LineAsString(line2).Data(), - rv)); - - return rv; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::IsLineClosed(const TPolyLine& line) const -{ - /// check if polyline is already closed (i.e. last point = first point) - - Double_t* x = line.GetX(); - Double_t* y = line.GetY(); - - if ( IsEqual(x[line.GetLastPoint()],x[0]) && - IsEqual(y[line.GetLastPoint()],y[0]) ) - { - return kTRUE; - } - else - { - return kFALSE; - } -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::Local2Global(Int_t detElemId, - Double_t xl, Double_t yl, Double_t zl, - Double_t& xg, Double_t& yg, Double_t& zg) const -{ - /// Convert local coordinates to global ones - TGeoHMatrix* matrix = static_cast(fGlobalTransformations->GetValue(detElemId)); - Double_t pl[3] = { xl, yl, zl }; - Double_t pg[3] = { 0., 0., 0. }; - matrix->LocalToMaster(pl, pg); - xg = pg[0]; - yg = pg[1]; - zg = pg[2]; -} - -//_____________________________________________________________________________ -void -AliMUONPainterContourMaker::Print(Option_t* opt) const -{ - /// Printout - - cout << "Local Contours" << endl; - - TIter next(fLocalManuContours); - TObjString* key; - - while ( ( key = static_cast(next()) ) ) - { - cout << key->String().Data() << endl; - AliMUONPainterContour* contour = static_cast(fLocalManuContours->GetValue(key)); - contour->Print(opt); - } - - cout << "Global Contours" << endl; - - TIter nextC(fContours); - - while ( ( key = static_cast(nextC()) ) ) - { - AliMUONPainterContour* contour = static_cast(fContours->GetValue(key)); - contour->Print(opt); - } -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::CountPoint(const TObjArray& segments, - Double_t x, Double_t y) const -{ - /// Count the number of times the point (x,y) appears in the segment array - - Int_t n(0); - - for ( Int_t i = 0; i <= segments.GetLast(); ++i ) - { - TLine* line = static_cast(segments.UncheckedAt(i)); - - if ( IsEqual(x,line->GetX1()) && - IsEqual(y,line->GetY1()) ) - { - ++n; - } - - if ( IsEqual(x,line->GetX2()) && - IsEqual(y,line->GetY2()) ) - { - ++n; - } - } - - return n; -} - -//_____________________________________________________________________________ -Bool_t -AliMUONPainterContourMaker::SanityCheck(const TObjArray& contours, - const TObjArray& segments, Bool_t check) const -{ - /// (debug) check - - Bool_t ok(kTRUE); - - // cross-check that we have no more complete duplicates - // and that we have no orphan point - - Double_t xmin(FLT_MAX), xmax(-FLT_MAX); - Double_t ymin(FLT_MAX), ymax(-FLT_MAX); - - for ( Int_t i = 0; i <= segments.GetLast(); ++i ) - { - TLine* li = static_cast(segments.UncheckedAt(i)); - - if (!IsHorizontal(*li) && !IsVertical(*li)) - { - AliError("Got an oblique line !"); - return kFALSE; - } - - xmin = TMath::Min(xmin,li->GetX1()); - xmin = TMath::Min(xmin,li->GetX2()); - - xmax = TMath::Max(xmax,li->GetX1()); - xmax = TMath::Max(xmax,li->GetX2()); - - ymin = TMath::Min(ymin,li->GetY1()); - ymin = TMath::Min(ymin,li->GetY2()); - - ymax = TMath::Max(ymax,li->GetY1()); - ymax = TMath::Max(ymax,li->GetY2()); - - } - - AliDebug(1,Form("xmin=%7.3f ymin=%7.3f xmax=%7.3f ymax=%7.3f", - xmin,ymin,xmax,ymax)); - - for ( Int_t i = 0; i <= segments.GetLast(); ++i ) - { - TLine* li = static_cast(segments.UncheckedAt(i)); - - if (!check) - { - for ( Int_t j = 0; j <= segments.GetLast(); ++j ) - { - TLine* lj = static_cast(segments.UncheckedAt(j)); - - if ( i != j && IsEqual(*li,*lj) ) - { - ok = kFALSE; - PrintLine(*li); - PrintLine(*lj); - AliFatal(""); - } - } - } - - - Int_t rv(0); - - Double_t x = (li->GetX1()+li->GetX2())/2.0; - Double_t y = (li->GetY1()+li->GetY2())/2.0; - - if ( ShouldBeRemoved(contours,x,y) ) rv = 1; - - AliDebug(1,Form("Line %4d %7.3f,%7.3f -> %7.3f,%7.3f [ %d ]", - i, - li->GetX1(),li->GetY1(), - li->GetX2(),li->GetY2(), - rv)); - } - - return kTRUE; -} - -//_____________________________________________________________________________ -TPolyLine* -AliMUONPainterContourMaker::Simplify(const TPolyLine& lines) const -{ - /// try to simplify the polyline, by minimizing the number of points - - if ( lines.Size() < 3 ) - { - AliError("Cannot simplify lines with less that 3 points !"); - return 0x0; - } - - AliCodeTimerAuto("") - -// cout << "Before simplify" << endl; -// -// for ( Int_t i = 0; i < lines.Size(); ++i ) -// { -// cout << Form("Point %3d %7.3f %7.3f",i,lines.GetX()[i],lines.GetY()[i]) << endl; -// } - - TPolyLine* l = new TPolyLine; - - Double_t* x = lines.GetX(); - Double_t* y = lines.GetY(); - - l->SetNextPoint(x[0],y[0]); - - Bool_t verticalCurrent = IsEqual(x[1],x[0]); - Bool_t horizontalCurrent = IsEqual(y[1],y[0]); - - Int_t i(2); - - while ( i < lines.Size() ) - { - Bool_t vertical = IsEqual(x[i],x[i-1]); - Bool_t horizontal = IsEqual(y[i],y[i-1]); - -// cout << Form("i %3d %7.3f %7.3f vert %d horiz %d (current vert %d horiz %d)", -// i,x[i],y[i],vertical,horizontal,verticalCurrent,horizontalCurrent) -// << endl; - - if ( ( vertical != verticalCurrent ) || - ( horizontal != horizontalCurrent ) ) - { -// cout << Form("Changing direction : adding point %7.3f %7.3f",x[i-1],y[i-1]) << endl; - l->SetNextPoint(x[i-1],y[i-1]); - verticalCurrent = vertical; - horizontalCurrent = horizontal; - } - ++i; - } - - l->SetNextPoint(l->GetX()[0],l->GetY()[0]); - -// cout << "After simplify" << endl; -// -// for ( Int_t i = 0; i < l->Size(); ++i ) -// { -// cout << Form("Point %3d %7.3f %7.3f",i,l->GetX()[i],l->GetY()[i]) << endl; -// } - - return l; -} - -//_____________________________________________________________________________ -Int_t -AliMUONPainterContourMaker::Size() const -{ - /// Number of contours we have already - - return fContours->GetSize(); -} - diff --git a/MUON/AliMUONPainterContourMaker.h b/MUON/AliMUONPainterContourMaker.h deleted file mode 100644 index 7c0582d6c51..00000000000 --- a/MUON/AliMUONPainterContourMaker.h +++ /dev/null @@ -1,234 +0,0 @@ -#ifndef ALIMUONPAINTERCONTOURMAKER_H -#define ALIMUONPAINTERCONTOURMAKER_H - -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * -* See cxx source for full Copyright notice */ - -// $Id$ - -/// \ingroup graphics -/// \class AliMUONPainterContourMaker -/// \brief Utility class to build painter contours -/// -// Author Laurent Aphecetche, Subatech - -#ifndef ROOT_TVector2 -# include "TVector2.h" -#endif - -#ifndef ROOT_TObject -# include "TObject.h" -#endif - -#ifndef ALIMUONVPAINTER_H -# include "AliMUONVPainter.h" -#endif - -class AliMpExMap; -class AliMpMotifPosition; -class AliMUONAttPainter; -class AliMUONPainterContour; -class AliMUONPainterPadStore; -class TArrayI; -class TMap; -#include -class TPolyLine; -class TObjArray; - -class AliMUONPainterContourMaker : public TObject -{ -public: - AliMUONPainterContourMaker(AliMpExMap* globalTransformations=0x0); - virtual ~AliMUONPainterContourMaker(); - - void Add(AliMUONPainterContour* contour); - - AliMUONPainterContour* FindLocalManuContour(Int_t detElemId, Int_t manuId) const; - - AliMUONPainterContour* GetContour(const char* name) const; - - AliMUONPainterContour* GenerateManuContour(const char* name, - Int_t detElemId, - Int_t manuId, - AliMUONAttPainter viewType) const; - - Bool_t HasContour(const char* name) const; - - AliMUONPainterContour* MergeContours(const TObjArray& contours, - const char* contourName) const; - - Int_t Size() const; - - void Print(Option_t* opt="") const; - -public: - - /// \ingroup graphics - /// \brief Store information about one pad's neighbours. - /// \author Laurent Aphecetche, Subatech - class AliMUONNeighbour : public TObject - { -public: - /// default ctor - AliMUONNeighbour() - : fID(-1), fPosition(), fDimensions(), - fLeft(kFALSE), fRight(kFALSE), - fTop(kFALSE), fBottom(kFALSE) {} - - /// normal ctor - AliMUONNeighbour(Int_t absID, - const TVector2& position, - const TVector2& dimensions, - Bool_t hasLeftNeighbour, Bool_t hasRightNeighbour, - Bool_t hasTopNeighbour, Bool_t hasBottomNeighbour) - : fID(absID), fPosition(position), fDimensions(dimensions), - fLeft(hasLeftNeighbour), fRight(hasRightNeighbour), - fTop(hasTopNeighbour), fBottom(hasBottomNeighbour) {} - - /// dtor - virtual ~AliMUONNeighbour() {} - - /// we are sortable - virtual Bool_t IsSortable() const { return kTRUE; } - - virtual Int_t Compare(const TObject* object) const; - - /// our id - Int_t ID() const { return fID; } - - /// Whether we have a neighbour on our left - Bool_t HasLeftNeighbour() const { return fLeft; } - /// Whether we have a neighbour on our right - Bool_t HasRightNeighbour() const { return fRight; } - /// Whether we have a neighbour above - Bool_t HasTopNeighbour() const { return fTop; } - /// Whether we have a neighbour below - Bool_t HasBottomNeighbour() const { return fBottom; } - - /// Our position - TVector2 Position() const { return fPosition; } - /// Our (half-)dimensions - TVector2 Dimensions() const { return fDimensions; } - - /// Lower left corner - TVector2 LowerLeft() const { return fPosition - fDimensions; } - /// Upper right corner - TVector2 UpperRight() const { return fPosition + fDimensions; } - - void Print(Option_t* opt="") const; - - /// Set our position - void SetPosition(Double_t x, Double_t y) { fPosition.Set(x,y); } - -private: - Int_t fID; ///< id of the pad - TVector2 fPosition; ///< position - TVector2 fDimensions; ///< (half)dimension - Bool_t fLeft; ///< do we have a neighbour on our left ? - Bool_t fRight; ///< do we have a neighbour on our right ? - Bool_t fTop; ///< do we have a neighbour on top of us ? - Bool_t fBottom; ///< do we have a neighbour below us ? - - ClassDef(AliMUONNeighbour,1) // Neighbour internal class - }; - - -public: - - - void AddSegments(TObjArray& segments, const AliMUONPainterContour& contour) const; - - void AddSegment(TObjArray& segments, Double_t x1, Double_t y1, - Double_t x2, Double_t y2, Int_t padID) const; - - TLine* AddToLine(TPolyLine& line, TObjArray& segments, Int_t i) const; - - AliMpMotifPosition* FindMotifPosition(Int_t detElemId, Int_t manuId) const; - - Int_t FindPoint(const TPolyLine& lines, Double_t x, Double_t y) const; - - Int_t FindPoint(Double_t x, Double_t y, TObjArray& segments) const; - - TLine* InsertSegment(TPolyLine& lines, TLine& l) const; - - using TObject::IsEqual; - - Bool_t IsEqual(Double_t x, Double_t y) const; - - Int_t Overlap(const TLine& line1, const TLine& line2) const; - - Bool_t IsLineClosed(const TPolyLine& line) const; - - AliMUONPainterContour* ConvertEdgePadsToContour(TObjArray& edgePads, const char* name) const; - - AliMUONPainterContour* ConvertSegmentsToContour(TObjArray& segments, const char* name) const; - - void Local2Global(Int_t detElemId, Double_t xl, Double_t yl, Double_t zl, - Double_t& xg, Double_t& yg, Double_t& zg) const; - - TString NameIt(const AliMpMotifPosition& motifPosition) const; - - TPolyLine* Simplify(const TPolyLine& lines) const; - - Double_t Slope(const TLine& line) const; - - Bool_t IsPoint(const TLine& line) const; - - void PrintLine(const TLine& line, const char* msg="") const; - - void PrintSegments(const TObjArray& segments) const; - - Bool_t SameDirection(const TLine& line1, const TLine& line2) const; - - void Swap(TLine& line) const; - - TLine Shift(const TLine& line, Double_t x, Double_t y) const; - - Int_t IsInside(const TLine& line1, const TLine& line2, - Bool_t useEndPoints=kFALSE) const; - - Bool_t IsInside(const TObjArray& segments, const TLine& line) const; - - Int_t IsInLine(const TLine& line, Double_t x, Double_t y, - Bool_t strict=kTRUE) const; - - Bool_t IsEqual(const TLine& line1, const TLine& line2) const; - - Bool_t SanityCheck(const TObjArray& contours, const TObjArray& segments, Bool_t check=kTRUE) const; - - TString LineAsString(const TLine& line, Bool_t slope=kTRUE) const; - - Int_t IsInRange(Double_t x, Double_t a, Double_t b, - Bool_t strict=kTRUE) const; - - Bool_t HasLine(const TObjArray& segments, const TLine& line) const; - - void CleanSegments(TObjArray& segments, const TArrayI& toBeRemoved) const; - - Int_t SplitSegments(TObjArray& segments) const; - - Int_t RemoveInsideSegments(const TObjArray& contours, TObjArray& segments) const; - - Bool_t IsHorizontal(const TLine& line) const; - - Bool_t IsVertical(const TLine& line) const; - - Int_t CountPoint(const TObjArray& segments, Double_t x, Double_t y) const; - - Bool_t ShouldBeRemoved(const TObjArray& contours, Double_t x, Double_t y) const; - -private: - /// not implemented - AliMUONPainterContourMaker(const AliMUONPainterContourMaker& rhs); - /// not implemented - AliMUONPainterContourMaker& operator=(const AliMUONPainterContourMaker& rhs); - - AliMpExMap* fGlobalTransformations; ///< store of global transformations for DEs - TMap* fLocalManuContours; ///< store for local contours of all manus - TMap* fContours; ///< store for all our contours - - ClassDef(AliMUONPainterContourMaker,1) // Painter contour builder -}; - -#endif - diff --git a/MUON/AliMUONPainterDataRegistry.cxx b/MUON/AliMUONPainterDataRegistry.cxx new file mode 100644 index 00000000000..b3294fce601 --- /dev/null +++ b/MUON/AliMUONPainterDataRegistry.cxx @@ -0,0 +1,279 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id: AliMUONPainterDataRegistry.cxx 26812 2008-06-20 15:22:59Z laphecet $ + +#include "AliMUONPainterDataRegistry.h" + +#include "AliMpManuIterator.h" +#include "AliMUON2DMap.h" +#include "AliMUONCalibParamND.h" +#include "AliMUONTrackerData.h" +#include "AliMUONVTrackerDataMaker.h" +#include "AliLog.h" +#include +#include +#include +#include + +///\class AliMUONPainterDataRegistry +/// +/// Registry for AliMUONVPainter related stuff : painter data sources +/// and painter matrices +/// +///\author Laurent Aphecetche, Subatech + +///\cond CLASSIMP +ClassImp(AliMUONPainterDataRegistry) +///\endcond + +AliMUONPainterDataRegistry* AliMUONPainterDataRegistry::fgInstance(0x0); + +//_____________________________________________________________________________ +AliMUONPainterDataRegistry::AliMUONPainterDataRegistry() : TObject(), TQObject(), +fDataMakers(new TObjArray), +fZombies(new TObjArray), +fInteractiveReadOutConfig(0x0) +{ + /// ctor + fDataMakers->SetOwner(kTRUE); + fZombies->SetOwner(kTRUE); +} + +//_____________________________________________________________________________ +AliMUONPainterDataRegistry::~AliMUONPainterDataRegistry() +{ + /// dtor + delete fDataMakers; + delete fInteractiveReadOutConfig; +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::CreateInteractiveReadOutConfig() const +{ + /// Create a base config + + fInteractiveReadOutConfig = new AliMUONTrackerData("IROC","IROC",1); + fInteractiveReadOutConfig->SetDimensionName(0,"Switch"); + fInteractiveReadOutConfig->DisableChannelLevel(); + AliMpManuIterator it; + Int_t detElemId; + Int_t manuId; + AliMUON2DMap store(true); + + while ( it.Next(detElemId,manuId) ) + { + AliMUONVCalibParam* param = new AliMUONCalibParamND(1,64,detElemId,manuId,1); + store.Add(param); + } + fInteractiveReadOutConfig->Add(store); +} + +//_____________________________________________________________________________ +AliMUONVTrackerDataMaker* +AliMUONPainterDataRegistry::DataMaker(Int_t i) const +{ + /// Get one data source + if ( i >= 0 && i <= fDataMakers->GetLast() ) + { + return static_cast(fDataMakers->At(i)); + } + else + { + AliError(Form("Index out of bounds : %d / %d",i,fDataMakers->GetLast()+1)); + return 0x0; + } +} + +//_____________________________________________________________________________ +AliMUONVTrackerData* +AliMUONPainterDataRegistry::DataSource(Int_t i) const +{ + /// Get one data source + + AliMUONVTrackerDataMaker* maker = DataMaker(i); + if ( maker ) return maker->Data(); + return 0x0; +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::DataMakerWasRegistered(AliMUONVTrackerDataMaker* data) +{ + /// A new reader source was registered + Long_t param[] = { (Long_t)data }; + + Emit("DataMakerWasRegistered(AliMUONVTrackerDataMaker*)",param); +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::DataMakerWasUnregistered(AliMUONVTrackerDataMaker* data) +{ + /// A data reader was unregistered + Long_t param[] = { (Long_t)data }; + + Emit("DataMakerWasUnregistered(AliMUONVTrackerDataMaker*)",param); + +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::DataSourceWasRegistered(AliMUONVTrackerData* data) +{ + /// A new data source was registered + Long_t param[] = { (Long_t)data }; + + Emit("DataSourceWasRegistered(AliMUONVTrackerData*)",param); +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::DataSourceWasUnregistered(AliMUONVTrackerData* data) +{ + /// A data source was unregistered + Long_t param[] = { (Long_t)data }; + + Emit("DataSourceWasUnregistered(AliMUONVTrackerData*)",param); + +} + +//_____________________________________________________________________________ +AliMUONVTrackerData* +AliMUONPainterDataRegistry::DataSource(const char* name) const +{ + /// Find a data source by name + for ( Int_t i = 0; i < NumberOfDataMakers(); ++i ) + { + AliMUONVTrackerData* data = DataMaker(i)->Data(); + if ( data ) + { + TString dname(data->GetName()); + if ( dname == name ) return data; + } + } + return 0x0; +} + +//_____________________________________________________________________________ +AliMUONPainterDataRegistry* +AliMUONPainterDataRegistry::Instance() +{ + /// Get unique instance of this class + if ( !fgInstance ) fgInstance = new AliMUONPainterDataRegistry; + return fgInstance; +} + +//_____________________________________________________________________________ +AliMUONVTrackerData* +AliMUONPainterDataRegistry::InteractiveReadOutConfig() const +{ + /// Return an object that contains the parts of the detector selected + /// (using the mouse) to be part of the readout. + + if (!fInteractiveReadOutConfig) CreateInteractiveReadOutConfig(); + return fInteractiveReadOutConfig; +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::Print(Option_t* opt) const +{ + /// Printout + TString sopt(opt); + sopt.ToUpper(); + + cout << "Number of data readers = " << NumberOfDataMakers() << endl; + + if ( sopt.Contains("FULL") || sopt.Contains("READER") || sopt.Contains("DATA") ) + { + TIter next(fDataMakers); + AliMUONVTrackerDataMaker* reader; + + while ( ( reader = static_cast(next()) ) ) + { + if ( sopt.Contains("DATA") ) + { + AliMUONVTrackerData* data = reader->Data(); + if ( data ) data->Print(); + } + else + { + reader->Print(); + } + } + } +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::Register(AliMUONVTrackerDataMaker* reader) +{ + /// reader is adopted, i.e. the registry becomes the owner of it. + fDataMakers->AddLast(reader); + DataMakerWasRegistered(reader); + if ( reader->Data() ) DataSourceWasRegistered(reader->Data()); +} + +//_____________________________________________________________________________ +Int_t +AliMUONPainterDataRegistry::NumberOfDataMakers() const +{ + /// The number of data readers we handle + return fDataMakers->GetLast()+1; +} + +//_____________________________________________________________________________ +void +AliMUONPainterDataRegistry::DeleteZombies() +{ + /// Delete zombies + fZombies->Delete(); +} + +//_____________________________________________________________________________ +Bool_t +AliMUONPainterDataRegistry::Unregister(AliMUONVTrackerDataMaker* reader) +{ + /// Unregister some reader + + if (!reader) return kFALSE; + + if ( reader->Data() ) + { + DataSourceWasUnregistered(reader->Data()); + reader->Data()->Destroyed(); // we pretend it's deleted now, even + // if it will be only later on when zombie are killed, so that + // for instance painters depending on it will no longer try to access it + } + + DataMakerWasUnregistered(reader); + + TObject* o = fDataMakers->Remove(reader); + + fZombies->Add(o); // for later deletion + +// if ( o ) +// { +// delete o; +// } +// else +// { +// AliError(Form("Could not unregister data named %s title %s",reader->GetName(), +// reader->GetTitle())); +// } + return ( o != 0x0 ); +} diff --git a/MUON/AliMUONPainterDataRegistry.h b/MUON/AliMUONPainterDataRegistry.h new file mode 100644 index 00000000000..ae0a8c70f7b --- /dev/null +++ b/MUON/AliMUONPainterDataRegistry.h @@ -0,0 +1,81 @@ +#ifndef ALIMUONPAINTERDATAREGISTRY_H +#define ALIMUONPAINTERDATAREGISTRY_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id: AliMUONPainterDataRegistry.h 26812 2008-06-20 15:22:59Z laphecet $ + +/// \ingroup graphics +/// \class AliMUONPainterDataRegistry +/// \brief Registry for painter data sources +/// +// Author Laurent Aphecetche, Subatech + +#ifndef ROOT_TObject +# include "TObject.h" +#endif +#ifndef ROOT_TQObject +# include +#endif + +class TObjArray; +class AliMUONVTrackerData; +class AliMUONVTrackerDataMaker; + +class AliMUONPainterDataRegistry : public TObject, public TQObject +{ +public: + virtual ~AliMUONPainterDataRegistry(); + + AliMUONVTrackerDataMaker* DataMaker(Int_t i) const; + + AliMUONVTrackerData* DataSource(Int_t i) const; + + AliMUONVTrackerData* DataSource(const char* name) const; + + AliMUONVTrackerData* InteractiveReadOutConfig() const; + + void DataSourceWasRegistered(AliMUONVTrackerData* data); // *SIGNAL* + + void DataSourceWasUnregistered(AliMUONVTrackerData* data); // *SIGNAL* + + void DataMakerWasRegistered(AliMUONVTrackerDataMaker* reader); // *SIGNAL* + + void DataMakerWasUnregistered(AliMUONVTrackerDataMaker* reader); // *SIGNAL* + + static AliMUONPainterDataRegistry* Instance(); + + Int_t NumberOfDataMakers() const; + + /// Number of data sources = data makers + Int_t NumberOfDataSources() const { return NumberOfDataMakers(); } + + void Print(Option_t* opt) const; + + void Register(AliMUONVTrackerDataMaker* reader); + + Bool_t Unregister(AliMUONVTrackerDataMaker* reader); + + void DeleteZombies(); + +private: + /// Not implemented + AliMUONPainterDataRegistry(); + /// Not implemented + AliMUONPainterDataRegistry(const AliMUONPainterDataRegistry&); + /// Not implemented + AliMUONPainterDataRegistry& operator=(const AliMUONPainterDataRegistry&); + + void CreateInteractiveReadOutConfig() const; + +private: + static AliMUONPainterDataRegistry* fgInstance; ///< unique instance + TObjArray* fDataMakers; ///< data makers + TObjArray* fZombies; ///< data readers to be deleted + mutable AliMUONVTrackerData* fInteractiveReadOutConfig; ///< clickable readout configuration + + ClassDef(AliMUONPainterDataRegistry,1) // Registry for AliMUONVTrackerDataMaker objects +}; + +#endif diff --git a/MUON/AliMUONPointWithRef.cxx b/MUON/AliMUONPointWithRef.cxx new file mode 100644 index 00000000000..2c38730034a --- /dev/null +++ b/MUON/AliMUONPointWithRef.cxx @@ -0,0 +1,89 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +///\class AliMUONPointWithRef +/// +/// A class used to represent a point with an external integer reference +/// and with a specific sorting method (see AliMUONContourMaker) +/// +/// \author Laurent Aphecetche, Subatech +/// + +#include "AliMUONPointWithRef.h" + +#include "AliMUONSegment.h" +#include "Riostream.h" +#include "TString.h" + +//\cond CLASSIMP +ClassImp(AliMUONPointWithRef) +//\endcond + +//_____________________________________________________________________________ +AliMUONPointWithRef::AliMUONPointWithRef() : fX(), fY(), fRef(-1) +{ + /// ctor +} + +//_____________________________________________________________________________ +AliMUONPointWithRef::AliMUONPointWithRef(Double_t x, Double_t y, Int_t ref) +: fX(x), fY(y), fRef(ref) +{ + /// dtor +} + +//_____________________________________________________________________________ +Int_t +AliMUONPointWithRef::Compare(const TObject* obj) const +{ + // Should serve to sort the vertical edges in ascending order, first on absissa, + // then on ordinate + + if ( this == obj ) return 0; + + const AliMUONPointWithRef* rhs = static_cast(obj); + + if ( AliMUONSegment::AreEqual(Y(),rhs->Y()) ) + { + if ( AliMUONSegment::AreEqual(X(),rhs->X()) ) + { + return 0; + } + else if ( X() > rhs->X() ) + { + return 1; + } + else + return -1; + } + else if ( Y() < rhs->Y() ) + { + return -1; + } + else + { + return 1; + } +} + +//_____________________________________________________________________________ +void +AliMUONPointWithRef::Print(Option_t*) const +{ + /// Printout + cout << Form("(%10.5f,%10.5f) [%4d]",X(),Y(),Ref()) << endl; +} diff --git a/MUON/AliMUONPointWithRef.h b/MUON/AliMUONPointWithRef.h new file mode 100644 index 00000000000..33fe4646fb6 --- /dev/null +++ b/MUON/AliMUONPointWithRef.h @@ -0,0 +1,47 @@ +#ifndef ALIMUONPOINTWITHREF_H +#define ALIMUONPOINTWITHREF_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONPointWithRef +/// \brief A TVector2 with an integer ref, and a specific Compare +/// +// author Laurent Aphecetche + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +class AliMUONPointWithRef : public TObject +{ +public: + AliMUONPointWithRef(Double_t x, Double_t y, Int_t ref); + AliMUONPointWithRef(); + virtual ~AliMUONPointWithRef() {} + + /// We are sortable + virtual Bool_t IsSortable() const { return kTRUE; } + + virtual Int_t Compare(const TObject* obj) const; + + Double_t X() const { return fX; } + + Double_t Y() const { return fY; } + + Int_t Ref() const { return fRef; } + + void Print(Option_t* opt="") const; + +private: + Double_t fX; //< x value + Double_t fY; //< y value + Int_t fRef; //< index of the original point in some array + + ClassDef(AliMUONPointWithRef,1) // A point with an external integer reference +}; + +#endif diff --git a/MUON/AliMUONPolygon.cxx b/MUON/AliMUONPolygon.cxx new file mode 100644 index 00000000000..5aa62b70fcf --- /dev/null +++ b/MUON/AliMUONPolygon.cxx @@ -0,0 +1,208 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// \class AliMUONPolygon +/// +/// A simple planar polygon, with a given orientation +/// +/// \author Laurent Aphecetche, Subatech + +#include "AliMUONPolygon.h" + +#include "AliLog.h" +#include "Riostream.h" +#include "TMath.h" + +///\cond CLASSIMP +ClassImp(AliMUONPolygon) +///\endcond + +//_____________________________________________________________________________ +AliMUONPolygon::AliMUONPolygon(Int_t nvertices) +: TObject(), +fN(nvertices), +fX(new Double_t[fN]), +fY(new Double_t[fN]) +{ + /// Ctor with a predefined number of vertices. +} + +//_____________________________________________________________________________ +AliMUONPolygon::AliMUONPolygon(Double_t xpos, Double_t ypos, Double_t halfsizex, Double_t halfsizey) +: TObject(), +fN(5), +fX(new Double_t[fN]), +fY(new Double_t[fN]) +{ + /// Ctor. Polygon will be a rectangle. + + + double xmin(xpos-halfsizex); + double xmax(xpos+halfsizex); + double ymin(ypos-halfsizey); + double ymax(ypos+halfsizey); + + SetVertex(0,xmin,ymin); + SetVertex(1,xmax,ymin); + SetVertex(2,xmax,ymax); + SetVertex(3,xmin,ymax); + + Close(); +} + + +//_____________________________________________________________________________ +AliMUONPolygon::~AliMUONPolygon() +{ + /// dtor + delete[] fX; + delete[] fY; +} + +//______________________________________________________________________________ +AliMUONPolygon::AliMUONPolygon(const AliMUONPolygon& rhs) +: TObject(rhs), +fN(0), +fX(0x0), +fY(0x0) +{ + /// Copy constructor. + + ((AliMUONPolygon&)rhs).Copy(*this); +} + +//______________________________________________________________________________ +AliMUONPolygon& +AliMUONPolygon::operator=(const AliMUONPolygon& rhs) +{ + /// Assignment operator + if ( this != &rhs ) + { + rhs.Copy(*this); + } + return *this; +} + +//______________________________________________________________________________ +Bool_t +AliMUONPolygon::Contains(Double_t x, Double_t y) const +{ + /// Whether the polygon contains point (x,y) + + // Note that the polygon must be a closed polygon (1st and last point + // must be identical), which should be the case here. + + return TMath::IsInside(x,y,fN,fX,fY); +} + +//______________________________________________________________________________ +void AliMUONPolygon::Copy(TObject& obj) const +{ + /// Copy this to obj + + AliMUONPolygon& rhs = static_cast(obj); + + Double_t* x = new Double_t[fN]; + Double_t* y = new Double_t[fN]; + + for ( Int_t i = 0; i < fN; ++i ) + { + x[i] = fX[i]; + y[i] = fY[i]; + } + + delete rhs.fX; + delete rhs.fY; + + rhs.fX = x; + rhs.fY = y; + rhs.fN = fN; +} + +//_____________________________________________________________________________ +void +AliMUONPolygon::Close() +{ + /// Make that last point = first point + + SetVertex(fN-1,X(0),Y(0)); +} + +//_____________________________________________________________________________ +void AliMUONPolygon::Print(Option_t*) const +{ + /// Printout + cout << Form("AliMUONPolygon : %3d vertices. Signed Area=%e",NumberOfVertices(),SignedArea()) << endl; + for ( Int_t i = 0; i < NumberOfVertices(); ++i ) + { + cout << Form("%10.5f,%10.5f",X(i),Y(i)) << endl; + } +} + +//_____________________________________________________________________________ +Double_t +AliMUONPolygon::SignedArea() const +{ + /// Compute the signed area of this polygon + /// Algorithm from F. Feito, J.C. Torres and A. Urena, + /// Comput. & Graphics, Vol. 19, pp. 595-600, 1995 + + Double_t area(0.0); + + for ( Int_t i = 0; i < NumberOfVertices()-1; ++i ) + { + area += X(i)*Y(i+1) - X(i+1)*Y(i); + } + + return area; +} + +//_____________________________________________________________________________ +void +AliMUONPolygon::ReverseOrientation() +{ + /// Reverse the orientation of this polygon + Double_t* x = new Double_t[fN]; + Double_t* y = new Double_t[fN]; + + for ( Int_t i = fN-1; i >= 0; --i ) + { + x[i] = X(fN-i-1); + y[i] = Y(fN-i-1); + } + + delete[] fX; + delete[] fY; + + fX = x; + fY = y; +} + +//_____________________________________________________________________________ +void +AliMUONPolygon::SetVertex(Int_t i, Double_t x, Double_t y) +{ + /// Set one vertex + if ( i >= fN ) + { + TObject* o(0x0); + o->Print(); // to crash + } + fX[i] = x; + fY[i] = y; +} + diff --git a/MUON/AliMUONPolygon.h b/MUON/AliMUONPolygon.h new file mode 100644 index 00000000000..c49baddbf35 --- /dev/null +++ b/MUON/AliMUONPolygon.h @@ -0,0 +1,61 @@ +#ifndef ALIMUONPOLYGON_H +#define ALIMUONPOLYGON_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONPolygon +/// \brief A planar polygon +/// +// author Laurent Aphecetche + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +class AliMUONPolygon : public TObject +{ +public: + AliMUONPolygon(Int_t nvertices=5); + AliMUONPolygon(Double_t xpos, Double_t ypos, Double_t halfsizex, Double_t halfsizey); + AliMUONPolygon(const AliMUONPolygon& rhs); + AliMUONPolygon& operator=(const AliMUONPolygon& rhs); + virtual ~AliMUONPolygon(); + + virtual TObject* Clone(const char* /*newname*/="") const { return new AliMUONPolygon(*this); } + + Bool_t Contains(Double_t x, Double_t y) const; + + Double_t SignedArea() const; + + /// Whether this polygon is oriented counter clockwise + Bool_t IsCounterClockwiseOriented() const { return SignedArea() > 0.0; } + + void ReverseOrientation(); + + void SetVertex(Int_t i, Double_t x, Double_t y); + + Double_t X(Int_t i) const { return fX[i]; } + + Double_t Y(Int_t i) const { return fY[i]; } + + Int_t NumberOfVertices() const { return fN; } + + void Print(Option_t* opt="") const; + + void Copy(TObject& obj) const; + + void Close(); + +private: + Int_t fN; /// Number of vertices + Double_t* fX; //[fN] + Double_t* fY; //[fN] + + ClassDef(AliMUONPolygon,1) // A simple polygon +}; + +#endif diff --git a/MUON/AliMUONSegment.cxx b/MUON/AliMUONSegment.cxx new file mode 100644 index 00000000000..4a463b2f70c --- /dev/null +++ b/MUON/AliMUONSegment.cxx @@ -0,0 +1,148 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// \class AliMUONSegment +/// +/// A basic line segment, to be used in contour making algorithms. +/// +/// In particular, this class defines what a left or right edge is. +/// +/// Also, please note that, due to the way Root collections are sorted (relying +/// on TObject::Compare method), the way the AliMUONSegment::Compare method +/// is implemented below is really important when it comes to understand +/// contour making algorithm. Keep that in mind. +/// +/// \author Laurent Aphecetche, Subatech +/// + +#include "AliMUONSegment.h" + +#include "TMath.h" +#include "Riostream.h" +#include "AliMpConstants.h" + +/// \cond CLASSIMP +ClassImp(AliMUONSegment) +/// \endcond + +const Double_t AliMUONSegment::fgkPrecision(AliMpConstants::LengthTolerance()); + +//_____________________________________________________________________________ +AliMUONSegment::AliMUONSegment() : +TObject(), +fStartX(), fStartY(), fEndX(), fEndY(), fSmallerY(), fIsHorizontal(), fIsVertical(), +fIsLeftEdge(), fIsRightEdge(), fIsAPoint(kTRUE) +{ + /// Ctor + Set(fStartX,fStartY,fEndX,fEndY); +} + +//_____________________________________________________________________________ +AliMUONSegment::AliMUONSegment(Double_t xstart, Double_t ystart, Double_t xend, Double_t yend) +: TObject(), +fStartX(xstart), fStartY(ystart), fEndX(xend), fEndY(yend), fSmallerY(), fIsHorizontal(), fIsVertical(), +fIsLeftEdge(), fIsRightEdge(), fIsAPoint(kTRUE) +{ + /// Ctor + Set(xstart,ystart,xend,yend); +} + +//_____________________________________________________________________________ +Bool_t +AliMUONSegment::AreEqual(double a, double b) +{ + /// Whether the two floats are equal within the given precision + return (TMath::Abs(b-a) < fgkPrecision); +} + +//_____________________________________________________________________________ +Int_t +AliMUONSegment::Compare(const TObject* obj) const +{ + /// Compare method, which sort segments in ascending x order + /// if same x, insure that left edges are before right edges + /// within same x, order by increasing bottommost y + /// Mind your steps ! This method is critical to the contour merging algorithm ! + + const AliMUONSegment* rhs = static_cast(obj); + + if ( AreEqual(StartX(),rhs->StartX()) ) + { + if ( IsLeftEdge() && rhs->IsRightEdge() ) return -1; + if ( IsRightEdge() && rhs->IsLeftEdge() ) return 1; + if ( SmallerY() < rhs->SmallerY() ) return -1; + if ( SmallerY() > rhs->SmallerY() ) return 1; + return 0; + } + else if ( StartX() < rhs->StartX() ) + { + return -1; + } + else //if ( StartX() > rhs->StartX() ) + { + return 1; + } +} + +//_____________________________________________________________________________ +double AliMUONSegment::Top() const +{ + /// Max Y of the segment + return TMath::Max(fStartY,fEndY); +} + +//_____________________________________________________________________________ +double AliMUONSegment::Distance() const +{ + /// Length of the segment + return TMath::Sqrt((fStartX-fEndX)*(fStartX-fEndX) + + (fStartY-fEndY)*(fStartY-fEndY)); +} + +//_____________________________________________________________________________ +void AliMUONSegment::Print(Option_t*) const +{ + /// Printout + cout << AsString() << endl; +} + +//_____________________________________________________________________________ +const char* AliMUONSegment::AsString() const +{ + /// Return a string representation of this object + return Form("[ (%10.5f,%10.5f) -> (%10.5f,%10.5f) %s ] (d=%e)",fStartX,fStartY,fEndX,fEndY, + IsLeftEdge() ? "L" : ( IsRightEdge() ? "R" : ( IsHorizontal() ? "H" : "" )), + Distance() ); +} + +//_____________________________________________________________________________ +void +AliMUONSegment::Set(Double_t xstart, Double_t ystart, Double_t xend, Double_t yend) +{ + /// Set start and end point, and (re)compute internal values + fStartX = xstart; + fEndX = xend; + fStartY = ystart; + fEndY = yend; + fSmallerY = TMath::Min(fStartY,fEndY); + fIsHorizontal = AreEqual(fStartY,fEndY); + fIsVertical = AreEqual(fStartX,fEndX); + fIsLeftEdge = fIsVertical && ( fStartY > fEndY ); + fIsRightEdge = fIsVertical && ( fStartY < fEndY ); + fIsAPoint = ( Distance() < fgkPrecision ); +} + diff --git a/MUON/AliMUONSegment.h b/MUON/AliMUONSegment.h new file mode 100644 index 00000000000..4e987f95b91 --- /dev/null +++ b/MUON/AliMUONSegment.h @@ -0,0 +1,91 @@ +#ifndef ALIMUONSEGMENT_H +#define ALIMUONSEGMENT_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONSegment +/// \brief A basic line segment, used for contour making algorithm(s) +/// +// author Laurent Aphecetche + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +class AliMUONSegment : public TObject +{ +public: + AliMUONSegment(); + AliMUONSegment(Double_t xstart, Double_t ystart, Double_t xend, Double_t yend); + virtual ~AliMUONSegment() {} + + virtual Int_t Compare(const TObject* obj) const; + + /// We are sortable + virtual Bool_t IsSortable() const { return kTRUE; } + + /// Return the x-coordinate of our starting point + Double_t StartX() const { return fStartX; } + /// Return the y-coordinate of our starting point + Double_t StartY() const { return fStartY; } + /// Return the x-coordinate of our ending point + Double_t EndX() const { return fEndX; } + /// Return the y-coordinate of our ending point + Double_t EndY() const { return fEndY; } + + /// Return our smallest y (of starting or ending point) + double SmallerY() const { return fSmallerY; } + + /// Whether we are a horizontal segment + Bool_t IsHorizontal() const { return fIsHorizontal; } + + /// Whethere we are a vertical segment + Bool_t IsVertical() const { return fIsVertical; } + + /// Whether we are a left edge + Bool_t IsLeftEdge() const { return fIsLeftEdge; } + + /// Whether we are a right edge + Bool_t IsRightEdge() const { return fIsRightEdge; } + + /// Return our bottom y + double Bottom() const { return SmallerY(); } + + double Top() const; + + double Distance() const; + + /// Whether we're just a point + Bool_t IsAPoint() const { return fIsAPoint; } + + const char* AsString() const; + + static Bool_t AreEqual(double a, double b); + + void Print(Option_t* opt="") const; + + void Set(Double_t xstart, Double_t ystart, Double_t xend, Double_t yend); + +private: + Double_t fStartX; /// x of start point + Double_t fStartY; /// y of start point + Double_t fEndX; /// x of end point + Double_t fEndY; /// y of end point + Double_t fSmallerY; /// Either StartY or EndY + Bool_t fIsHorizontal; /// Whether the segment is horizontal + Bool_t fIsVertical; /// Whether the segment is vertical + Bool_t fIsLeftEdge; /// Whether the segment is a left edge + Bool_t fIsRightEdge; /// Whether the segment is a right edge + Bool_t fIsAPoint; /// Whether start==end + + static const Double_t fgkPrecision; /// Floating point precision used in comparisons + + ClassDef(AliMUONSegment,1) // A basic line segment +}; + + +#endif diff --git a/MUON/AliMUONSegmentTree.cxx b/MUON/AliMUONSegmentTree.cxx new file mode 100644 index 00000000000..e987ba53b8c --- /dev/null +++ b/MUON/AliMUONSegmentTree.cxx @@ -0,0 +1,118 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +/// +/// \class AliMUONSegmentTree +/// +/// Implementation of a segment tree, which is used to make contour +/// merging (see AliMUONContourMaker) +/// +/// \author Laurent Aphecetche, Subatech +/// + +#include "AliMUONSegmentTree.h" + +#include "AliLog.h" +#include "AliMUONNode.h" +#include "Riostream.h" +#include "TArrayD.h" +#include "TMath.h" + +/// \cond CLASSIMP +ClassImp(AliMUONSegmentTree) +/// \endcond + +//_____________________________________________________________________________ +AliMUONSegmentTree::AliMUONSegmentTree(const TArrayD& values) +: fRoot(0x0), fStack() +{ + /// Values should be sorted and have at least 2 elements. + + fStack.SetOwner(kTRUE); + + if ( values.GetSize() < 2 ) + { + AliError("cannot build a segmenttree with less than 2 values !"); + TObject* forceACrash(0x0); + forceACrash->Print(); + } + + fRoot = Build(values,0,values.GetSize()-1); +} + +//_____________________________________________________________________________ +AliMUONSegmentTree::~AliMUONSegmentTree() +{ + /// dtor + delete fRoot; +} + +//_____________________________________________________________________________ +AliMUONNode* +AliMUONSegmentTree::Build(const TArrayD& values, Int_t i, Int_t j) +{ + /// Build the segment tree from a list of values + + double midpoint(TMath::Sqrt(-1.0)); + Int_t mid((i+j)/2); + + if ( mid != i && mid != j ) midpoint = values[mid]; + + AliMUONNode* node = new AliMUONNode(values[i],values[j],midpoint); + + if ( j - i == 1 ) return node; + + node->LeftNode(Build(values,i,(i+j)/2)); + node->RightNode(Build(values,(i+j)/2,j)); + + return node; +} + +//_____________________________________________________________________________ +void +AliMUONSegmentTree::Contribution(double b, double e) +{ + /// Compute the contribution of edge (b,e) + fRoot->Contribution(b,e,fStack); +} + +//_____________________________________________________________________________ +void +AliMUONSegmentTree::InsertInterval(double b, double e) +{ + /// Insert interval (b,e) + fRoot->InsertInterval(b,e,fStack); +} + +//_____________________________________________________________________________ +void +AliMUONSegmentTree::DeleteInterval(double b, double e) +{ + /// Delete interval (b,e) + fRoot->DeleteInterval(b,e,fStack); +} + +//_____________________________________________________________________________ +void +AliMUONSegmentTree::Print(Option_t*) const +{ + /// Printout + if (fRoot) + fRoot->Print(); + else + cout << "Empty binary tree" << endl; +} diff --git a/MUON/AliMUONSegmentTree.h b/MUON/AliMUONSegmentTree.h new file mode 100644 index 00000000000..b1d75c85c36 --- /dev/null +++ b/MUON/AliMUONSegmentTree.h @@ -0,0 +1,60 @@ +#ifndef ALIMUONSEGMENTTREE_H +#define ALIMUONSEGMENTTREE_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup geometry +/// \class AliMUONSegmentTree +/// \brief Implementation of a segment tree +/// +// author Laurent Aphecetche + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +#ifndef ROOT_TObjArray +# include "TObjArray.h" +#endif + +class TArrayD; +class AliMUONNode; + +class AliMUONSegmentTree : public TObject +{ +public: + AliMUONSegmentTree(const TArrayD& values); + virtual ~AliMUONSegmentTree(); + + AliMUONNode* Build(const TArrayD& values, Int_t i, Int_t j); + + void Print(Option_t* opt="") const; + + /// Get the stack + const TObjArray& Stack() const { return fStack; } + + /// Reset the stack + void ResetStack() { fStack.Clear(); } + + void Contribution(double b, double e); + + void InsertInterval(double b, double e); + + void DeleteInterval(double d, double e); + +private: + /// not implemented + AliMUONSegmentTree(const AliMUONSegmentTree& rhs); + /// not implemented + AliMUONSegmentTree& operator=(const AliMUONSegmentTree& rhs); + + AliMUONNode* fRoot; /// root of the tree + TObjArray fStack; /// array of AliMUONSegment objects + + ClassDef(AliMUONSegmentTree,1) // Implementation of a segment tree +}; + +#endif diff --git a/MUON/mapping/AliMpUID.cxx b/MUON/mapping/AliMpUID.cxx new file mode 100644 index 00000000000..5861b9c15ae --- /dev/null +++ b/MUON/mapping/AliMpUID.cxx @@ -0,0 +1,363 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ + +// $Id$ + +#include "AliMpUID.h" + +#include "AliLog.h" +#include "Riostream.h" +#include "TObjArray.h" +#include "TObjString.h" +#include "TSystem.h" + +/// +/// station/chamber/de/bp/manu +/// +/// station/chamber/pcb/manu + +ClassImp(AliMpUID) + +namespace +{ + const char* nameTemplateMANU = "MANU %d"; + const char* nameTemplateDE = "DE %d"; + const char* nameTemplateBP = "BusPatch %d"; + const char* nameTemplateCHAMBER = "Chamber %d"; + const char* nameTemplateSTATION = "Station %d"; + const char* nameTemplatePCB = "PCB %d"; + + const char* pathTemplateMANU = "Cathode%d/Station%d/Chamber%d/DE%04d/BUSPATCH%04d/MANU%04d"; + const char* pathTemplateBP = "Cathode%d/Station%d/Chamber%d/DE%04d/BUSPATCH%04d"; + const char* pathTemplateDE = "Cathode%d/Station%d/Chamber%d/DE%04d"; + const char* pathTemplateCHAMBER = "Cathode%d/Station%d/Chamber%d"; + const char* pathTemplateSTATION = "Cathode%d/Station%d"; + + const char* pathTemplateMANUPCB = "Cathode%d/Station%d/Chamber%d/DE%04d/PCB%d/MANU%04d"; + const char* pathTemplatePCB = "Cathode%d/Station%d/Chamber%d/DE%04d/PCB%d"; +} + +//_____________________________________________________________________________ +AliMpUID::AliMpUID() +: +fCathodeId(-1), +fStationId(-1), +fChamberId(-1), +fDetElemId(-1), +fBusPatchId(-1), +fManuId(-1), +fPCBId(-1) +{ + /// empty ctor +} + +//_____________________________________________________________________________ +AliMpUID::AliMpUID(AliMp::CathodType cathodeType, Int_t station, Int_t chamber, Int_t de, Int_t bp, Int_t manu, Int_t pcb) +: +fCathodeId(cathodeType), +fStationId(station), +fChamberId(chamber), +fDetElemId(de), +fBusPatchId(bp), +fManuId(manu), +fPCBId(pcb) +{ + /// default ctor +} + +//_____________________________________________________________________________ +AliMpUID::AliMpUID(AliMp::CathodType cathodeType, const AliMpUID& b) +: +fCathodeId(cathodeType), +fStationId(b.StationId()), +fChamberId(b.ChamberId()), +fDetElemId(b.DetElemId()), +fBusPatchId(b.BusPatchId()), +fManuId(b.ManuId()), +fPCBId(b.PCBId()) +{ + /// build the id from b, but using the given cathodeType +} + +//_____________________________________________________________________________ +AliMpUID::AliMpUID(AliMp::CathodType cathodeType, const char* pathname) +: +fCathodeId(cathodeType), +fStationId(-1), +fChamberId(-1), +fDetElemId(-1), +fBusPatchId(-1), +fManuId(-1), +fPCBId(-1) +{ + /// build id from path, but using the given cathodeType + + if ( CheckTemplate(pathname,pathTemplateMANUPCB,fPCBId) && fPCBId >= 0 ) return; + if ( CheckTemplate(pathname,pathTemplatePCB,fPCBId) && fPCBId >= 0 ) return; + + if ( CheckTemplate(pathname,pathTemplateMANU,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateBP,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateDE,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateCHAMBER,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateSTATION,fBusPatchId) ) return; +} + + +//_____________________________________________________________________________ +AliMpUID::AliMpUID(const char* pathname) +: +fCathodeId(2), +fStationId(-1), +fChamberId(-1), +fDetElemId(-1), +fBusPatchId(-1), +fManuId(-1), +fPCBId(-1) +{ + /// Build id from path + + if ( CheckTemplate(pathname,pathTemplateMANUPCB,fPCBId) && fPCBId >= 0 ) return; + if ( CheckTemplate(pathname,pathTemplatePCB,fPCBId) && fPCBId >= 0 ) return; + + if ( CheckTemplate(pathname,pathTemplateMANU,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateBP,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateDE,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateCHAMBER,fBusPatchId) ) return; + if ( CheckTemplate(pathname,pathTemplateSTATION,fBusPatchId) ) return; +} + +//_____________________________________________________________________________ +TString +AliMpUID::BaseName() const +{ + /// Get the basename + return gSystem->BaseName(PathName().Data()); +} + +//_____________________________________________________________________________ +AliMp::CathodType +AliMpUID::CathodeId() const +{ + /// return cathode id (not always valid) + return AliMp::GetCathodType(fCathodeId); +} + +//_____________________________________________________________________________ +Bool_t +AliMpUID::CheckTemplate(const char* name, const char* pathTemplateName, Int_t& value) +{ + /// Check a name against a template + + if ( TString(name).Contains("Cathode") ) + { + sscanf(name,pathTemplateName,&fCathodeId,&fStationId,&fChamberId,&fDetElemId,&value,&fManuId); + } + else + { + TString templ(pathTemplateName); + Int_t i = templ.Index("/"); + templ = templ(i+1,templ.Length()-i-1); + sscanf(name,templ.Data(),&fStationId,&fChamberId,&fDetElemId,&value,&fManuId); + } + return IsValid(); +} + +//_____________________________________________________________________________ +TString +AliMpUID::DirName() const +{ + /// Get dirname + return gSystem->DirName(PathName().Data()); +} + +//_____________________________________________________________________________ +Bool_t +AliMpUID::IsStation() const +{ + /// Whether we identify a station + return fCathodeId >= 0 && fStationId >= 0 && fChamberId == -1 ; +} + +//_____________________________________________________________________________ +Bool_t +AliMpUID::IsChamber() const +{ + /// Whether we identify a chamber + + return fCathodeId >= 0 && fStationId >= 0 && fChamberId >= 0 && fDetElemId == -1; +} + +//_____________________________________________________________________________ +Bool_t +AliMpUID::IsDetectionElement() const +{ + /// whether we identify a detection element + return fCathodeId >= 0 && fStationId >= 0 && fChamberId >= 0 && fDetElemId >= 0 && fBusPatchId==-1 && fPCBId == -1; +} + +//_____________________________________________________________________________ +Bool_t +AliMpUID::IsBusPatch() const +{ + /// whether we identify a bus patch + return fCathodeId >= 0 && fStationId >= 0 && fChamberId >= 0 && fDetElemId >= 0 && fBusPatchId>=0 && fManuId ==-1; +} + +//_____________________________________________________________________________ +Bool_t AliMpUID::IsManu() const +{ + /// whether we identify a manu + return + fCathodeId >= 0 && + fStationId >= 0 && + fChamberId >= 0 && + fDetElemId >= 0 && + ( fBusPatchId>=0 || fPCBId >=0 ) && + fManuId >=0; +} + +//_____________________________________________________________________________ +Bool_t AliMpUID::IsPCB() const +{ + /// Whether we identify a PCB + return fCathodeId >= 0 && fPCBId >= 0 && fManuId == -1; +} + +//_____________________________________________________________________________ +Bool_t AliMpUID::IsValid() const +{ + /// Whether we're a valid UID... + return IsStation() || IsChamber() || IsDetectionElement() || IsBusPatch() || IsManu() || IsPCB(); +} + +//_____________________________________________________________________________ +TString +AliMpUID::Name() const +{ + /// Get our name + if ( IsManu() ) + { + return Form(nameTemplateMANU,ManuId()); + } + + if ( IsPCB() ) + { + return Form(nameTemplatePCB,PCBId()); + } + + if ( IsBusPatch() ) + { + return Form(nameTemplateBP,BusPatchId()); + } + + if ( IsDetectionElement() ) + { + return Form(nameTemplateDE,DetElemId()); + } + + if ( IsChamber() ) + { + return Form(nameTemplateCHAMBER,ChamberId()); + } + + if ( IsStation() ) + { + return Form(nameTemplateSTATION,StationId()); + } + + return "INVALID NAME"; +} + +//_____________________________________________________________________________ +TString +AliMpUID::PathName() const +{ + /// Get our pathname + if ( IsManu() ) + { + if ( fPCBId >= 0 ) + { + return StripCathode(Form(pathTemplateMANUPCB,CathodeId(),StationId(),ChamberId(),DetElemId(),PCBId(),ManuId())); + } + else + { + return StripCathode(Form(pathTemplateMANU,CathodeId(),StationId(),ChamberId(),DetElemId(),BusPatchId(),ManuId())); + } + } + + if ( IsPCB() ) + { + return StripCathode(Form(pathTemplatePCB,CathodeId(),StationId(),ChamberId(),DetElemId(),PCBId())); + } + + if ( IsBusPatch() ) + { + return StripCathode(Form(pathTemplateBP,CathodeId(),StationId(),ChamberId(),DetElemId(),BusPatchId())); + } + + if ( IsDetectionElement() ) + { + return StripCathode(Form(pathTemplateDE,CathodeId(),StationId(),ChamberId(),DetElemId())); + } + + if ( IsChamber() ) + { + return StripCathode(Form(pathTemplateCHAMBER,CathodeId(),StationId(),ChamberId())); + } + + if ( IsStation() ) + { + return StripCathode(Form(pathTemplateSTATION,CathodeId(),StationId())); + } + + return "INVALID PATHNAME"; +} + +//_____________________________________________________________________________ +void +AliMpUID::Print(Option_t*) const +{ + /// Printout + cout << Name().Data() << " (" << PathName().Data() << ")" << endl; +} + +//_____________________________________________________________________________ +TString +AliMpUID::StripCathode(const char* name) const +{ + /// Remove cathode information if both cathodes are present + + TString rv(name); + + if ( fCathodeId == 2 ) + { + rv.ReplaceAll("Cathode2/",""); + } + + return rv; +} + +//_____________________________________________________________________________ +TString +AliMpUID::Type() const +{ + /// Remove cathode information if both cathodes are present + TString n(Name()); + TObjArray* s = n.Tokenize(" "); + TString rv(static_cast(s->At(0))->String()); + delete s; + return rv; +} + diff --git a/MUON/mapping/AliMpUID.h b/MUON/mapping/AliMpUID.h new file mode 100644 index 00000000000..999f714d42d --- /dev/null +++ b/MUON/mapping/AliMpUID.h @@ -0,0 +1,80 @@ +#ifndef ALIMPUID_H +#define ALIMPUID_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* See cxx source for full Copyright notice */ + +// $Id$ + +/// \ingroup management +/// \class AliMpUID +/// \brief Global (string-eable) ID of a tracker channel +/// +// Author Laurent Aphecetche, Subatech + +#ifndef ROOT_TObject +# include "TObject.h" +#endif +#ifndef ROOT_TString +# include "TString.h" +#endif +#ifndef ALI_MP_CATHOD_TYPE_H +# include "AliMpCathodType.h" +#endif + +class AliMpUID : public TObject +{ +public: + AliMpUID(); + AliMpUID(AliMp::CathodType cathodeType, Int_t station, Int_t chamber=-1, Int_t de=-1, + Int_t bp=-1, Int_t manu=-1, Int_t pcb=-1); + AliMpUID(AliMp::CathodType cathodeType, const AliMpUID& b); + AliMpUID(AliMp::CathodType cathodeType, const char* pathname); + AliMpUID(const char* pathname); + + virtual ~AliMpUID() {} + + TString Name() const; + TString PathName() const; + TString BaseName() const; + TString DirName() const; + + Bool_t IsStation() const; + Bool_t IsChamber() const; + Bool_t IsDetectionElement() const; + Bool_t IsBusPatch() const; + Bool_t IsManu() const; + Bool_t IsPCB() const; + Bool_t IsValid() const; + + AliMp::CathodType CathodeId() const; + Int_t StationId() const { return fStationId; } + Int_t ChamberId() const { return fChamberId; } + Int_t DetElemId() const { return fDetElemId; } + Int_t BusPatchId() const { return fBusPatchId; } + Int_t ManuId() const { return fManuId; } + Int_t PCBId() const { return fPCBId; } + + virtual void Print(Option_t* opt="") const; + + /// Return our type (e.g. PCB, Chamber, DE, MANU, etc...) + TString Type() const; + +private: + + Bool_t CheckTemplate(const char* name, const char* templateName, Int_t& value); + TString StripCathode(const char* name) const; + +private: + Int_t fCathodeId; // Cathode number + Int_t fStationId; // Station id + Int_t fChamberId; // Chamber id + Int_t fDetElemId; // Detection element id + Int_t fBusPatchId; // Bus patch id + Int_t fManuId; // Manu id + Int_t fPCBId; // PCB id + + ClassDef(AliMpUID,1) // UID of a tracker channel +}; + +#endif -- 2.43.0