10846dcf2c3ddda8b623dd4a088fda165c4f5df5
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpSlat.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: AliMpSlat.cxx,v 1.6 2006/05/24 13:58:50 ivana Exp $
18
19 #include "AliMpSlat.h"
20
21 #include "AliLog.h"
22 #include "AliMpMotifPosition.h"
23 #include "AliMpPCB.h"
24
25 #include "Riostream.h"
26
27 #include "TArrayI.h"
28
29 //-----------------------------------------------------------------------------
30 /// Representation of a slat cathode (bending or non-bending).
31 ///
32 /// A slat can be viewed as a "collection" of PCBs of various densities
33 /// (the density is defined by the size of the pads composing the PCB).
34 ///
35 /// All the PCBs have a least the same height, if not the same width. In most
36 /// of the case, height=width=40 cm, at least for St345 (for trigger,
37 /// width varies)
38 // 
39 /// \author Laurent Aphecetche
40 //-----------------------------------------------------------------------------
41
42 /// \cond CLASSIMP
43 ClassImp(AliMpSlat)
44 /// \endcond
45
46 //_____________________________________________________________________________
47 AliMpSlat::AliMpSlat() 
48 : TObject(), 
49   fId(""), 
50   fPlaneType(AliMp::kNonBendingPlane),
51   fDX(0), 
52   fDY(0),
53   fNofPadsX(0), 
54   fMaxNofPadsY(0),
55   fManuMap(),
56   fPCBs(),
57   fPosition(),
58   fNofPads(0)
59 {
60     ///
61     /// Empty ctor.
62     ///
63   AliDebug(1,Form("this=%p Empty ctor",this));
64 #ifdef WITH_ROOT    
65     fPCBs.SetOwner(kTRUE);
66 #endif    
67     fManuMap.SetOwner(kFALSE);
68 }
69
70 //_____________________________________________________________________________
71 AliMpSlat::AliMpSlat(const char* id, AliMp::PlaneType bendingOrNonBending)
72 : TObject(), 
73   fId(id), 
74   fPlaneType(bendingOrNonBending),
75   fDX(0), 
76   fDY(0),
77   fNofPadsX(0), 
78   fMaxNofPadsY(0),
79   fManuMap(kTRUE),
80   fPCBs(),
81   fPosition(),
82   fNofPads(0)
83 {
84     ///
85     /// Normal ctor
86     ///
87   AliDebug(1,Form("this=%p id=%s",this,id));                    
88 #ifdef WITH_ROOT    
89     fPCBs.SetOwner(kTRUE);
90 #endif    
91     fManuMap.SetOwner(kFALSE);
92 }
93
94 //_____________________________________________________________________________
95 AliMpSlat::~AliMpSlat()
96 {
97   ///
98   /// Dtor.
99   ///
100   AliDebug(1,Form("this=%p fId=%s",this,fId.Data()));                   
101 #ifdef WITH_ROOT    
102   fPCBs.Delete();
103 #else
104   for ( size_t i = 0; i < fPCBs.size(); ++i )
105   {
106     delete fPCBs[i];
107   }
108 #endif    
109 }
110
111 //_____________________________________________________________________________
112 void
113 AliMpSlat::Add(const AliMpPCB& pcbType, const TArrayI& manuList) 
114 {
115   ///
116   /// Adds a PCB to this slat. The manuList specifies the ids of the manu
117   /// that compose the PCB. The manuList ordering is important, as the 
118   /// assumption is that it's ordered counter-clockwise, starting from
119   /// the lower-left of the PCB.
120   ///
121   Int_t ixOffset = 0;
122   if ( GetSize() )
123         {
124                 ixOffset = GetPCB(GetSize()-1)->Ixmax()+1;
125         }
126   else
127   {
128     ixOffset = pcbType.Ixmin();
129   }
130   Double_t xOffset = DX()*2;
131   AliMpPCB* pcb = pcbType.Clone(manuList,ixOffset,xOffset);
132 #ifdef WITH_ROOT
133   fPCBs.AddLast(pcb);
134 #else
135   fPCBs.push_back(pcb);
136 #endif  
137   fDY = TMath::Max(pcb->DY(),fDY);
138   fDX += pcb->DX();
139   fNofPadsX += pcb->GetNofPadsX();
140   fMaxNofPadsY = TMath::Max(fMaxNofPadsY,pcb->GetNofPadsY());
141   for ( AliMpPCB::Size_t i = 0; i < pcb->GetSize(); ++i )
142         {
143                 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
144                 Int_t manuID = mp->GetID();
145     // Before inserting a new key, check if it's already there
146 //#ifdef WITH_ROOT
147     TObject* there = fManuMap.GetValue(manuID);
148     if ( there == 0 )
149     {
150       fManuMap.Add(manuID,(TObject*)mp);
151     }
152     else
153     {
154       AliError(Form("ManuID %d is duplicated for PCB %s",manuID,pcbType.GetID()));      
155     }
156 //#else
157 //  fManuMap[manuID] = mp;
158 //#endif  
159         }
160   fPosition.Set(DX(),DY());
161   fNofPads += pcb->NofPads();
162 }
163
164 //_____________________________________________________________________________
165 TVector2
166 AliMpSlat::Dimensions() const
167 {
168   ///
169   /// Returns the half-sizes of the slat.
170   ///
171   return TVector2(DX(),DY());
172 }
173
174 //_____________________________________________________________________________
175 Double_t
176 AliMpSlat::DX() const
177 {
178   ///
179   /// Returns the x-half-size of the slat.
180   ///
181   return fDX;
182 }
183
184 //_____________________________________________________________________________
185 Double_t
186 AliMpSlat::DY() const
187 {
188   ///
189   /// Returns the y-half-size of the slat.
190   ///
191   return fDY;
192 }
193
194 //_____________________________________________________________________________
195 AliMpMotifPosition*
196 AliMpSlat::FindMotifPosition(Int_t manuID) const
197 {
198   ///
199   /// Returns the motifPosition referenced by it manuID
200   ///
201 //#ifdef WITH_ROOT
202   return static_cast<AliMpMotifPosition*>(fManuMap.GetValue(manuID));
203 //#else
204 //  std::map<int,AliMpMotifPosition*>::const_iterator it = fManuMap.find(manuID);
205 //  if ( it != fManuMap.end() )
206 //      {
207 //            return it->second;
208 //      }
209 //  else
210 //  {
211 //    return 0;
212 //  }
213 //#endif      
214 }
215
216 //_____________________________________________________________________________
217 AliMpMotifPosition*
218 AliMpSlat::FindMotifPosition(Int_t ix, Int_t iy) const
219 {
220   ///
221   /// - 1. Find the PCB containing ix (iy not needed for this)
222   /// - 2. Forward the request to the PCB, using pcb local indices.
223         //
224   const AliMpPCB* pcb = FindPCB(ix);
225   if ( pcb )
226         {
227                 return pcb->FindMotifPosition(ix,iy);
228         }
229   else
230         {
231                 return 0;
232         }
233 }
234
235 //_____________________________________________________________________________
236 AliMpMotifPosition*
237 AliMpSlat::FindMotifPosition(Double_t x, Double_t y) const
238 {
239   ///
240   /// Returns the motifPosition containing position (x,y)
241   ///
242   const AliMpPCB* pcb = FindPCB(x,y);
243   if (pcb)
244         {
245                 return pcb->FindMotifPosition(x,y);
246         }
247   else
248         {
249                 return 0;
250         }
251 }
252
253 //_____________________________________________________________________________
254 AliMpPCB*
255 AliMpSlat::FindPCB(Int_t ix) const
256 {
257   ///
258   /// Returns the PCB containing x-integer-position ix
259   ///
260   for ( Size_t i = 0; i < GetSize(); ++i ) 
261         {
262                 AliMpPCB* pcb = GetPCB(i);
263                 if ( ix >= pcb->Ixmin() && ix <= pcb->Ixmax() )
264                 {
265                         return pcb;
266                 }
267         }
268   return 0;
269 }
270
271 //_____________________________________________________________________________
272 Int_t
273 AliMpSlat::FindPCBIndex(Int_t ix) const
274 {
275   ///
276   /// Returns the index of the PCB containing x-integer-position ix.
277   ///
278   for ( Size_t i = 0; i < GetSize(); ++i ) 
279         {
280                 AliMpPCB* pcb = GetPCB(i);
281                 if ( ix >= pcb->Ixmin() && ix <= pcb->Ixmax() )
282                 {
283                         return i;
284                 }
285         }
286   return -1;
287 }
288
289 //_____________________________________________________________________________
290 AliMpPCB*
291 AliMpSlat::FindPCB(Double_t x, Double_t y) const
292 {
293   ///
294   /// Returns the PCB containing position (x,y)
295   ///
296   for ( Size_t i = 0; i < GetSize(); ++i ) 
297         {
298                 AliMpPCB* pcb = GetPCB(i);
299 //              if ( x >= pcb->Xmin() && x < pcb->Xmax() &&
300 //                               y >= pcb->Ymin() && y < pcb->Ymax() )
301 //              {
302 //                      return pcb;
303 //              }
304     if ( x < pcb->Xmin() || x >= pcb->Xmax() ||
305          y < pcb->Ymin() || y >= pcb->Ymax() )
306     {
307       continue;
308     }
309     return pcb;
310         }
311   return 0;
312 }
313
314 //_____________________________________________________________________________
315 Int_t
316 AliMpSlat::FindPCBIndex(Double_t x, Double_t y) const
317 {
318   ///
319   /// Returns the index of the PCB containing position (x,y)
320   ///
321   for ( Size_t i = 0; i < GetSize(); ++i ) 
322         {
323                 AliMpPCB* pcb = GetPCB(i);
324                 if ( x >= pcb->Xmin() && x < pcb->Xmax() &&
325                                  y >= pcb->Ymin() && y < pcb->Ymax() )
326                 {
327                         return i;
328                 }
329         }
330   return -1;
331 }
332
333 //_____________________________________________________________________________
334 Int_t 
335 AliMpSlat::FindPCBIndexByMotifPositionID(Int_t manuId) const
336 {
337   /// Find the index of the PCB containing a given manu
338   for ( Size_t i = 0; i< GetSize(); ++i )
339   {
340     AliMpPCB* pcb = GetPCB(i);
341     if ( pcb->HasMotifPositionID(manuId) ) return i;
342   }
343   return -1;
344 }
345
346 //_____________________________________________________________________________
347 void
348 AliMpSlat::ForcePosition(const TVector2& pos)
349 {
350   ///
351   /// Force the position to be different from (DX(),DY()).
352   /// Normally only used by triggerSlats (for layers).
353   /// Beware that this method must be called once all PCB have been added,
354   /// as the Add() method resets the position.
355   ///
356   fPosition = pos;
357 }
358
359 //_____________________________________________________________________________
360 void
361 AliMpSlat::GetAllMotifPositionsIDs(TArrayI& ecn) const
362 {
363   ///
364   /// Return all the manuIds (=MotifPositionIDs) of this slat
365   ///
366   ecn.Set(GetNofElectronicCards());
367 //#ifdef WITH_ROOT
368   TExMapIter it(fManuMap.GetIterator());
369   Long_t key;
370   Long_t value;
371   Int_t n(0);
372   while ( it.Next(key,value) == kTRUE )
373   {
374     ecn.AddAt((Int_t)(key),n);
375     ++n;
376   }
377 //#else
378   // missing here
379 //#endif      
380 }
381
382 //_____________________________________________________________________________
383 const char*
384 AliMpSlat::GetID() const
385 {
386   ///
387   /// Returns the name of this slat.
388   ///
389   return fId.Data();
390 }
391
392 //_____________________________________________________________________________
393 Int_t 
394 AliMpSlat::GetMaxNofPadsY() const
395 {
396   ///
397   /// Returns the maximum number of pads to be found in this slat y-direction.
398   /// 
399   return fMaxNofPadsY;
400 }
401
402 //_____________________________________________________________________________
403 Int_t 
404 AliMpSlat::GetMaxPadIndexX() const
405 {
406   ///
407   /// Returns the max ix that is valid for this slat.
408   ///
409   AliMpPCB* last = GetPCB(GetSize()-1);
410   if (last)
411   {
412     return last->Ixmax();
413   }
414   return 0;
415 }
416
417 //_____________________________________________________________________________
418 const char*
419 AliMpSlat::GetName() const
420 {
421   ///
422   /// Returns the name of this slat, which is composed of its ID with
423   /// the plane type as a suffix.
424   ///
425   TString name(GetID());
426   if ( fPlaneType == AliMp::kBendingPlane )
427   {
428     name += ".Bending";
429   }
430   else if ( fPlaneType == AliMp::kNonBendingPlane )
431   {
432     name += ".NonBending";
433   }
434   else
435   {
436     name += ".Invalid";
437   }
438   return name.Data();  
439 }
440
441 //_____________________________________________________________________________
442 Int_t
443 AliMpSlat::GetNofElectronicCards() const
444 {
445   ///
446   /// Returns the number of manus that compose the readout of this slat.
447   ///
448   return fManuMap.GetSize();
449 }
450
451 //_____________________________________________________________________________
452 Int_t
453 AliMpSlat::GetNofPadsX() const
454 {
455   ///
456   /// Returns the number of pad in x-direction.
457   ///
458   return fNofPadsX;
459 }
460
461 //_____________________________________________________________________________
462 AliMpPCB*
463 AliMpSlat::GetPCB(AliMpSlat::Size_t i) const
464 {
465   ///
466   /// Returns the i-th PCB of this slat.
467   ///
468 #ifdef WITH_ROOT
469   if ( i >= fPCBs.GetEntriesFast() ) return 0;
470   return (AliMpPCB*)fPCBs[i];
471 #else
472   if ( i >= fPCBs.size() ) return 0;
473   return fPCBs[i];
474 #endif  
475 }
476
477 //_____________________________________________________________________________
478 AliMpSlat::Size_t
479 AliMpSlat::GetSize() const
480 {
481   ///
482   /// Returns the number of PCB in this slat.
483   ///
484 #ifdef WITH_ROOT
485   return fPCBs.GetEntriesFast();
486 #else
487   return fPCBs.size();
488 #endif  
489 }
490
491 //_____________________________________________________________________________
492 void
493 AliMpSlat::Print(Option_t* option) const
494 {
495   ///
496   /// Prints the slat characteristics.
497   ///
498   cout << "SLAT " << GetID() <<  " 1/2 DIM = (" << DX() << "," << DY() << ")"
499   << " POS = " << Position().X() << "," << Position().Y()
500         << " NPADSX = " << GetNofPadsX() 
501   << " MAXNPADSY = " << GetMaxNofPadsY()
502   << " NPCBs=" << GetSize() << endl;
503   
504   TString soption(option);
505   
506   if ( soption.Contains("P") )
507         {
508     for ( Size_t i = 0; i < GetSize() ; ++i )
509                 {
510       cout << "    ";
511                         if ( option )
512             {
513                                 fPCBs[i]->Print(option+1);
514             }
515                         else
516             {
517               fPCBs[i]->Print();
518             }
519                 }
520         }
521   
522   if ( soption.Contains("M") || soption.Contains("L") )
523   {
524     cout << fManuMap.GetSize() << " ";
525     cout << "Electronic card (manu or local board) Ids : ";
526     
527     TExMapIter iter(fManuMap.GetIterator());
528     Long_t key, value;
529     while ( iter.Next(key,value) )
530     {
531       cout << key << " ";
532     }
533     cout << endl;
534   }
535 }