]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpPCB.cxx
Updated comments for Doxygen - corrected warnings
[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.8 2006/05/24 13:58:50 ivana Exp $
18
19 #include "AliMpPCB.h"
20
21 #include "AliMpMotif.h"
22 #include "AliMpMotifPosition.h"
23 #include "AliMpMotifSpecial.h"
24 #include "AliMpMotifType.h"
25 #include "AliLog.h"
26
27 #include "Riostream.h"
28 #include "TMath.h"
29 #include <sstream>
30
31 /// 
32 /// \class AliMpPCB
33 ///
34 /// A PCB for station 3,4 or 5
35 /// 
36 /// A PCB is a group of pads having the same size
37 /// Pads are grouped in motifs, where 1 motif = 1 MANU
38 ///
39 /// The notion of PCB enveloppe is due to the fact that not all PCBs are
40 /// "full" of pads, e.g. the rounded or short ones miss some pads,
41 /// but the enveloppe is a virtual size that should be constant 
42 /// across the slats, and is 400x400 mm.
43 /// It's a usefull notion to compute e.g. slat center in a uniform way, 
44 /// considering that a slat is N PCBs, of the same "virtual" size, that of 
45 /// the enveloppe.
46 ///
47 /// \author L. Aphecetche
48
49 /// \cond CLASSIMP
50 ClassImp(AliMpPCB)
51 /// \endcond
52
53 //_____________________________________________________________________________
54 AliMpPCB::AliMpPCB() 
55   : TObject(), fId(""), 
56     fPadSizeX(0), fPadSizeY(0), 
57     fEnveloppeSizeX(0), fEnveloppeSizeY(0),
58     fXoffset(0),
59     fActiveXmin(0), fActiveXmax(0),
60     fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
61     fNofPads(0)
62 {
63       //
64       // Default ctor.
65       //
66 }
67
68 //_____________________________________________________________________________
69 AliMpPCB::AliMpPCB(const char* id, Double_t padSizeX, Double_t padSizeY,
70                    Double_t enveloppeSizeX, Double_t enveloppeSizeY)
71   : TObject(), fId(id), 
72     fPadSizeX(padSizeX), fPadSizeY(padSizeY), 
73     fEnveloppeSizeX(enveloppeSizeX), fEnveloppeSizeY(enveloppeSizeY),
74     fXoffset(0),
75     fActiveXmin(0), fActiveXmax(0),
76     fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
77     fNofPads(0)
78 {
79       //
80       // Normal ctor. Must be fed with the PCB's name (id), the pad dimensions
81       // and the global dimension of the virtual enveloppe of the PCB
82       // (usually 400x400 mm)
83 }
84
85 //_____________________________________________________________________________
86 AliMpPCB::AliMpPCB(const AliMpPCB& o) 
87   : TObject(o),
88     fPadSizeX(0), fPadSizeY(0), 
89     fEnveloppeSizeX(0), fEnveloppeSizeY(0),
90     fXoffset(0),
91     fActiveXmin(0), fActiveXmax(0),
92     fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
93     fNofPads(0)
94 {
95   o.Copy(*this);
96 }
97
98 //_____________________________________________________________________________
99 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
100 : TObject(), fId(id), fPadSizeX(-1.0), fPadSizeY(-1.0),
101   fXoffset(0)
102 {
103   //
104   // Very special ctor to be used by trigger stations only (and for a very
105   // specific case).
106   //
107   // Note that in this very case, we only allow one (special) motif per PCB.
108   // This limitation might not be justified, except that it's all we need
109   // so far ;-)
110   //
111   fXoffset = 0.0;
112   fEnveloppeSizeX = ms->Dimensions().X()*2.0;
113   fEnveloppeSizeY = ms->Dimensions().Y()*2.0;
114   fActiveXmin = 0.0;
115   fActiveXmax = fEnveloppeSizeX;
116   fIxmin = fIymin = 0;
117   fIxmax = ms->GetMotifType()->GetNofPadsX()-1;
118   fIymax = ms->GetMotifType()->GetNofPadsY()-1;
119   TVector2 position(ms->Dimensions());
120   AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,position);
121   mp->SetLowIndicesLimit(AliMpIntPair(fIxmin,fIymin));
122   mp->SetHighIndicesLimit(AliMpIntPair(fIxmax,fIymax));
123 #ifdef WITH_ROOT
124   fMotifs.AddLast(mp);
125 #else
126   fMotifs.push_back(mp);
127 #endif
128   fNofPads = ms->GetMotifType()->GetNofPads();
129 }
130
131 //_____________________________________________________________________________
132 AliMpPCB&
133 AliMpPCB::operator=(const AliMpPCB& o)
134 {
135   o.Copy(*this);
136   return *this;  
137 }
138
139 //_____________________________________________________________________________
140 AliMpPCB::~AliMpPCB()
141 {
142   //
143   // Dtor.
144   //
145 }
146
147 //_____________________________________________________________________________
148 Double_t
149 AliMpPCB::ActiveXmin() const
150 {
151   //
152   // Returns the mininum x for which there is a pad in this PCB.
153   // Different from Xmin only for PCB which are not full of pads.
154   //
155   
156   return fActiveXmin;
157 }
158
159 //_____________________________________________________________________________
160 Double_t
161 AliMpPCB::ActiveXmax() const
162 {
163   //
164   // Returns the maximum x for which there is a pad in this PCB.
165   // Different from Xmax only for PCB which are not full of pads.
166   //  
167   
168   return fActiveXmax;
169 }
170
171 //_____________________________________________________________________________
172 void
173 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
174 {
175   //
176   // Add a motif to this PCB. (ix,iy) indicates one corner position of the motif
177   // where the sign of ix and iy is used to indicate which corner is the 
178   // reference (then for values, abs(ix) and abs(iy) are used indeed) :
179   //
180   // (ix>0,iy>0) : bottom-left corner
181   // (ix<0,iy>0) : bottom-right corner
182   // (ix<0,iy<0) : top-right corner
183   // (ix>0,iy<0) : top-left corner.
184   
185   AliMpVMotif* motif = 
186     new AliMpMotif(mt->GetID(),mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
187   TVector2 position;
188   Int_t ixmin(-1);
189   Int_t iymin(-1);
190   
191   if ( ix >= 0 && iy >= 0 )
192   {
193     position.Set(ix*PadSizeX(),iy*PadSizeY());
194     ixmin = ix;
195     iymin = iy;
196   }
197   else
198   if ( ix >= 0 && iy < 0 )
199   {
200     position.Set(ix*PadSizeX(),Ymax()+iy*PadSizeY());
201     ixmin = ix;
202     iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
203   }
204   else
205   if ( ix < 0 && iy < 0 )
206   {
207     position.Set(Xmax()+ix*PadSizeX(),Ymax()+iy*PadSizeY());
208     ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
209     iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
210   }
211   else
212   if ( ix < 0 && iy >=0 )
213   {
214     position.Set(Xmax()+ix*PadSizeX(),iy*PadSizeY());
215     ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
216     iymin = iy;
217   }
218
219   position += motif->Dimensions();
220
221   AliMpMotifPosition* mp = new AliMpMotifPosition(-1,motif,position);
222   Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
223   Int_t iymax = iymin + mt->GetNofPadsY() - 1;
224
225   mp->SetLowIndicesLimit(AliMpIntPair(ixmin,iymin));
226   mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
227
228 #ifdef WITH_ROOT
229   fMotifs.AddLast(mp);
230 #else
231   fMotifs.push_back(mp);
232 #endif
233
234   fIxmin = std::min(fIxmin,ixmin);
235   fIxmax = std::max(fIxmax,ixmax);
236   fIymin = std::min(fIymin,iymin);
237   fIymax = std::max(fIymax,iymax);
238
239   fActiveXmin = fIxmin*PadSizeX();
240   fActiveXmax = (fIxmax+1)*PadSizeX();
241   fNofPads += mt->GetNofPads();
242 }
243
244 //_____________________________________________________________________________
245 TObject*
246 AliMpPCB::Clone(const char* /*newname*/) const
247 {
248   //
249   // Return a full copy of this object.
250   //
251   return new AliMpPCB(*this);
252 }
253
254 //_____________________________________________________________________________
255 AliMpPCB*
256 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
257 {
258   //
259   // Get a full copy of *this, and then apply 2 changes to it :
260   //
261   // a) define the relationship motifType <-> manu id
262   // b) define the x-offset
263   // c) shift ix indices backwards to insure that e.g. the first
264   //    pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
265   //
266
267   // First get a full clone.
268   AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
269
270   if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
271   {
272       AliError(Form("Cannot Clone PCB %s because I do not get the correct number of "
273                     "manu ids (got %d, wanted %d)",pcb->GetID(),
274                     manuids.GetSize(),pcb->GetSize()));
275       return 0;
276   }
277
278   AliMpIntPair shift(-fIxmin,0);
279
280   // Then change the internal MotifPositions wrt manu id
281   // and position (offset in x).
282   for ( Size_t i = 0; i < pcb->GetSize(); ++i )
283     {
284       AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
285       mp->SetID(manuids[i]);
286       mp->SetPosition(mp->Position() + TVector2(xOffset,0));
287       mp->SetLowIndicesLimit(mp->GetLowIndicesLimit()+
288                              shift+
289                              AliMpIntPair(ixOffset,0));
290       mp->SetHighIndicesLimit(mp->GetHighIndicesLimit()+
291                               shift+
292                               AliMpIntPair(ixOffset,0));
293     }
294   
295   pcb->fIxmin += ixOffset + shift.GetFirst();
296   pcb->fIxmax += ixOffset + shift.GetFirst();
297   pcb->fXoffset = xOffset;
298
299   pcb->fActiveXmin += xOffset;
300   pcb->fActiveXmax += xOffset;
301
302   return pcb;
303 }
304
305 //_____________________________________________________________________________
306 void
307 AliMpPCB::Copy(TObject& o) const
308 {
309   // Copy *this into o
310
311   TObject::Copy(o);
312   AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
313   pcb.fId = fId;
314   pcb.fPadSizeX = fPadSizeX;
315   pcb.fPadSizeY = fPadSizeY;
316   pcb.fEnveloppeSizeX = fEnveloppeSizeX;
317   pcb.fEnveloppeSizeY = fEnveloppeSizeY;
318   pcb.fXoffset = fXoffset;
319   pcb.fIxmin = fIxmin;
320   pcb.fIxmax = fIxmax;
321   pcb.fIymin = fIymin;
322   pcb.fIymax = fIymax;
323   pcb.fActiveXmin = fActiveXmin;
324   pcb.fActiveXmax = fActiveXmax;
325
326 #ifdef WITH_ROOT
327   pcb.fMotifs.Clear();
328 #else
329   pcb.fMotifs.clear();
330 #endif
331
332 #ifdef WITH_ROOT
333   for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
334 #else
335   for ( Size_t i = 0; i < fMotifs.size(); ++i )
336 #endif  
337     {
338       AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifs[i];
339       AliMpMotifPosition* pcbpos = 
340         new AliMpMotifPosition(pos->GetID(),pos->GetMotif(),pos->Position());
341       pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
342       pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
343 #ifdef WITH_ROOT
344       pcb.fMotifs.AddLast(pcbpos);
345 #else      
346       pcb.fMotifs.push_back(pcbpos);
347 #endif      
348     }
349     
350     pcb.fNofPads = fNofPads;  
351 }
352
353 //_____________________________________________________________________________
354 Double_t
355 AliMpPCB::ActiveDX() const
356 {
357   //
358   // Half-length (in x-direction) occupied by pads  
359   //
360   
361   return GetNofPadsX()*fPadSizeX/2.0;
362 }
363
364 //_____________________________________________________________________________
365 Double_t
366 AliMpPCB::DX() const
367 {
368   //
369   // Half-length (in x-direction) of the PCB.
370   // This length is the one of the virtual enveloppe of the PCB and might
371   // be bigger than the length occupied by pads (e.g. for rounded or short
372   // PCBs).  
373   // See also ActiveDX().
374   //
375   
376   return fEnveloppeSizeX/2.0;
377 }
378
379 //_____________________________________________________________________________
380 Double_t
381 AliMpPCB::ActiveDY() const
382 {
383   //
384   // Half-length (in y-direction) occupied by pads
385   //
386   
387   return GetNofPadsY()*fPadSizeY/2.0;
388 }
389
390 //_____________________________________________________________________________
391 Double_t
392 AliMpPCB::DY() const
393 {
394   //
395   // Half-length (in y-direction) of the PCB.
396   // This length is the one of the virtual enveloppe of the PCB and might
397   // be bigger than the length occupied by pads (e.g. for rounded or short
398   // PCBs).
399   // See also ActiveDY().
400   //
401   
402   return fEnveloppeSizeY/2.0;
403 }
404
405 //_____________________________________________________________________________
406 AliMpMotifPosition*
407 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
408 {
409   //
410   // Returns the motifPosition located at the position referenced by
411   // integer indices (ix,iy).
412   //
413   
414 #ifdef WITH_ROOT
415   for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
416 #else  
417   for (Size_t i = 0; i < fMotifs.size(); ++i )
418 #endif
419     {
420       AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
421       if ( mp->HasPad(AliMpIntPair(ix,iy)) )
422       {
423         return mp;
424       }
425     }
426   return 0;
427 }
428
429 //_____________________________________________________________________________
430 AliMpMotifPosition*
431 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
432 {
433   //
434   // Returns the motifPosition located at position (x,y)
435   //
436   
437 #ifdef WITH_ROOT
438   for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
439 #else  
440   for (Size_t i = 0; i < fMotifs.size(); ++i )
441 #endif   
442   {
443     AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
444     
445     TVector2 localPos( TVector2(x,y) - mp->Position() );
446     
447     AliMpIntPair localIndices(mp->GetMotif()->PadIndicesLocal(localPos));
448     
449     if ( localIndices.IsValid() && mp->GetMotif()->GetMotifType()->HasPad(localIndices) )
450     {
451       return mp;
452     }
453   }
454     return 0;
455 }
456
457 //_____________________________________________________________________________
458 const char*
459 AliMpPCB::GetID() const
460 {
461   //
462   // Returns the name of this PCB.
463   //
464   
465   return fId.Data();
466 }
467
468 //_____________________________________________________________________________
469 AliMpMotifPosition*
470 AliMpPCB::GetMotifPosition(AliMpPCB::Size_t i) const
471 {
472   //
473   // Get the i-th motifPosition stored in this PCB's internal array.
474   //
475   
476 #ifdef WITH_ROOT
477   if ( i >= fMotifs.GetEntriesFast() ) return 0;
478 #else
479   if ( i >= fMotifs.size() ) return 0;
480 #endif  
481   return (AliMpMotifPosition*)fMotifs[i];
482 }
483
484 //_____________________________________________________________________________
485 Int_t
486 AliMpPCB::GetNofPadsX() const
487 {
488   //
489   // Returns the number of pads in x-direction.
490   //
491   
492   return fIxmax-fIxmin+1;
493 }
494
495 //_____________________________________________________________________________
496 Int_t
497 AliMpPCB::GetNofPadsY() const
498 {
499   //
500   // Returns the number of pads in y-direction.
501   //
502   
503   return fIymax-fIymin+1;
504 }
505
506 //_____________________________________________________________________________
507 AliMpPCB::Size_t
508 AliMpPCB::GetSize() const
509 {
510   //
511   // Returns the number of motifPositions stored in this PCB.
512   //
513   
514 #ifdef WITH_ROOT
515   return fMotifs.GetEntriesFast();
516 #else  
517   return fMotifs.size();
518 #endif  
519 }
520
521
522 //_____________________________________________________________________________
523 Int_t
524 AliMpPCB::Ixmin() const
525 {
526   //
527   // Returns the index value of the leftmost pad.
528   //
529   
530   return fIxmin;
531 }
532
533 //_____________________________________________________________________________
534 Int_t
535 AliMpPCB::Ixmax() const
536 {
537   //
538   // Returns the index value of the rightmost pad.
539   //
540   
541   return Ixmin() + GetNofPadsX() - 1;
542 }
543
544 //_____________________________________________________________________________
545 Int_t
546 AliMpPCB::Iymin() const
547 {
548   //
549   // Returns the index value of the bottom pad.
550   //
551   
552   return fIymin;
553 }
554
555 //_____________________________________________________________________________
556 Int_t
557 AliMpPCB::Iymax() const
558 {
559   //
560   // Returns the index value of the top pad.
561   //
562   
563   return Iymin() + GetNofPadsY() - 1;
564 }
565
566 //_____________________________________________________________________________
567 Double_t
568 AliMpPCB::PadSizeX() const
569 {
570   //
571   // Returns the pad size in x-direction (in mm)
572   //
573   
574   return fPadSizeX;
575 }
576
577 //_____________________________________________________________________________
578 Double_t
579 AliMpPCB::PadSizeY() const
580 {
581   //
582   // Returns the pad size in y-direction (in mm)
583   //
584   
585   return fPadSizeY;
586 }
587
588 //_____________________________________________________________________________
589 void
590 AliMpPCB::Print(Option_t* option) const
591 {
592   //
593   // Printout of this PCB.
594   // If option="M", the contained motifs are printed too.
595   //
596   
597   cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
598   << fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
599   << "iMax=(" << fIxmax << "," << fIymax << ") " 
600   << " EnvXmin,max=(" << Xmin() << "," << Xmax() 
601   << ") Xmin,max=(" << ActiveXmin() << "," << ActiveXmax() << ")"
602   << endl;
603   
604   if ( option && option[0] == 'M' )
605   {
606 #ifdef WITH_ROOT
607     for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
608 #else  
609     for ( Size_t i = 0; i < fMotifs.size(); ++i )
610 #endif    
611     {
612       if (option)
613             {
614               fMotifs[i]->Print(option+1);
615             }
616       else
617             {
618               fMotifs[i]->Print();
619             }
620     }
621   }
622 }
623
624 //_____________________________________________________________________________
625 Double_t
626 AliMpPCB::X() const
627 {
628   //
629   // Returns the x-position of the PCB center.
630   //
631   
632   return fXoffset + DX();
633 }
634
635 //_____________________________________________________________________________
636 Double_t
637 AliMpPCB::Xmin() const
638 {
639   //
640   // Returns the leftmost x-position in this PCB.
641   //
642   
643   return X() - DX();
644 }
645
646 //_____________________________________________________________________________
647 Double_t
648 AliMpPCB::Xmax() const
649 {
650   //
651   // Returns the rightmost x-position in this PCB.
652   //
653   
654   return X() + DX();
655 }
656
657 //_____________________________________________________________________________
658 Double_t
659 AliMpPCB::Y() const
660 {
661   //
662   // Returns the y-position of the PCB center.
663   //
664   
665   return DY(); // this works as PCB are organized in a single row within slats.
666 }
667
668 //_____________________________________________________________________________
669 Double_t
670 AliMpPCB::Ymin() const
671 {
672   //
673   // Returns the smallest y-position in this PCB.
674   //
675   
676   return Y() - DY();
677 }
678
679 //_____________________________________________________________________________
680 Double_t
681 AliMpPCB::Ymax() const
682 {
683   //
684   // Returns the largest y-position in this PCB.
685   //
686   
687   return Y() + DY();
688 }
689