]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/mapping/AliMpMotifType.cxx
Fixing a backward compatibility issue
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpMotifType.cxx
index e98c70ce21a5abf4227d341fa1b60c27bb460fed..5b169501140e7e709cf4bff9e060d45a6717ec59 100755 (executable)
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
 // $Id$
+// $MpId: AliMpMotifType.cxx,v 1.10 2006/05/24 13:58:41 ivana Exp $
 // Category: motif
-//
+
+//-----------------------------------------------------------------------------
 // Class AliMpMotifType
 // --------------------
 // Class that defines the motif properties.
 // Included in AliRoot: 2003/05/02
 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
-
-#include <stdlib.h>
-#include <Riostream.h>
+//-----------------------------------------------------------------------------
 
 #include "AliMpMotifType.h"
+#include "AliMpExMapIterator.h"
 #include "AliMpMotifTypePadIterator.h"
 #include "AliMpConnection.h"
+#include "AliMpConstants.h"
+#include "AliMpFiles.h"
+#include "AliMpEncodePair.h"
+
+#include "AliLog.h"
+
+#include <TSystem.h>
+#include <Riostream.h>
 
+#include <cstdlib>
+
+/// \cond CLASSIMP
 ClassImp(AliMpMotifType)
+/// \endcond
 
 const Int_t AliMpMotifType::fgkPadNumForA = 65;
-#ifdef WITH_ROOT
-const Int_t AliMpMotifType::fgkSeparator = 10000;
-#endif
-
 
 //______________________________________________________________________________
 AliMpMotifType::AliMpMotifType(const TString &id) 
-  : TObject(),
-    fID(id),
-    fNofPadsX(0),   
-    fNofPadsY(0),
-    fVerboseLevel(0),
-    fConnections()
+: TObject(),
+fID(id),
+fNofPadsX(0),   
+fNofPadsY(0),
+fNofPads(0),
+fMaxNofPads(AliMpConstants::ManuNofChannels()),
+fConnectionsByLocalIndices(fMaxNofPads*fMaxNofPads),
+fConnectionsByManuChannel(fMaxNofPads)
 {
-  // Constructor
+  /// Standard constructor                                                   \n
+  /// Please note that id should be of the form %s for station 1,2,
+  //  %s-%e-%e for station345 and %sx%e for stationTrigger
+
+  fConnectionsByLocalIndices.SetOwner(kTRUE);
+  fConnectionsByManuChannel.SetOwner(kFALSE);
+  AliDebug(1,Form("this=%p id=%s",this,id.Data()));
 }
 
 //______________________________________________________________________________
-AliMpMotifType::AliMpMotifType() 
-  : TObject(),
-    fID(""),
-    fNofPadsX(0),   
-    fNofPadsY(0),
-    fVerboseLevel(0),
-    fConnections()
+AliMpMotifType::AliMpMotifType(TRootIOCtor*) 
+: TObject(),
+fID(""),
+fNofPadsX(0),   
+fNofPadsY(0),
+fNofPads(0),
+fMaxNofPads(0),
+fConnectionsByLocalIndices(),
+fConnectionsByManuChannel()
 {
-  // Default constructor (dummy)
+  /// Default constructor
+  AliDebug(1,Form("this=%p",this));
 }
 
 //______________________________________________________________________________
-AliMpMotifType::~AliMpMotifType() {
-// Destructor
-
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   delete i->second;
-
-  fConnections.erase(fConnections.begin(),fConnections.end());
-#endif  
-
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) delete (AliMpConnection*)value;
-#endif  
+AliMpMotifType::AliMpMotifType(const AliMpMotifType& rhs)
+: TObject(),
+fID(""),
+fNofPadsX(0),   
+fNofPadsY(0),
+fNofPads(0),
+fMaxNofPads(0),
+fConnectionsByLocalIndices(),
+fConnectionsByManuChannel()
+{
+  /// Copy constructor
+  AliDebug(1,Form("this=%p (copy ctor)",this));
+  rhs.Copy(*this);
 }
 
-#ifdef WITH_ROOT
 //______________________________________________________________________________
