1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 // $MpId: AliMpPCB.cxx,v 1.5 2006/01/11 10:14:17 ivana Exp $
21 #include "AliMpMotif.h"
22 #include "AliMpMotifPosition.h"
23 #include "AliMpMotifSpecial.h"
24 #include "AliMpMotifType.h"
27 #include "Riostream.h"
33 //_____________________________________________________________________________
36 fPadSizeX(0), fPadSizeY(0),
37 fEnveloppeSizeX(0), fEnveloppeSizeY(0),
39 fActiveXmin(0), fActiveXmax(0),
40 fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0)
47 //_____________________________________________________________________________
48 AliMpPCB::AliMpPCB(const char* id, Double_t padSizeX, Double_t padSizeY,
49 Double_t enveloppeSizeX, Double_t enveloppeSizeY)
51 fPadSizeX(padSizeX), fPadSizeY(padSizeY),
52 fEnveloppeSizeX(enveloppeSizeX), fEnveloppeSizeY(enveloppeSizeY),
54 fActiveXmin(0), fActiveXmax(0),
55 fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0)
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)
63 //_____________________________________________________________________________
64 AliMpPCB::AliMpPCB(const AliMpPCB& o)
66 fPadSizeX(0), fPadSizeY(0),
67 fEnveloppeSizeX(0), fEnveloppeSizeY(0),
69 fActiveXmin(0), fActiveXmax(0),
70 fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0)
75 //_____________________________________________________________________________
76 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
77 : TObject(), fId(id), fPadSizeX(-1.0), fPadSizeY(-1.0),
81 // Very special ctor to be used by trigger stations only (and for a very
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
89 fEnveloppeSizeX = ms->Dimensions().X()*2.0;
90 fEnveloppeSizeY = ms->Dimensions().Y()*2.0;
92 fActiveXmax = fEnveloppeSizeX;
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));
103 fMotifs.push_back(mp);
107 //_____________________________________________________________________________
109 AliMpPCB::operator=(const AliMpPCB& o)
115 //_____________________________________________________________________________
116 AliMpPCB::~AliMpPCB()
123 //_____________________________________________________________________________
125 AliMpPCB::ActiveXmin() const
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.
135 //_____________________________________________________________________________
137 AliMpPCB::ActiveXmax() const
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.
147 //_____________________________________________________________________________
149 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
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) :
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.
162 new AliMpMotif(mt->GetID(),mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
167 if ( ix >= 0 && iy >= 0 )
169 position.Set(ix*PadSizeX(),iy*PadSizeY());
174 if ( ix >= 0 && iy < 0 )
176 position.Set(ix*PadSizeX(),Ymax()+iy*PadSizeY());
178 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
181 if ( ix < 0 && iy < 0 )
183 position.Set(Xmax()+ix*PadSizeX(),Ymax()+iy*PadSizeY());
184 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
185 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
188 if ( ix < 0 && iy >=0 )
190 position.Set(Xmax()+ix*PadSizeX(),iy*PadSizeY());
191 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
195 position += motif->Dimensions();
197 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,motif,position);
198 Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
199 Int_t iymax = iymin + mt->GetNofPadsY() - 1;
201 mp->SetLowIndicesLimit(AliMpIntPair(ixmin,iymin));
202 mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
207 fMotifs.push_back(mp);
210 fIxmin = std::min(fIxmin,ixmin);
211 fIxmax = std::max(fIxmax,ixmax);
212 fIymin = std::min(fIymin,iymin);
213 fIymax = std::max(fIymax,iymax);
215 fActiveXmin = fIxmin*PadSizeX();
216 fActiveXmax = (fIxmax+1)*PadSizeX();
219 //_____________________________________________________________________________
221 AliMpPCB::Clone(const char* /*newname*/) const
224 // Return a full copy of this object.
226 return new AliMpPCB(*this);
229 //_____________________________________________________________________________
231 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
234 // Get a full copy of *this, and then apply 2 changes to it :
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).
242 // First get a full clone.
243 AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
245 if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
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(),
249 manuids.GetSize(),pcb->GetSize()));
253 AliMpIntPair shift(-fIxmin,0);
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 )
259 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
260 mp->SetID(manuids[i]);
261 mp->SetPosition(mp->Position() + TVector2(xOffset,0));
262 mp->SetLowIndicesLimit(mp->GetLowIndicesLimit()+
264 AliMpIntPair(ixOffset,0));
265 mp->SetHighIndicesLimit(mp->GetHighIndicesLimit()+
267 AliMpIntPair(ixOffset,0));
270 pcb->fIxmin += ixOffset + shift.GetFirst();
271 pcb->fIxmax += ixOffset + shift.GetFirst();
272 pcb->fXoffset = xOffset;
274 pcb->fActiveXmin += xOffset;
275 pcb->fActiveXmax += xOffset;
280 //_____________________________________________________________________________
282 AliMpPCB::Copy(TObject& o) const
285 AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
287 pcb.fPadSizeX = fPadSizeX;
288 pcb.fPadSizeY = fPadSizeY;
289 pcb.fEnveloppeSizeX = fEnveloppeSizeX;
290 pcb.fEnveloppeSizeY = fEnveloppeSizeY;
291 pcb.fXoffset = fXoffset;
296 pcb.fActiveXmin = fActiveXmin;
297 pcb.fActiveXmax = fActiveXmax;
306 for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
308 for ( Size_t i = 0; i < fMotifs.size(); ++i )
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());
317 pcb.fMotifs.AddLast(pcbpos);
319 pcb.fMotifs.push_back(pcbpos);
324 //_____________________________________________________________________________
326 AliMpPCB::ActiveDX() const
329 // Half-length (in x-direction) occupied by pads
332 return GetNofPadsX()*fPadSizeX/2.0;
335 //_____________________________________________________________________________
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
344 // See also ActiveDX().
347 return fEnveloppeSizeX/2.0;
350 //_____________________________________________________________________________
352 AliMpPCB::ActiveDY() const
355 // Half-length (in y-direction) occupied by pads
358 return GetNofPadsY()*fPadSizeY/2.0;
361 //_____________________________________________________________________________
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
370 // See also ActiveDY().
373 return fEnveloppeSizeY/2.0;
376 //_____________________________________________________________________________
378 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
381 // Returns the motifPosition located at the position referenced by
382 // integer indices (ix,iy).
386 for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
388 for (Size_t i = 0; i < fMotifs.size(); ++i )
391 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
392 if ( mp->HasPad(AliMpIntPair(ix,iy)) )
400 //_____________________________________________________________________________
402 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
405 // Returns the motifPosition located at position (x,y)
409 for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
411 for (Size_t i = 0; i < fMotifs.size(); ++i )
414 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
416 TVector2 localPos( TVector2(x,y) - mp->Position() );
418 AliMpIntPair localIndices(mp->GetMotif()->PadIndicesLocal(localPos));
420 if ( localIndices.IsValid() && mp->GetMotif()->GetMotifType()->HasPad(localIndices) )
428 //_____________________________________________________________________________
430 AliMpPCB::GetID() const
433 // Returns the name of this PCB.
439 //_____________________________________________________________________________
441 AliMpPCB::GetMotifPosition(AliMpPCB::Size_t i) const
444 // Get the i-th motifPosition stored in this PCB's internal array.
448 if ( i >= fMotifs.GetEntriesFast() ) return 0;
450 if ( i >= fMotifs.size() ) return 0;
452 return (AliMpMotifPosition*)fMotifs[i];
455 //_____________________________________________________________________________
457 AliMpPCB::GetNofPadsX() const
460 // Returns the number of pads in x-direction.
463 return fIxmax-fIxmin+1;
466 //_____________________________________________________________________________
468 AliMpPCB::GetNofPadsY() const
471 // Returns the number of pads in y-direction.
474 return fIymax-fIymin+1;
477 //_____________________________________________________________________________
479 AliMpPCB::GetSize() const
482 // Returns the number of motifPositions stored in this PCB.
486 return fMotifs.GetEntriesFast();
488 return fMotifs.size();
493 //_____________________________________________________________________________
495 AliMpPCB::Ixmin() const
498 // Returns the index value of the leftmost pad.
504 //_____________________________________________________________________________
506 AliMpPCB::Ixmax() const
509 // Returns the index value of the rightmost pad.
512 return Ixmin() + GetNofPadsX() - 1;
515 //_____________________________________________________________________________
517 AliMpPCB::Iymin() const
520 // Returns the index value of the bottom pad.
526 //_____________________________________________________________________________
528 AliMpPCB::Iymax() const
531 // Returns the index value of the top pad.
534 return Iymin() + GetNofPadsY() - 1;
537 //_____________________________________________________________________________
539 AliMpPCB::PadSizeX() const
542 // Returns the pad size in x-direction (in mm)
548 //_____________________________________________________________________________
550 AliMpPCB::PadSizeY() const
553 // Returns the pad size in y-direction (in mm)
559 //_____________________________________________________________________________
561 AliMpPCB::Print(Option_t* option) const
564 // Printout of this PCB.
565 // If option="M", the contained motifs are printed too.
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() << ")"
575 if ( option && option[0] == 'M' )
578 for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
580 for ( Size_t i = 0; i < fMotifs.size(); ++i )
585 fMotifs[i]->Print(option+1);
595 //_____________________________________________________________________________
600 // Returns the x-position of the PCB center.
603 return fXoffset + DX();
606 //_____________________________________________________________________________
608 AliMpPCB::Xmin() const
611 // Returns the leftmost x-position in this PCB.
617 //_____________________________________________________________________________
619 AliMpPCB::Xmax() const
622 // Returns the rightmost x-position in this PCB.
628 //_____________________________________________________________________________
633 // Returns the y-position of the PCB center.
636 return DY(); // this works as PCB are organized in a single row within slats.
639 //_____________________________________________________________________________
641 AliMpPCB::Ymin() const
644 // Returns the smallest y-position in this PCB.
650 //_____________________________________________________________________________
652 AliMpPCB::Ymax() const
655 // Returns the largest y-position in this PCB.