# Path: ssbio/protein/structure/utils/structureio.py
# class StructureIO(PDBIO):
#     """Extended class to load any structure file into a Biopython Structure object
# 
#     Loads the first model when there are multiple available.
#     Also adds some logging methods.
#     """
# 
#     # XTODO: need to revamp this module to be clearer on what files are supported, how file path is parsed
#     # (should explicitly define it)
#     def __init__(self, structure_file, file_type=None):
#         PDBIO.__init__(self)
# 
#         dirname, filename_without_extension, file_type2 = ssbio.utils.split_folder_and_path(structure_file)
#         self.structure_file = structure_file
# 
#         # Unzip the file if it is zipped
#         if file_type == '.gz':
#             unzipped = ssbio.utils.gunzip_file(structure_file, outdir=dirname)
#             dirname, filename_without_extension, file_type2 = ssbio.utils.split_folder_and_path(unzipped)
# 
#         if not file_type:
#             file_type = file_type2
#         else:
#             if '.' not in file_type:
#                 file_type = '.{}'.format(file_type)
# 
#         if file_type.lower() in ['.pdb', '.ent', '.mmcif', '.cif', '.mmtf']:
#             # Load the structure
#             if file_type.lower() == '.pdb' or file_type.lower() == '.ent':
#                 structure = pdbp.get_structure(id='ssbio_pdb', file=structure_file)
#             if file_type.lower() == '.mmcif' or file_type.lower() == '.cif':
#                 with warnings.catch_warnings():
#                     warnings.simplefilter('ignore', PDBConstructionWarning)
#                     structure = cifp.get_structure(structure_id='ssbio_cif', filename=structure_file)
#             if file_type.lower() == '.mmtf':
#                 with warnings.catch_warnings():
#                     warnings.simplefilter('ignore', PDBConstructionWarning)
#                     structure = mmtfp.get_structure(file_path=structure_file)
#             log.debug('{}: parsed 3D coordinates of structure'.format(op.basename(structure_file)))
#         else:
#             raise ValueError('{}: unsupported file type'.format(file_type))
# 
#         self.set_structure(structure)
#         try:
#             self.first_model = structure[0]
#         except KeyError:
#             raise KeyError('{}: no models contained in structure! Please check structure file contents.'.format(structure_file))
# 
#     def write_pdb(self, custom_name='', out_suffix='', out_dir=None, custom_selection=None, force_rerun=False):
#         """Write a new PDB file for the Structure's FIRST MODEL.
# 
#         Set custom_selection to a PDB.Select class for custom SMCRA selections.
# 
#         Args:
#             custom_name: Filename of the new file (without extension)
#             out_suffix: Optional string to append to new PDB file
#             out_dir: Optional directory to output the file
#             custom_selection: Optional custom selection class
#             force_rerun: If existing file should be overwritten
# 
#         Returns:
#             out_file: filepath of new PDB file
# 
#         """
#         if not custom_selection:
#             custom_selection = ModelSelection([0])
# 
#         # If no output directory, custom name, or suffix is specified, add a suffix "_new"
#         if not out_dir or not custom_name:
#             if not out_suffix:
#                 out_suffix = '_new'
# 
#         # Prepare the output file path
#         outfile = ssbio.utils.outfile_maker(inname=self.structure_file,
#                                             outname=custom_name,
#                                             append_to_name=out_suffix,
#                                             outdir=out_dir,
#                                             outext='.pdb')
#         try:
#             if ssbio.utils.force_rerun(flag=force_rerun, outfile=outfile):
#                 self.save(outfile, custom_selection)
#         except TypeError as e:
#             # If trying to save something that can't be saved as a PDB (example: 5iqr.cif), log an error and return None
#             # The error thrown by PDBIO.py is "TypeError: %c requires int or char"
#             log.error('{}: unable to save structure in PDB file format'.format(self.structure_file))
#             raise TypeError(e)
# 
#         return outfile


