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"
37 /// A PCB for station 3,4 or 5
39 /// A PCB is a group of pads having the same size
40 /// Pads are grouped in motifs, where 1 motif = 1 MANU
42 /// The notion of PCB enveloppe is due to the fact that not all PCBs are
43 /// "full" of pads, e.g. the rounded or short ones miss some pads,
44 /// but the enveloppe is a virtual size that should be constant
45 /// across the slats, and is 400x400 mm.
46 /// It's a usefull notion to compute e.g. slat center in a uniform way,
47 /// considering that a slat is N PCBs, of the same "virtual" size, that of
50 /// \author L. Aphecetche
56 //_____________________________________________________________________________
79 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)
109 fMotifPositions.SetOwner(kTRUE);
111 AliDebug(1,Form("this=%p id=%s",this,id));
114 //_____________________________________________________________________________
115 AliMpPCB::AliMpPCB(const AliMpPCB& o)
137 fMotifPositions.SetOwner(kTRUE);
139 AliDebug(1,Form("this=%p (copy ctor) : begin",this));
141 AliDebug(1,Form("this=%p (copy ctor) : end",this));
144 //_____________________________________________________________________________
145 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
150 fEnveloppeSizeX(ms->Dimensions().X()*2.0),
151 fEnveloppeSizeY(ms->Dimensions().Y()*2.0),
154 fActiveXmax(fEnveloppeSizeX),
156 fIxmax(ms->GetMotifType()->GetNofPadsX()-1),
158 fIymax(ms->GetMotifType()->GetNofPadsY()-1),
160 fNofPads(ms->GetMotifType()->GetNofPads()),
164 // Very special ctor to be used by trigger stations only (and for a very
167 // Note that in this very case, we only allow one (special) motif per PCB.
168 // This limitation might not be justified, except that it's all we need
172 AliDebug(1,Form("this=%p (ctor special motif)",this));
175 fMotifPositions.SetOwner(kTRUE);
177 TVector2 position(ms->Dimensions());
178 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,position);
179 mp->SetLowIndicesLimit(AliMpIntPair(fIxmin,fIymin));
180 mp->SetHighIndicesLimit(AliMpIntPair(fIxmax,fIymax));
182 fMotifPositions.AddLast(mp);
184 fMotifPositions.push_back(mp);
188 //_____________________________________________________________________________
190 AliMpPCB::operator=(const AliMpPCB& o)
192 // Assignment operator
194 AliDebug(1,Form("this=%p (assignment op) : begin",this));
196 AliDebug(1,Form("this=%p (assignment op) : end",this));
200 //_____________________________________________________________________________
201 AliMpPCB::~AliMpPCB()
206 AliDebug(1,Form("this=%p",this));
208 for ( size_t i = 0; i < fMotifPositions.size(); ++i )
210 delete fMotifPositions[i];
216 //_____________________________________________________________________________
218 AliMpPCB::ActiveXmin() const
221 // Returns the mininum x for which there is a pad in this PCB.
222 // Different from Xmin only for PCB which are not full of pads.
228 //_____________________________________________________________________________
230 AliMpPCB::ActiveXmax() const
233 // Returns the maximum x for which there is a pad in this PCB.
234 // Different from Xmax only for PCB which are not full of pads.
240 //_____________________________________________________________________________
242 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
245 // Add a motif to this PCB. (ix,iy) indicates one corner position of the motif
246 // where the sign of ix and iy is used to indicate which corner is the
247 // reference (then for values, abs(ix) and abs(iy) are used indeed) :
249 // (ix>0,iy>0) : bottom-left corner
250 // (ix<0,iy>0) : bottom-right corner
251 // (ix<0,iy<0) : top-right corner
252 // (ix>0,iy<0) : top-left corner.
254 TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
256 AliMpVMotif* motif = fMotifMap->FindMotif(id);
260 motif = new AliMpMotif(id,mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
261 AliDebug(1,Form("Adding motif %s to motifMap",id.Data()));
262 fMotifMap->AddMotif(motif);
266 AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
273 if ( ix >= 0 && iy >= 0 )
275 position.Set(ix*PadSizeX(),iy*PadSizeY());
280 if ( ix >= 0 && iy < 0 )
282 position.Set(ix*PadSizeX(),Ymax()+iy*PadSizeY());
284 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
287 if ( ix < 0 && iy < 0 )
289 position.Set(Xmax()+ix*PadSizeX(),Ymax()+iy*PadSizeY());
290 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
291 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
294 if ( ix < 0 && iy >=0 )
296 position.Set(Xmax()+ix*PadSizeX(),iy*PadSizeY());
297 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
301 position += motif->Dimensions();
303 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,motif,position);
304 Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
305 Int_t iymax = iymin + mt->GetNofPadsY() - 1;
307 mp->SetLowIndicesLimit(AliMpIntPair(ixmin,iymin));
308 mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
311 fMotifPositions.AddLast(mp);
313 fMotifPositions.push_back(mp);
316 fIxmin = std::min(fIxmin,ixmin);
317 fIxmax = std::max(fIxmax,ixmax);
318 fIymin = std::min(fIymin,iymin);
319 fIymax = std::max(fIymax,iymax);
321 fActiveXmin = fIxmin*PadSizeX();
322 fActiveXmax = (fIxmax+1)*PadSizeX();
323 fNofPads += mt->GetNofPads();
326 //_____________________________________________________________________________
328 AliMpPCB::Area() const
330 return AliMpArea(TVector2( (Xmin()+Xmax())/2.0,DY()),
331 TVector2( DX(), DY() ) );
334 //_____________________________________________________________________________
336 AliMpPCB::Clone(const char* /*newname*/) const
339 // Return a full copy of this object.
342 TObject* object = new AliMpPCB(*this);
347 //_____________________________________________________________________________
349 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
352 // Get a full copy of *this, and then apply 2 changes to it :
354 // a) define the relationship motifType <-> manu id
355 // b) define the x-offset
356 // c) shift ix indices backwards to insure that e.g. the first
357 // pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
362 // First get a full clone.
363 AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
365 if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
367 AliError(Form("Cannot Clone PCB %s because I do not get the correct number of "
368 "manu ids (got %d, wanted %d)",pcb->GetID(),
369 manuids.GetSize(),pcb->GetSize()));
373 AliMpIntPair shift(-fIxmin+ixOffset,0);
375 // Then change the internal MotifPositions wrt manu id
376 // and position (offset in x).
377 for ( Size_t i = 0; i < pcb->GetSize(); ++i )
379 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
380 mp->SetID(manuids[i]);
381 TVector2 pos(mp->Position());
382 pos += TVector2(xOffset,0);
383 mp->SetPosition(pos);
384 AliMpIntPair offset(ixOffset,0);
385 AliMpIntPair low(mp->GetLowIndicesLimit());
387 mp->SetLowIndicesLimit(low);
388 AliMpIntPair high(mp->GetHighIndicesLimit());
390 mp->SetHighIndicesLimit(high);
393 pcb->fIxmin += shift.GetFirst();
394 pcb->fIxmax += shift.GetFirst();
395 pcb->fXoffset = xOffset;
397 pcb->fActiveXmin += xOffset;
398 pcb->fActiveXmax += xOffset;
405 //_____________________________________________________________________________
407 AliMpPCB::Copy(TObject& o) const
414 AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
416 pcb.fPadSizeX = fPadSizeX;
417 pcb.fPadSizeY = fPadSizeY;
418 pcb.fEnveloppeSizeX = fEnveloppeSizeX;
419 pcb.fEnveloppeSizeY = fEnveloppeSizeY;
420 pcb.fXoffset = fXoffset;
425 pcb.fActiveXmin = fActiveXmin;
426 pcb.fActiveXmax = fActiveXmax;
429 AliDebug(1,"Deleting pcb.fMotifPositions");
430 pcb.fMotifPositions.Delete();
431 AliDebug(1,"Deleting pcb.fMotifPositions : done");
433 for ( Size_t i = 0; i < pcb.fMotifPositions.size(); ++i )
435 delete pcb.fMotifPositions[i];
440 for ( Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
442 for ( Size_t i = 0; i < fMotifPositions.size(); ++i )
445 AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifPositions[i];
446 AliMpMotifPosition* pcbpos = new AliMpMotifPosition(pos->GetID(),
449 pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
450 pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
452 pcb.fMotifPositions.AddLast(pcbpos);
454 pcb.fMotifPositions.push_back(pcbpos);
458 pcb.fNofPads = fNofPads;
460 pcb.fMotifMap = fMotifMap; // warning : we do share the motifmap.
465 //_____________________________________________________________________________
467 AliMpPCB::ActiveDX() const
470 // Half-length (in x-direction) occupied by pads
473 return GetNofPadsX()*fPadSizeX/2.0;
476 //_____________________________________________________________________________
481 // Half-length (in x-direction) of the PCB.
482 // This length is the one of the virtual enveloppe of the PCB and might
483 // be bigger than the length occupied by pads (e.g. for rounded or short
485 // See also ActiveDX().
488 return fEnveloppeSizeX/2.0;
491 //_____________________________________________________________________________
493 AliMpPCB::ActiveDY() const
496 // Half-length (in y-direction) occupied by pads
499 return GetNofPadsY()*fPadSizeY/2.0;
502 //_____________________________________________________________________________
507 // Half-length (in y-direction) of the PCB.
508 // This length is the one of the virtual enveloppe of the PCB and might
509 // be bigger than the length occupied by pads (e.g. for rounded or short
511 // See also ActiveDY().
514 return fEnveloppeSizeY/2.0;
517 //_____________________________________________________________________________
519 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
522 // Returns the motifPosition located at the position referenced by
523 // integer indices (ix,iy).
527 for (Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
529 for (Size_t i = 0; i < fMotifPositions.size(); ++i )
532 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
533 if ( mp->HasPad(AliMpIntPair(ix,iy)) )
541 //_____________________________________________________________________________
543 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
546 // Returns the motifPosition located at position (x,y)
550 for (Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
552 for (Size_t i = 0; i < fMotifPositions.size(); ++i )
555 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
557 TVector2 localPos( TVector2(x,y) - mp->Position() );
559 AliMpIntPair localIndices(mp->GetMotif()->PadIndicesLocal(localPos));
561 if ( localIndices.IsValid() && mp->GetMotif()->GetMotifType()->HasPad(localIndices) )
569 //_____________________________________________________________________________
571 AliMpPCB::GetID() const
574 // Returns the name of this PCB.
580 //_____________________________________________________________________________
582 AliMpPCB::GetMotifPosition(AliMpPCB::Size_t i) const
585 // Get the i-th motifPosition stored in this PCB's internal array.
589 if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
591 if ( i >= fMotifPositions.size() ) return 0;
593 return (AliMpMotifPosition*)fMotifPositions[i];
596 //_____________________________________________________________________________
598 AliMpPCB::GetNofPadsX() const
601 // Returns the number of pads in x-direction.
604 return fIxmax-fIxmin+1;
607 //_____________________________________________________________________________
609 AliMpPCB::GetNofPadsY() const
612 // Returns the number of pads in y-direction.
615 return fIymax-fIymin+1;
618 //_____________________________________________________________________________
620 AliMpPCB::GetSize() const
623 // Returns the number of motifPositions stored in this PCB.
627 return fMotifPositions.GetEntriesFast();
629 return fMotifPositions.size();
634 //_____________________________________________________________________________
636 AliMpPCB::Ixmin() const
639 // Returns the index value of the leftmost pad.
645 //_____________________________________________________________________________
647 AliMpPCB::Ixmax() const
650 // Returns the index value of the rightmost pad.
653 return Ixmin() + GetNofPadsX() - 1;
656 //_____________________________________________________________________________
658 AliMpPCB::Iymin() const
661 // Returns the index value of the bottom pad.
667 //_____________________________________________________________________________
669 AliMpPCB::Iymax() const
672 // Returns the index value of the top pad.
675 return Iymin() + GetNofPadsY() - 1;
678 //_____________________________________________________________________________
680 AliMpPCB::PadSizeX() const
683 // Returns the pad size in x-direction (in mm)
689 //_____________________________________________________________________________
691 AliMpPCB::PadSizeY() const
694 // Returns the pad size in y-direction (in mm)
700 //_____________________________________________________________________________
702 AliMpPCB::Print(Option_t* option) const
705 // Printout of this PCB.
706 // If option="M", the contained motifs are printed too.
709 cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
710 << fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
711 << "iMax=(" << fIxmax << "," << fIymax << ") "
712 << " EnvXmin,max=(" << Xmin() << "," << Xmax()
713 << ") Xmin,max=(" << ActiveXmin() << "," << ActiveXmax() << ")"
716 if ( option && option[0] == 'M' )
719 for ( Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
721 for ( Size_t i = 0; i < fMotifPositions.size(); ++i )
726 fMotifPositions[i]->Print(option+1);
730 fMotifPositions[i]->Print();
736 //_____________________________________________________________________________
738 AliMpPCB::Save() const
741 // Save this PCB in the file
743 TString fileName(fId);
746 lines.SetOwner(kTRUE);
749 for ( Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
751 for ( Size_t i = 0; i < fMotifPositions.size(); ++i )
754 AliMpMotifPosition* pos = GetMotifPosition(i);
755 AliMpVMotif* motif = pos->GetMotif();
756 TVector2 lowerLeft(pos->Position()-pos->Dimensions());
757 TString id(motif->GetID());
758 // id is supposed to be of the form %s-%e-%e, and we're only
759 // interested in the %s part of it
760 Ssiz_t index = id.Index("-");
763 AliError(Form("id=%s does not meet expectations",id.Data()));
766 TString motifName(id(0,index));
767 lines.Add(new TObjString(Form("MOTIF %s %d %d",
769 TMath::Nint(lowerLeft.X()/fPadSizeX),
770 TMath::Nint(lowerLeft.Y()/fPadSizeY))));
773 ofstream out(fileName.Data());
775 out << "SIZES " << fPadSizeX << " " << fPadSizeY
776 << " " << fEnveloppeSizeX << " " << fEnveloppeSizeY
781 while ( ( s = (TObjString*)next() ) )
783 out << s->String().Data() << endl;
788 //_____________________________________________________________________________
793 // Returns the x-position of the PCB center.
796 return fXoffset + DX();
799 //_____________________________________________________________________________
801 AliMpPCB::Xmin() const
804 // Returns the leftmost x-position in this PCB.
810 //_____________________________________________________________________________
812 AliMpPCB::Xmax() const
815 // Returns the rightmost x-position in this PCB.
821 //_____________________________________________________________________________
826 // Returns the y-position of the PCB center.
829 return DY(); // this works as PCB are organized in a single row within slats.
832 //_____________________________________________________________________________
834 AliMpPCB::Ymin() const
837 // Returns the smallest y-position in this PCB.
843 //_____________________________________________________________________________
845 AliMpPCB::Ymax() const
848 // Returns the largest y-position in this PCB.