]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpPCB.cxx
1. Adding the new histograms TPC z vertex correlation in order
[u/mrichter/AliRoot.git] / MUON / mapping / 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 /// \cond CLASSIMP
55 ClassImp(AliMpPCB)
56 /// \endcond
57
58 //_____________________________________________________________________________
59 AliMpPCB::AliMpPCB() 
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),
73   fMotifPositions(),
74   fNofPads(0),
75   fMotifMap(0)
76 {
77       ///
78       /// Default ctor.
79       ///
80     fMotifPositions.SetOwner(kTRUE);
81     AliDebug(1,Form("this=%p",this));
82 }
83
84 //_____________________________________________________________________________
85 AliMpPCB::AliMpPCB(AliMpSlatMotifMap* motifMap, const char* id, Double_t padSizeX, Double_t padSizeY,
86                    Double_t enveloppeSizeX, Double_t enveloppeSizeY)
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),
100   fMotifPositions(),
101   fNofPads(0),
102   fMotifMap(motifMap)
103 {
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)
108     fMotifPositions.SetOwner(kTRUE);
109     AliDebug(1,Form("this=%p id=%s",this,id));
110 }
111
112 //_____________________________________________________________________________
113 AliMpPCB::AliMpPCB(const AliMpPCB& o) 
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),
127   fMotifPositions(),
128   fNofPads(0),
129   fMotifMap(0x0)
130 {
131   ///
132   /// Copy constructor
133
134   fMotifPositions.SetOwner(kTRUE);
135
136   AliDebug(1,Form("this=%p (copy ctor) : begin",this));
137   o.Copy(*this);
138   AliDebug(1,Form("this=%p (copy ctor) : end",this));
139 }
140
141 //_____________________________________________________________________________
142 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
143 : TObject(), 
144   fId(id), 
145   fPadSizeX(-1.0), 
146   fPadSizeY(-1.0),
147   fEnveloppeSizeX(ms->DimensionX()*2.0),
148   fEnveloppeSizeY(ms->DimensionY()*2.0),
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),
156   fMotifPositions(),
157   fNofPads(ms->GetMotifType()->GetNofPads()),
158   fMotifMap(0x0)
159 {
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   ///
168  
169   AliDebug(1,Form("this=%p (ctor special motif)",this));
170     
171   fMotifPositions.SetOwner(kTRUE);
172
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);
179 }
180
181 //_____________________________________________________________________________
182 AliMpPCB&
183 AliMpPCB::operator=(const AliMpPCB& o)
184 {
185   /// Assignment operator
186
187   AliDebug(1,Form("this=%p (assignment op) : begin",this));
188   o.Copy(*this);
189   AliDebug(1,Form("this=%p (assignment op) : end",this));
190   return *this;  
191 }
192
193 //_____________________________________________________________________________
194 AliMpPCB::~AliMpPCB()
195 {
196   ///
197   /// Dtor.
198   ///
199   AliDebug(1,Form("this=%p",this));
200 }
201
202 //_____________________________________________________________________________
203 Double_t
204 AliMpPCB::ActiveXmin() const
205 {
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   ///
210   
211   return fActiveXmin;
212 }
213
214 //_____________________________________________________________________________
215 Double_t
216 AliMpPCB::ActiveXmax() const
217 {
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   ///  
222   
223   return fActiveXmax;
224 }
225
226 //_____________________________________________________________________________
227 void
228 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
229 {
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.
239   
240   TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
241
242   AliMpVMotif* motif = fMotifMap->FindMotif(id);
243   
244   if (!motif)
245   {
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);
249   }
250   else
251   {
252     AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
253   }
254   
255   Double_t posx(0.);
256   Double_t posy(0.);
257   Int_t ixmin(-1);
258   Int_t iymin(-1);
259   
260   if ( ix >= 0 && iy >= 0 )
261   {
262     posx = ix*PadSizeX();
263     posy = iy*PadSizeY();
264     ixmin = ix;
265     iymin = iy;
266   }
267   else
268   if ( ix >= 0 && iy < 0 )
269   {
270     posx = ix*PadSizeX();
271     posy = Ymax()+iy*PadSizeY();
272     ixmin = ix;
273     iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
274   }
275   else
276   if ( ix < 0 && iy < 0 )
277   {
278     posx = Xmax()+ix*PadSizeX();
279     posy = Ymax()+iy*PadSizeY();
280     ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
281     iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
282   }
283   else
284   if ( ix < 0 && iy >=0 )
285   {
286     posx = Xmax()+ix*PadSizeX();
287     posy = iy*PadSizeY();
288     ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
289     iymin = iy;
290   }
291
292   posx += motif->DimensionX();
293   posy += motif->DimensionY();
294   AliMpMotifPosition* mp 
295     = new AliMpMotifPosition(-1,motif,posx, posy);
296
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);
301
302   fMotifPositions.AddLast(mp);
303
304   fIxmin = TMath::Min(fIxmin,ixmin);
305   fIxmax = TMath::Max(fIxmax,ixmax);
306   fIymin = TMath::Min(fIymin,iymin);
307   fIymax = TMath::Max(fIymax,iymax);
308
309   fActiveXmin = fIxmin*PadSizeX();
310   fActiveXmax = (fIxmax+1)*PadSizeX();
311   fNofPads += mt->GetNofPads();
312 }
313
314 //_____________________________________________________________________________
315 AliMpArea 
316 AliMpPCB::Area() const
317 {
318   /// Return the area of this PCB
319
320   return AliMpArea((Xmin()+Xmax())/2.0,DY(), DX(), DY() );
321 }
322
323 //_____________________________________________________________________________
324 TObject*
325 AliMpPCB::Clone(const char* /*newname*/) const
326 {
327   ///
328   /// Return a full copy of this object.
329   ///
330   AliDebug(1,"begin");
331   TObject* object = new AliMpPCB(*this);
332   AliDebug(1,"end");
333   return object;
334 }
335
336 //_____________________________________________________________________________
337 AliMpPCB*
338 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
339 {
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   ///
348
349   AliDebug(1,"begin");
350   
351   // First get a full clone.
352   AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
353
354   if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
355   {
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()));
359       return 0;
360   }
361
362   MpPair_t shift = AliMp::Pair(-fIxmin+ixOffset,0);
363
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 )
367     {
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();
374       low += shift;
375       mp->SetLowIndicesLimit(low);
376       MpPair_t high = mp->GetHighIndicesLimit();
377       high += shift;
378       mp->SetHighIndicesLimit(high);
379     }
380   
381   pcb->fIxmin += AliMp::PairFirst(shift);
382   pcb->fIxmax += AliMp::PairFirst(shift);
383   pcb->fXoffset = xOffset;
384
385   pcb->fActiveXmin += xOffset;
386   pcb->fActiveXmax += xOffset;
387
388   AliDebug(1,"end");
389
390   return pcb;
391 }
392
393 //_____________________________________________________________________________
394 void
395 AliMpPCB::Copy(TObject& o) const
396 {
397   /// Copy *this into o
398
399   AliDebug(1,"begin");
400   
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
416   AliDebug(1,"Deleting pcb.fMotifPositions");
417   pcb.fMotifPositions.Delete();
418   AliDebug(1,"Deleting pcb.fMotifPositions : done");
419
420   for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
421     {
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);
429     }
430     
431     pcb.fNofPads = fNofPads;  
432   
433   pcb.fMotifMap = fMotifMap; // warning : we do share the motifmap.
434   
435   AliDebug(1,"end");
436 }
437
438 //_____________________________________________________________________________
439 Double_t
440 AliMpPCB::ActiveDX() const
441 {
442   ///
443   /// Half-length (in x-direction) occupied by pads  
444   ///
445   
446   return GetNofPadsX()*fPadSizeX/2.0;
447 }
448
449 //_____________________________________________________________________________
450 Double_t
451 AliMpPCB::DX() const
452 {
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   ///
460   
461   return fEnveloppeSizeX/2.0;
462 }
463
464 //_____________________________________________________________________________
465 Double_t
466 AliMpPCB::ActiveDY() const
467 {
468   ///
469   /// Half-length (in y-direction) occupied by pads
470   ///
471   
472   return GetNofPadsY()*fPadSizeY/2.0;
473 }
474
475 //_____________________________________________________________________________
476 Double_t
477 AliMpPCB::DY() const
478 {
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   ///
486   
487   return fEnveloppeSizeY/2.0;
488 }
489
490 //_____________________________________________________________________________
491 AliMpMotifPosition*
492 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
493 {
494   ///
495   /// Returns the motifPosition located at the position referenced by
496   /// integer indices (ix,iy).
497   ///
498   
499   for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
500     {
501       AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
502       if ( mp->HasPadByIndices(AliMp::Pair(ix,iy)) )
503       {
504         return mp;
505       }
506     }
507   return 0;
508 }
509
510 //_____________________________________________________________________________
511 AliMpMotifPosition*
512 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
513 {
514   ///
515   /// Returns the motifPosition located at position (x,y)
516   ///
517   
518   for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
519   {
520     AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
521     
522     Double_t localPosX = x - mp->GetPositionX(); 
523     Double_t localPosY = y - mp->GetPositionY();
524     
525     MpPair_t localIndices(
526       mp->GetMotif()->PadIndicesLocal(localPosX, localPosY));
527     
528     if ( localIndices >= 0 && 
529          mp->GetMotif()->GetMotifType()->HasPadByLocalIndices(localIndices) )
530     {
531       return mp;
532     }
533   }
534     return 0;
535 }
536
537 //_____________________________________________________________________________
538 const char*
539 AliMpPCB::GetID() const
540 {
541   ///
542   /// Returns the name of this PCB.
543   ///
544   
545   return fId.Data();
546 }
547
548 //_____________________________________________________________________________
549 AliMpMotifPosition*
550 AliMpPCB::GetMotifPosition(Int_t i) const
551 {
552   ///
553   /// Get the i-th motifPosition stored in this PCB's internal array.
554   ///
555   
556   if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
557
558   return (AliMpMotifPosition*)fMotifPositions[i];
559 }
560
561 //_____________________________________________________________________________
562 Int_t
563 AliMpPCB::GetNofPadsX() const
564 {
565   ///
566   /// Returns the number of pads in x-direction.
567   ///
568   
569   return fIxmax-fIxmin+1;
570 }
571
572 //_____________________________________________________________________________
573 Int_t
574 AliMpPCB::GetNofPadsY() const
575 {
576   ///
577   /// Returns the number of pads in y-direction.
578   ///
579   
580   return fIymax-fIymin+1;
581 }
582
583 //_____________________________________________________________________________
584 Int_t
585 AliMpPCB::GetSize() const
586 {
587   ///
588   /// Returns the number of motifPositions stored in this PCB.
589   ///
590   
591   return fMotifPositions.GetEntriesFast();
592 }
593
594 //_____________________________________________________________________________
595 Bool_t 
596 AliMpPCB::HasMotifPositionID(Int_t manuId) const
597 {
598   /// Returns whether or not we have manuId
599
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;
607 }
608
609
610 //_____________________________________________________________________________
611 Int_t
612 AliMpPCB::Ixmin() const
613 {
614   ///
615   /// Returns the index value of the leftmost pad.
616   ///
617   
618   return fIxmin;
619 }
620
621 //_____________________________________________________________________________
622 Int_t
623 AliMpPCB::Ixmax() const
624 {
625   ///
626   /// Returns the index value of the rightmost pad.
627   ///
628   
629   return Ixmin() + GetNofPadsX() - 1;
630 }
631
632 //_____________________________________________________________________________
633 Int_t
634 AliMpPCB::Iymin() const
635 {
636   ///
637   /// Returns the index value of the bottom pad.
638   ///
639   
640   return fIymin;
641 }
642
643 //_____________________________________________________________________________
644 Int_t
645 AliMpPCB::Iymax() const
646 {
647   ///
648   /// Returns the index value of the top pad.
649   ///
650   
651   return Iymin() + GetNofPadsY() - 1;
652 }
653
654 //_____________________________________________________________________________
655 Double_t
656 AliMpPCB::PadSizeX() const
657 {
658   ///
659   /// Returns the pad size in x-direction (in mm)
660   ///
661   
662   return fPadSizeX;
663 }
664
665 //_____________________________________________________________________________
666 Double_t
667 AliMpPCB::PadSizeY() const
668 {
669   ///
670   /// Returns the pad size in y-direction (in mm)
671   ///
672   
673   return fPadSizeY;
674 }
675
676 //_____________________________________________________________________________
677 void
678 AliMpPCB::Print(Option_t* option) const
679 {
680   ///
681   /// Printout of this PCB.
682   /// If option="M", the contained motifs are printed too.
683   ///
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   {
694     for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
695     {
696       if (option)
697             {
698               fMotifPositions[i]->Print(option+1);
699             }
700       else
701             {
702               fMotifPositions[i]->Print();
703             }
704     }
705   }
706 }
707
708 //_____________________________________________________________________________
709 void 
710 AliMpPCB::Save() const
711 {
712   /// 
713   /// Save this PCB in the file
714
715   TString fileName(fId);
716   fileName += ".pcb";
717   TList lines;
718   lines.SetOwner(kTRUE);
719   
720   for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
721   {
722     AliMpMotifPosition* pos = GetMotifPosition(i);
723     AliMpVMotif* motif = pos->GetMotif();
724     
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("-");
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(),
739                                   TMath::Nint(lowerLeftX/fPadSizeX),
740                                   TMath::Nint(lowerLeftY/fPadSizeY))));
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 //_____________________________________________________________________________
759 Double_t
760 AliMpPCB::X() const
761 {
762   ///
763   /// Returns the x-position of the PCB center.
764   ///
765   
766   return fXoffset + DX();
767 }
768
769 //_____________________________________________________________________________
770 Double_t
771 AliMpPCB::Xmin() const
772 {
773   ///
774   /// Returns the leftmost x-position in this PCB.
775   ///
776   
777   return X() - DX();
778 }
779
780 //_____________________________________________________________________________
781 Double_t
782 AliMpPCB::Xmax() const
783 {
784   ///
785   /// Returns the rightmost x-position in this PCB.
786   ///
787   
788   return X() + DX();
789 }
790
791 //_____________________________________________________________________________
792 Double_t
793 AliMpPCB::Y() const
794 {
795   ///
796   /// Returns the y-position of the PCB center.
797   ///
798   
799   return DY(); // this works as PCB are organized in a single row within slats.
800 }
801
802 //_____________________________________________________________________________
803 Double_t
804 AliMpPCB::Ymin() const
805 {
806   ///
807   /// Returns the smallest y-position in this PCB.
808   ///
809   
810   return Y() - DY();
811 }
812
813 //_____________________________________________________________________________
814 Double_t
815 AliMpPCB::Ymax() const
816 {
817   ///
818   /// Returns the largest y-position in this PCB.
819   ///
820   
821   return Y() + DY();
822 }
823