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