]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/mapping/AliMpPCB.cxx
Adding comment lines to class description needed for Root documentation,
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpPCB.cxx
index 561d91f03f0acd9dca6a97d40e74f75698288370..d54f544a5e239d1b2dd738664181f746d50af082 100644 (file)
  **************************************************************************/
 
 // $Id$
-// $MpId: AliMpPCB.cxx,v 1.6 2006/03/17 16:42:33 ivana Exp $
+// $MpId: AliMpPCB.cxx,v 1.8 2006/05/24 13:58:50 ivana Exp $
 
 #include "AliMpPCB.h"
 
 #include "AliMpMotif.h"
+#include "AliMpSlatMotifMap.h"
 #include "AliMpMotifPosition.h"
 #include "AliMpMotifSpecial.h"
 #include "AliMpMotifType.h"
 #include "AliLog.h"
 
 #include "Riostream.h"
+#include "TList.h"
+#include "TObjString.h"
 #include "TMath.h"
 #include <sstream>
 
-/// 
+//-----------------------------------------------------------------------------
 /// \class AliMpPCB
 ///
 /// A PCB for station 3,4 or 5
 /// the enveloppe.
 ///
 /// \author L. Aphecetche
+//-----------------------------------------------------------------------------
 
+/// \cond CLASSIMP
 ClassImp(AliMpPCB)
+/// \endcond
 
 //_____________________________________________________________________________
 AliMpPCB::AliMpPCB() 