-Int_t  AliMpMotifType::GetIndex(const AliMpIntPair& pair) const
+AliMpMotifType&
+AliMpMotifType::operator=(const AliMpMotifType& rhs)
 {
-// Converts the pair of integers to integer.
-// ---
+  /// Assignment operator
+  
+  TObject::operator=(rhs);
+  rhs.Copy(*this);
+  return *this;  
+}
 
-  if (pair.GetFirst() >= fgkSeparator || pair.GetSecond() >= fgkSeparator)
-    Fatal("GetIndex", "Index out of limit.");
-      
-  return pair.GetFirst()*fgkSeparator + pair.GetSecond() + 1;
-}  
+//______________________________________________________________________________
+TObject*
+AliMpMotifType::Clone(const char* /*newname*/) const 
+{
+  /// Returns a full copy of this object
+  return new AliMpMotifType(*this);
+}
 
 //______________________________________________________________________________
-AliMpIntPair  AliMpMotifType::GetPair(Int_t index) const
+void
+AliMpMotifType::Copy(TObject& object) const
 {
-// Converts the integer index to the pair of integers.
-// ---
+  /// Copy object
+
+  TObject::Copy(object);
+  AliMpMotifType& mt = static_cast<AliMpMotifType&>(object);
+  mt.fID = fID;
+  mt.fNofPadsX = fNofPadsX;
+  mt.fNofPadsY = fNofPadsY;
+  mt.fNofPads = fNofPads;
+  mt.fMaxNofPads = fMaxNofPads;
+  mt.fConnectionsByLocalIndices = fConnectionsByLocalIndices;
+  mt.fConnectionsByManuChannel = fConnectionsByManuChannel;  
+}
 
-  return AliMpIntPair((index-1)/fgkSeparator,(index-1)%fgkSeparator);
-}  
-#endif
+//______________________________________________________________________________
+AliMpMotifType::~AliMpMotifType() 
+{
+  /// Destructor
+
+  AliDebug(1,Form("this=%p",this));
+}
 
 //______________________________________________________________________________
 AliMpVPadIterator* AliMpMotifType::CreateIterator() const
 {
+/// Create new motif type iterator
+
   return new AliMpMotifTypePadIterator(this);
 }
 
 //______________________________________________________________________________
 void AliMpMotifType::SetNofPads(Int_t nofPadsX, Int_t nofPadsY)
 {
-  // Change the number of pads in this motif
+  /// Change the number of pads in this motif
 
   fNofPadsX = nofPadsX;
   fNofPadsY = nofPadsY;
@@ -107,7 +162,8 @@ void AliMpMotifType::SetNofPads(Int_t nofPadsX, Int_t nofPadsY)
 //______________________________________________________________________________
 Int_t AliMpMotifType::PadNum(const TString &padName) const
 {
-  // Transform a pad name into the equivalent pad number
+  /// Transform a pad name into the equivalent pad number
+
   if ( (padName[0]>='A') && (padName[0]<='Z') )
     return fgkPadNumForA+padName[0]-'A';
   else
@@ -117,7 +173,8 @@ Int_t AliMpMotifType::PadNum(const TString &padName) const
 //______________________________________________________________________________
 TString AliMpMotifType::PadName(Int_t padNum) const
 {
-  // Transform a pad number into its equivalent pad name
+  /// Transform a pad number into its equivalent pad name
+
   if (padNum<fgkPadNumForA)
     return Form("%d",padNum);
   else
@@ -125,289 +182,239 @@ TString AliMpMotifType::PadName(Int_t padNum) const
 }
 
 //______________________________________________________________________________
-void AliMpMotifType::AddConnection(const AliMpIntPair &localIndices, 
-                               AliMpConnection* connection)
+Bool_t 
+AliMpMotifType::AddConnection(AliMpConnection* connection)
 {
-  // Add the connection to the map
+  /// Add the connection to the map
   
-#ifdef WITH_STL
-  fConnections[localIndices]=connection;
-#endif
-
-#ifdef WITH_ROOT
-  fConnections.Add(GetIndex(localIndices), (Long_t)connection);
-#endif   
-
-  connection->SetOwner(this);
+  if (!connection) return kFALSE;
+  
+  Int_t ix = connection->GetLocalIx();
+  Int_t iy = connection->GetLocalIy();
+  
+  Int_t manuChannel = connection->GetManuChannel();
+  
+  if ( ix >=0 && ix < fMaxNofPads &&
+      iy >=0 && iy < fMaxNofPads && 
+      manuChannel >= 0 && manuChannel < AliMpConstants::ManuNofChannels())
+  {
+  
+    Int_t index = ix + iy*AliMpConstants::ManuNofChannels();
+    
+    AliMpConnection* c = FindConnectionByLocalIndices(
+                             connection->GetLocalIndices());
+    
+    if (c)
+    {
+      AliError(Form("Connection already exists for ix=%d iy=%d",ix,iy));
+      return kFALSE;
+    }
+    
+    ++fNofPads;
+
+    fConnectionsByLocalIndices[index] = connection;
+    fConnectionsByManuChannel[manuChannel] = connection;
+    
+    connection->SetOwner(this);
+    
+    return kTRUE;
+  
+  }
+  return kFALSE;
 }  
 
 //______________________________________________________________________________
-AliMpConnection *AliMpMotifType::FindConnectionByPadNum(Int_t padNum) const
+AliMpConnection*
+AliMpMotifType::FindConnectionByPadNum(Int_t padNum) const
 {
-  // Retrieve the AliMpConnection pointer from its pad num
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetPadNum()==padNum) return i->second;
- return 0;
-#endif
-
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
+  /// Retrieve the AliMpConnection pointer from its pad num
+  /// This method is quite inefficient as we're looping over all connections
+  
+  TIter next(&fConnectionsByManuChannel);
+  AliMpConnection* connection;
+  
+  while ( ( connection = static_cast<AliMpConnection*>(next()) ) )
+  {
     if (connection->GetPadNum()==padNum) return connection;
-  }  
- return 0;
-#endif
+  }    
+  return 0x0;
 }
 
 //______________________________________________________________________________
