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 //_____________________________________________________________________________
81 fMotifPositions.SetOwner(kTRUE);
83 AliDebug(1,Form("this=%p",this));
86 //_____________________________________________________________________________
87 AliMpPCB::AliMpPCB(AliMpSlatMotifMap* motifMap, const char* id, Double_t padSizeX, Double_t padSizeY,
88 Double_t enveloppeSizeX, Double_t enveloppeSizeY)
93 fEnveloppeSizeX(enveloppeSizeX),
94 fEnveloppeSizeY(enveloppeSizeY),
107 /// Normal ctor. Must be fed with the PCB's name (id), the pad dimensions
108 /// and the global dimension of the virtual enveloppe of the PCB
109 /// (usually 400x400 mm)
111 fMotifPositions.SetOwner(kTRUE);
113 AliDebug(1,Form("this=%p id=%s",this,id));
116 //_____________________________________________________________________________
117 AliMpPCB::AliMpPCB(const AliMpPCB& o)
139 fMotifPositions.SetOwner(kTRUE);
141 AliDebug(1,Form("this=%p (copy ctor) : begin",this));
143 AliDebug(1,Form("this=%p (copy ctor) : end",this));
146 //_____________________________________________________________________________
147 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
152 fEnveloppeSizeX(ms->Dimensions().X()*2.0),
153 fEnveloppeSizeY(ms->Dimensions().Y()*2.0),
156 fActiveXmax(fEnveloppeSizeX),
158 fIxmax(ms->GetMotifType()->GetNofPadsX()-1),
160 fIymax(ms->GetMotifType()->GetNofPadsY()-1),
162 fNofPads(ms->GetMotifType()->GetNofPads()),
166 /// Very special ctor to be used by trigger stations only (and for a very
169 /// Note that in this very case, we only allow one (special) motif per PCB.
170 /// This limitation might not be justified, except that it's all we need
174 AliDebug(1,Form("this=%p (ctor special motif)",this));
177 fMotifPositions.SetOwner(kTRUE);
179 TVector2 position(ms->Dimensions());
180 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,position);
181 mp->SetLowIndicesLimit(AliMpIntPair(fIxmin,fIymin));
182 mp->SetHighIndicesLimit(AliMpIntPair(fIxmax,fIymax));
184 fMotifPositions.AddLast(mp);
186 fMotifPositions.push_back(mp);
190 //_____________________________________________________________________________
192 AliMpPCB::operator=(const AliMpPCB& o)
194 /// Assignment operator
196 AliDebug(1,Form("this=%p (assignment op) : begin",this));
198 AliDebug(1,Form("this=%p (assignment op) : end",this));
202 //_____________________________________________________________________________
203 AliMpPCB::~AliMpPCB()
208 AliDebug(1,Form("this=%p",this));
210 for ( UInt_t i = 0; i < fMotifPositions.size(); ++i )
212 delete fMotifPositions[i];
218 //_____________________________________________________________________________
220 AliMpPCB::ActiveXmin() const
223 /// Returns the mininum x for which there is a pad in this PCB.
224 /// Different from Xmin only for PCB which are not full of pads.
230 //_____________________________________________________________________________
232 AliMpPCB::ActiveXmax() const
235 /// Returns the maximum x for which there is a pad in this PCB.
236 /// Different from Xmax only for PCB which are not full of pads.
242 //_____________________________________________________________________________
244 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
247 /// Add a motif to this PCB. (ix,iy) indicates one corner position of the motif
248 /// where the sign of ix and iy is used to indicate which corner is the
249 /// reference (then for values, abs(ix) and abs(iy) are used indeed) :
251 /// (ix>0,iy>0) : bottom-left corner
252 /// (ix<0,iy>0) : bottom-right corner
253 /// (ix<0,iy<0) : top-right corner
254 /// (ix>0,iy<0) : top-left corner.
256 TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
258 AliMpVMotif* motif = fMotifMap->FindMotif(id);
262 motif = new AliMpMotif(id,mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
263 AliDebug(1,Form("Adding motif %s to motifMap",id.Data()));
264 fMotifMap->AddMotif(motif);
268 AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
275 if ( ix >= 0 && iy >= 0 )
277 position.Set(ix*PadSizeX(),iy*PadSizeY());
282 if ( ix >= 0 && iy < 0 )
284 position.Set(ix*PadSizeX(),Ymax()+iy*PadSizeY());
286 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
289 if ( ix < 0 && iy < 0 )
291 position.Set(Xmax()+ix*PadSizeX(),Ymax()+iy*PadSizeY());
292 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
293 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
296 if ( ix < 0 && iy >=0 )
298 position.Set(Xmax()+ix*PadSizeX(),iy*PadSizeY());
299 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
303 position += motif->Dimensions();
305 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,motif,position);
306 Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
307 Int_t iymax = iymin + mt->GetNofPadsY() - 1;
309 mp->SetLowIndicesLimit(AliMpIntPair(ixmin,iymin));
310 mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
313 fMotifPositions.AddLast(mp);
315 fMotifPositions.push_back(mp);
318 fIxmin = TMath::Min(fIxmin,ixmin);
319 fIxmax = TMath::Max(fIxmax,ixmax);
320 fIymin = TMath::Min(fIymin,iymin);
321 fIymax = TMath::Max(fIymax,iymax);
323 fActiveXmin = fIxmin*PadSizeX();
324 fActiveXmax = (fIxmax+1)*PadSizeX();
325 fNofPads += mt->GetNofPads();
328 //_____________________________________________________________________________
330 AliMpPCB::Area() const
332 /// Return the area of this PCB
334 return AliMpArea(TVector2( (Xmin()+Xmax())/2.0,DY()),
335 TVector2( DX(), DY() ) );
338 //_____________________________________________________________________________
340 AliMpPCB::Clone(const char* /*newname*/) const
343 /// Return a full copy of this object.
346 TObject* object = new AliMpPCB(*this);
351 //_____________________________________________________________________________
353 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
356 /// Get a full copy of *this, and then apply 2 changes to it :
358 /// a) define the relationship motifType <-> manu id
359 /// b) define the x-offset
360 /// c) shift ix indices backwards to insure that e.g. the first
361 /// pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
366 // First get a full clone.
367 AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
369 if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
371 AliError(Form("Cannot Clone PCB %s because I do not get the correct number of "
372 "manu ids (got %d, wanted %d)",pcb->GetID(),
373 manuids.GetSize(),pcb->GetSize()));
377 AliMpIntPair shift(-fIxmin+ixOffset,0);
379 // Then change the internal MotifPositions wrt manu id
380 // and position (offset in x).
381 for ( Int_t i = 0; i < pcb->GetSize(); ++i )
383 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
384 mp->SetID(manuids[i]);
385 TVector2 pos(mp->Position());
386 pos += TVector2(xOffset,0);
387 mp->SetPosition(pos);
388 AliMpIntPair offset(ixOffset,0);
389 AliMpIntPair low(mp->GetLowIndicesLimit());
391 mp->SetLowIndicesLimit(low);
392 AliMpIntPair high(mp->GetHighIndicesLimit());
394 mp->SetHighIndicesLimit(high);
397 pcb->fIxmin += shift.GetFirst();
398 pcb->fIxmax += shift.GetFirst();
399 pcb->fXoffset = xOffset;
401 pcb->fActiveXmin += xOffset;
402 pcb->fActiveXmax += xOffset;
409 //_____________________________________________________________________________
411 AliMpPCB::Copy(TObject& o) const
413 /// Copy *this into o
418 AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
420 pcb.fPadSizeX = fPadSizeX;
421 pcb.fPadSizeY = fPadSizeY;
422 pcb.fEnveloppeSizeX = fEnveloppeSizeX;
423 pcb.fEnveloppeSizeY = fEnveloppeSizeY;
424 pcb.fXoffset = fXoffset;
429 pcb.fActiveXmin = fActiveXmin;
430 pcb.fActiveXmax = fActiveXmax;
433 AliDebug(1,"Deleting pcb.fMotifPositions");
434 pcb.fMotifPositions.Delete();
435 AliDebug(1,"Deleting pcb.fMotifPositions : done");
437 for ( UInt_t i = 0; i < pcb.fMotifPositions.size(); ++i )
439 delete pcb.fMotifPositions[i];
444 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
446 for ( UInt_t i = 0; i < fMotifPositions.size(); ++i )
449 AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifPositions[i];
450 AliMpMotifPosition* pcbpos = new AliMpMotifPosition(pos->GetID(),
453 pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
454 pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
456 pcb.fMotifPositions.AddLast(pcbpos);
458 pcb.fMotifPositions.push_back(pcbpos);
462 pcb.fNofPads = fNofPads;
464 pcb.fMotifMap = fMotifMap; // warning : we do share the motifmap.
469 //_____________________________________________________________________________
471 AliMpPCB::ActiveDX() const
474 /// Half-length (in x-direction) occupied by pads
477 return GetNofPadsX()*fPadSizeX/2.0;
480 //_____________________________________________________________________________
485 /// Half-length (in x-direction) of the PCB.
486 /// This length is the one of the virtual enveloppe of the PCB and might
487 /// be bigger than the length occupied by pads (e.g. for rounded or short
489 /// See also ActiveDX().
492 return fEnveloppeSizeX/2.0;
495 //_____________________________________________________________________________
497 AliMpPCB::ActiveDY() const
500 /// Half-length (in y-direction) occupied by pads
503 return GetNofPadsY()*fPadSizeY/2.0;
506 //_____________________________________________________________________________
511 /// Half-length (in y-direction) of the PCB.
512 /// This length is the one of the virtual enveloppe of the PCB and might
513 /// be bigger than the length occupied by pads (e.g. for rounded or short
515 /// See also ActiveDY().
518 return fEnveloppeSizeY/2.0;
521 //_____________________________________________________________________________
523 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
526 /// Returns the motifPosition located at the position referenced by
527 /// integer indices (ix,iy).
531 for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
533 for (UInt_t i = 0; i < fMotifPositions.size(); ++i )
536 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
537 if ( mp->HasPadByIndices(AliMpIntPair(ix,iy)) )
545 //_____________________________________________________________________________
547 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
550 /// Returns the motifPosition located at position (x,y)
554 for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
556 for (UInt_t i = 0; i < fMotifPositions.size(); ++i )
559 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
561 TVector2 localPos( TVector2(x,y) - mp->Position() );
563 AliMpIntPair localIndices(mp->GetMotif()->PadIndicesLocal(localPos));
565 if ( localIndices.IsValid() && mp->GetMotif()->GetMotifType()->HasPadByLocalIndices(localIndices) )
573 //_____________________________________________________________________________
575 AliMpPCB::GetID() const
578 /// Returns the name of this PCB.
584 //_____________________________________________________________________________
586 AliMpPCB::GetMotifPosition(Int_t i) const
589 /// Get the i-th motifPosition stored in this PCB's internal array.
593 if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
595 if ( i >= Int_t(fMotifPositions.size()) ) return 0;
597 return (AliMpMotifPosition*)fMotifPositions[i];
600 //_____________________________________________________________________________
602 AliMpPCB::GetNofPadsX() const
605 /// Returns the number of pads in x-direction.
608 return fIxmax-fIxmin+1;
611 //_____________________________________________________________________________
613 AliMpPCB::GetNofPadsY() const
616 /// Returns the number of pads in y-direction.
619 return fIymax-fIymin+1;
622 //_____________________________________________________________________________
624 AliMpPCB::GetSize() const
627 /// Returns the number of motifPositions stored in this PCB.
631 return fMotifPositions.GetEntriesFast();
633 return fMotifPositions.size();
637 //_____________________________________________________________________________
639 AliMpPCB::HasMotifPositionID(Int_t manuId) const
641 /// Returns whether or not we have manuId
644 TIter next(&fMotifPositions);
645 AliMpMotifPosition* pos;
646 while ( ( pos = static_cast<AliMpMotifPosition*>(next()) ) )
648 if ( pos->GetID() == manuId ) return kTRUE;
652 for ( UInt_t i=0; i<fMotifPositions.size(); ++i ) {
653 if ( fMotifPositions[i]->GetID() == manuId ) return kTRUE;
660 //_____________________________________________________________________________
662 AliMpPCB::Ixmin() const
665 /// Returns the index value of the leftmost pad.
671 //_____________________________________________________________________________
673 AliMpPCB::Ixmax() const
676 /// Returns the index value of the rightmost pad.
679 return Ixmin() + GetNofPadsX() - 1;
682 //_____________________________________________________________________________
684 AliMpPCB::Iymin() const
687 /// Returns the index value of the bottom pad.
693 //_____________________________________________________________________________
695 AliMpPCB::Iymax() const
698 /// Returns the index value of the top pad.
701 return Iymin() + GetNofPadsY() - 1;
704 //_____________________________________________________________________________
706 AliMpPCB::PadSizeX() const
709 /// Returns the pad size in x-direction (in mm)
715 //_____________________________________________________________________________
717 AliMpPCB::PadSizeY() const
720 /// Returns the pad size in y-direction (in mm)
726 //_____________________________________________________________________________
728 AliMpPCB::Print(Option_t* option) const
731 /// Printout of this PCB.
732 /// If option="M", the contained motifs are printed too.
735 cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
736 << fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
737 << "iMax=(" << fIxmax << "," << fIymax << ") "
738 << " EnvXmin,max=(" << Xmin() << "," << Xmax()
739 << ") Xmin,max=(" << ActiveXmin() << "," << ActiveXmax() << ")"
742 if ( option && option[0] == 'M' )
745 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
747 for ( UInt_t i = 0; i < fMotifPositions.size(); ++i )
752 fMotifPositions[i]->Print(option+1);
756 fMotifPositions[i]->Print();
762 //_____________________________________________________________________________
764 AliMpPCB::Save() const
767 /// Save this PCB in the file
769 TString fileName(fId);
772 lines.SetOwner(kTRUE);
775 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
777 for ( UInt_t i = 0; i < fMotifPositions.size(); ++i )
780 AliMpMotifPosition* pos = GetMotifPosition(i);
781 AliMpVMotif* motif = pos->GetMotif();
782 TVector2 lowerLeft(pos->Position()-pos->Dimensions());
783 TString id(motif->GetID());
784 // id is supposed to be of the form %s-%e-%e, and we're only
785 // interested in the %s part of it
786 Ssiz_t index = id.Index("-");
789 AliError(Form("id=%s does not meet expectations",id.Data()));
792 TString motifName(id(0,index));
793 lines.Add(new TObjString(Form("MOTIF %s %d %d",
795 TMath::Nint(lowerLeft.X()/fPadSizeX),
796 TMath::Nint(lowerLeft.Y()/fPadSizeY))));
799 ofstream out(fileName.Data());
801 out << "SIZES " << fPadSizeX << " " << fPadSizeY
802 << " " << fEnveloppeSizeX << " " << fEnveloppeSizeY
807 while ( ( s = (TObjString*)next() ) )
809 out << s->String().Data() << endl;
814 //_____________________________________________________________________________
819 /// Returns the x-position of the PCB center.
822 return fXoffset + DX();
825 //_____________________________________________________________________________
827 AliMpPCB::Xmin() const
830 /// Returns the leftmost x-position in this PCB.
836 //_____________________________________________________________________________
838 AliMpPCB::Xmax() const
841 /// Returns the rightmost x-position in this PCB.
847 //_____________________________________________________________________________
852 /// Returns the y-position of the PCB center.
855 return DY(); // this works as PCB are organized in a single row within slats.
858 //_____________________________________________________________________________
860 AliMpPCB::Ymin() const
863 /// Returns the smallest y-position in this PCB.
869 //_____________________________________________________________________________
871 AliMpPCB::Ymax() const
874 /// Returns the largest y-position in this PCB.