Fixes for #86059: Install data when ALICE_ROOT does not point to source (Christian)
[u/mrichter/AliRoot.git] / MUON / AliMUONContour.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17
18 ///\class AliMUONContour
19 ///
20 /// A contour is a set of (closed and counter-clockwise-oriented) polygons
21 ///
22 /// \author Laurent Aphecetche, Subatech
23
24 #include "AliMUONContour.h"
25
26 #include "AliLog.h"
27 #include "AliMUONPolygon.h"
28 #include "AliMpArea.h"
29 #include <Riostream.h>
30 #include <TGeoMatrix.h>
31 #include <TMath.h>
32 #include <TObjArray.h>
33 #include <TPolyLine.h>
34 #include <TString.h>
35 #include <TVector2.h>
36 #include <float.h>
37
38 ///\cond CLASSIMP
39 ClassImp(AliMUONContour)
40 ///\endcond
41
42 //_____________________________________________________________________________
43 AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""), 
44 fPolygons(new TObjArray),
45 fXmin(FLT_MAX),
46 fXmax(-FLT_MAX),
47 fYmin(FLT_MAX),
48 fYmax(-FLT_MAX),
49 fNofVertices(0)
50 {
51   /// ctor
52   fPolygons->SetOwner(kTRUE);
53 }
54
55 //_____________________________________________________________________________
56 AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area) 
57 : TNamed(name,""), 
58 fPolygons(new TObjArray),
59 fXmin(area.LeftBorder()),
60 fXmax(area.RightBorder()),
61 fYmin(area.DownBorder()),
62 fYmax(area.UpBorder()),
63 fNofVertices(0)
64 {
65   /// ctor
66   fPolygons->SetOwner(kTRUE);
67   
68   AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(),
69                                            area.GetPositionY(),
70                                            area.GetDimensionX(),
71                                            area.GetDimensionY());
72   
73   fPolygons->AddLast(pol);
74   
75   fNofVertices = pol->NumberOfVertices();
76 }
77
78 //______________________________________________________________________________
79 AliMUONContour::AliMUONContour(const AliMUONContour& rhs) 
80 : TNamed(rhs), 
81 fPolygons(0x0),
82 fXmin(FLT_MAX),
83 fXmax(-FLT_MAX),
84 fYmin(FLT_MAX),
85 fYmax(-FLT_MAX),
86 fNofVertices(0)
87 {
88   /// Copy constructor.
89   
90   ((AliMUONContour&)rhs).Copy(*this);
91 }
92
93 //______________________________________________________________________________
94 AliMUONContour&
95 AliMUONContour::operator=(const AliMUONContour& rhs)
96 {
97   /// Assignment operator
98   if ( this != &rhs ) 
99   {
100     delete fPolygons;
101     fPolygons = 0;
102     rhs.Copy(*this);
103   }
104   return *this;
105 }
106
107 //_____________________________________________________________________________
108 AliMUONContour::~AliMUONContour()
109 {
110   /// dtor
111   delete fPolygons;
112 }
113
114 //_____________________________________________________________________________
115 void 
116 AliMUONContour::Add(const AliMUONPolygon& polygon)
117 {
118   /// Add points from the polygon
119   
120   for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i ) 
121   {
122     Double_t x = polygon.X(i);
123     Double_t y = polygon.Y(i);
124     fXmin = TMath::Min(fXmin,x);
125     fXmax = TMath::Max(fXmax,x);
126     fYmin = TMath::Min(fYmin,y);
127     fYmax = TMath::Max(fYmax,y);
128   }
129   
130   fPolygons->AddLast(new AliMUONPolygon(polygon));
131   
132   fNofVertices += polygon.NumberOfVertices();
133 }
134
135 //_____________________________________________________________________________
136 AliMpArea
137 AliMUONContour::Area() const
138 {
139   /// Return the area covered by this contour (i.e. the area that
140   /// contains all the poylines)
141   
142   return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 ,
143                     TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 );
144 }
145
146 //______________________________________________________________________________
147 void 
148 AliMUONContour::AssertOrientation(Bool_t autoCorrect)
149 {
150   /// Insure that all our polygons are counter-clockwise oriented
151   /// If autoCorrect==kTRUE, we change the orientation if it is not 
152   /// already correct.
153   /// If autoCorrect==kFALSE and the orientation is not correct, we
154   /// just issue an error message.
155   
156   for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i )
157   {
158     AliMUONPolygon* pol = static_cast<AliMUONPolygon*>(fPolygons->UncheckedAt(i));
159     if ( !pol->IsCounterClockwiseOriented() ) 
160     {
161       if ( autoCorrect ) 
162       {
163         pol->ReverseOrientation();
164       }
165       else
166       {
167         AliError("Got a polygon oriented the wrong way");
168         StdoutToAliError(Print(););
169         return;
170       }
171     }
172   }
173 }
174
175 //______________________________________________________________________________
176 void AliMUONContour::Copy(TObject& obj) const
177 {
178   /// Copy this to obj
179   
180   AliMUONContour& rhs = static_cast<AliMUONContour&>(obj);
181   TNamed::Copy(rhs);
182   delete rhs.fPolygons;
183   rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1);
184   rhs.fPolygons->SetOwner(kTRUE);
185   TIter next(fPolygons);
186   AliMUONPolygon* pol;
187   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
188   {
189     rhs.fPolygons->AddLast(pol->Clone());
190   }
191   rhs.fXmin = fXmin;
192   rhs.fXmax = fXmax;
193   rhs.fYmin = fYmin;
194   rhs.fYmax = fYmax;
195   rhs.fNofVertices = fNofVertices;
196 }
197
198 //_____________________________________________________________________________
199 Bool_t 
200 AliMUONContour::IsInside(Double_t x, Double_t y) const
201 {
202   /// Whether the point (x,y) is inside one of ours polylines
203
204   if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax ) 
205   {
206     TIter next(fPolygons);
207     AliMUONPolygon* pol;
208     while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
209     {
210       if ( pol->Contains(x,y) ) 
211       {
212         return kTRUE;
213       }
214     }      
215   }
216   
217   return kFALSE;
218 }
219
220 //_____________________________________________________________________________
221 void 
222 AliMUONContour::Offset(Double_t x, Double_t y)
223 {
224   /// Offset all lines by a given offset
225   
226   TIter next(fPolygons);
227   AliMUONPolygon* pol;
228   
229   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
230   {
231     for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i ) 
232     {
233       pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y);
234     }
235   }
236
237   fXmin += x;
238   fXmax += x;
239   fYmin += y;
240   fYmax += y;
241 }
242
243 //_____________________________________________________________________________
244 void 
245 AliMUONContour::Print(Option_t* opt) const
246 {
247   /// Printout
248   
249   cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl;
250   TString sopt(opt);
251   sopt.ToUpper();
252   if (sopt.Contains("B"))
253   {
254     Area().Print("B");
255   }
256
257   TIter next(fPolygons);
258   AliMUONPolygon* pol;
259   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
260   {
261     pol->Print(opt);
262   }
263   
264   
265   cout << endl;
266 }  
267
268 //_____________________________________________________________________________
269 void 
270 AliMUONContour::Transform(const TGeoHMatrix& matrix)
271 {
272   /// Transform the polygons using the given transformation
273   
274   TIter next(fPolygons);
275   AliMUONPolygon* pol;
276   
277   fXmin = fYmin = FLT_MAX;
278   fXmax = fYmax = -FLT_MAX;
279   
280   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
281   {
282     for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i ) 
283     {
284       Double_t pl[3] = { pol->X(i), pol->Y(i), 0 };
285       Double_t pg[3] = { 0., 0., 0. };
286       matrix.LocalToMaster(pl, pg);
287       pol->SetVertex(i,pg[0],pg[1]);
288       fXmin = TMath::Min(fXmin,pg[0]);
289       fYmin = TMath::Min(fYmin,pg[1]);
290       fXmax = TMath::Max(fXmax,pg[0]);
291       fYmax = TMath::Max(fYmax,pg[1]);
292     }
293   }
294   
295   AssertOrientation(kTRUE);
296 }
297
298 //_____________________________________________________________________________
299 Bool_t 
300 AliMUONContour::IsValid() const
301 {
302   /// A valid contour is one with a valid area and at least 3 vertices.
303   return fNofVertices >= 3 && Area().IsValid();
304 }