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 "AliMpSlatMotifMap.h"
23 #include "AliMpMotifPosition.h"
24 #include "AliMpMotifSpecial.h"
25 #include "AliMpMotifType.h"
28 #include "Riostream.h"
30 #include "TObjString.h"
35 //-----------------------------------------------------------------------------
38 /// A PCB for station 3,4 or 5
40 /// A PCB is a group of pads having the same size
41 /// Pads are grouped in motifs, where 1 motif = 1 MANU
43 /// The notion of PCB enveloppe is due to the fact that not all PCBs are
44 /// "full" of pads, e.g. the rounded or short ones miss some pads,
45 /// but the enveloppe is a virtual size that should be constant
46 /// across the slats, and is 400x400 mm.
47 /// It's a usefull notion to compute e.g. slat center in a uniform way,
48 /// considering that a slat is N PCBs, of the same "virtual" size, that of
51 /// \author L. Aphecetche
52 //-----------------------------------------------------------------------------
58 //_____________________________________________________________________________
80 fMotifPositions.SetOwner(kTRUE);
81 AliDebug(1,Form("this=%p",this));
84 //_____________________________________________________________________________
85 AliMpPCB::AliMpPCB(AliMpSlatMotifMap* motifMap, const char* id, Double_t padSizeX, Double_t padSizeY,
86 Double_t enveloppeSizeX, Double_t enveloppeSizeY)
91 fEnveloppeSizeX(enveloppeSizeX),
92 fEnveloppeSizeY(enveloppeSizeY),
105 /// Normal ctor. Must be fed with the PCB's name (id), the pad dimensions
106 /// and the global dimension of the virtual enveloppe of the PCB
107 /// (usually 400x400 mm)
108 fMotifPositions.SetOwner(kTRUE);
109 AliDebug(1,Form("this=%p id=%s",this,id));
112 //_____________________________________________________________________________
113 AliMpPCB::AliMpPCB(const AliMpPCB& o)
134 fMotifPositions.SetOwner(kTRUE);
136 AliDebug(1,Form("this=%p (copy ctor) : begin",this));
138 AliDebug(1,Form("this=%p (copy ctor) : end",this));
141 //_____________________________________________________________________________
142 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
147 fEnveloppeSizeX(ms->DimensionX()*2.0),
148 fEnveloppeSizeY(ms->DimensionY()*2.0),
151 fActiveXmax(fEnveloppeSizeX),
153 fIxmax(ms->GetMotifType()->GetNofPadsX()-1),
155 fIymax(ms->GetMotifType()->GetNofPadsY()-1),
157 fNofPads(ms->GetMotifType()->GetNofPads()),
161 /// Very special ctor to be used by trigger stations only (and for a very
164 /// Note that in this very case, we only allow one (special) motif per PCB.
165 /// This limitation might not be justified, except that it's all we need
169 AliDebug(1,Form("this=%p (ctor special motif)",this));
171 fMotifPositions.SetOwner(kTRUE);
173 Double_t posx = ms->DimensionX();
174 Double_t posy = ms->DimensionY();
175 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,posx,posy);
176 mp->SetLowIndicesLimit(fIxmin,fIymin);
177 mp->SetHighIndicesLimit(fIxmax,fIymax);
178 fMotifPositions.AddLast(mp);
181 //_____________________________________________________________________________
183 AliMpPCB::operator=(const AliMpPCB& o)
185 /// Assignment operator
187 AliDebug(1,Form("this=%p (assignment op) : begin",this));
189 AliDebug(1,Form("this=%p (assignment op) : end",this));
193 //_____________________________________________________________________________
194 AliMpPCB::~AliMpPCB()
199 AliDebug(1,Form("this=%p",this));
202 //_____________________________________________________________________________
204 AliMpPCB::ActiveXmin() const
207 /// Returns the mininum x for which there is a pad in this PCB.
208 /// Different from Xmin only for PCB which are not full of pads.
214 //_____________________________________________________________________________
216 AliMpPCB::ActiveXmax() const
219 /// Returns the maximum x for which there is a pad in this PCB.
220 /// Different from Xmax only for PCB which are not full of pads.
226 //_____________________________________________________________________________
228 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
231 /// Add a motif to this PCB. (ix,iy) indicates one corner position of the motif
232 /// where the sign of ix and iy is used to indicate which corner is the
233 /// reference (then for values, abs(ix) and abs(iy) are used indeed) :
235 /// (ix>0,iy>0) : bottom-left corner
236 /// (ix<0,iy>0) : bottom-right corner
237 /// (ix<0,iy<0) : top-right corner
238 /// (ix>0,iy<0) : top-left corner.
240 TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
242 AliMpVMotif* motif = fMotifMap->FindMotif(id);
246 motif = new AliMpMotif(id,mt,PadSizeX()/2.0,PadSizeY()/2.0);
247 AliDebug(1,Form("Adding motif %s to motifMap",id.Data()));
248 fMotifMap->AddMotif(motif);
252 AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
260 if ( ix >= 0 && iy >= 0 )
262 posx = ix*PadSizeX();
263 posy = iy*PadSizeY();
268 if ( ix >= 0 && iy < 0 )
270 posx = ix*PadSizeX();
271 posy = Ymax()+iy*PadSizeY();
273 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
276 if ( ix < 0 && iy < 0 )
278 posx = Xmax()+ix*PadSizeX();
279 posy = Ymax()+iy*PadSizeY();
280 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
281 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
284 if ( ix < 0 && iy >=0 )
286 posx = Xmax()+ix*PadSizeX();
287 posy = iy*PadSizeY();
288 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
292 posx += motif->DimensionX();
293 posy += motif->DimensionY();
294 AliMpMotifPosition* mp
295 = new AliMpMotifPosition(-1,motif,posx, posy);
297 Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
298 Int_t iymax = iymin + mt->GetNofPadsY() - 1;
299 mp->SetLowIndicesLimit(ixmin,iymin);
300 mp->SetHighIndicesLimit(ixmax,iymax);
302 fMotifPositions.AddLast(mp);
304 fIxmin = TMath::Min(fIxmin,ixmin);
305 fIxmax = TMath::Max(fIxmax,ixmax);
306 fIymin = TMath::Min(fIymin,iymin);
307 fIymax = TMath::Max(fIymax,iymax);
309 fActiveXmin = fIxmin*PadSizeX();
310 fActiveXmax = (fIxmax+1)*PadSizeX();
311 fNofPads += mt->GetNofPads();
314 //_____________________________________________________________________________
316 AliMpPCB::Area() const
318 /// Return the area of this PCB
320 return AliMpArea((Xmin()+Xmax())/2.0,DY(), DX(), DY() );
323 //_____________________________________________________________________________
325 AliMpPCB::Clone(const char* /*newname*/) const
328 /// Return a full copy of this object.
331 TObject* object = new AliMpPCB(*this);
336 //_____________________________________________________________________________
338 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
341 /// Get a full copy of *this, and then apply 2 changes to it :
343 /// a) define the relationship motifType <-> manu id
344 /// b) define the x-offset
345 /// c) shift ix indices backwards to insure that e.g. the first
346 /// pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
351 // First get a full clone.
352 AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
354 if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
356 AliError(Form("Cannot Clone PCB %s because I do not get the correct number of "
357 "manu ids (got %d, wanted %d)",pcb->GetID(),
358 manuids.GetSize(),pcb->GetSize()));
362 MpPair_t shift = AliMp::Pair(-fIxmin+ixOffset,0);
364 // Then change the internal MotifPositions wrt manu id
365 // and position (offset in x).
366 for ( Int_t i = 0; i < pcb->GetSize(); ++i )
368 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
369 mp->SetID(manuids[i]);
370 Double_t posx = mp->GetPositionX() + xOffset;
371 Double_t posy = mp->GetPositionY();
372 mp->SetPosition(posx, posy);
373 MpPair_t low = mp->GetLowIndicesLimit();
375 mp->SetLowIndicesLimit(low);
376 MpPair_t high = mp->GetHighIndicesLimit();
378 mp->SetHighIndicesLimit(high);
381 pcb->fIxmin += AliMp::PairFirst(shift);
382 pcb->fIxmax += AliMp::PairFirst(shift);
383 pcb->fXoffset = xOffset;
385 pcb->fActiveXmin += xOffset;
386 pcb->fActiveXmax += xOffset;
393 //_____________________________________________________________________________
395 AliMpPCB::Copy(TObject& o) const
397 /// Copy *this into o
402 AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
404 pcb.fPadSizeX = fPadSizeX;
405 pcb.fPadSizeY = fPadSizeY;
406 pcb.fEnveloppeSizeX = fEnveloppeSizeX;
407 pcb.fEnveloppeSizeY = fEnveloppeSizeY;
408 pcb.fXoffset = fXoffset;
413 pcb.fActiveXmin = fActiveXmin;
414 pcb.fActiveXmax = fActiveXmax;
416 AliDebug(1,"Deleting pcb.fMotifPositions");
417 pcb.fMotifPositions.Delete();
418 AliDebug(1,"Deleting pcb.fMotifPositions : done");
420 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
422 AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifPositions[i];
423 AliMpMotifPosition* pcbpos
424 = new AliMpMotifPosition(pos->GetID(), pos->GetMotif(),
425 pos->GetPositionX(), pos->GetPositionY());
426 pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
427 pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
428 pcb.fMotifPositions.AddLast(pcbpos);
431 pcb.fNofPads = fNofPads;
433 pcb.fMotifMap = fMotifMap; // warning : we do share the motifmap.
438 //_____________________________________________________________________________
440 AliMpPCB::ActiveDX() const
443 /// Half-length (in x-direction) occupied by pads
446 return GetNofPadsX()*fPadSizeX/2.0;
449 //_____________________________________________________________________________
454 /// Half-length (in x-direction) of the PCB.
455 /// This length is the one of the virtual enveloppe of the PCB and might
456 /// be bigger than the length occupied by pads (e.g. for rounded or short
458 /// See also ActiveDX().
461 return fEnveloppeSizeX/2.0;
464 //_____________________________________________________________________________
466 AliMpPCB::ActiveDY() const
469 /// Half-length (in y-direction) occupied by pads
472 return GetNofPadsY()*fPadSizeY/2.0;
475 //_____________________________________________________________________________
480 /// Half-length (in y-direction) of the PCB.
481 /// This length is the one of the virtual enveloppe of the PCB and might
482 /// be bigger than the length occupied by pads (e.g. for rounded or short
484 /// See also ActiveDY().
487 return fEnveloppeSizeY/2.0;
490 //_____________________________________________________________________________
492 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
495 /// Returns the motifPosition located at the position referenced by
496 /// integer indices (ix,iy).
499 for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
501 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
502 if ( mp->HasPadByIndices(AliMp::Pair(ix,iy)) )
510 //_____________________________________________________________________________
512 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
515 /// Returns the motifPosition located at position (x,y)
518 for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
520 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
522 Double_t localPosX = x - mp->GetPositionX();
523 Double_t localPosY = y - mp->GetPositionY();
525 MpPair_t localIndices(
526 mp->GetMotif()->PadIndicesLocal(localPosX, localPosY));
528 if ( localIndices >= 0 &&
529 mp->GetMotif()->GetMotifType()->HasPadByLocalIndices(localIndices) )
537 //_____________________________________________________________________________
539 AliMpPCB::GetID() const
542 /// Returns the name of this PCB.
548 //_____________________________________________________________________________
550 AliMpPCB::GetMotifPosition(Int_t i) const
553 /// Get the i-th motifPosition stored in this PCB's internal array.
556 if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
558 return (AliMpMotifPosition*)fMotifPositions[i];
561 //_____________________________________________________________________________
563 AliMpPCB::GetNofPadsX() const
566 /// Returns the number of pads in x-direction.
569 return fIxmax-fIxmin+1;
572 //_____________________________________________________________________________
574 AliMpPCB::GetNofPadsY() const
577 /// Returns the number of pads in y-direction.
580 return fIymax-fIymin+1;
583 //_____________________________________________________________________________
585 AliMpPCB::GetSize() const
588 /// Returns the number of motifPositions stored in this PCB.
591 return fMotifPositions.GetEntriesFast();
594 //_____________________________________________________________________________
596 AliMpPCB::HasMotifPositionID(Int_t manuId) const
598 /// Returns whether or not we have manuId
600 TIter next(&fMotifPositions);
601 AliMpMotifPosition* pos;
602 while ( ( pos = static_cast<AliMpMotifPosition*>(next()) ) )
604 if ( pos->GetID() == manuId ) return kTRUE;
610 //_____________________________________________________________________________
612 AliMpPCB::Ixmin() const
615 /// Returns the index value of the leftmost pad.
621 //_____________________________________________________________________________
623 AliMpPCB::Ixmax() const
626 /// Returns the index value of the rightmost pad.
629 return Ixmin() + GetNofPadsX() - 1;
632 //_____________________________________________________________________________
634 AliMpPCB::Iymin() const
637 /// Returns the index value of the bottom pad.
643 //_____________________________________________________________________________
645 AliMpPCB::Iymax() const
648 /// Returns the index value of the top pad.
651 return Iymin() + GetNofPadsY() - 1;
654 //_____________________________________________________________________________
656 AliMpPCB::PadSizeX() const
659 /// Returns the pad size in x-direction (in mm)
665 //_____________________________________________________________________________
667 AliMpPCB::PadSizeY() const
670 /// Returns the pad size in y-direction (in mm)
676 //_____________________________________________________________________________
678 AliMpPCB::Print(Option_t* option) const
681 /// Printout of this PCB.
682 /// If option="M", the contained motifs are printed too.
685 cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
686 << fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
687 << "iMax=(" << fIxmax << "," << fIymax << ") "
688 << " EnvXmin,max=(" << Xmin() << "," << Xmax()
689 << ") Xmin,max=(" << ActiveXmin() << "," << ActiveXmax() << ")"
692 if ( option && option[0] == 'M' )
694 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
698 fMotifPositions[i]->Print(option+1);
702 fMotifPositions[i]->Print();
708 //_____________________________________________________________________________
710 AliMpPCB::Save() const
713 /// Save this PCB in the file
715 TString fileName(fId);
718 lines.SetOwner(kTRUE);
720 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
722 AliMpMotifPosition* pos = GetMotifPosition(i);
723 AliMpVMotif* motif = pos->GetMotif();
725 Double_t lowerLeftX = pos->GetPositionX()-pos->GetDimensionX();
726 Double_t lowerLeftY = pos->GetPositionY()-pos->GetDimensionY();
727 TString id(motif->GetID());
728 // id is supposed to be of the form %s-%e-%e, and we're only
729 // interested in the %s part of it
730 Ssiz_t index = id.Index("-");
733 AliError(Form("id=%s does not meet expectations",id.Data()));
736 TString motifName(id(0,index));
737 lines.Add(new TObjString(Form("MOTIF %s %d %d",
739 TMath::Nint(lowerLeftX/fPadSizeX),
740 TMath::Nint(lowerLeftY/fPadSizeY))));
743 ofstream out(fileName.Data());
745 out << "SIZES " << fPadSizeX << " " << fPadSizeY
746 << " " << fEnveloppeSizeX << " " << fEnveloppeSizeY
751 while ( ( s = (TObjString*)next() ) )
753 out << s->String().Data() << endl;
758 //_____________________________________________________________________________
763 /// Returns the x-position of the PCB center.
766 return fXoffset + DX();
769 //_____________________________________________________________________________
771 AliMpPCB::Xmin() const
774 /// Returns the leftmost x-position in this PCB.
780 //_____________________________________________________________________________
782 AliMpPCB::Xmax() const
785 /// Returns the rightmost x-position in this PCB.
791 //_____________________________________________________________________________
796 /// Returns the y-position of the PCB center.
799 return DY(); // this works as PCB are organized in a single row within slats.
802 //_____________________________________________________________________________
804 AliMpPCB::Ymin() const
807 /// Returns the smallest y-position in this PCB.
813 //_____________________________________________________________________________
815 AliMpPCB::Ymax() const
818 /// Returns the largest y-position in this PCB.