o add Reset function to CalPad and CalROC o Add functionality to AliTPCdataQA - Reset...
[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 using std::cout;
39 using std::endl;
40 ///\cond CLASSIMP
41 ClassImp(AliMUONContour)
42 ///\endcond
43
44 //_____________________________________________________________________________
45 AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""), 
46 fPolygons(new TObjArray),
47 fXmin(FLT_MAX),
48 fXmax(-FLT_MAX),
49 fYmin(FLT_MAX),
50 fYmax(-FLT_MAX),
51 fNofVertices(0)
52 {
53   /// ctor
54   fPolygons->SetOwner(kTRUE);
55 }
56
57 //_____________________________________________________________________________
58 AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area) 
59 : TNamed(name,""), 
60 fPolygons(new TObjArray),
61 fXmin(area.LeftBorder()),
62 fXmax(area.RightBorder()),
63 fYmin(area.DownBorder()),
64 fYmax(area.UpBorder()),
65 fNofVertices(0)
66 {
67   /// ctor
68   fPolygons->SetOwner(kTRUE);
69   
70   AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(),
71                                            area.GetPositionY(),
72                                            area.GetDimensionX(),
73                                            area.GetDimensionY());
74   
75   fPolygons->AddLast(pol);
76   
77   fNofVertices = pol->NumberOfVertices();
78 }
79
80 //______________________________________________________________________________
81 AliMUONContour::AliMUONContour(const AliMUONContour& rhs) 
82 : TNamed(rhs), 
83 fPolygons(0x0),
84 fXmin(FLT_MAX),
85 fXmax(-FLT_MAX),
86 fYmin(FLT_MAX),
87 fYmax(-FLT_MAX),
88 fNofVertices(0)
89 {
90   /// Copy constructor.
91   
92   ((AliMUONContour&)rhs).Copy(*this);
93 }
94
95 //______________________________________________________________________________
96 AliMUONContour&
97 AliMUONContour::operator=(const AliMUONContour& rhs)
98 {
99   /// Assignment operator
100   if ( this != &rhs ) 
101   {
102     delete fPolygons;
103     fPolygons = 0;
104     rhs.Copy(*this);
105   }
106   return *this;
107 }
108
109 //_____________________________________________________________________________
110 AliMUONContour::~AliMUONContour()
111 {
112   /// dtor
113   delete fPolygons;
114 }
115
116 //_____________________________________________________________________________
117 void 
118 AliMUONContour::Add(const AliMUONPolygon& polygon)
119 {
120   /// Add points from the polygon
121   
122   for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i ) 
123   {
124     Double_t x = polygon.X(i);
125     Double_t y = polygon.Y(i);
126     fXmin = TMath::Min(fXmin,x);
127     fXmax = TMath::Max(fXmax,x);
128     fYmin = TMath::Min(fYmin,y);
129     fYmax = TMath::Max(fYmax,y);
130   }
131   
132   fPolygons->AddLast(new AliMUONPolygon(polygon));
133   
134   fNofVertices += polygon.NumberOfVertices();
135 }
136
137 //_____________________________________________________________________________
138 AliMpArea
139 AliMUONContour::Area() const
140 {
141   /// Return the area covered by this contour (i.e. the area that
142   /// contains all the poylines)
143   
144   return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 ,
145                     TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 );
146 }
147
148 //______________________________________________________________________________
149 void 
150 AliMUONContour::AssertOrientation(Bool_t autoCorrect)
151 {
152   /// Insure that all our polygons are counter-clockwise oriented
153   /// If autoCorrect==kTRUE, we change the orientation if it is not 
154   /// already correct.
155   /// If autoCorrect==kFALSE and the orientation is not correct, we
156   /// just issue an error message.
157   
158   for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i )
159   {
160     AliMUONPolygon* pol = static_cast<AliMUONPolygon*>(fPolygons->UncheckedAt(i));
161     if ( !pol->IsCounterClockwiseOriented() ) 
162     {
163       if ( autoCorrect ) 
164       {
165         pol->ReverseOrientation();
166       }
167       else
168       {
169         AliError("Got a polygon oriented the wrong way");
170         StdoutToAliError(Print(););
171         return;
172       }
173     }
174   }
175 }
176
177 //______________________________________________________________________________
178 void AliMUONContour::Copy(TObject& obj) const
179 {
180   /// Copy this to obj
181   
182   AliMUONContour& rhs = static_cast<AliMUONContour&>(obj);
183   TNamed::Copy(rhs);
184   delete rhs.fPolygons;
185   rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1);
186   rhs.fPolygons->SetOwner(kTRUE);
187   TIter next(fPolygons);
188   AliMUONPolygon* pol;
189   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
190   {
191     rhs.fPolygons->AddLast(pol->Clone());
192   }
193   rhs.fXmin = fXmin;
194   rhs.fXmax = fXmax;
195   rhs.fYmin = fYmin;
196   rhs.fYmax = fYmax;
197   rhs.fNofVertices = fNofVertices;
198 }
199
200 //_____________________________________________________________________________
201 Bool_t 
202 AliMUONContour::IsInside(Double_t x, Double_t y) const
203 {
204   /// Whether the point (x,y) is inside one of ours polylines
205
206   if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax ) 
207   {
208     TIter next(fPolygons);
209     AliMUONPolygon* pol;
210     while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
211     {
212       if ( pol->Contains(x,y) ) 
213       {
214         return kTRUE;
215       }
216     }      
217   }
218   
219   return kFALSE;
220 }
221
222 //_____________________________________________________________________________
223 void 
224 AliMUONContour::Offset(Double_t x, Double_t y)
225 {
226   /// Offset all lines by a given offset
227   
228   TIter next(fPolygons);
229   AliMUONPolygon* pol;
230   
231   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
232   {
233     for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i ) 
234     {
235       pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y);
236     }
237   }
238
239   fXmin += x;
240   fXmax += x;
241   fYmin += y;
242   fYmax += y;
243 }
244
245 //_____________________________________________________________________________
246 void 
247 AliMUONContour::Print(Option_t* opt) const
248 {
249   /// Printout
250   
251   cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl;
252   TString sopt(opt);
253   sopt.ToUpper();
254   if (sopt.Contains("B"))
255   {
256     Area().Print("B");
257   }
258
259   TIter next(fPolygons);
260   AliMUONPolygon* pol;
261   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
262   {
263     pol->Print(opt);
264   }
265   
266   
267   cout << endl;
268 }  
269
270 //_____________________________________________________________________________
271 void 
272 AliMUONContour::Transform(const TGeoHMatrix& matrix)
273 {
274   /// Transform the polygons using the given transformation
275   
276   TIter next(fPolygons);
277   AliMUONPolygon* pol;
278   
279   fXmin = fYmin = FLT_MAX;
280   fXmax = fYmax = -FLT_MAX;
281   
282   while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
283   {
284     for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i ) 
285     {
286       Double_t pl[3] = { pol->X(i), pol->Y(i), 0 };
287       Double_t pg[3] = { 0., 0., 0. };
288       matrix.LocalToMaster(pl, pg);
289       pol->SetVertex(i,pg[0],pg[1]);
290       fXmin = TMath::Min(fXmin,pg[0]);
291       fYmin = TMath::Min(fYmin,pg[1]);
292       fXmax = TMath::Max(fXmax,pg[0]);
293       fYmax = TMath::Max(fYmax,pg[1]);
294     }
295   }
296   
297   AssertOrientation(kTRUE);
298 }
299
300 //_____________________________________________________________________________
301 Bool_t 
302 AliMUONContour::IsValid() const
303 {
304   /// A valid contour is one with a valid area and at least 3 vertices.
305   return fNofVertices >= 3 && Area().IsValid();
306 }