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