-AliMpConnection *AliMpMotifType::FindConnectionByLocalIndices(
-                                       const AliMpIntPair& localIndices) const
+AliMpConnection*
+AliMpMotifType::FindConnectionByLocalIndices(MpPair_t localIndices) const
 {
-  // Retrieve the AliMpConnection pointer from its position (in pad unit)
-  if (!localIndices.IsValid()) return 0;
-
-#ifdef WITH_STL
-  ConnectionMapCIterator i = fConnections.find(localIndices);
- if (i != fConnections.end())
-   return i->second;
- else return 0;
-#endif
-
-#ifdef WITH_ROOT
-  Long_t value = fConnections.GetValue(GetIndex(localIndices));
-  if (value) 
-    return (AliMpConnection*)value;
+  /// Retrieve the AliMpConnection pointer from its position (in pad unit)
+
+  return FindConnectionByLocalIndices(AliMp::PairFirst(localIndices),
+                                      AliMp::PairSecond(localIndices));
+}
+
+//______________________________________________________________________________
+AliMpConnection*
+AliMpMotifType::FindConnectionByLocalIndices(Int_t ix, Int_t iy) const
+{
+  /// Retrieve the AliMpConnection pointer from its position (in pad unit)
+
+  if ( ix < fNofPadsX && iy < fNofPadsY && ix >= 0 && iy >= 0 )
+  {  
+    Int_t index = ix + iy*fMaxNofPads;
+
+    return static_cast<AliMpConnection*>(fConnectionsByLocalIndices.UncheckedAt(index));
+  }
   else
-    return 0;  
-#endif
+  {
+    return 0x0;
+  }
 }
 
 //______________________________________________________________________________
-AliMpConnection *AliMpMotifType::FindConnectionByGassiNum(Int_t gassiNum) const
+AliMpConnection*
+AliMpMotifType::FindConnectionByGassiNum(Int_t gassiNum) const
 {
-  // Return the connection for the given gassiplex number
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetGassiNum()==gassiNum) return i->second;
- return 0;
-#endif
-
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetGassiNum()==gassiNum) return connection;
-  }  
- return 0;
-#endif
+  /// Return the connection for the given gassiplex number
+  
+  if ( gassiNum >=0 && gassiNum < fMaxNofPads ) 
+  {
+    return static_cast<AliMpConnection*>(fConnectionsByManuChannel.UncheckedAt(gassiNum));
+  }
+  
+  return 0x0;
 }
 
 //______________________________________________________________________________
