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