# Path: lib/malignpy/maps/MalignerMap.py
# class MalignerMap(object):
# 
#     def __init__(self, *args, **kwargs):
#         if 'line' in kwargs:
#             self.makeFromLine(kwargs['line'])
#         else:
#             self.makeFromAttributes(**kwargs)
#         self.checkMap()
# 
#     # Create a MalignerMap from a line in maps file
#     def makeFromLine(self, line):
#         """
#         Create a MalignerMap from a line in a SOMA Maps file.
#         """
#         fields = line.strip().split()
#         self.mapId = fields[0]
#         self.length = int(fields[1])
#         self.numFrags = int(fields[2])
#         self.frags = [int(f) for f in fields[3:]]
# 
#     # Create from mapId and frags attribute
#     def makeFromAttributes(self, **kwargs):
#         self.frags = list(kwargs['frags'])
#         self.mapId = kwargs['mapId']
#         self.numFrags = len(self.frags)
#         self.length = sum(self.frags)
#        
#         # Add any other attributes from kwargs 
#         for attr in kwargs.iterkeys():
#             if attr not in self.__dict__:
#                 self.__dict__[attr] = kwargs[attr]
# 
#     # write the MalignerMap to file
#     def write(self, handle):
#         f = handle
#         fields = [self.mapId,
#                   str(self.length),
#                   str(len(self.frags))]
#         fields.extend(str(frag) for frag in self.frags)
#         outS = '\t'.join(fields) + '\n'
#         f.write(outS)
# 
#     def get_data(self):
#         """
#         Return dict representation of a MalignerMap
#         """
#         fields = ['mapId', 'length', 'numFrags', 'frags']
#         d = { k:getattr(self,k) for k in fields }
#         return d
# 
#     # Check the consistency of the object
#     def checkMap(self):
#         if len(self.frags) != self.numFrags:
#             raise Exception('MalignerMap attributes are inconsistent!')
# 
#     @property
#     def name(self):
#         return self.mapId
# 
# Path: lib/malignpy/common/wrap_file_function.py
# class wrap_file_function(object):
#   """
#   Wrap a function which takes a file or a str as it's first argument.
#   If a str is provided, replace the first argument of the wrapped function
#   with a file handle, and close the file afterwards
# 
#   Example:
# 
#   @wrap_file_function('w')
#   def write_hi(f):
#     f.write('hi!\n')
# 
#   # This will write to already open file handle.
#   f = open('f1.txt', 'w')
#   write_hi(f)
#   f.close()
# 
#   # This will open file f2.txt with mode 'w', write to it, and close the file.
#   write_hi('f2.txt')
#   """
# 
#   def __init__(self, *args):
#     self.modes = args if args else ('r',)
# 
#   def __call__(self, func):
# 
#     @wraps(func)
#     def wrapped(*args, **kwargs):
# 
#       close = [] # Files that should be closed
#       files = [] # File handles that should be passed to func
#       num_files = len(self.modes)
# 
#       for i, mode in enumerate(self.modes):
# 
#         fp = args[i]
# 
#         if isinstance(fp, str):
#           fp = open(fp, mode)
#           close.append(fp)
# 
#         files.append(fp)
# 
#       try:
# 
#         # Replace the files in args when calling func
#         args = files + list(args[num_files:])
# 
#         # Make function call and return value
#         return func(*args, **kwargs)
# 
#       finally:
# 
#         for fp in close: 
#             fp.close()
# 
#     return wrapped


import sys
import re
from .MalignerMap import MalignerMap
from ..common import wrap_file_function
    sys.stderr.write(msg)

    # Optical maps for chromosomes 
    # Remove all white space from restriction map names
    for opMap in opMapList:
        opMap.mapId = ''.join(opMap.mapId.split())
    writeMaps(opMapList, opMapFileOut)
    result = { 'enzyme' : enzyme,
               'opMapList' : opMapList,
               'opticalMapFile' : opMapFileOut}
    return result

#############################################################################################
# Read an optical map in the Schwartz format
# Return a list of OpticalMapData instances
def readMapDataSchwartz(filename, verbose = False):
    omaps = []
    fin = open(filename)
    mapGen = mapDataSchwartzGen(fin)

    if verbose:
        omaps = []
        for map in mapGen:
            omaps.append(map)
            print 'Read map from chromosome %s with enzyme %s and %i fragments'%(map.mapId, map.enzyme, len(map.frags))
    else:
        omaps = [m for m in mapGen]
    fin.close()
    return omaps