-AliMpConnection *AliMpMotifType::FindConnectionByKaptonNum(Int_t kaptonNum) const
+AliMpConnection*
+AliMpMotifType::FindConnectionByKaptonNum(Int_t kaptonNum) const
 {
-  // Gives the connection related to the given kapton number
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetKaptonNum()==kaptonNum) return i->second;
- return 0;
-#endif
-
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetKaptonNum()==kaptonNum) return connection;
-  }  
- return 0;
-#endif
+  /// Give the connection related to the given kapton number
+  /// Inefficient method as we loop over connections to find the right one
+  
+  TIter next(&fConnectionsByManuChannel);
+  AliMpConnection* connection;
+  
+  while ( ( connection = static_cast<AliMpConnection*>(next()) ) )
+  {
+    if ( connection && connection->GetKaptonNum()==kaptonNum) return connection;
+  }
+  return 0x0;
 }
+
 //______________________________________________________________________________
-AliMpConnection *AliMpMotifType::FindConnectionByBergNum(Int_t bergNum) const
+AliMpConnection*
+AliMpMotifType::FindConnectionByBergNum(Int_t bergNum) const
 {
-  // Retrieve the connection from a Berg connector number
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetBergNum()==bergNum) return i->second;
- return 0;
-#endif
-
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetBergNum()==bergNum) return connection;
-  }  
-  return 0;
-#endif
+  /// Retrieve the connection from a Berg connector number
+  /// Inefficient method as we loop over connections to find the right one
+  
+  TIter next(&fConnectionsByManuChannel);
+  AliMpConnection* connection;
+  
+  while ( ( connection = static_cast<AliMpConnection*>(next()) ) )
+  {
+    if ( connection && connection->GetBergNum()==bergNum) return connection;
+  }
+  return 0x0;
 }
 
 
 //______________________________________________________________________________
-AliMpIntPair AliMpMotifType::FindLocalIndicesByConnection(
-                                 const AliMpConnection* connection) const
+MpPair_t AliMpMotifType::FindLocalIndicesByConnection(const AliMpConnection* connection) const
 {
-  // Retrieve the pad position from the connection pointer.
-  // Not to be used widely, since it use a search in the
-  // connection list...
-
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second==connection) return i->first;
-#endif
-
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* aConnection = (AliMpConnection*)value;
-    if (aConnection == connection) return GetPair(key);
-  }  
-#endif
-
-  return AliMpIntPair::Invalid();
+  /// Reurn the pad position from the connection pointer.
+
+  return connection->GetLocalIndices();
 }
 
 //______________________________________________________________________________
-AliMpIntPair AliMpMotifType::FindLocalIndicesByPadNum(Int_t padNum) const
+MpPair_t AliMpMotifType::FindLocalIndicesByPadNum(Int_t padNum) const
 {
-  // Retrieve the AliMpConnection pointer from its pad num
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetPadNum()==padNum) return i->first;
-#endif
-   
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetPadNum() == padNum) return GetPair(key);
-  }  
-#endif
- return AliMpIntPair::Invalid();
+  /// Retrieve the AliMpConnection pointer from its pad num
+  
+  AliMpConnection* connection = FindConnectionByPadNum(padNum);
+  
+  if ( ! connection) return -1;
+  
+  return connection->GetLocalIndices();
 }
 
 //______________________________________________________________________________
-AliMpIntPair AliMpMotifType::FindLocalIndicesByGassiNum(Int_t gassiNum) const
+MpPair_t AliMpMotifType::FindLocalIndicesByGassiNum(Int_t gassiNum) const
 {
-  // return the connection for the given gassiplex number
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetGassiNum()==gassiNum) return i->first;
-#endif
-   
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetGassiNum()==gassiNum) return GetPair(key);
-  }  
-#endif
-   
- return AliMpIntPair::Invalid();
+  /// Return the connection for the given gassiplex number
+  
+  AliMpConnection* connection = FindConnectionByGassiNum(gassiNum);
+  
+  if ( ! connection) return -1;
+
+  return connection->GetLocalIndices();
 }
 
 //______________________________________________________________________________