-  : TObject(), fId(""), 
-    fPadSizeX(0), fPadSizeY(0), 
-    fEnveloppeSizeX(0), fEnveloppeSizeY(0),
-    fXoffset(0),
-    fActiveXmin(0), fActiveXmax(0),
-    fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
-    fNofPads(0)
-{
-      //
-      // Default ctor.
-      //
+: TObject(), 
+  fId(""), 
+  fPadSizeX(0), 
+  fPadSizeY(0), 
+  fEnveloppeSizeX(0), 
+  fEnveloppeSizeY(0),
+  fXoffset(0),
+  fActiveXmin(0), 
+  fActiveXmax(0),
+  fIxmin(99999), 
+  fIxmax(0), 
+  fIymin(99999), 
+  fIymax(0),
+  fMotifPositions(),
+  fNofPads(0),
+  fMotifMap(0)
+{
+      ///
+      /// Default ctor.
+      ///
+#ifdef WITH_ROOT
+    fMotifPositions.SetOwner(kTRUE);
+#endif
+    AliDebug(1,Form("this=%p",this));
 }
 
 //_____________________________________________________________________________
-AliMpPCB::AliMpPCB(const char* id, Double_t padSizeX, Double_t padSizeY,
+AliMpPCB::AliMpPCB(AliMpSlatMotifMap* motifMap, const char* id, Double_t padSizeX, Double_t padSizeY,
                   Double_t enveloppeSizeX, Double_t enveloppeSizeY)
-  : TObject(), fId(id), 
-    fPadSizeX(padSizeX), fPadSizeY(padSizeY), 
-    fEnveloppeSizeX(enveloppeSizeX), fEnveloppeSizeY(enveloppeSizeY),
-    fXoffset(0),
-    fActiveXmin(0), fActiveXmax(0),
-    fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
-    fNofPads(0)
-{
-      //
-      // Normal ctor. Must be fed with the PCB's name (id), the pad dimensions
-      // and the global dimension of the virtual enveloppe of the PCB
-      // (usually 400x400 mm)
+: TObject(), 
+  fId(id), 
+  fPadSizeX(padSizeX),
+  fPadSizeY(padSizeY), 
+  fEnveloppeSizeX(enveloppeSizeX), 
+  fEnveloppeSizeY(enveloppeSizeY),
+  fXoffset(0),
+  fActiveXmin(0), 
+  fActiveXmax(0),
+  fIxmin(99999), 
+  fIxmax(0),
+  fIymin(99999), 
+  fIymax(0),
+  fMotifPositions(),
+  fNofPads(0),
+  fMotifMap(motifMap)
+{
+      ///
+      /// Normal ctor. Must be fed with the PCB's name (id), the pad dimensions
+      /// and the global dimension of the virtual enveloppe of the PCB
+      /// (usually 400x400 mm)
+#ifdef WITH_ROOT
+    fMotifPositions.SetOwner(kTRUE);
+#endif
+    AliDebug(1,Form("this=%p id=%s",this,id));
 }
 
 //_____________________________________________________________________________
 AliMpPCB::AliMpPCB(const AliMpPCB& o) 
-  : TObject(o),
-    fPadSizeX(0), fPadSizeY(0), 
-    fEnveloppeSizeX(0), fEnveloppeSizeY(0),
-    fXoffset(0),
-    fActiveXmin(0), fActiveXmax(0),
-    fIxmin(99999), fIxmax(0), fIymin(99999), fIymax(0),
-    fNofPads(0)
-{
+: TObject(o),
+  fId(0),
+  fPadSizeX(0), 
+  fPadSizeY(0), 
+  fEnveloppeSizeX(0),
+  fEnveloppeSizeY(0),
+  fXoffset(0),
+  fActiveXmin(0), 
+  fActiveXmax(0),
+  fIxmin(99999), 
+  fIxmax(0), 
+  fIymin(99999), 
+  fIymax(0),
+  fMotifPositions(),
+  fNofPads(0),
+  fMotifMap(0x0)
+{
+  ///
+  /// Copy constructor
+
+#ifdef WITH_ROOT
+    fMotifPositions.SetOwner(kTRUE);
+#endif
+  AliDebug(1,Form("this=%p (copy ctor) : begin",this));
   o.Copy(*this);
+  AliDebug(1,Form("this=%p (copy ctor) : end",this));
 }
 
 //_____________________________________________________________________________
 AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
-: TObject(), fId(id), fPadSizeX(-1.0), fPadSizeY(-1.0),
-  fXoffset(0)
-{
-  //
-  // Very special ctor to be used by trigger stations only (and for a very
-  // specific case).
-  //
-  // Note that in this very case, we only allow one (special) motif per PCB.
-  // This limitation might not be justified, except that it's all we need
-  // so far ;-)
-  //
-  fXoffset = 0.0;
-  fEnveloppeSizeX = ms->Dimensions().X()*2.0;
-  fEnveloppeSizeY = ms->Dimensions().Y()*2.0;
-  fActiveXmin = 0.0;
-  fActiveXmax = fEnveloppeSizeX;
-  fIxmin = fIymin = 0;
-  fIxmax = ms->GetMotifType()->GetNofPadsX()-1;
-  fIymax = ms->GetMotifType()->GetNofPadsY()-1;
+: TObject(), 
+  fId(id), 
+  fPadSizeX(-1.0), 
+  fPadSizeY(-1.0),
+  fEnveloppeSizeX(ms->Dimensions().X()*2.0),
+  fEnveloppeSizeY(ms->Dimensions().Y()*2.0),
+  fXoffset(0.0),
+  fActiveXmin(0.0),
+  fActiveXmax(fEnveloppeSizeX),
+  fIxmin(0),
+  fIxmax(ms->GetMotifType()->GetNofPadsX()-1),
+  fIymin(0),
+  fIymax(ms->GetMotifType()->GetNofPadsY()-1),
+  fMotifPositions(),
+  fNofPads(ms->GetMotifType()->GetNofPads()),
+  fMotifMap(0x0)
+{
+  ///
+  /// Very special ctor to be used by trigger stations only (and for a very
+  /// specific case).
+  ///
+  /// Note that in this very case, we only allow one (special) motif per PCB.
+  /// This limitation might not be justified, except that it's all we need
+  /// so far ;-)
+  ///
+    AliDebug(1,Form("this=%p (ctor special motif)",this));
+    
+#ifdef WITH_ROOT
+    fMotifPositions.SetOwner(kTRUE);
+#endif
   TVector2 position(ms->Dimensions());
   AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,position);
   mp->SetLowIndicesLimit(AliMpIntPair(fIxmin,fIymin));
   mp->SetHighIndicesLimit(AliMpIntPair(fIxmax,fIymax));
 #ifdef WITH_ROOT
-  fMotifs.AddLast(mp);
+  fMotifPositions.AddLast(mp);
 #else
-  fMotifs.push_back(mp);
+  fMotifPositions.push_back(mp);
 #endif
-  fNofPads = ms->GetMotifType()->GetNofPads();
 }
 
 //_____________________________________________________________________________
 AliMpPCB&
 AliMpPCB::operator=(const AliMpPCB& o)
 {
+  /// Assignment operator
+
+  AliDebug(1,Form("this=%p (assignment op) : begin",this));
   o.Copy(*this);
+  AliDebug(1,Form("this=%p (assignment op) : end",this));
   return *this;  
 }
 
 //_____________________________________________________________________________
 AliMpPCB::~AliMpPCB()
 {
-  //
-  // Dtor.
-  //
+  ///
+  /// Dtor.
+  ///
+  AliDebug(1,Form("this=%p",this));
+#ifndef WITH_ROOT
+  for ( size_t i = 0; i < fMotifPositions.size(); ++i )
+  {
+    delete fMotifPositions[i];
+  }
+#endif
+  
 }
 
 //_____________________________________________________________________________
 Double_t
 AliMpPCB::ActiveXmin() const
 {
-  //
-  // Returns the mininum x for which there is a pad in this PCB.
-  // Different from Xmin only for PCB which are not full of pads.
-  //
+  ///
+  /// Returns the mininum x for which there is a pad in this PCB.
+  /// Different from Xmin only for PCB which are not full of pads.
+  ///
   
   return fActiveXmin;
 }
@@ -158,10 +231,10 @@ AliMpPCB::ActiveXmin() const
 Double_t
 AliMpPCB::ActiveXmax() const
 {
-  //
-  // Returns the maximum x for which there is a pad in this PCB.
-  // Different from Xmax only for PCB which are not full of pads.
-  //  
+  ///
+  /// Returns the maximum x for which there is a pad in this PCB.
+  /// Different from Xmax only for PCB which are not full of pads.
+  ///  
   
   return fActiveXmax;
 }
@@ -170,18 +243,31 @@ AliMpPCB::ActiveXmax() const
 void
 AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
 {
-  //
-  // Add a motif to this PCB. (ix,iy) indicates one corner position of the motif
-  // where the sign of ix and iy is used to indicate which corner is the 
-  // reference (then for values, abs(ix) and abs(iy) are used indeed) :
-  //
-  // (ix>0,iy>0) : bottom-left corner
-  // (ix<0,iy>0) : bottom-right corner
-  // (ix<0,iy<0) : top-right corner
-  // (ix>0,iy<0) : top-left corner.
-  
-  AliMpVMotif* motif = 
-    new AliMpMotif(mt->GetID(),mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
+  ///
+  /// Add a motif to this PCB. (ix,iy) indicates one corner position of the motif
+  /// where the sign of ix and iy is used to indicate which corner is the 
+  /// reference (then for values, abs(ix) and abs(iy) are used indeed) :
+  ///
+  /// (ix>0,iy>0) : bottom-left corner
+  /// (ix<0,iy>0) : bottom-right corner
+  /// (ix<0,iy<0) : top-right corner
+  /// (ix>0,iy<0) : top-left corner.
+  
+  TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
+
+  AliMpVMotif* motif = fMotifMap->FindMotif(id);
+  
+  if (!motif)
+  {
+    motif = new AliMpMotif(id,mt,TVector2(PadSizeX()/2.0,PadSizeY()/2.0));
+    AliDebug(1,Form("Adding motif %s to motifMap",id.Data()));
+    fMotifMap->AddMotif(motif);
+  }
+  else
+  {
+    AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
+  }
+  
   TVector2 position;
   Int_t ixmin(-1);
   Int_t iymin(-1);
@@ -224,44 +310,59 @@ AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
   mp->SetHighIndicesLimit(AliMpIntPair(ixmax,iymax));
 
 #ifdef WITH_ROOT
-  fMotifs.AddLast(mp);
+  fMotifPositions.AddLast(mp);
 #else
-  fMotifs.push_back(mp);
+  fMotifPositions.push_back(mp);
 #endif
 
-  fIxmin = std::min(fIxmin,ixmin);
-  fIxmax = std::max(fIxmax,ixmax);
-  fIymin = std::min(fIymin,iymin);
-  fIymax = std::max(fIymax,iymax);
+  fIxmin = TMath::Min(fIxmin,ixmin);
+  fIxmax = TMath::Max(fIxmax,ixmax);
+  fIymin = TMath::Min(fIymin,iymin);
+  fIymax = TMath::Max(fIymax,iymax);
 
   fActiveXmin = fIxmin*PadSizeX();
   fActiveXmax = (fIxmax+1)*PadSizeX();
   fNofPads += mt->GetNofPads();
 }
 
+//_____________________________________________________________________________
+AliMpArea 
+AliMpPCB::Area() const
+{
+  /// Return the area of this PCB
+
+  return AliMpArea(TVector2( (Xmin()+Xmax())/2.0,DY()),
+                   TVector2( DX(), DY() ) );
+}
+
 //_____________________________________________________________________________
 TObject*
 AliMpPCB::Clone(const char* /*newname*/) const
 {
-  //
-  // Return a full copy of this object.
-  //
-  return new AliMpPCB(*this);
+  ///
+  /// Return a full copy of this object.
+  ///
+  AliDebug(1,"begin");
+  TObject* object = new AliMpPCB(*this);
+  AliDebug(1,"end");
+  return object;
 }
 
 //_____________________________________________________________________________
 AliMpPCB*
 AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
 {
-  //
-  // Get a full copy of *this, and then apply 2 changes to it :
-  //
-  // a) define the relationship motifType <-> manu id
-  // b) define the x-offset
-  // c) shift ix indices backwards to insure that e.g. the first
-  //    pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
-  //
+  ///
+  /// Get a full copy of *this, and then apply 2 changes to it :
+  ///
+  /// a) define the relationship motifType <-> manu id
+  /// b) define the x-offset
+  /// c) shift ix indices backwards to insure that e.g. the first
+  ///    pcb of a slat will start at ix=0 (only relevant for rounded pcbs).
+  ///
 
+  AliDebug(1,"begin");
+  
   // First get a full clone.
   AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
 
@@ -273,7 +374,7 @@ AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
       return 0;
   }
 
-  AliMpIntPair shift(-fIxmin,0);
+  AliMpIntPair shift(-fIxmin+ixOffset,0);
 
   // Then change the internal MotifPositions wrt manu id
   // and position (offset in x).
@@ -281,22 +382,27 @@ AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
     {
       AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
       mp->SetID(manuids[i]);
-      mp->SetPosition(mp->Position() + TVector2(xOffset,0));
-      mp->SetLowIndicesLimit(mp->GetLowIndicesLimit()+
-                            shift+
-                            AliMpIntPair(ixOffset,0));
-      mp->SetHighIndicesLimit(mp->GetHighIndicesLimit()+
-                             shift+
-                             AliMpIntPair(ixOffset,0));
+      TVector2 pos(mp->Position());
+      pos += TVector2(xOffset,0);
+      mp->SetPosition(pos);
+      AliMpIntPair offset(ixOffset,0);
+      AliMpIntPair low(mp->GetLowIndicesLimit());
+      low += shift;
+      mp->SetLowIndicesLimit(low);
+      AliMpIntPair high(mp->GetHighIndicesLimit());
+      high += shift;
+      mp->SetHighIndicesLimit(high);
     }
   
-  pcb->fIxmin += ixOffset + shift.GetFirst();
-  pcb->fIxmax += ixOffset + shift.GetFirst();
+  pcb->fIxmin += shift.GetFirst();
+  pcb->fIxmax += shift.GetFirst();
   pcb->fXoffset = xOffset;
 
   pcb->fActiveXmin += xOffset;
   pcb->fActiveXmax += xOffset;
 
+  AliDebug(1,"end");
+
   return pcb;
 }
 
@@ -304,8 +410,10 @@ AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
 void
 AliMpPCB::Copy(TObject& o) const
 {
-  // Copy *this into o
+  /// Copy *this into o
 
+  AliDebug(1,"begin");
+  
   TObject::Copy(o);
   AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
   pcb.fId = fId;
@@ -322,39 +430,49 @@ AliMpPCB::Copy(TObject& o) const
   pcb.fActiveXmax = fActiveXmax;
 
 #ifdef WITH_ROOT
-  pcb.fMotifs.Clear();
+  AliDebug(1,"Deleting pcb.fMotifPositions");
+  pcb.fMotifPositions.Delete();
+  AliDebug(1,"Deleting pcb.fMotifPositions : done");
 #else
-  pcb.fMotifs.clear();
+  for ( Size_t i = 0; i < pcb.fMotifPositions.size(); ++i )
+  {
+    delete pcb.fMotifPositions[i];
+  }
 #endif
 
 #ifdef WITH_ROOT
-  for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
+  for ( Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
 #else
-  for ( Size_t i = 0; i < fMotifs.size(); ++i )
+  for ( Size_t i = 0; i < fMotifPositions.size(); ++i )
 #endif  
     {
-      AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifs[i];
-      AliMpMotifPosition* pcbpos = 
-       new AliMpMotifPosition(pos->GetID(),pos->GetMotif(),pos->Position());
+      AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifPositions[i];
+      AliMpMotifPosition* pcbpos = new AliMpMotifPosition(pos->GetID(),
+                                                          pos->GetMotif(),
+                                                          pos->Position());
       pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
       pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
 #ifdef WITH_ROOT
-      pcb.fMotifs.AddLast(pcbpos);
+      pcb.fMotifPositions.AddLast(pcbpos);
 #else      
-      pcb.fMotifs.push_back(pcbpos);
+      pcb.fMotifPositions.push_back(pcbpos);
 #endif      
     }
     
     pcb.fNofPads = fNofPads;  
+  
+  pcb.fMotifMap = fMotifMap; // warning : we do share the motifmap.
+  
+  AliDebug(1,"end");
 }
 
 //_____________________________________________________________________________
 Double_t
 AliMpPCB::ActiveDX() const
 {
-  //
-  // Half-length (in x-direction) occupied by pads  
-  //
+  ///
+  /// Half-length (in x-direction) occupied by pads  
+  ///
   
   return GetNofPadsX()*fPadSizeX/2.0;
 }
@@ -363,13 +481,13 @@ AliMpPCB::ActiveDX() const
 Double_t
 AliMpPCB::DX() const
 {
-  //
-  // Half-length (in x-direction) of the PCB.
-  // This length is the one of the virtual enveloppe of the PCB and might
-  // be bigger than the length occupied by pads (e.g. for rounded or short
-  // PCBs).  
-  // See also ActiveDX().
-  //
+  ///
+  /// Half-length (in x-direction) of the PCB.
+  /// This length is the one of the virtual enveloppe of the PCB and might
+  /// be bigger than the length occupied by pads (e.g. for rounded or short
+  /// PCBs).  
+  /// See also ActiveDX().
+  ///
   
   return fEnveloppeSizeX/2.0;
 }
@@ -378,9 +496,9 @@ AliMpPCB::DX() const
 Double_t
 AliMpPCB::ActiveDY() const
 {
-  //
-  // Half-length (in y-direction) occupied by pads
-  //
+  ///
+  /// Half-length (in y-direction) occupied by pads
+  ///
   
   return GetNofPadsY()*fPadSizeY/2.0;
 }
@@ -389,13 +507,13 @@ AliMpPCB::ActiveDY() const
 Double_t
 AliMpPCB::DY() const
 {
-  //
-  // Half-length (in y-direction) of the PCB.
-  // This length is the one of the virtual enveloppe of the PCB and might
-  // be bigger than the length occupied by pads (e.g. for rounded or short
-  // PCBs).
-  // See also ActiveDY().
-  //
+  ///
+  /// Half-length (in y-direction) of the PCB.
+  /// This length is the one of the virtual enveloppe of the PCB and might
+  /// be bigger than the length occupied by pads (e.g. for rounded or short
+  /// PCBs).
+  /// See also ActiveDY().
+  ///
   
   return fEnveloppeSizeY/2.0;
 }
@@ -404,18 +522,18 @@ AliMpPCB::DY() const
 AliMpMotifPosition*
 AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
 {
-  //
-  // Returns the motifPosition located at the position referenced by
-  // integer indices (ix,iy).
-  //
+  ///
+  /// Returns the motifPosition located at the position referenced by
+  /// integer indices (ix,iy).
+  ///
   
 #ifdef WITH_ROOT
-  for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
+  for (Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
 #else  
-  for (Size_t i = 0; i < fMotifs.size(); ++i )
+  for (Size_t i = 0; i < fMotifPositions.size(); ++i )
 #endif
     {
-      AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
+      AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
       if ( mp->HasPad(AliMpIntPair(ix,iy)) )
       {
         return mp;
@@ -428,17 +546,17 @@ AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
 AliMpMotifPosition*
 AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
 {
-  //
-  // Returns the motifPosition located at position (x,y)
-  //
+  ///
+  /// Returns the motifPosition located at position (x,y)
+  ///
   
 #ifdef WITH_ROOT
-  for (Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
+  for (Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
 #else  
-  for (Size_t i = 0; i < fMotifs.size(); ++i )
+  for (Size_t i = 0; i < fMotifPositions.size(); ++i )
 #endif   
   {
-    AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifs[i];
+    AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
     
     TVector2 localPos( TVector2(x,y) - mp->Position() );
     
@@ -456,9 +574,9 @@ AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
 const char*
 AliMpPCB::GetID() const
 {
-  //
-  // Returns the name of this PCB.
-  //
+  ///
+  /// Returns the name of this PCB.
+  ///
   
   return fId.Data();
 }
@@ -467,25 +585,25 @@ AliMpPCB::GetID() const
 AliMpMotifPosition*
 AliMpPCB::GetMotifPosition(AliMpPCB::Size_t i) const
 {
-  //
-  // Get the i-th motifPosition stored in this PCB's internal array.
-  //
+  ///
+  /// Get the i-th motifPosition stored in this PCB's internal array.
+  ///
   
 #ifdef WITH_ROOT
-  if ( i >= fMotifs.GetEntriesFast() ) return 0;
+  if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
 #else
-  if ( i >= fMotifs.size() ) return 0;
+  if ( i >= fMotifPositions.size() ) return 0;
 #endif  
-  return (AliMpMotifPosition*)fMotifs[i];
+  return (AliMpMotifPosition*)fMotifPositions[i];
 }
 
 //_____________________________________________________________________________
 Int_t
 AliMpPCB::GetNofPadsX() const
 {
-  //
-  // Returns the number of pads in x-direction.
-  //
+  ///
+  /// Returns the number of pads in x-direction.
+  ///
   
   return fIxmax-fIxmin+1;
 }
@@ -494,9 +612,9 @@ AliMpPCB::GetNofPadsX() const
 Int_t
 AliMpPCB::GetNofPadsY() const
 {
-  //
-  // Returns the number of pads in y-direction.
-  //
+  ///
+  /// Returns the number of pads in y-direction.
+  ///
   
   return fIymax-fIymin+1;
 }
@@ -505,14 +623,14 @@ AliMpPCB::GetNofPadsY() const
 AliMpPCB::Size_t
 AliMpPCB::GetSize() const
 {
-  //
-  // Returns the number of motifPositions stored in this PCB.
-  //
+  ///
+  /// Returns the number of motifPositions stored in this PCB.
+  ///
   
 #ifdef WITH_ROOT
-  return fMotifs.GetEntriesFast();
+  return fMotifPositions.GetEntriesFast();
 #else  
-  return fMotifs.size();
+  return fMotifPositions.size();
 #endif  
 }
 
@@ -521,9 +639,9 @@ AliMpPCB::GetSize() const
 Int_t
 AliMpPCB::Ixmin() const
 {
-  //
-  // Returns the index value of the leftmost pad.
-  //
+  ///
+  /// Returns the index value of the leftmost pad.
+  ///
   
   return fIxmin;
 }
@@ -532,9 +650,9 @@ AliMpPCB::Ixmin() const
 Int_t
 AliMpPCB::Ixmax() const
 {
-  //
-  // Returns the index value of the rightmost pad.
-  //
+  ///
+  /// Returns the index value of the rightmost pad.
+  ///
   
   return Ixmin() + GetNofPadsX() - 1;
 }
@@ -543,9 +661,9 @@ AliMpPCB::Ixmax() const
 Int_t
 AliMpPCB::Iymin() const
 {
-  //
-  // Returns the index value of the bottom pad.
-  //
+  ///
+  /// Returns the index value of the bottom pad.
+  ///
   
   return fIymin;
 }
@@ -554,9 +672,9 @@ AliMpPCB::Iymin() const
 Int_t
 AliMpPCB::Iymax() const
 {
-  //
-  // Returns the index value of the top pad.
-  //
+  ///
+  /// Returns the index value of the top pad.
+  ///
   
   return Iymin() + GetNofPadsY() - 1;
 }
@@ -565,9 +683,9 @@ AliMpPCB::Iymax() const
 Double_t
 AliMpPCB::PadSizeX() const
 {
-  //
-  // Returns the pad size in x-direction (in mm)
-  //
+  ///
+  /// Returns the pad size in x-direction (in mm)
+  ///
   
   return fPadSizeX;
 }
@@ -576,9 +694,9 @@ AliMpPCB::PadSizeX() const
 Double_t
 AliMpPCB::PadSizeY() const
 {
-  //
-  // Returns the pad size in y-direction (in mm)
-  //
+  ///
+  /// Returns the pad size in y-direction (in mm)
+  ///
   
   return fPadSizeY;
 }
@@ -587,10 +705,10 @@ AliMpPCB::PadSizeY() const
 void
 AliMpPCB::Print(Option_t* option) const
 {
-  //
-  // Printout of this PCB.
-  // If option="M", the contained motifs are printed too.
-  //
+  ///
+  /// Printout of this PCB.
+  /// If option="M", the contained motifs are printed too.
+  ///
   
   cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
   << fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
@@ -602,30 +720,82 @@ AliMpPCB::Print(Option_t* option) const
   if ( option && option[0] == 'M' )
   {
 #ifdef WITH_ROOT
-    for ( Size_t i = 0; i < fMotifs.GetEntriesFast(); ++i )
+    for ( Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
 #else  
-    for ( Size_t i = 0; i < fMotifs.size(); ++i )
+    for ( Size_t i = 0; i < fMotifPositions.size(); ++i )
 #endif    
     {
       if (option)
            {
-             fMotifs[i]->Print(option+1);
+             fMotifPositions[i]->Print(option+1);
            }
       else
            {
-             fMotifs[i]->Print();
+             fMotifPositions[i]->Print();
            }
     }
   }
 }
 
+//_____________________________________________________________________________
+void 
+AliMpPCB::Save() const
+{
+  /// 
+  /// Save this PCB in the file
+
+  TString fileName(fId);
+  fileName += ".pcb";
+  TList lines;
+  lines.SetOwner(kTRUE);
+  
+#ifdef WITH_ROOT
+  for ( Size_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
+#else  
+  for ( Size_t i = 0; i < fMotifPositions.size(); ++i )
+#endif    
+  {
+    AliMpMotifPosition* pos = GetMotifPosition(i);
+    AliMpVMotif* motif = pos->GetMotif();
+    TVector2 lowerLeft(pos->Position()-pos->Dimensions());
+    TString id(motif->GetID());
+    // id is supposed to be of the form %s-%e-%e, and we're only
+    // interested in the %s part of it
+    Ssiz_t index = id.Index("-");
+    if ( index < 1 )
+    {
+      AliError(Form("id=%s does not meet expectations",id.Data()));
+      return;
+    }
+    TString motifName(id(0,index));
+    lines.Add(new TObjString(Form("MOTIF %s %d %d",
+                                  motifName.Data(),
+                                  TMath::Nint(lowerLeft.X()/fPadSizeX),
+                                  TMath::Nint(lowerLeft.Y()/fPadSizeY))));
+  }
+
+  ofstream out(fileName.Data());
+  out.precision(9);
+  out << "SIZES " << fPadSizeX << " " << fPadSizeY
+    << " " << fEnveloppeSizeX << " " << fEnveloppeSizeY
+    << endl;
+  
+  TIter next(&lines);
+  TObjString* s;
+  while ( ( s = (TObjString*)next() ) )
+  {
+    out << s->String().Data() << endl;
+  }
+  out.close();
+}
+
 //_____________________________________________________________________________
 Double_t
 AliMpPCB::X() const
 {
-  //
-  // Returns the x-position of the PCB center.
-  //
+  ///
+  /// Returns the x-position of the PCB center.
+  ///
   
   return fXoffset + DX();
 }
@@ -634,9 +804,9 @@ AliMpPCB::X() const
 Double_t
 AliMpPCB::Xmin() const
 {
-  //
-  // Returns the leftmost x-position in this PCB.
-  //
+  ///
+  /// Returns the leftmost x-position in this PCB.
+  ///
   
   return X() - DX();
 }
@@ -645,9 +815,9 @@ AliMpPCB::Xmin() const
 Double_t
 AliMpPCB::Xmax() const
 {
-  //
-  // Returns the rightmost x-position in this PCB.
-  //
+  ///
+  /// Returns the rightmost x-position in this PCB.
+  ///
   
   return X() + DX();
 }
@@ -656,9 +826,9 @@ AliMpPCB::Xmax() const
 Double_t
 AliMpPCB::Y() const
 {
-  //
-  // Returns the y-position of the PCB center.
-  //
+  ///
+  /// Returns the y-position of the PCB center.
+  ///
   
   return DY(); // this works as PCB are organized in a single row within slats.
 }
@@ -667,9 +837,9 @@ AliMpPCB::Y() const
 Double_t
 AliMpPCB::Ymin() const
 {
-  //
-  // Returns the smallest y-position in this PCB.
-  //
+  ///
+  /// Returns the smallest y-position in this PCB.
+  ///
   
   return Y() - DY();
 }
@@ -678,9 +848,9 @@ AliMpPCB::Ymin() const
 Double_t
 AliMpPCB::Ymax() const
 {
-  //
-  // Returns the largest y-position in this PCB.
-  //
+  ///
+  /// Returns the largest y-position in this PCB.
+  ///
   
   return Y() + DY();
 }