9401ea9323a7ba9171d30feb6693999e49a45593
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpPCB.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: AliMpPCB.cxx,v 1.3 2005/09/19 19:01:31 ivana Exp $
18
19 #include "AliMpPCB.h"
20
21 #include "AliMpMotif.h"
22 #include "AliMpMotifPosition.h"
23 #include "AliMpMotifType.h"
24 #include "AliLog.h"
25
26 #include "Riostream.h"
27 #include <sstream>
28
29 ClassImp(AliMpPCB)
30
31 //_____________________________________________________________________________
32 AliMpPCB::AliMpPCB() 
33   : TObject(), fId(""), 
34     fPadSizeX(0), fPadSizeY(0), 
35     fEnveloppeSizeX(0), fEnveloppeSizeY(0),
36     fXoffset(0),
37     fActiveXmin(0), fActiveXmax(0),
38     fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0)
39 {
40       //
41       // Default ctor.
42       //
43 }
44
45 //_____________________________________________________________________________
46 AliMpPCB::AliMpPCB(const char* id, Double_t padSizeX, Double_t padSizeY,
47                    Double_t enveloppeSizeX, Double_t enveloppeSizeY)
48   : TObject(), fId(id), 
49     fPadSizeX(padSizeX), fPadSizeY(padSizeY), 
50     fEnveloppeSizeX(enveloppeSizeX), fEnveloppeSizeY(enveloppeSizeY),
51     fXoffset(0),
52     fActiveXmin(0), fActiveXmax(0),
53     fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0)
54 {
55       //
56       // Normal ctor. Must be fed with the PCB's name (id), the pad dimensions
57       // and the global dimension of the virtual enveloppe of the PCB
58       // (usually 400x400 mm)
59 }
60
61 //_____________________________________________________________________________
62 AliMpPCB::AliMpPCB(const AliMpPCB& o) 
63   : TObject(o),
64     fPadSizeX(0), fPadSizeY(0), 
65     fEnveloppeSizeX(0), fEnveloppeSizeY(0),
66     fXoffset(0),
67     fActiveXmin(0), fActiveXmax(0),
68     fIxmin(0), fIxmax(0), fIymin(0), fIymax(0)
69 {
70   o.Copy(*this);
71 }
72
73 //_____________________________________________________________________________
74 AliMpPCB&
75 AliMpPCB::operator=(const AliMpPCB& o)
76 {
77   o.Copy(*this);
78   return *this;  
79 }
80
81 //_____________________________________________________________________________
82 AliMpPCB::~AliMpPCB()
83 {
84   //
85   // Dtor.
86   //
87 }
88
89 //_____________________________________________________________________________
90 Double_t
91 AliMpPCB::ActiveXmin() const
92 {
93   //
94   // Returns the mininum x for which there is a pad in this PCB.
95   // Different from Xmin only for PCB which are not full of pads.
96   //
97   
98   return fActiveXmin;
99 }
100
101 //_____________________________________________________________________________
102 Double_t
103 AliMpPCB::ActiveXmax() const
104 {
105   //
106   // Returns the maximum x for which there is a pad in this PCB.
107   // Different from Xmax only for PCB which are not full of pads.
108   //  
109   
110   return fActiveXmax;
111 }
112
113 //_____________________________________________________________________________
114 void
115 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
116 {
117   //
118   // Add a motif to this PCB. (ix,iy) is the lower-left position of the motif.
119   //
120   
121   AliMpVMotif* motif = 
122     new AliMpMotif(mt->GetID(),mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
123   TVector2 position(ix*PadSizeX(),iy*PadSizeY());
124   position += motif->Dimensions();
125
126   AliMpMotifPosition* mp = new AliMpMotifPosition(-1,motif,position);
127   Int_t ixmin = ix;
128   Int_t iymin = iy;
129   Int_t ixmax = ix + mt->GetNofPadsX() - 1;
130   Int_t iymax = iy + mt->GetNofPadsY() - 1;
131
132   mp->SetLowIndicesLimit(AliMpIntPair(ixmin,iymin));
133   mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
134
135 #ifdef WITH_ROOT
136   fMotifs.AddLast(mp);
137 #else
138   fMotifs.push_back(mp);
139 #endif
140
141   fIxmin = std::min(fIxmin,ixmin);
142   fIxmax = std::max(fIxmax,ixmax);
143   fIymin = std::min(fIymin,iymin);
144   fIymax = std::max(fIymax,iymax);
145
146   fActiveXmin = fIxmin*PadSizeX();
147   fActiveXmax = (fIxmax+1)*PadSizeX();
148 }
149
150 //_____________________________________________________________________________
151 TObject*
152 AliMpPCB::Clone(const char* /*newname*/) const
153 {
154   //
155   // Return a full copy of this object.
156   //
157   return new AliMpPCB(*this);
158 }
159
160 //_____________________________________________________________________________
161 AliMpPCB*
162 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
163 {
164   //
165   // Get a full copy of *this, and then apply 2 changes to it :
166   //
167   // a) define the relationship motifType <-> manu id
168   // b) define the x-offset
169   // c) shift ix indices backwards to insure that e.g. the first
170   //    pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
171   //
172
173   // First get a full clone.
174   AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
175
176   if ( pcb->GetSize() != manuids.GetSize() )
177   {
178       AliError(Form("Cannot Clone because I do not get the correct number of "
179                     "manu ids (got %d, wanted %d)",
180                     manuids.GetSize(),pcb->GetSize()));
181       return 0;
182   }
183
184   AliMpIntPair shift(-fIxmin,0);
185
186   // Then change the internal MotifPositions wrt manu id
187   // and position (offset in x).
188   for ( Size_t i = 0; i < pcb->GetSize(); ++i )
189     {
190       AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
191       mp->SetID(manuids[i]);
192       mp->SetPosition(mp->Position() + TVector2(xOffset,0));
193       mp->SetLowIndicesLimit(mp->GetLowIndicesLimit()+
194                              shift+
195                              AliMpIntPair(ixOffset,0));
196       mp->SetHighIndicesLimit(mp->GetHighIndicesLimit()+
197                               shift+
198                               AliMpIntPair(ixOffset,0));
199     }
200   
201   pcb->fIxmin += ixOffset + shift.GetFirst();
202   pcb->fIxmax += ixOffset + shift.GetFirst();
203   pcb->fXoffset = xOffset;
204
205   pcb->fActiveXmin += xOffset;
206   pcb->fActiveXmax += xOffset;
207
208   return pcb;
209 }
210
211 //_____________________________________________________________________________
212 void
213 AliMpPCB::Copy(TObject& o) const
214 {
215   TObject::Copy(o);
216   AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
217   pcb.fId = fId;
218   pcb.fPadSizeX = fPadSizeX;
219   pcb.fPadSizeY = fPadSizeY;
220   pcb.fEnveloppeSizeX = fEnveloppeSizeX;
221   pcb.fEnveloppeSizeY = fEnveloppeSizeY;
222   pcb.fXoffset = fXoffset;
223   pcb.fIxmin = fIxmin;
224   pcb.fIxmax = fIxmax;
225   pcb.fIymin = fIymin;
226   pcb.fIymax = fIymax;
227   pcb.fActiveXmin = fActiveXmin;
228   pcb.fActiveXmax = fActiveXmax;
229
230 #ifdef WITH_ROOT
231   pcb.fMotifs.Clear();
232 #else
233   pcb.fMotifs.clear();
234 #endif
235
236 #ifdef WITH_ROOT
237   for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
238 #else
239   for ( Size_t i = 0; i < fMotifs.size(); ++i )
240 #endif  
241     {
242       AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifs[i];
243       AliMpMotifPosition* pcbpos = 
244         new AliMpMotifPosition(pos->GetID(),pos->GetMotif(),pos->Position());
245       pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
246       pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
247 #ifdef WITH_ROOT
248       pcb.fMotifs.AddLast(pcbpos);
249 #else      
250       pcb.fMotifs.push_back(pcbpos);
251 #endif      
252     }
253 }
254
255 //_____________________________________________________________________________
256 Double_t
257 AliMpPCB::ActiveDX() const
258 {
259   //
260   // Half-length (in x-direction) occupied by pads  
261   //
262   
263   return GetNofPadsX()*fPadSizeX/2.0;
264 }
265
266 //_____________________________________________________________________________
267 Double_t
268 AliMpPCB::DX() const
269 {
270   //
271   // Half-length (in x-direction) of the PCB.
272   // This length is the one of the virtual enveloppe of the PCB and might
273   // be bigger than the length occupied by pads (e.g. for rounded or short
274   // PCBs).  
275   // See also ActiveDX().
276   //
277   
278   return fEnveloppeSizeX/2.0;
279 }
280
281 //_____________________________________________________________________________
282 Double_t
283 AliMpPCB::ActiveDY() const
284 {
285   //
286   // Half-length (in y-direction) occupied by pads
287   //
288   
289   return GetNofPadsY()*fPadSizeY/2.0;
290 }
291
292 //_____________________________________________________________________________
293 Double_t
294 AliMpPCB::DY() const
295 {
296   //
297   // Half-length (in y-direction) of the PCB.
298   // This length is the one of the virtual enveloppe of the PCB and might
299   // be bigger than the length occupied by pads (e.g. for rounded or short
300   // PCBs).
301   // See also ActiveDY().
302   //
303   
304   return fEnveloppeSizeY/2.0;
305 }
306
307 //_____________________________________________________________________________
308 AliMpMotifPosition*
309 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
310 {
311   //
312   // Returns the motifPosition located at the position referenced by
313   // integer indices (ix,iy).
314   //
315   
316 #ifdef WITH_ROOT
317   for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
318 #else  
319   for (Size_t i = 0; i < fMotifs.size(); ++i )
320 #endif
321     {
322       AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
323       if ( mp->HasPad(AliMpIntPair(ix,iy)) )
324         {
325           return mp;
326         }
327     }
328   return 0;
329 }
330
331 //_____________________________________________________________________________
332 AliMpMotifPosition*
333 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
334 {
335   //
336   // Returns the motifPosition located at position (x,y)
337   //
338   
339 #ifdef WITH_ROOT
340   for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
341 #else  
342   for (Size_t i = 0; i < fMotifs.size(); ++i )
343 #endif   
344   {
345     AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
346     
347     TVector2 localPos( TVector2(x,y) - mp->Position() );
348     
349     AliMpIntPair localIndices(mp->GetMotif()->PadIndicesLocal(localPos));
350     
351     if ( mp->GetMotif()->GetMotifType()->HasPad(localIndices) )
352     {
353       return mp;
354     }
355   }
356     return 0;
357 }
358
359 //_____________________________________________________________________________
360 const char*
361 AliMpPCB::GetID() const
362 {
363   //
364   // Returns the name of this PCB.
365   //
366   
367   return fId.Data();
368 }
369
370 //_____________________________________________________________________________
371 AliMpMotifPosition*
372 AliMpPCB::GetMotifPosition(AliMpPCB::Size_t i) const
373 {
374   //
375   // Get the i-th motifPosition stored in this PCB's internal array.
376   //
377   
378 #ifdef WITH_ROOT
379   if ( i >= fMotifs.GetEntriesFast() ) return 0;
380 #else
381   if ( i >= fMotifs.size() ) return 0;
382 #endif  
383   return (AliMpMotifPosition*)fMotifs[i];
384 }
385
386 //_____________________________________________________________________________
387 Int_t
388 AliMpPCB::GetNofPadsX() const
389 {
390   //
391   // Returns the number of pads in x-direction.
392   //
393   
394   return fIxmax-fIxmin+1;
395 }
396
397 //_____________________________________________________________________________
398 Int_t
399 AliMpPCB::GetNofPadsY() const
400 {
401   //
402   // Returns the number of pads in y-direction.
403   //
404   
405   return fIymax-fIymin+1;
406 }
407
408 //_____________________________________________________________________________
409 AliMpPCB::Size_t
410 AliMpPCB::GetSize() const
411 {
412   //
413   // Returns the number of motifPositions stored in this PCB.
414   //
415   
416 #ifdef WITH_ROOT
417   return fMotifs.GetEntriesFast();
418 #else  
419   return fMotifs.size();
420 #endif  
421 }
422
423
424 //_____________________________________________________________________________
425 Int_t
426 AliMpPCB::Ixmin() const
427 {
428   //
429   // Returns the index value of the leftmost pad.
430   //
431   
432   return fIxmin;
433 }
434
435 //_____________________________________________________________________________
436 Int_t
437 AliMpPCB::Ixmax() const
438 {
439   //
440   // Returns the index value of the rightmost pad.
441   //
442   
443   return Ixmin() + GetNofPadsX() - 1;
444 }
445
446 //_____________________________________________________________________________
447 Double_t
448 AliMpPCB::PadSizeX() const
449 {
450   //
451   // Returns the pad size in x-direction (in mm)
452   //
453   
454   return fPadSizeX;
455 }
456
457 //_____________________________________________________________________________
458 Double_t
459 AliMpPCB::PadSizeY() const
460 {
461   //
462   // Returns the pad size in y-direction (in mm)
463   //
464   
465   return fPadSizeY;
466 }
467
468 //_____________________________________________________________________________
469 void
470 AliMpPCB::Print(Option_t* option) const
471 {
472   //
473   // Printout of this PCB.
474   // If option="M", the contained motifs are printed too.
475   //
476   
477   cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
478   << fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
479   << "iMax=(" << fIxmax << "," << fIymax << ") " 
480   << " EnvXmin,max=(" << Xmin() << "," << Xmax() 
481   << ") Xmin,max=(" << ActiveXmin() << "," << ActiveXmax() << ")"
482   << endl;
483   
484   if ( option && option[0] == 'M' )
485   {
486 #ifdef WITH_ROOT
487     for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
488 #else  
489     for ( Size_t i = 0; i < fMotifs.size(); ++i )
490 #endif    
491     {
492       if (option)
493             {
494               fMotifs[i]->Print(option+1);
495             }
496       else
497             {
498               fMotifs[i]->Print();
499             }
500     }
501   }
502 }
503
504 //_____________________________________________________________________________
505 Double_t
506 AliMpPCB::X() const
507 {
508   //
509   // Returns the x-position of the PCB center.
510   //
511   
512   return fXoffset + DX();
513 }
514
515 //_____________________________________________________________________________
516 Double_t
517 AliMpPCB::Xmin() const
518 {
519   //
520   // Returns the leftmost x-position in this PCB.
521   //
522   
523   return X() - DX();
524 }
525
526 //_____________________________________________________________________________
527 Double_t
528 AliMpPCB::Xmax() const
529 {
530   //
531   // Returns the rightmost x-position in this PCB.
532   //
533   
534   return X() + DX();
535 }
536
537 //_____________________________________________________________________________
538 Double_t
539 AliMpPCB::Y() const
540 {
541   //
542   // Returns the y-position of the PCB center.
543   //
544   
545   return DY(); // this works as PCB are organized in a single row within slats.
546 }
547
548 //_____________________________________________________________________________
549 Double_t
550 AliMpPCB::Ymin() const
551 {
552   //
553   // Returns the smallest y-position in this PCB.
554   //
555   
556   return Y() - DY();
557 }
558
559 //_____________________________________________________________________________
560 Double_t
561 AliMpPCB::Ymax() const
562 {
563   //
564   // Returns the largest y-position in this PCB.
565   //
566   
567   return Y() + DY();
568 }
569