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.8 2006/05/24 13:58:50 ivana Exp $
21 #include "AliMpMotif.h"
22 #include "AliMpMotifPosition.h"
23 #include "AliMpMotifSpecial.h"
24 #include "AliMpMotifType.h"
27 #include "Riostream.h"
34 /// A PCB for station 3,4 or 5
36 /// A PCB is a group of pads having the same size
37 /// Pads are grouped in motifs, where 1 motif = 1 MANU
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
47 /// \author L. Aphecetche
53 //_____________________________________________________________________________
56 fPadSizeX(0), fPadSizeY(0),
57 fEnveloppeSizeX(0), fEnveloppeSizeY(0),
59 fActiveXmin(0), fActiveXmax(0),
60 fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
68 //_____________________________________________________________________________
69 AliMpPCB::AliMpPCB(const char* id, Double_t padSizeX, Double_t padSizeY,
70 Double_t enveloppeSizeX, Double_t enveloppeSizeY)
72 fPadSizeX(padSizeX), fPadSizeY(padSizeY),
73 fEnveloppeSizeX(enveloppeSizeX), fEnveloppeSizeY(enveloppeSizeY),
75 fActiveXmin(0), fActiveXmax(0),
76 fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
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)
85 //_____________________________________________________________________________
86 AliMpPCB::AliMpPCB(const AliMpPCB& o)
88 fPadSizeX(0), fPadSizeY(0),
89 fEnveloppeSizeX(0), fEnveloppeSizeY(0),
91 fActiveXmin(0), fActiveXmax(0),
92 fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
98 //_____________________________________________________________________________
99 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
100 : TObject(), fId(id), fPadSizeX(-1.0), fPadSizeY(-1.0),
104 // Very special ctor to be used by trigger stations only (and for a very
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
112 fEnveloppeSizeX = ms->Dimensions().X()*2.0;
113 fEnveloppeSizeY = ms->Dimensions().Y()*2.0;
115 fActiveXmax = fEnveloppeSizeX;
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));
126 fMotifs.push_back(mp);
128 fNofPads = ms->GetMotifType()->GetNofPads();
131 //_____________________________________________________________________________
133 AliMpPCB::operator=(const AliMpPCB& o)
139 //_____________________________________________________________________________
140 AliMpPCB::~AliMpPCB()
147 //_____________________________________________________________________________
149 AliMpPCB::ActiveXmin() const
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.
159 //_____________________________________________________________________________
161 AliMpPCB::ActiveXmax() const
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.
171 //_____________________________________________________________________________
173 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
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) :
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.
186 new AliMpMotif(mt->GetID(),mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
191 if ( ix >= 0 && iy >= 0 )
193 position.Set(ix*PadSizeX(),iy*PadSizeY());
198 if ( ix >= 0 && iy < 0 )
200 position.Set(ix*PadSizeX(),Ymax()+iy*PadSizeY());
202 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
205 if ( ix < 0 && iy < 0 )
207 position.Set(Xmax()+ix*PadSizeX(),Ymax()+iy*PadSizeY());
208 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
209 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
212 if ( ix < 0 && iy >=0 )
214 position.Set(Xmax()+ix*PadSizeX(),iy*PadSizeY());
215 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
219 position += motif->Dimensions();
221 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,motif,position);
222 Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
223 Int_t iymax = iymin + mt->GetNofPadsY() - 1;
225 mp->SetLowIndicesLimit(AliMpIntPair(ixmin,iymin));
226 mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
231 fMotifs.push_back(mp);
234 fIxmin = std::min(fIxmin,ixmin);
235 fIxmax = std::max(fIxmax,ixmax);
236 fIymin = std::min(fIymin,iymin);
237 fIymax = std::max(fIymax,iymax);
239 fActiveXmin = fIxmin*PadSizeX();
240 fActiveXmax = (fIxmax+1)*PadSizeX();
241 fNofPads += mt->GetNofPads();
244 //_____________________________________________________________________________
246 AliMpPCB::Clone(const char* /*newname*/) const
249 // Return a full copy of this object.
251 return new AliMpPCB(*this);
254 //_____________________________________________________________________________
256 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
259 // Get a full copy of *this, and then apply 2 changes to it :
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).
267 // First get a full clone.
268 AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
270 if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
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()));
278 AliMpIntPair shift(-fIxmin,0);
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 )
284 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
285 mp->SetID(manuids[i]);
286 mp->SetPosition(mp->Position() + TVector2(xOffset,0));
287 mp->SetLowIndicesLimit(mp->GetLowIndicesLimit()+
289 AliMpIntPair(ixOffset,0));
290 mp->SetHighIndicesLimit(mp->GetHighIndicesLimit()+
292 AliMpIntPair(ixOffset,0));
295 pcb->fIxmin += ixOffset + shift.GetFirst();
296 pcb->fIxmax += ixOffset + shift.GetFirst();
297 pcb->fXoffset = xOffset;
299 pcb->fActiveXmin += xOffset;
300 pcb->fActiveXmax += xOffset;
305 //_____________________________________________________________________________
307 AliMpPCB::Copy(TObject& o) const
312 AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
314 pcb.fPadSizeX = fPadSizeX;
315 pcb.fPadSizeY = fPadSizeY;
316 pcb.fEnveloppeSizeX = fEnveloppeSizeX;
317 pcb.fEnveloppeSizeY = fEnveloppeSizeY;
318 pcb.fXoffset = fXoffset;
323 pcb.fActiveXmin = fActiveXmin;
324 pcb.fActiveXmax = fActiveXmax;
333 for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
335 for ( Size_t i = 0; i < fMotifs.size(); ++i )
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());
344 pcb.fMotifs.AddLast(pcbpos);
346 pcb.fMotifs.push_back(pcbpos);
350 pcb.fNofPads = fNofPads;
353 //_____________________________________________________________________________
355 AliMpPCB::ActiveDX() const
358 // Half-length (in x-direction) occupied by pads
361 return GetNofPadsX()*fPadSizeX/2.0;
364 //_____________________________________________________________________________
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
373 // See also ActiveDX().
376 return fEnveloppeSizeX/2.0;
379 //_____________________________________________________________________________
381 AliMpPCB::ActiveDY() const
384 // Half-length (in y-direction) occupied by pads
387 return GetNofPadsY()*fPadSizeY/2.0;
390 //_____________________________________________________________________________
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
399 // See also ActiveDY().
402 return fEnveloppeSizeY/2.0;
405 //_____________________________________________________________________________
407 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
410 // Returns the motifPosition located at the position referenced by
411 // integer indices (ix,iy).
415 for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
417 for (Size_t i = 0; i < fMotifs.size(); ++i )
420 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
421 if ( mp->HasPad(AliMpIntPair(ix,iy)) )
429 //_____________________________________________________________________________
431 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
434 // Returns the motifPosition located at position (x,y)
438 for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
440 for (Size_t i = 0; i < fMotifs.size(); ++i )
443 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
445 TVector2 localPos( TVector2(x,y) - mp->Position() );
447 AliMpIntPair localIndices(mp->GetMotif()->PadIndicesLocal(localPos));
449 if ( localIndices.IsValid() && mp->GetMotif()->GetMotifType()->HasPad(localIndices) )
457 //_____________________________________________________________________________
459 AliMpPCB::GetID() const
462 // Returns the name of this PCB.
468 //_____________________________________________________________________________
470 AliMpPCB::GetMotifPosition(AliMpPCB::Size_t i) const
473 // Get the i-th motifPosition stored in this PCB's internal array.
477 if ( i >= fMotifs.GetEntriesFast() ) return 0;
479 if ( i >= fMotifs.size() ) return 0;
481 return (AliMpMotifPosition*)fMotifs[i];
484 //_____________________________________________________________________________
486 AliMpPCB::GetNofPadsX() const
489 // Returns the number of pads in x-direction.
492 return fIxmax-fIxmin+1;
495 //_____________________________________________________________________________
497 AliMpPCB::GetNofPadsY() const
500 // Returns the number of pads in y-direction.
503 return fIymax-fIymin+1;
506 //_____________________________________________________________________________
508 AliMpPCB::GetSize() const
511 // Returns the number of motifPositions stored in this PCB.
515 return fMotifs.GetEntriesFast();
517 return fMotifs.size();
522 //_____________________________________________________________________________
524 AliMpPCB::Ixmin() const
527 // Returns the index value of the leftmost pad.
533 //_____________________________________________________________________________
535 AliMpPCB::Ixmax() const
538 // Returns the index value of the rightmost pad.
541 return Ixmin() + GetNofPadsX() - 1;
544 //_____________________________________________________________________________
546 AliMpPCB::Iymin() const
549 // Returns the index value of the bottom pad.
555 //_____________________________________________________________________________
557 AliMpPCB::Iymax() const
560 // Returns the index value of the top pad.
563 return Iymin() + GetNofPadsY() - 1;
566 //_____________________________________________________________________________
568 AliMpPCB::PadSizeX() const
571 // Returns the pad size in x-direction (in mm)
577 //_____________________________________________________________________________
579 AliMpPCB::PadSizeY() const
582 // Returns the pad size in y-direction (in mm)
588 //_____________________________________________________________________________
590 AliMpPCB::Print(Option_t* option) const
593 // Printout of this PCB.
594 // If option="M", the contained motifs are printed too.
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() << ")"
604 if ( option && option[0] == 'M' )
607 for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
609 for ( Size_t i = 0; i < fMotifs.size(); ++i )
614 fMotifs[i]->Print(option+1);
624 //_____________________________________________________________________________
629 // Returns the x-position of the PCB center.
632 return fXoffset + DX();
635 //_____________________________________________________________________________
637 AliMpPCB::Xmin() const
640 // Returns the leftmost x-position in this PCB.
646 //_____________________________________________________________________________
648 AliMpPCB::Xmax() const
651 // Returns the rightmost x-position in this PCB.
657 //_____________________________________________________________________________
662 // Returns the y-position of the PCB center.
665 return DY(); // this works as PCB are organized in a single row within slats.
668 //_____________________________________________________________________________
670 AliMpPCB::Ymin() const
673 // Returns the smallest y-position in this PCB.
679 //_____________________________________________________________________________
681 AliMpPCB::Ymax() const
684 // Returns the largest y-position in this PCB.