Fixing a backward compatibility issue
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpPCB.cxx
CommitLineData
dee1d5f1 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16// $Id$
13985652 17// $MpId: AliMpPCB.cxx,v 1.8 2006/05/24 13:58:50 ivana Exp $
dee1d5f1 18
19#include "AliMpPCB.h"
20
21#include "AliMpMotif.h"
f35ac2f6 22#include "AliMpSlatMotifMap.h"
dee1d5f1 23#include "AliMpMotifPosition.h"
b7762666 24#include "AliMpMotifSpecial.h"
dee1d5f1 25#include "AliMpMotifType.h"
26#include "AliLog.h"
27
28#include "Riostream.h"
f35ac2f6 29#include "TList.h"
30#include "TObjString.h"
b7762666 31#include "TMath.h"
dee1d5f1 32#include <sstream>
33
3d1463c8 34
35//-----------------------------------------------------------------------------
85fec35d 36/// \class AliMpPCB
37///
38/// A PCB for station 3,4 or 5
39///
40/// A PCB is a group of pads having the same size
41/// Pads are grouped in motifs, where 1 motif = 1 MANU
42///
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
49/// the enveloppe.
50///
51/// \author L. Aphecetche
3d1463c8 52//-----------------------------------------------------------------------------
85fec35d 53
13985652 54/// \cond CLASSIMP
dee1d5f1 55ClassImp(AliMpPCB)
13985652 56/// \endcond
dee1d5f1 57
58//_____________________________________________________________________________
59AliMpPCB::AliMpPCB()
ab31db03 60: TObject(),
61 fId(""),
62 fPadSizeX(0),
63 fPadSizeY(0),
64 fEnveloppeSizeX(0),
65 fEnveloppeSizeY(0),
66 fXoffset(0),
67 fActiveXmin(0),
68 fActiveXmax(0),
69 fIxmin(99999),
70 fIxmax(0),
71 fIymin(99999),
72 fIymax(0),
f35ac2f6 73 fMotifPositions(),
74 fNofPads(0),
75 fMotifMap(0)
dee1d5f1 76{
71a2d3aa 77 ///
78 /// Default ctor.
79 ///
f35ac2f6 80 fMotifPositions.SetOwner(kTRUE);
f35ac2f6 81 AliDebug(1,Form("this=%p",this));
dee1d5f1 82}
83
84//_____________________________________________________________________________
f35ac2f6 85AliMpPCB::AliMpPCB(AliMpSlatMotifMap* motifMap, const char* id, Double_t padSizeX, Double_t padSizeY,
dee1d5f1 86 Double_t enveloppeSizeX, Double_t enveloppeSizeY)
ab31db03 87: TObject(),
88 fId(id),
89 fPadSizeX(padSizeX),
90 fPadSizeY(padSizeY),
91 fEnveloppeSizeX(enveloppeSizeX),
92 fEnveloppeSizeY(enveloppeSizeY),
93 fXoffset(0),
94 fActiveXmin(0),
95 fActiveXmax(0),
96 fIxmin(99999),
97 fIxmax(0),
98 fIymin(99999),
99 fIymax(0),
f35ac2f6 100 fMotifPositions(),
101 fNofPads(0),
102 fMotifMap(motifMap)
dee1d5f1 103{
71a2d3aa 104 ///
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)
f35ac2f6 108 fMotifPositions.SetOwner(kTRUE);
f35ac2f6 109 AliDebug(1,Form("this=%p id=%s",this,id));
dee1d5f1 110}
111
112//_____________________________________________________________________________
113AliMpPCB::AliMpPCB(const AliMpPCB& o)
ab31db03 114: TObject(o),
115 fId(0),
116 fPadSizeX(0),
117 fPadSizeY(0),
118 fEnveloppeSizeX(0),
119 fEnveloppeSizeY(0),
120 fXoffset(0),
121 fActiveXmin(0),
122 fActiveXmax(0),
123 fIxmin(99999),
124 fIxmax(0),
125 fIymin(99999),
126 fIymax(0),
f35ac2f6 127 fMotifPositions(),
128 fNofPads(0),
129 fMotifMap(0x0)
dee1d5f1 130{
71a2d3aa 131 ///
132 /// Copy constructor
144129ae 133
2294822d 134 fMotifPositions.SetOwner(kTRUE);
135
f35ac2f6 136 AliDebug(1,Form("this=%p (copy ctor) : begin",this));
dee1d5f1 137 o.Copy(*this);
f35ac2f6 138 AliDebug(1,Form("this=%p (copy ctor) : end",this));
dee1d5f1 139}
140
141//_____________________________________________________________________________
b7762666 142AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
ab31db03 143: TObject(),
144 fId(id),
145 fPadSizeX(-1.0),
146 fPadSizeY(-1.0),
6e97fbb8 147 fEnveloppeSizeX(ms->DimensionX()*2.0),
148 fEnveloppeSizeY(ms->DimensionY()*2.0),
ab31db03 149 fXoffset(0.0),
150 fActiveXmin(0.0),
151 fActiveXmax(fEnveloppeSizeX),
152 fIxmin(0),
153 fIxmax(ms->GetMotifType()->GetNofPadsX()-1),
154 fIymin(0),
155 fIymax(ms->GetMotifType()->GetNofPadsY()-1),
f35ac2f6 156 fMotifPositions(),
157 fNofPads(ms->GetMotifType()->GetNofPads()),
158 fMotifMap(0x0)
b7762666 159{
71a2d3aa 160 ///
161 /// Very special ctor to be used by trigger stations only (and for a very
162 /// specific case).
163 ///
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
166 /// so far ;-)
167 ///
ab31db03 168
6e97fbb8 169 AliDebug(1,Form("this=%p (ctor special motif)",this));
f35ac2f6 170
6e97fbb8 171 fMotifPositions.SetOwner(kTRUE);
2294822d 172
6e97fbb8 173 Double_t posx = ms->DimensionX();
174 Double_t posy = ms->DimensionY();
175 AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,posx,posy);
168e9c4d 176 mp->SetLowIndicesLimit(fIxmin,fIymin);
177 mp->SetHighIndicesLimit(fIxmax,fIymax);
f35ac2f6 178 fMotifPositions.AddLast(mp);
b7762666 179}
180
181//_____________________________________________________________________________
dee1d5f1 182AliMpPCB&
183AliMpPCB::operator=(const AliMpPCB& o)
184{
71a2d3aa 185 /// Assignment operator
144129ae 186
f35ac2f6 187 AliDebug(1,Form("this=%p (assignment op) : begin",this));
dee1d5f1 188 o.Copy(*this);
f35ac2f6 189 AliDebug(1,Form("this=%p (assignment op) : end",this));
dee1d5f1 190 return *this;
191}
192
193//_____________________________________________________________________________
194AliMpPCB::~AliMpPCB()
195{
71a2d3aa 196 ///
197 /// Dtor.
198 ///
f35ac2f6 199 AliDebug(1,Form("this=%p",this));
dee1d5f1 200}
201
202//_____________________________________________________________________________
203Double_t
204AliMpPCB::ActiveXmin() const
205{
71a2d3aa 206 ///
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.
209 ///
dee1d5f1 210
211 return fActiveXmin;
212}
213
214//_____________________________________________________________________________
215Double_t
216AliMpPCB::ActiveXmax() const
217{
71a2d3aa 218 ///
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.
221 ///
dee1d5f1 222
223 return fActiveXmax;
224}
225
226//_____________________________________________________________________________
227void
228AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
229{
71a2d3aa 230 ///
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) :
234 ///
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.
dee1d5f1 239
f35ac2f6 240 TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
241
242 AliMpVMotif* motif = fMotifMap->FindMotif(id);
243
244 if (!motif)
245 {
6e97fbb8 246 motif = new AliMpMotif(id,mt,PadSizeX()/2.0,PadSizeY()/2.0);
f35ac2f6 247 AliDebug(1,Form("Adding motif %s to motifMap",id.Data()));
248 fMotifMap->AddMotif(motif);
249 }
250 else
251 {
252 AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
253 }
254
6e97fbb8 255 Double_t posx(0.);
256 Double_t posy(0.);
b7762666 257 Int_t ixmin(-1);
258 Int_t iymin(-1);
259
260 if ( ix >= 0 && iy >= 0 )
261 {
6e97fbb8 262 posx = ix*PadSizeX();
263 posy = iy*PadSizeY();
b7762666 264 ixmin = ix;
265 iymin = iy;
266 }
267 else
268 if ( ix >= 0 && iy < 0 )
269 {
6e97fbb8 270 posx = ix*PadSizeX();
271 posy = Ymax()+iy*PadSizeY();
b7762666 272 ixmin = ix;
273 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
274 }
275 else
276 if ( ix < 0 && iy < 0 )
277 {
6e97fbb8 278 posx = Xmax()+ix*PadSizeX();
279 posy = Ymax()+iy*PadSizeY();
b7762666 280 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
281 iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
282 }
283 else
284 if ( ix < 0 && iy >=0 )
285 {
6e97fbb8 286 posx = Xmax()+ix*PadSizeX();
287 posy = iy*PadSizeY();
b7762666 288 ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
289 iymin = iy;
290 }
291
6e97fbb8 292 posx += motif->DimensionX();
293 posy += motif->DimensionY();
294 AliMpMotifPosition* mp
295 = new AliMpMotifPosition(-1,motif,posx, posy);
dee1d5f1 296
6e97fbb8 297 Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
b7762666 298 Int_t iymax = iymin + mt->GetNofPadsY() - 1;
168e9c4d 299 mp->SetLowIndicesLimit(ixmin,iymin);
300 mp->SetHighIndicesLimit(ixmax,iymax);
dee1d5f1 301
f35ac2f6 302 fMotifPositions.AddLast(mp);
dee1d5f1 303
1b36647b 304 fIxmin = TMath::Min(fIxmin,ixmin);
305 fIxmax = TMath::Max(fIxmax,ixmax);
306 fIymin = TMath::Min(fIymin,iymin);
307 fIymax = TMath::Max(fIymax,iymax);
dee1d5f1 308
309 fActiveXmin = fIxmin*PadSizeX();
310 fActiveXmax = (fIxmax+1)*PadSizeX();
efb408b3 311 fNofPads += mt->GetNofPads();
dee1d5f1 312}
313
314//_____________________________________________________________________________
f35ac2f6 315AliMpArea
316AliMpPCB::Area() const
317{
71a2d3aa 318 /// Return the area of this PCB
319
6e97fbb8 320 return AliMpArea((Xmin()+Xmax())/2.0,DY(), DX(), DY() );
f35ac2f6 321}
322
323//_____________________________________________________________________________
dee1d5f1 324TObject*
325AliMpPCB::Clone(const char* /*newname*/) const
326{
71a2d3aa 327 ///
328 /// Return a full copy of this object.
329 ///
f35ac2f6 330 AliDebug(1,"begin");
331 TObject* object = new AliMpPCB(*this);
332 AliDebug(1,"end");
333 return object;
dee1d5f1 334}
335
336//_____________________________________________________________________________
337AliMpPCB*
338AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
339{
71a2d3aa 340 ///
341 /// Get a full copy of *this, and then apply 2 changes to it :
342 ///
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).
347 ///
dee1d5f1 348
f35ac2f6 349 AliDebug(1,"begin");
350
dee1d5f1 351 // First get a full clone.
352 AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
353
c6e05ab2 354 if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
dee1d5f1 355 {
b7762666 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(),
dee1d5f1 358 manuids.GetSize(),pcb->GetSize()));
359 return 0;
360 }
361
168e9c4d 362 MpPair_t shift = AliMp::Pair(-fIxmin+ixOffset,0);
dee1d5f1 363
364 // Then change the internal MotifPositions wrt manu id
365 // and position (offset in x).
630711ed 366 for ( Int_t i = 0; i < pcb->GetSize(); ++i )
dee1d5f1 367 {
368 AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
369 mp->SetID(manuids[i]);
6e97fbb8 370 Double_t posx = mp->GetPositionX() + xOffset;
371 Double_t posy = mp->GetPositionY();
372 mp->SetPosition(posx, posy);
168e9c4d 373 MpPair_t low = mp->GetLowIndicesLimit();
f35ac2f6 374 low += shift;
375 mp->SetLowIndicesLimit(low);
168e9c4d 376 MpPair_t high = mp->GetHighIndicesLimit();
f35ac2f6 377 high += shift;
378 mp->SetHighIndicesLimit(high);
dee1d5f1 379 }
380
168e9c4d 381 pcb->fIxmin += AliMp::PairFirst(shift);
382 pcb->fIxmax += AliMp::PairFirst(shift);
dee1d5f1 383 pcb->fXoffset = xOffset;
384
385 pcb->fActiveXmin += xOffset;
386 pcb->fActiveXmax += xOffset;
387
f35ac2f6 388 AliDebug(1,"end");
389
dee1d5f1 390 return pcb;
391}
392
393//_____________________________________________________________________________
394void
395AliMpPCB::Copy(TObject& o) const
396{
71a2d3aa 397 /// Copy *this into o
85fec35d 398
f35ac2f6 399 AliDebug(1,"begin");
400
dee1d5f1 401 TObject::Copy(o);
402 AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
403 pcb.fId = fId;
404 pcb.fPadSizeX = fPadSizeX;
405 pcb.fPadSizeY = fPadSizeY;
406 pcb.fEnveloppeSizeX = fEnveloppeSizeX;
407 pcb.fEnveloppeSizeY = fEnveloppeSizeY;
408 pcb.fXoffset = fXoffset;
409 pcb.fIxmin = fIxmin;
410 pcb.fIxmax = fIxmax;
411 pcb.fIymin = fIymin;
412 pcb.fIymax = fIymax;
413 pcb.fActiveXmin = fActiveXmin;
414 pcb.fActiveXmax = fActiveXmax;
415
f35ac2f6 416 AliDebug(1,"Deleting pcb.fMotifPositions");
417 pcb.fMotifPositions.Delete();
418 AliDebug(1,"Deleting pcb.fMotifPositions : done");
dee1d5f1 419
630711ed 420 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
dee1d5f1 421 {
f35ac2f6 422 AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifPositions[i];
6e97fbb8 423 AliMpMotifPosition* pcbpos
424 = new AliMpMotifPosition(pos->GetID(), pos->GetMotif(),
425 pos->GetPositionX(), pos->GetPositionY());
dee1d5f1 426 pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
427 pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
f35ac2f6 428 pcb.fMotifPositions.AddLast(pcbpos);
dee1d5f1 429 }
efb408b3 430
431 pcb.fNofPads = fNofPads;
f35ac2f6 432
433 pcb.fMotifMap = fMotifMap; // warning : we do share the motifmap.
434
435 AliDebug(1,"end");
dee1d5f1 436}
437
438//_____________________________________________________________________________
439Double_t
440AliMpPCB::ActiveDX() const
441{
71a2d3aa 442 ///
443 /// Half-length (in x-direction) occupied by pads
444 ///
dee1d5f1 445
446 return GetNofPadsX()*fPadSizeX/2.0;
447}
448
449//_____________________________________________________________________________
450Double_t
451AliMpPCB::DX() const
452{
71a2d3aa 453 ///
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
457 /// PCBs).
458 /// See also ActiveDX().
459 ///
dee1d5f1 460
461 return fEnveloppeSizeX/2.0;
462}
463
464//_____________________________________________________________________________
465Double_t
466AliMpPCB::ActiveDY() const
467{
71a2d3aa 468 ///
469 /// Half-length (in y-direction) occupied by pads
470 ///
dee1d5f1 471
472 return GetNofPadsY()*fPadSizeY/2.0;
473}
474
475//_____________________________________________________________________________
476Double_t
477AliMpPCB::DY() const
478{
71a2d3aa 479 ///
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
483 /// PCBs).
484 /// See also ActiveDY().
485 ///
dee1d5f1 486
487 return fEnveloppeSizeY/2.0;
488}
489
490//_____________________________________________________________________________
491AliMpMotifPosition*
492AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
493{
71a2d3aa 494 ///
495 /// Returns the motifPosition located at the position referenced by
496 /// integer indices (ix,iy).
497 ///
dee1d5f1 498
630711ed 499 for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
dee1d5f1 500 {
f35ac2f6 501 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
168e9c4d 502 if ( mp->HasPadByIndices(AliMp::Pair(ix,iy)) )
b7762666 503 {
504 return mp;
505 }
dee1d5f1 506 }
507 return 0;
508}
509
510//_____________________________________________________________________________
511AliMpMotifPosition*
512AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
513{
71a2d3aa 514 ///
515 /// Returns the motifPosition located at position (x,y)
516 ///
dee1d5f1 517
630711ed 518 for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
dee1d5f1 519 {
f35ac2f6 520 AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
dee1d5f1 521
6e97fbb8 522 Double_t localPosX = x - mp->GetPositionX();
523 Double_t localPosY = y - mp->GetPositionY();
dee1d5f1 524
6e97fbb8 525 MpPair_t localIndices(
526 mp->GetMotif()->PadIndicesLocal(localPosX, localPosY));
dee1d5f1 527
168e9c4d 528 if ( localIndices >= 0 &&
529 mp->GetMotif()->GetMotifType()->HasPadByLocalIndices(localIndices) )
dee1d5f1 530 {
531 return mp;
532 }
533 }
534 return 0;
535}
536
537//_____________________________________________________________________________
538const char*
539AliMpPCB::GetID() const
540{
71a2d3aa 541 ///
542 /// Returns the name of this PCB.
543 ///
dee1d5f1 544
545 return fId.Data();
546}
547
548//_____________________________________________________________________________
549AliMpMotifPosition*
630711ed 550AliMpPCB::GetMotifPosition(Int_t i) const
dee1d5f1 551{
71a2d3aa 552 ///
553 /// Get the i-th motifPosition stored in this PCB's internal array.
554 ///
dee1d5f1 555
f35ac2f6 556 if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
2294822d 557
f35ac2f6 558 return (AliMpMotifPosition*)fMotifPositions[i];
dee1d5f1 559}
560
561//_____________________________________________________________________________
562Int_t
563AliMpPCB::GetNofPadsX() const
564{
71a2d3aa 565 ///
566 /// Returns the number of pads in x-direction.
567 ///
dee1d5f1 568
569 return fIxmax-fIxmin+1;
570}
571
572//_____________________________________________________________________________
573Int_t
574AliMpPCB::GetNofPadsY() const
575{
71a2d3aa 576 ///
577 /// Returns the number of pads in y-direction.
578 ///
dee1d5f1 579
580 return fIymax-fIymin+1;
581}
582
583//_____________________________________________________________________________
630711ed 584Int_t
dee1d5f1 585AliMpPCB::GetSize() const
586{
71a2d3aa 587 ///
588 /// Returns the number of motifPositions stored in this PCB.
589 ///
dee1d5f1 590
f35ac2f6 591 return fMotifPositions.GetEntriesFast();
dee1d5f1 592}
593
5f5c0c3d 594//_____________________________________________________________________________
595Bool_t
596AliMpPCB::HasMotifPositionID(Int_t manuId) const
597{
598 /// Returns whether or not we have manuId
599
5f5c0c3d 600 TIter next(&fMotifPositions);
601 AliMpMotifPosition* pos;
602 while ( ( pos = static_cast<AliMpMotifPosition*>(next()) ) )
603 {
604 if ( pos->GetID() == manuId ) return kTRUE;
605 }
606 return kFALSE;
5f5c0c3d 607}
608
dee1d5f1 609
610//_____________________________________________________________________________
611Int_t
612AliMpPCB::Ixmin() const
613{
71a2d3aa 614 ///
615 /// Returns the index value of the leftmost pad.
616 ///
dee1d5f1 617
618 return fIxmin;
619}
620
621//_____________________________________________________________________________
622Int_t
623AliMpPCB::Ixmax() const
624{
71a2d3aa 625 ///
626 /// Returns the index value of the rightmost pad.
627 ///
dee1d5f1 628
629 return Ixmin() + GetNofPadsX() - 1;
630}
631
632//_____________________________________________________________________________
b7762666 633Int_t
634AliMpPCB::Iymin() const
635{
71a2d3aa 636 ///
637 /// Returns the index value of the bottom pad.
638 ///
b7762666 639
640 return fIymin;
641}
642
643//_____________________________________________________________________________
644Int_t
645AliMpPCB::Iymax() const
646{
71a2d3aa 647 ///
648 /// Returns the index value of the top pad.
649 ///
b7762666 650
651 return Iymin() + GetNofPadsY() - 1;
652}
653
654//_____________________________________________________________________________
dee1d5f1 655Double_t
656AliMpPCB::PadSizeX() const
657{
71a2d3aa 658 ///
659 /// Returns the pad size in x-direction (in mm)
660 ///
dee1d5f1 661
662 return fPadSizeX;
663}
664
665//_____________________________________________________________________________
666Double_t
667AliMpPCB::PadSizeY() const
668{
71a2d3aa 669 ///
670 /// Returns the pad size in y-direction (in mm)
671 ///
dee1d5f1 672
673 return fPadSizeY;
674}
675
676//_____________________________________________________________________________
677void
678AliMpPCB::Print(Option_t* option) const
679{
71a2d3aa 680 ///
681 /// Printout of this PCB.
682 /// If option="M", the contained motifs are printed too.
683 ///
dee1d5f1 684
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() << ")"
690 << endl;
691
692 if ( option && option[0] == 'M' )
693 {
630711ed 694 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
dee1d5f1 695 {
696 if (option)
697 {
f35ac2f6 698 fMotifPositions[i]->Print(option+1);
dee1d5f1 699 }
700 else
701 {
f35ac2f6 702 fMotifPositions[i]->Print();
dee1d5f1 703 }
704 }
705 }
706}
707
708//_____________________________________________________________________________
f35ac2f6 709void
710AliMpPCB::Save() const
711{
71a2d3aa 712 ///
713 /// Save this PCB in the file
144129ae 714
f35ac2f6 715 TString fileName(fId);
716 fileName += ".pcb";
717 TList lines;
718 lines.SetOwner(kTRUE);
719
630711ed 720 for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
f35ac2f6 721 {
722 AliMpMotifPosition* pos = GetMotifPosition(i);
723 AliMpVMotif* motif = pos->GetMotif();
6e97fbb8 724
725 Double_t lowerLeftX = pos->GetPositionX()-pos->GetDimensionX();
726 Double_t lowerLeftY = pos->GetPositionY()-pos->GetDimensionY();
f35ac2f6 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("-");
731 if ( index < 1 )
732 {
733 AliError(Form("id=%s does not meet expectations",id.Data()));
734 return;
735 }
736 TString motifName(id(0,index));
737 lines.Add(new TObjString(Form("MOTIF %s %d %d",
738 motifName.Data(),
6e97fbb8 739 TMath::Nint(lowerLeftX/fPadSizeX),
740 TMath::Nint(lowerLeftY/fPadSizeY))));
f35ac2f6 741 }
742
743 ofstream out(fileName.Data());
744 out.precision(9);
745 out << "SIZES " << fPadSizeX << " " << fPadSizeY
746 << " " << fEnveloppeSizeX << " " << fEnveloppeSizeY
747 << endl;
748
749 TIter next(&lines);
750 TObjString* s;
751 while ( ( s = (TObjString*)next() ) )
752 {
753 out << s->String().Data() << endl;
754 }
755 out.close();
756}
757
758//_____________________________________________________________________________
dee1d5f1 759Double_t
760AliMpPCB::X() const
761{
71a2d3aa 762 ///
763 /// Returns the x-position of the PCB center.
764 ///
dee1d5f1 765
766 return fXoffset + DX();
767}
768
769//_____________________________________________________________________________
770Double_t
771AliMpPCB::Xmin() const
772{
71a2d3aa 773 ///
774 /// Returns the leftmost x-position in this PCB.
775 ///
dee1d5f1 776
777 return X() - DX();
778}
779
780//_____________________________________________________________________________
781Double_t
782AliMpPCB::Xmax() const
783{
71a2d3aa 784 ///
785 /// Returns the rightmost x-position in this PCB.
786 ///
dee1d5f1 787
788 return X() + DX();
789}
790
791//_____________________________________________________________________________
792Double_t
793AliMpPCB::Y() const
794{
71a2d3aa 795 ///
796 /// Returns the y-position of the PCB center.
797 ///
dee1d5f1 798
799 return DY(); // this works as PCB are organized in a single row within slats.
800}
801
802//_____________________________________________________________________________
803Double_t
804AliMpPCB::Ymin() const
805{
71a2d3aa 806 ///
807 /// Returns the smallest y-position in this PCB.
808 ///
dee1d5f1 809
810 return Y() - DY();
811}
812
813//_____________________________________________________________________________
814Double_t
815AliMpPCB::Ymax() const
816{
71a2d3aa 817 ///
818 /// Returns the largest y-position in this PCB.
819 ///
dee1d5f1 820
821 return Y() + DY();
822}
823