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