-AliMpIntPair AliMpMotifType::FindLocalIndicesByKaptonNum(Int_t kaptonNum) const
+MpPair_t AliMpMotifType::FindLocalIndicesByKaptonNum(Int_t kaptonNum) const
 {
-  // Gives the connection related to the given kapton number
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetKaptonNum()==kaptonNum) return i->first;
-#endif
-   
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetKaptonNum()==kaptonNum) return GetPair(key);
-  }  
-#endif
-   
- return AliMpIntPair::Invalid();
+  /// Give the connection related to the given kapton number
+
+  AliMpConnection* connection = FindConnectionByKaptonNum(kaptonNum);
+  
+  if ( ! connection) return -1;
+
+  return connection->GetLocalIndices();
 }
 
 //______________________________________________________________________________
-AliMpIntPair AliMpMotifType::FindLocalIndicesByBergNum(Int_t bergNum) const
+MpPair_t AliMpMotifType::FindLocalIndicesByBergNum(Int_t bergNum) const
 {
-  // Retrieve the connection from a Berg connector number
-#ifdef WITH_STL
- for(ConnectionMapCIterator i = fConnections.begin();
-  i!=fConnections.end();++i)
-   if (i->second->GetBergNum()==bergNum) return i->first;
-#endif
-   
-#ifdef WITH_ROOT
-  ConnectionMapCIterator i(&fConnections);
-  Long_t key, value;
-  while ( i.Next(key, value) ) {
-    AliMpConnection* connection = (AliMpConnection*)value;
-    if (connection->GetBergNum()==bergNum) return GetPair(key);
-  }  
-#endif
-   
- return AliMpIntPair::Invalid();
+  /// Retrieve the connection from a Berg connector number
+  
+  AliMpConnection* connection = FindConnectionByBergNum(bergNum);
+  
+  if ( ! connection) return -1;
+
+  return connection->GetLocalIndices();
 }
 
 //______________________________________________________________________________
-Int_t  AliMpMotifType::GetNofPads() const   
+Bool_t 
+AliMpMotifType::HasPadByLocalIndices(MpPair_t localIndices) const
 {
-// Returns the number of pads
-
-#ifdef WITH_STL
-  return fConnections.size();
-#endif
-   
-#ifdef WITH_ROOT
-  return fConnections.GetSize();
-#endif
+  /// Return true if the pad indexed by \a localIndices has a connection
+    
+  return ( FindConnectionByLocalIndices(localIndices) != 0x0 );
 }
 
 //______________________________________________________________________________
-Bool_t AliMpMotifType::HasPad(const AliMpIntPair& localIndices) const
+Bool_t 
+AliMpMotifType::HasPadByLocalIndices(Int_t localIx, Int_t localIy) const
 {
-  // Return true if the pad indexed by <localIndices> has a connection
-  if (!localIndices.IsValid()) return false;
-
-#ifdef WITH_STL
-  return fConnections.find(localIndices)!=fConnections.end();
-#endif
+  /// Return true if the pad indexed by \a localIndices has a connection
+    
+  return ( FindConnectionByLocalIndices(localIx, localIy) != 0x0 );
+}
 
