Replacement of TVector2 object with two doubles
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpSlatSegmentation.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 // $MpId: AliMpSlatSegmentation.cxx,v 1.12 2006/05/24 13:58:50 ivana Exp $
18
19 //-----------------------------------------------------------------------------
20 // Caution !!
21 // Implementation note.
22 // The position(s) used in the interface are supposed to be relative
23 // to the slat center (AliMpSlat::Position()), whereas internally
24 // the x,y are relative to bottom-left corner.
25 //-----------------------------------------------------------------------------
26
27 #include "AliMpSlatSegmentation.h"
28
29 #include "AliLog.h"
30 #include "AliMpArea.h"
31 #include "AliMpConnection.h"
32 #include "AliMpConstants.h"
33 #include "AliLog.h"
34 #include "AliMpMotif.h"
35 #include "AliMpMotifPosition.h"
36 #include "AliMpMotifType.h"
37 #include "AliMpSlat.h"
38 #include "AliMpSlatPadIterator.h"
39 #include "AliMpEncodePair.h"
40
41 /// \cond CLASSIMP
42 ClassImp(AliMpSlatSegmentation)
43 /// \endcond
44
45 //_____________________________________________________________________________
46 AliMpSlatSegmentation::AliMpSlatSegmentation() 
47 : AliMpVSegmentation(),
48   fkSlat(0),
49   fIsOwner(false)
50 {
51   ///
52   /// Default ctor. Not to be used really.
53   ///
54   AliDebug(1,Form("this=%p Empty ctor",this));
55 }
56
57 //_____________________________________________________________________________
58 AliMpSlatSegmentation::AliMpSlatSegmentation(const AliMpSlat* slat, Bool_t own) 
59 : AliMpVSegmentation(), 
60   fkSlat(slat),
61   fIsOwner(own)
62 {
63   ///
64   /// Normal ctor.
65   ///
66   AliDebug(1,Form("this=%p Normal ctor slat=%p",this,slat));
67 }
68
69 //_____________________________________________________________________________
70 AliMpSlatSegmentation::~AliMpSlatSegmentation()
71 {
72   ///
73   /// Dtor (empty).
74   ///
75  
76   if ( fIsOwner ) delete fkSlat;
77  
78   // Int_t i(0);//just to be able to put a breakpoint in gdb
79   AliDebug(1,Form("this=%p",this));                     
80 }
81
82 //_____________________________________________________________________________
83 AliMpVPadIterator*
84 AliMpSlatSegmentation::CreateIterator(const AliMpArea& area) const
85 {
86   ///
87   /// Returns an iterator to loop over the pad contained within given area.
88   ///
89   AliMpArea a(area.GetPositionX()+fkSlat->GetPositionX(),
90               area.GetPositionY()+fkSlat->GetPositionY(),
91               area.GetDimensionX(), 
92               area.GetDimensionY());
93   AliDebug(3,Form("Converted input area wrt to slat center : "
94                   "%7.2f,%7.2f->%7.2f,%7.2f to wrt slat lower-left : "
95                   "%7.2f,%7.2f->%7.2f,%7.2f ",
96                   area.LeftBorder(),area.DownBorder(),
97                   area.RightBorder(),area.UpBorder(),
98                   a.LeftBorder(),a.DownBorder(),
99                   a.RightBorder(),a.UpBorder()));
100                   
101   return new AliMpSlatPadIterator(fkSlat,a);
102 }
103
104 //_____________________________________________________________________________
105 AliMpVPadIterator*
106 AliMpSlatSegmentation::CreateIterator() const
107 {
108   /// Returns an iterator to loop over all pads of that segmentation
109   ///
110   /// FIXME: we currently just forward this to the other CreateIterator,
111   /// with the proper region. Might be more efficient to write a dedicated
112   /// iterator ? Test that idea.
113   
114   AliMpArea area(0.0,0.0,fkSlat->DX(),fkSlat->DY());
115   return CreateIterator(area);
116 }
117
118 //_____________________________________________________________________________
119 Int_t 
120 AliMpSlatSegmentation::GetNeighbours(const AliMpPad& pad, 
121                                      TObjArray& neighbours,
122                                      Bool_t includeSelf,
123                                      Bool_t includeVoid) const
124 {
125   /// Uses default implementation
126   return AliMpVSegmentation::GetNeighbours(pad,neighbours,includeSelf,includeVoid);
127 }
128
129 //_____________________________________________________________________________
130 Double_t  
131 AliMpSlatSegmentation::GetDimensionX() const
132 {
133 /// Return slat x dimensions
134   return Slat()->DX();
135 }
136
137 //_____________________________________________________________________________
138 Double_t  
139 AliMpSlatSegmentation::GetDimensionY() const
140 {
141 /// Return slat y dimensions
142   return Slat()->DY();
143 }
144
145 //_____________________________________________________________________________
146 void 
147 AliMpSlatSegmentation::GetAllElectronicCardIDs(TArrayI& ecn) const
148 {
149   /// Fill the array ecn with all manuIds
150
151   Slat()->GetAllMotifPositionsIDs(ecn);
152 }
153
154 //_____________________________________________________________________________
155 const char*
156 AliMpSlatSegmentation::GetName() const
157 {
158   /// The name of this segmentation is "SlatSegmentation"+slatName
159
160   TString name("SlatSegmentation");
161   if ( fkSlat) 
162   {
163     name += ".";
164     name += fkSlat->GetName();
165   }
166   return name.Data();
167 }
168
169 //_____________________________________________________________________________
170 Int_t 
171 AliMpSlatSegmentation::MaxPadIndexX() const
172 {
173   ///
174   /// Returns the value of the largest pad index in x-direction.
175   ///
176   
177   return fkSlat->GetMaxPadIndexX();
178 }
179
180 //_____________________________________________________________________________
181 Int_t 
182 AliMpSlatSegmentation::MaxPadIndexY() const
183 {
184   ///
185   /// Returns the value of the largest pad index in y-direction.
186   ///
187   
188   return fkSlat->GetMaxNofPadsY()-1;
189 }
190
191 //_____________________________________________________________________________
192 Int_t 
193 AliMpSlatSegmentation::NofPads() const
194 {
195 /// Return number of pads defined in the slat
196   
197   return fkSlat->NofPads();
198 }
199
200 //_____________________________________________________________________________
201 AliMpPad
202 AliMpSlatSegmentation::PadByLocation(Int_t manuId, Int_t manuChannel, 
203                                      Bool_t warning) const
204 {
205   ///
206   /// Returns the pad specified by its location, where location is the 
207   /// pair (ManuID,ManuChannel).
208   /// If warning=kTRUE and the pad does not exist, a warning message is 
209   /// printed.
210   ///
211   /// AliMpPad::Invalid() is returned if there's no pad at the given location.
212   ///
213   AliMpMotifPosition* motifPos = fkSlat->FindMotifPosition(manuId);
214         
215   if (!motifPos)
216   {
217     if (warning)
218     {
219       AliWarning(Form("Manu ID %d not found in slat %s",
220                        manuId, fkSlat->GetID()));
221     }
222     return AliMpPad::Invalid();
223   }
224   AliMpVMotif* motif = motifPos->GetMotif();
225   MpPair_t localIndices = 
226     motif->GetMotifType()->FindLocalIndicesByGassiNum(manuChannel);
227         
228   if ( localIndices < 0 ) 
229   {
230     if (warning) 
231     {
232       AliWarning(Form("The pad number %d doesn't exists",
233                  manuChannel));
234     }
235     return AliMpPad::Invalid();
236   }
237
238   Double_t posx, posy;
239   motif->PadPositionLocal(localIndices, posx, posy);
240   posx += motifPos->GetPositionX() - fkSlat->GetPositionX();
241   posy += motifPos->GetPositionY() - fkSlat->GetPositionY();
242
243   Double_t dx, dy;
244   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
245         
246   return AliMpPad(manuId, manuChannel,
247                   motifPos->GlobalIndices(localIndices),
248                   posx, posy, dx, dy);
249 }
250
251 //_____________________________________________________________________________
252 AliMpPad
253 AliMpSlatSegmentation::PadByIndices(Int_t ix, Int_t iy, 
254                                     Bool_t warning) const
255 {
256   ///
257   /// Returns the pad specified by its integer indices.
258   /// If warning=kTRUE and the pad does not exist, a warning message is 
259   /// printed.
260   ///
261   /// AliMpPad::Invalid() is returned if there's no pad at the given location.
262   ///
263   ///  
264   /// FIXME: except for the FindMotifPosition below, this method
265   /// is exactly as the one in AliMpSectorSegmentation.
266   /// See if we can merge them somehow.
267         
268   AliMpMotifPosition* motifPos = fkSlat->FindMotifPosition(ix,iy);
269   
270   if (!motifPos)
271   {
272     if ( warning ) 
273     {
274       AliWarning(Form("No motif found containing pad location (%d,%d)",ix,iy));   
275     }
276     return AliMpPad::Invalid();
277   }
278         
279   AliMpVMotif* motif = motifPos->GetMotif();
280   AliMpMotifType* motifType = motif->GetMotifType();
281   MpPair_t localIndices = AliMp::Pair(ix,iy) - motifPos->GetLowIndicesLimit();
282   AliMpConnection* connection 
283     = motifType->FindConnectionByLocalIndices(localIndices);
284   
285   if (!connection)
286   {
287     if ( warning )
288     {
289       AliWarning(Form("No connection for pad location (%d,%d)",ix,iy));
290     }
291     return AliMpPad::Invalid();
292   }
293
294   Double_t posx, posy;
295   motif->PadPositionLocal(localIndices, posx, posy);
296   posx += motifPos->GetPositionX() - fkSlat->GetPositionX();
297   posy += motifPos->GetPositionY() - fkSlat->GetPositionY();
298
299   Double_t dx, dy;
300   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
301
302   return AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
303                   ix, iy, posx, posy, dx, dy);
304 }
305
306 //_____________________________________________________________________________
307 AliMpPad
308 AliMpSlatSegmentation::PadByPosition(Double_t x, Double_t y, 
309                                      Bool_t warning) const
310 {
311   ///
312   /// Returns the pad specified by its (floating point) position.
313   /// If warning=kTRUE and the pad does not exist, a warning message is 
314   /// printed.
315   ///
316   /// AliMpPad::Invalid() is returned if there's no pad at the given location.
317   ///
318   
319   Double_t blPosX(x);
320   Double_t blPosY(y);
321   
322   blPosX += fkSlat->GetPositionX();
323   blPosY += fkSlat->GetPositionY(); // position relative to bottom-left of the slat.
324   
325   AliMpMotifPosition* motifPos = fkSlat->FindMotifPosition(blPosX,blPosY);
326         
327   if (!motifPos)
328   {
329     if (warning) 
330     {
331       AliWarning(Form("Slat %s Position (%e,%e)/center (%e,%e)/bottom-left cm "
332                       " outside limits",fkSlat->GetID(),x,y,
333                       blPosX,blPosY));
334     }
335     return AliMpPad::Invalid();
336   }
337         
338   AliMpVMotif* motif =  motifPos->GetMotif();  
339
340   blPosX -= motifPos->GetPositionX();
341   blPosY -= motifPos->GetPositionY();
342   MpPair_t localIndices = motif->PadIndicesLocal(blPosX, blPosY);
343         
344   AliMpConnection* connect = 
345     motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
346         
347   if (!connect)
348   {
349     if (warning) 
350     {
351       AliWarning(Form("Slat %s localIndices (%d,%d) outside motif %s limits",
352                       fkSlat->GetID(),AliMp::PairFirst(localIndices),
353                       AliMp::PairSecond(localIndices),motif->GetID().Data()));
354     }
355     return AliMpPad::Invalid();
356   }
357
358   Double_t posx, posy;
359   motif->PadPositionLocal(localIndices, posx, posy);
360   posx += motifPos->GetPositionX() - fkSlat->GetPositionX();
361   posy += motifPos->GetPositionY() - fkSlat->GetPositionY();
362
363   Double_t dx, dy;
364   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
365     
366   return AliMpPad(motifPos->GetID(),connect->GetManuChannel(),
367                   motifPos->GlobalIndices(localIndices),
368                   posx, posy, dx, dy);
369 }
370
371 //_____________________________________________________________________________
372 AliMp::PlaneType
373 AliMpSlatSegmentation::PlaneType() const
374 {
375   return Slat()->PlaneType();
376 }
377
378 //_____________________________________________________________________________
379 void
380 AliMpSlatSegmentation::Print(Option_t* opt) const
381 {
382 /// Printing
383
384   fkSlat->Print(opt);
385 }
386
387 //_____________________________________________________________________________
388 const AliMpSlat* 
389 AliMpSlatSegmentation::Slat() const
390 {
391   ///
392   /// Returns the pointer to the referenced slat.
393   ///
394   
395   return fkSlat;
396 }
397
398 //_____________________________________________________________________________
399 Bool_t 
400 AliMpSlatSegmentation::HasPadByIndices(Int_t ix, Int_t iy) const
401 {
402   /// Tell whether we have a pad at indices=(ix,iy)
403   
404   AliMpMotifPosition* motifPos = Slat()->FindMotifPosition(ix, iy);
405   
406   if (motifPos) return motifPos->HasPadByIndices(AliMp::Pair(ix, iy));
407   
408   return kFALSE;
409 }
410
411 //_____________________________________________________________________________
412 Bool_t 
413 AliMpSlatSegmentation::HasPadByLocation(Int_t manuId, Int_t manuChannel) const
414 {
415   /// Tell whether we have a pad at location=(manuId,manuChannel)
416   
417   AliMpMotifPosition* motifPos = Slat()->FindMotifPosition(manuId);
418   
419   if ( motifPos ) return motifPos->HasPadByManuChannel(manuChannel);
420   
421   return kFALSE;  
422 }
423
424
425 //_____________________________________________________________________________
426 Int_t 
427 AliMpSlatSegmentation::GetNofElectronicCards() const
428 {
429   /// Get the number of manus of this slat
430   return Slat()->GetNofElectronicCards();
431
432 }
433
434 //_____________________________________________________________________________
435 Double_t  
436 AliMpSlatSegmentation::GetPositionX() const
437 {
438 /// Return x position of slat origin
439   return Slat()->GetPositionX();
440 }
441
442 //_____________________________________________________________________________
443 Double_t  
444 AliMpSlatSegmentation::GetPositionY() const
445 {
446 /// Return y position of slat origin
447
448   return Slat()->GetPositionY();
449 }
450
451 //_____________________________________________________________________________
452 Bool_t 
453 AliMpSlatSegmentation::HasMotifPosition(Int_t manuId) const
454 {
455   /// Use default implementation
456   return AliMpVSegmentation::HasMotifPosition(manuId);
457 }
458
459 //_____________________________________________________________________________
460 AliMpMotifPosition* 
461 AliMpSlatSegmentation::MotifPosition(Int_t manuId) const
462 {
463   /// Get back a given manu
464   return Slat()->FindMotifPosition(manuId);
465 }
466