# Path: lib/malignpy/maps/MalignerMap.py
# class MalignerMap(object):
# 
#     def __init__(self, *args, **kwargs):
#         if 'line' in kwargs:
#             self.makeFromLine(kwargs['line'])
#         else:
#             self.makeFromAttributes(**kwargs)
#         self.checkMap()
# 
#     # Create a MalignerMap from a line in maps file
#     def makeFromLine(self, line):
#         """
#         Create a MalignerMap from a line in a SOMA Maps file.
#         """
#         fields = line.strip().split()
#         self.mapId = fields[0]
#         self.length = int(fields[1])
#         self.numFrags = int(fields[2])
#         self.frags = [int(f) for f in fields[3:]]
# 
#     # Create from mapId and frags attribute
#     def makeFromAttributes(self, **kwargs):
#         self.frags = list(kwargs['frags'])
#         self.mapId = kwargs['mapId']
#         self.numFrags = len(self.frags)
#         self.length = sum(self.frags)
#        
#         # Add any other attributes from kwargs 
#         for attr in kwargs.iterkeys():
#             if attr not in self.__dict__:
#                 self.__dict__[attr] = kwargs[attr]
# 
#     # write the MalignerMap to file
#     def write(self, handle):
#         f = handle
#         fields = [self.mapId,
#                   str(self.length),
#                   str(len(self.frags))]
#         fields.extend(str(frag) for frag in self.frags)
#         outS = '\t'.join(fields) + '\n'
#         f.write(outS)
# 
#     def get_data(self):
#         """
#         Return dict representation of a MalignerMap
#         """
#         fields = ['mapId', 'length', 'numFrags', 'frags']
#         d = { k:getattr(self,k) for k in fields }
#         return d
# 
#     # Check the consistency of the object
#     def checkMap(self):
#         if len(self.frags) != self.numFrags:
#             raise Exception('MalignerMap attributes are inconsistent!')
# 
#     @property
#     def name(self):
#         return self.mapId
# 
# Path: lib/malignpy/common/wrap_file_function.py
# class wrap_file_function(object):
#   """
#   Wrap a function which takes a file or a str as it's first argument.
#   If a str is provided, replace the first argument of the wrapped function
#   with a file handle, and close the file afterwards
# 
#   Example:
# 
#   @wrap_file_function('w')
#   def write_hi(f):
#     f.write('hi!\n')
# 
#   # This will write to already open file handle.
#   f = open('f1.txt', 'w')
#   write_hi(f)
#   f.close()
# 
#   # This will open file f2.txt with mode 'w', write to it, and close the file.
#   write_hi('f2.txt')
#   """
# 
#   def __init__(self, *args):
#     self.modes = args if args else ('r',)
# 
#   def __call__(self, func):
# 
#     @wraps(func)
#     def wrapped(*args, **kwargs):
# 
#       close = [] # Files that should be closed
#       files = [] # File handles that should be passed to func
#       num_files = len(self.modes)
# 
#       for i, mode in enumerate(self.modes):
# 
#         fp = args[i]
# 
#         if isinstance(fp, str):
#           fp = open(fp, mode)
#           close.append(fp)
# 
#         files.append(fp)
# 
#       try:
# 
#         # Replace the files in args when calling func
#         args = files + list(args[num_files:])
# 
#         # Make function call and return value
#         return func(*args, **kwargs)
# 
#       finally:
# 
#         for fp in close: 
#             fp.close()
# 
#     return wrapped


# Path: lib/malignpy/maps/utils.py
import sys
import re
from .MalignerMap import MalignerMap
from ..common import wrap_file_function

    sys.stderr.write(msg)

    # Optical maps for chromosomes 
    # Remove all white space from restriction map names
    for opMap in opMapList:
        opMap.mapId = ''.join(opMap.mapId.split())
    writeMaps(opMapList, opMapFileOut)
    result = { 'enzyme' : enzyme,
               'opMapList' : opMapList,
               'opticalMapFile' : opMapFileOut}
    return result

#############################################################################################
# Read an optical map in the Schwartz format
# Return a list of OpticalMapData instances
def readMapDataSchwartz(filename, verbose = False):
    omaps = []
    fin = open(filename)
    mapGen = mapDataSchwartzGen(fin)

    if verbose:
        omaps = []
        for map in mapGen:
            omaps.append(map)
            print 'Read map from chromosome %s with enzyme %s and %i fragments'%(map.mapId, map.enzyme, len(map.frags))
    else:
        omaps = [m for m in mapGen]
    fin.close()
    return omaps


@wrap_file_function('r')