-#ifdef WITH_ROOT
-  Long_t value = fConnections.GetValue(GetIndex(localIndices));
-  return value!=0;
-#endif
+//______________________________________________________________________________
+Bool_t 
+AliMpMotifType::HasPadByManuChannel(Int_t manuChannel) const
+{
+  /// Return true if the pad indexed by \a localIndices has a connection
+  
+//  if ( manuChannel >= fNofPads ) return kFALSE;
+  
+  return ( FindConnectionByGassiNum(manuChannel) != 0x0 );
 }
 
 //______________________________________________________________________________
 void AliMpMotifType::Print(Option_t *option) const
 {
-  // Print the map of the motif. In each cel, the value
-  // printed depends of option, as the following:
-  // option="N" the "name" of the pad is written
-  // option="K" the Kapton connect. number attached to the pad is written
-  // option="B" the Berg connect. number attached to the pad is written
-  // option="G" the Gassiplex channel number attached to the pad is written
-  // otherwise the number of the pad is written
-
-  // NOTE : this method is really not optimized, in case 'N' or '',
-  // but the Print() this should not be very important in a Print() method
+  /// Print the map of the motif. In each cell, the value
+  /// printed depends of option, as the following:
+  /// - option="N" the "name" of the pad is written
+  /// - option="K" the Kapton connect. number attached to the pad is written
+  /// - option="B" the Berg connect. number attached to the pad is written
+  /// - option="G" the Gassiplex channel number attached to the pad is written
+  /// otherwise the number of the pad is written
+  ///
+  /// NOTE : this method is really not optimized, in case 'N' or '',
+  /// but the Print() this should not be very important in a Print() method
 
   switch (option[0]){
   case 'N':cout<<"Name mapping";
@@ -425,24 +432,92 @@ void AliMpMotifType::Print(Option_t *option) const
 
   for (Int_t j=fNofPadsY-1;j>=0;j--){
     for (Int_t i=0;i<fNofPadsX;i++){
-      AliMpConnection *connexion = FindConnectionByLocalIndices(AliMpIntPair(i,j));
+      AliMpConnection *connexion = FindConnectionByLocalIndices(i,j);
       TString str;
       if (connexion){
-       switch (option[0]){
-       case 'N':str=PadName(connexion->GetPadNum());
-         break;
-       case 'K':str=Form("%d",connexion->GetKaptonNum());
-         break;
-       case 'B':str=Form("%d",connexion->GetBergNum());
-         break;
-        case 'G':str=Form("%d",connexion->GetGassiNum());
-          break;
-       default:str= Form("%d",connexion->GetPadNum());
-       }
-       cout<<setw(2)<<str;
+        AliDebug(1,Form("i,j=%2d,%2d connexion=%p",i,j,connexion));
+        
+        switch (option[0]){
+          case 'N':str=PadName(connexion->GetPadNum());
+            break;
+          case 'K':str=Form("%d",connexion->GetKaptonNum());
+            break;
+          case 'B':str=Form("%d",connexion->GetBergNum());
+            break;
+          case 'G':str=Form("%d",connexion->GetManuChannel());
+            break;
+          default:str= Form("%d",connexion->GetPadNum());
+        }
+        cout<<setw(2)<<str;
       } else cout<<setw(2)<<"--";
       cout<<" ";
     }
     cout<<endl;
   }
 }
+
+//_____________________________________________________________________________
+Bool_t
+AliMpMotifType::Save() const
+{
+/// Save this motif type
+
+  return Save(fID.Data());
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMpMotifType::Save(const char* motifName) const
+{
+  /// Generate the 2 files needed to describe the motif
+  
+  TString padPosFileName(AliMpFiles::PadPosFileName(motifName));
+  
+  TString motifTypeFileName(AliMpFiles::MotifFileName(motifName));
+
+  // first a protection : do not allow overwriting existing files...
+  Bool_t test = gSystem->AccessPathName(padPosFileName.Data());
+  if (test==kFALSE) // AccessPathName has a strange return value convention...
+  {
+    AliError("Cannot overwrite existing padPos file");
+    return kFALSE;
+  }
+  test = gSystem->AccessPathName(motifTypeFileName.Data());
+  if (test==kFALSE)
+  {
+    AliError("Cannot overwrite existing motifType file");
+    return kFALSE;    
+  }
+  
+  ofstream padPosFile(padPosFileName.Data());
+  ofstream motifFile(motifTypeFileName.Data());
+  
+  motifFile <<  "# Motif " << motifName << endl
+    << "#" << endl
+    << "#connecteur_berg kapton padname not_used" << endl
+    << "#for slats there's no kapton connector, so it's always 1" 
+    << " (zero make the reader" << endl
+    << "#abort, so it's not a valid value here)." << endl
+    << "#" << endl;
+  
+  for ( Int_t ix = 0; ix < GetNofPadsX(); ++ix ) 
+  {
+    for ( Int_t iy = 0; iy < GetNofPadsY(); ++iy ) 
+    {
+      AliMpConnection* con = FindConnectionByLocalIndices(ix,iy);
+      if (con)
+      {
+        motifFile << con->GetBergNum() << "\t1\t" << con->GetPadNum() << "\t-" << endl;
+        padPosFile << con->GetPadNum() << "\t" << ix << "\t" << iy << endl;
+      }
+    }
+  }
+  
+  padPosFile.close();
+  motifFile.close();
+  
+  return kTRUE;
+}
+
+
+