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