import argparse
import logging
import os
import os.path as op
import textwrap
import ssbio.utils
from Bio import PDB
from tqdm import tqdm
from ssbio.protein.structure.utils.structureio import StructureIO
                                $ cleanpdb /path/to/pdb/files
                                """))
    p.add_argument('infile', help='PDB file or folder you want to clean', nargs='+', type=str)
    p.add_argument('--outsuffix', '-os', default='_clean', help='Suffix appended to PDB file')
    p.add_argument('--outdir', '-od', default='clean_pdbs', help='Directory to output clean PDBs')
    p.add_argument('--chain', '-c', default=None, help='Keep only specified chains')
    p.add_argument('--keephydro', '-hy', action='store_false', help='Keep hydrogen atoms (default is to remove)')
    p.add_argument('--keephetero', '-ht', action='store_false', help='Keep hetero atoms (default is to remove)')
    # TODO: if this flag is present, the alternate positions seem to switch line positions
    p.add_argument('--keepalt', '-ka', action='store_false', help='Keep alternate positions (default is to remove)')
    p.add_argument('--force', '-f', action='store_true', help='Force rerunning of cleaning even if the clean PDB exists')
    args = p.parse_args()

    if args.chain:
        args.chain = args.chain.split(',')

    if not op.isdir(args.outdir):
        os.mkdir(args.outdir)

    infiles = ssbio.utils.input_list_parser(args.infile)

    for pdb in tqdm(infiles):

        outfile = ssbio.utils.outfile_maker(inname=pdb,
                                            append_to_name=args.outsuffix,
                                            outdir=args.outdir,
                                            outext='.pdb')

        if ssbio.utils.force_rerun(flag=args.force, outfile=outfile):


# Path: ssbio/protein/structure/utils/structureio.py
# class StructureIO(PDBIO):
#     """Extended class to load any structure file into a Biopython Structure object
# 
#     Loads the first model when there are multiple available.
#     Also adds some logging methods.
#     """
# 
#     # XTODO: need to revamp this module to be clearer on what files are supported, how file path is parsed
#     # (should explicitly define it)
#     def __init__(self, structure_file, file_type=None):
#         PDBIO.__init__(self)
# 
#         dirname, filename_without_extension, file_type2 = ssbio.utils.split_folder_and_path(structure_file)
#         self.structure_file = structure_file
# 
#         # Unzip the file if it is zipped
#         if file_type == '.gz':
#             unzipped = ssbio.utils.gunzip_file(structure_file, outdir=dirname)
#             dirname, filename_without_extension, file_type2 = ssbio.utils.split_folder_and_path(unzipped)
# 
#         if not file_type:
#             file_type = file_type2
#         else:
#             if '.' not in file_type:
#                 file_type = '.{}'.format(file_type)
# 
#         if file_type.lower() in ['.pdb', '.ent', '.mmcif', '.cif', '.mmtf']:
#             # Load the structure
#             if file_type.lower() == '.pdb' or file_type.lower() == '.ent':
#                 structure = pdbp.get_structure(id='ssbio_pdb', file=structure_file)
#             if file_type.lower() == '.mmcif' or file_type.lower() == '.cif':
#                 with warnings.catch_warnings():
#                     warnings.simplefilter('ignore', PDBConstructionWarning)
#                     structure = cifp.get_structure(structure_id='ssbio_cif', filename=structure_file)
#             if file_type.lower() == '.mmtf':
#                 with warnings.catch_warnings():
#                     warnings.simplefilter('ignore', PDBConstructionWarning)
#                     structure = mmtfp.get_structure(file_path=structure_file)
#             log.debug('{}: parsed 3D coordinates of structure'.format(op.basename(structure_file)))
#         else:
#             raise ValueError('{}: unsupported file type'.format(file_type))
# 
#         self.set_structure(structure)
#         try:
#             self.first_model = structure[0]
#         except KeyError:
#             raise KeyError('{}: no models contained in structure! Please check structure file contents.'.format(structure_file))
# 
#     def write_pdb(self, custom_name='', out_suffix='', out_dir=None, custom_selection=None, force_rerun=False):
#         """Write a new PDB file for the Structure's FIRST MODEL.
# 
#         Set custom_selection to a PDB.Select class for custom SMCRA selections.
# 
#         Args:
#             custom_name: Filename of the new file (without extension)
#             out_suffix: Optional string to append to new PDB file
#             out_dir: Optional directory to output the file
#             custom_selection: Optional custom selection class
#             force_rerun: If existing file should be overwritten
# 
#         Returns:
#             out_file: filepath of new PDB file
# 
#         """
#         if not custom_selection:
#             custom_selection = ModelSelection([0])
# 
#         # If no output directory, custom name, or suffix is specified, add a suffix "_new"
#         if not out_dir or not custom_name:
#             if not out_suffix:
#                 out_suffix = '_new'
# 
#         # Prepare the output file path
#         outfile = ssbio.utils.outfile_maker(inname=self.structure_file,
#                                             outname=custom_name,
#                                             append_to_name=out_suffix,
#                                             outdir=out_dir,
#                                             outext='.pdb')
#         try:
#             if ssbio.utils.force_rerun(flag=force_rerun, outfile=outfile):
#                 self.save(outfile, custom_selection)
#         except TypeError as e:
#             # If trying to save something that can't be saved as a PDB (example: 5iqr.cif), log an error and return None
#             # The error thrown by PDBIO.py is "TypeError: %c requires int or char"
#             log.error('{}: unable to save structure in PDB file format'.format(self.structure_file))
#             raise TypeError(e)
# 
#         return outfile


# Path: ssbio/protein/structure/utils/cleanpdb.py
import argparse
import logging
import os
import os.path as op
import textwrap
import ssbio.utils
from Bio import PDB
from tqdm import tqdm
from ssbio.protein.structure.utils.structureio import StructureIO

                                $ cleanpdb /path/to/pdb/files
                                """))
    p.add_argument('infile', help='PDB file or folder you want to clean', nargs='+', type=str)
    p.add_argument('--outsuffix', '-os', default='_clean', help='Suffix appended to PDB file')
    p.add_argument('--outdir', '-od', default='clean_pdbs', help='Directory to output clean PDBs')
    p.add_argument('--chain', '-c', default=None, help='Keep only specified chains')
    p.add_argument('--keephydro', '-hy', action='store_false', help='Keep hydrogen atoms (default is to remove)')
    p.add_argument('--keephetero', '-ht', action='store_false', help='Keep hetero atoms (default is to remove)')
    # TODO: if this flag is present, the alternate positions seem to switch line positions
    p.add_argument('--keepalt', '-ka', action='store_false', help='Keep alternate positions (default is to remove)')
    p.add_argument('--force', '-f', action='store_true', help='Force rerunning of cleaning even if the clean PDB exists')
    args = p.parse_args()

    if args.chain:
        args.chain = args.chain.split(',')

    if not op.isdir(args.outdir):
        os.mkdir(args.outdir)

    infiles = ssbio.utils.input_list_parser(args.infile)

    for pdb in tqdm(infiles):

        outfile = ssbio.utils.outfile_maker(inname=pdb,
                                            append_to_name=args.outsuffix,
                                            outdir=args.outdir,
                                            outext='.pdb')

        if ssbio.utils.force_rerun(flag=args.force, outfile=outfile):


            my_pdb = StructureIO(pdb)