예제 #1
0
    def processDelPhiParams(self):
        # Storing DelPhi parameters and Creates DelPhi data structures
        logfile = "LOG_readFiles"

        delphimol = DelPhi4py(
            Config.pypka_params["f_crg"],
            Config.pypka_params["f_siz"],
            "delphi_in_stmod.pdb",
            Config.delphi_params["gsize"],
            Config.delphi_params["scaleM"],
            Config.delphi_params["precision"],
            epsin=Config.delphi_params["epsin"],
            epsout=Config.delphi_params["epssol"],
            conc=Config.delphi_params["ionicstr"],
            ibctyp=Config.delphi_params["bndcon"],
            res2=Config.delphi_params["maxc"],
            nlit=Config.delphi_params["nlit"],
            nonit=Config.delphi_params["nonit"],
            relfac=0.0,
            relpar=0.0,
            pbx=Config.delphi_params["pbx"],
            pby=Config.delphi_params["pby"],
            isurftype=Config.delphi_params["nanoshaper"],
            debug=Config.debug,
            outputfile=logfile,
        )

        if Config.pypka_params["f_structure_out"]:
            with open("delphi_in_stmod.pdb") as f:
                self.delphi_input_content = f.readlines()
        if Config.pypka_params["save_pdb"]:
            with open("delphi_in_stmod.pdb") as f, open(
                    Config.pypka_params["save_pdb"], "w") as f_new:
                content = f.read()
                f_new.write(content)

        if not Config.debug:
            os.remove("delphi_in_stmod.pdb")

        log.checkDelPhiErrors(logfile, "readFiles")

        lookup_atoms = {}
        for molecule in Config.titration.molecules.values():
            for atom_name, atom_id, atom_position in molecule.iterAtoms():
                lookup_atoms[atom_position] = (atom_id, atom_name)

        # Stores DelPhi4py object and attributes
        Config.delphi_params.store_run_params(delphimol)
        Config.delphi_params.lookup_atoms = lookup_atoms

        if Config.debug:
            for chain, molecule in self.molecules.items():
                print("### CHAIN {chain} ###".format(chain=chain))
                molecule.printAllSites()
                molecule.printAllTautomers()
            print(delphimol)
예제 #2
0
    def CalcPotentialTautomer(self):
        """Run DelPhi simulation of single site tautomer

        Ensures:
            self.esolvation (float): tautomer solvation energy
            self.p_sitpot (list): potential on site atoms
        """
        if Config.debug:
            t0 = time.process_time()
            print((self.name))
            print((self.charge_set))
        molecule = self.molecule

        delphimol, acent = self.setDetailsFromTautomer()

        if Config.delphi_params["bndcon"] == 3:
            ibctyp = 4
        else:
            ibctyp = Config.delphi_params["bndcon"]

        filename = "{0}_{1}.prm".format(self.name, self.site.res_number)
        logfile = "LOG_runDelPhi_{0}_{1}_modelcompound".format(
            self.name, self.site.res_number)
        if Config.debug:
            print(
                ("started", self.name, self.site.res_number, "modelcompound"))

        delphimol.runDelPhi(
            scale=Config.delphi_params["scaleM"],
            nonit=0,
            nlit=500,
            relpar=0,
            relfac=0,
            acent=acent,
            pbx=False,
            pby=False,
            debug=Config.debug,
            filename=filename,
            ibctyp=ibctyp,
            outputfile=logfile,
        )
        if Config.debug:
            print(("ended", self.name, self.site.res_number, "modelcompound"))

        log.checkDelPhiErrors(logfile, "runDelPhi")

        self.esolvation = delphimol.getSolvation()
        self.p_sitpot = delphimol.getSitePotential()
        if Config.debug:
            t1 = time.process_time() - t0
            filename = "{0}_{1}.profl".format(self.name,
                                              self.getSiteResNumber())
            with open(filename, "a") as f_new:
                f_new.write("time -> {0:10} {1:10}\n".format(t0, t1))

        return self.esolvation, self.p_sitpot[:]
예제 #3
0
파일: pypka.py 프로젝트: machuque/PypKa
    def processDelPhiParams(self):
        # Storing DelPhi parameters and Creates DelPhi data structures
        logfile = 'LOG_readFiles'

        delphimol = DelPhi4py(Config.pypka_params['f_crg'],
                              Config.pypka_params['f_siz'],
                              'delphi_in_stmod.pdb',
                              Config.delphi_params['gsize'],
                              Config.delphi_params['scaleM'],
                              Config.delphi_params['precision'],
                              epsin=Config.delphi_params['epsin'],
                              epsout=Config.delphi_params['epssol'],
                              conc=Config.delphi_params['ionicstr'],
                              ibctyp=Config.delphi_params['bndcon'],
                              res2=Config.delphi_params['maxc'],
                              nlit=Config.delphi_params['nlit'],
                              nonit=Config.delphi_params['nonit'],
                              relfac=0.0,
                              relpar=0.0,
                              pbx=Config.delphi_params['pbx'],
                              pby=Config.delphi_params['pby'],
                              isurftype=Config.delphi_params['nanoshaper'],
                              debug=Config.debug, outputfile=logfile)

        if Config.pypka_params['f_structure_out']:
            with open('delphi_in_stmod.pdb') as f:
                self.delphi_input_content = f.readlines()
        if not Config.debug:
            os.remove('delphi_in_stmod.pdb')

        log.checkDelPhiErrors(logfile, 'readFiles')

        lookup_atoms = {}
        for molecule in Config.titration.molecules.values():
            for atom_name, atom_id, atom_position in molecule.iterAtoms():
                lookup_atoms[atom_position] = (atom_id, atom_name)

        # Stores DelPhi4py object and attributes
        Config.delphi_params.store_run_params(delphimol)
        Config.delphi_params.lookup_atoms = lookup_atoms

        if Config.debug:
            for chain, molecule in self.molecules.items():
                print('### CHAIN {chain} ###'.format(chain=chain))
                molecule.printAllSites()
                molecule.printAllTautomers()
            print(delphimol)
예제 #4
0
파일: cleaning.py 프로젝트: machuque/PypKa
def cleanPDB(molecules, chains_res, inputpqr, outputpqr):
    """
    """
    pdb_filename = Config.pypka_params['f_in']
    pdb2pqr_path = Config.pypka_params['pdb2pqr']
    inputpdbfile = removeMembrane(pdb_filename)

    logfile = 'LOG_pdb2pqr'
    #errfile = 'LOG_pdb2pqr_err'

    #log.redirectOutput("start", logfile)
    #log.redirectErr("start", errfile)

    # CTR O1/O2 will be deleted and a O/OXT will be added
    os.system('python2 {0} {1} {2} --ff {4} --ffout {4} '
              '--drop-water -v --chain > {5} 2>&1 '.format(
                  pdb2pqr_path, inputpdbfile, inputpqr,
                  Config.pypka_params['ffinput'],
                  Config.pypka_params['ff_family'], logfile))
    if Config.pypka_params['f_structure_out']:
        ff_out = Config.pypka_params['ff_structure_out']
        if ff_out == 'gromos_cph':
            ff_out = 'gromos'
        os.system('python2 {0} {1} Hs.pqr --ff {3} --ffout {3} '
                  '--drop-water -v --chain >> {2} 2>&1 '.format(
                      pdb2pqr_path, inputpdbfile, logfile, ff_out))

    #log.redirectOutput("stop", logfile)
    #log.redirectErr("stop", errfile)

    if Config.pypka_params['f_structure_out']:
        with open('Hs.pqr') as f:
            for line in f:
                if line.startswith('ATOM '):
                    (aname, anumb, resname, chain, resnumb, x, y, z, charge,
                     radius) = read_pqr_line(line)

                    if resnumb in chains_res['A'] and \
                       resname in AMBER_Hs and \
                       aname in AMBER_Hs[resname] and \
                       aname not in AMBER_mainchain_Hs:
                        continue
                    elif aname[0] == 'H' and aname not in ('H1', 'H2', 'H3'):
                        if not resnumb in mainchain_Hs:
                            mainchain_Hs[resnumb] = []
                        mainchain_Hs[resnumb].append(
                            (aname, anumb, resname, chain, x, y, z))

    CYS_bridges = {}
    with open('LOG_pdb2pqr') as f:
        for line in f:
            if 'patched with CYX' in line:
                parts = line.split('patched')[0].replace('PATCH INFO: ',
                                                         '').split()
                resname, chain, resnumb = parts
                chain = chain.replace('_', ' ')
                if not chain in CYS_bridges:
                    CYS_bridges[chain] = []
                cys_res_numb = int(parts[-1])
                if cys_res_numb not in CYS_bridges[chain]:
                    CYS_bridges[chain].append(cys_res_numb)

    for chain, molecule in molecules.items():
        if chain in CYS_bridges:
            molecule.saveCYSBridges(CYS_bridges[chain])

    new_pdb_text = ''
    removed_pdb_text = ''
    removed_pdb_lines = []
    #ntr_trigger = True
    resnumb_max = 0
    chains = list(molecules.keys())

    with open(inputpqr) as f:
        for line in f:
            if "ATOM" in line[:4]:
                (aname, anumb, resname, original_chain, resnumb, x, y, z,
                 charge, radius) = read_pqr_line(line)

                if original_chain == '_':
                    chain = ' '
                else:
                    chain = original_chain

                termini_trigger = False
                if chain in chains:
                    molecule = molecules[chain]
                    NTR_numb = molecule.NTR
                    CTR_numb = molecule.CTR

                    sites_numbs = molecule.sites.keys()

                    aname, resname = correct_names(resnumb, resname, aname,
                                                   sites_numbs, NTR_numb,
                                                   CTR_numb)
                    resnumb_max = resnumb

                    if resnumb in (NTR_numb, CTR_numb):
                        termini_trigger = True

                if aname in ('O1', 'O2',
                             'OT1', 'OT2',
                             'H1', 'H2', 'H3') and \
                   not termini_trigger and resname in PROTEIN_RESIDUES:
                    if aname == 'O1':
                        aname = 'O'
                    elif aname == 'H1':
                        aname = 'H'
                    else:
                        continue

                if line[26] != ' ':
                    resnumb += TERMINAL_OFFSET

                new_line = new_pqr_line(anumb,
                                        aname,
                                        resname,
                                        resnumb,
                                        x,
                                        y,
                                        z,
                                        charge,
                                        radius,
                                        chain=original_chain)
                if chain in molecules:
                    new_pdb_text += new_line
                elif aname not in ('O1', 'O2', 'OT1', 'OT2', 'H1', 'H2', 'H3'):
                    if resname in ('SER', 'THR') and aname == 'HG1':
                        aname = 'HG'
                    removed_pdb_lines.append(new_line)

    resnumb_old = resnumb_max + 1
    for line in removed_pdb_lines:
        (aname, anumb_old, resname, chain, resnumb, x, y, z, charge,
         radius) = read_pqr_line(line)
        anumb += 1
        resnumb += resnumb_old
        while resnumb < resnumb_max:
            resnumb += resnumb_old
        removed_pdb_text += new_pqr_line(anumb, aname, resname, resnumb, x, y,
                                         z, charge, radius)
        resnumb_max = resnumb
    #            if ntr_trigger and :
    #                config.tit_mole._NTR = resnumb

    #chains = copy(chains_res['A'])
    #for res in chains:
    #    if str(res) > config.terminal_offset:
    #        print((res, chains_res['A'][res]))
    #        del chains_res['A'][res]
    #chains_res['A'][config.tit_mole._NTR] = 'NTR'
    #chains_res['A'][config.tit_mole._CTR] = 'CTR'

    with open('cleaned.pqr', 'w') as f_new:
        f_new.write(new_pdb_text)

    with open('removed.pqr', 'w') as f_new:
        f_new.write(removed_pdb_text)

    sites_addHtaut = ''
    for chain in molecules:
        for res in chains_res[chain]:
            if chains_res[chain][res] == 'NTR' or \
               (chain in CYS_bridges and res in CYS_bridges[chain]):
                continue
            sites_addHtaut += '{0}-{1}-{2},'.format(res,
                                                    chains_res[chain][res],
                                                    chain.replace(' ', '_'))

    if len(sites_addHtaut) > 0 and sites_addHtaut[-1] == ',':
        sites_addHtaut = sites_addHtaut[:-1]

    logfile = 'LOG_addHtaut'
    #log.redirectErr("start", logfile)

    script_dir = Config.pypka_params['script_dir']
    os.system('{}/addHtaut_{} cleaned.pqr {} > {} 2> {}'.format(
        script_dir, Config.pypka_params['ff_family'], sites_addHtaut,
        outputpqr, logfile))

    #log.redirectErr("stop", logfile)
    log.checkDelPhiErrors(logfile, 'addHtaut')

    with open(outputpqr) as f:
        content = f.read()
    with open(outputpqr, 'w') as f_new:
        f_new.write(content + removed_pdb_text)

    with open(pdb_filename) as f:
        box = None
        for line in f:
            if line.startswith('CRYST1'):
                tmp = line.split()[1:4]
                box = (float(tmp[0]), float(tmp[1]), float(tmp[2]))
        if not box:
            box = (1.0, 1.0, 1.0)

    #pdb2gro(outputpqr, "TMP.gro", chains_res, box, pqr=True, fix_termini=False)

    with open(outputpqr) as f,\
         open('TMP.pdb', 'w') as fnew:
        counter = 0
        new_pdb_text = "CRYST1  {:3.3f}  {:3.3f}  {:3.3f}  "\
                       "60.00  60.00  90.00 P 1           1\n".format(box[0],
                                                                      box[1], box[2])
        for line in f:
            counter += 1
            (aname, anumb_old, resname, chain, resnumb, x, y, z, charge,
             radius) = read_pqr_line(line)

            if chain == '_':
                chain = ' '

            new_pdb_text += new_pdb_line(counter,
                                         aname,
                                         resname,
                                         resnumb,
                                         x,
                                         y,
                                         z,
                                         chain=chain)
        fnew.write(new_pdb_text)

    keep_membrane = False
    keep_ions = False
    if Config.delphi_params['pbc_dim'] == 2:
        keep_membrane = True

    if Config.pypka_params['keep_ions']:
        keep_ions = True
    if keep_ions or keep_membrane:
        add_non_protein(pdb_filename,
                        'TMP.pdb',
                        keep_membrane=keep_membrane,
                        keep_ions=keep_ions)

    tmpfiles = ('LOG_pdb2pqr', 'LOG_pdb2pqr_err', 'clean.pqr', 'cleaned.pqr',
                'cleaned_tau.pqr', 'input_clean.pdb', 'removed.pqr', 'Hs.pqr')
    for filename in tmpfiles:
        if not Config.debug and os.path.isfile(filename):
            os.remove(filename)
예제 #5
0
    def CalcPotentialTitratingMolecule(self):
        """Run DelPhi simulation of the site tautomer
        within the whole molecule

        Ensures:
            self.esolvation (float): tautomer solvation energy
            self.p_sitpot (list): potential on site atoms
        """

        if Config.debug:
            start = time.process_time()
        molecule = self.molecule

        delphimol, acent = self.setDetailsFromWholeMolecule()

        if Config.debug:
            t0 = time.process_time() - start

            print((self.name, 'starting'))
            p_atpos = delphimol.get_atpos()
            p_rad3 = delphimol.get_rad3()
            p_chrgv4 = delphimol.get_chrgv4()
            atinf = delphimol.get_atinf()
            #for atom_name, atom_id, atom_position in molecule.iterAtoms():
            #    print (atinf[atom_position].value, p_chrgv4[atom_position], p_rad3[atom_position],
            #           p_atpos[atom_position][0], p_atpos[atom_position][1], p_atpos[atom_position][2])

        filename = '{0}_{1}.prm'.format(self.name, self.site.res_number)
        logfile = 'LOG_runDelPhi_{0}_{1}_wholeprotein'.format(
            self.name, self.site.res_number)

        if Config.debug:
            print(('started', self.name, self.site.res_number, 'wholeprotein'))
        if Config.delphi_params['pbc_dim'] == 2:
            delphimol.runDelPhi(scale_prefocus=Config.delphi_params['scaleP'],
                                scale=Config.delphi_params['scaleM'],
                                nlit_prefocus=Config.delphi_params['nlit'],
                                nonit=Config.delphi_params['nonit'],
                                nlit=500,
                                acent=acent,
                                nonit_focus=0,
                                relfac_focus=0.0,
                                relpar_focus=0.0,
                                relpar=Config.delphi_params['relpar'],
                                relfac=Config.delphi_params['relfac'],
                                pbx=True,
                                pby=True,
                                pbx_focus=False,
                                pby_focus=False,
                                ibctyp=4,
                                debug=Config.debug,
                                filename=filename,
                                outputfile=logfile)
        elif Config.delphi_params['pbc_dim'] == 0 and Config.delphi_params[
                'bndcon'] == 3:
            delphimol.runDelPhi(scale_prefocus=Config.delphi_params['scaleP'],
                                scale=Config.delphi_params['scaleM'],
                                nlit_prefocus=Config.delphi_params['nlit'],
                                nonit=0,
                                nlit=500,
                                acent=acent,
                                nonit_focus=0,
                                relfac_focus=0.0,
                                relpar_focus=0.0,
                                relpar=Config.delphi_params['relpar'],
                                relfac=Config.delphi_params['relfac'],
                                pbx=False,
                                pby=False,
                                pbx_focus=False,
                                pby_focus=False,
                                ibctyp=4,
                                debug=Config.debug,
                                filename=filename,
                                outputfile=logfile)
        else:
            delphimol.runDelPhi(scale=Config.delphi_params['scaleM'],
                                nonit=0,
                                nlit=500,
                                relpar=0,
                                relfac=0,
                                acent=acent,
                                pbx=False,
                                pby=False,
                                debug=Config.debug,
                                filename=filename,
                                outputfile=logfile)

        if Config.debug:
            print(('ended', self.name, self.site.res_number, 'wholeprotein'))

        log.checkDelPhiErrors(logfile, 'runDelPhi')

        self.esolvation = delphimol.getSolvation()
        self.p_sitpot = delphimol.getSitePotential()

        if Config.debug:
            filename = '{0}_{1}.frc'.format(self.name, self.site.res_number)
            with open(filename, 'w') as f:
                text = ''
                for atom_name, atom_id, atom_position in molecule.iterAtoms():
                    text += '{0} {1} {2} '\
                            '{3} {4} {5} {6}\n'.format(atinf[atom_position].value,
                                                       round(p_chrgv4[atom_position], 3),
                                                       round(p_rad3[atom_position], 4),
                                                       round(p_atpos[atom_position][0], 3),
                                                       round(p_atpos[atom_position][1], 3),
                                                       round(p_atpos[atom_position][2], 3),
                                                       self.p_sitpot[atom_position])
                f.write(text)

            t1 = time.process_time() - start
            filename = '{0}_{1}.profl'.format(self.name,
                                              self.getSiteResNumber())
            with open(filename, 'a') as f_new:
                f_new.write('time -> {0:10}     {1:10}\n'.format(t0, t1))

            print((self.esolvation, self.name))

        return self.esolvation, self.p_sitpot[:]
예제 #6
0
def cleanPDB(molecules, chains_res, inputpqr, outputpqr):
    """"""
    pdb_filename = Config.pypka_params["f_in"]
    pdb2pqr_path = Config.pypka_params["pdb2pqr"]
    inputpdbfile = removeMembrane(pdb_filename)

    logfile = "LOG_pdb2pqr"
    # errfile = 'LOG_pdb2pqr_err'

    # log.redirectOutput("start", logfile)
    # log.redirectErr("start", errfile)

    # CTR O1/O2 will be deleted and a O/OXT will be added
    os.system(
        "python2 {0} {1} {2} --ff {3} --ffout {4} "
        "--drop-water -v --chain > {5} 2>&1 ".format(
            pdb2pqr_path,
            inputpdbfile,
            inputpqr,
            Config.pypka_params["ffinput"],
            Config.pypka_params["ff_family"],
            logfile,
        )
    )

    if Config.pypka_params["f_structure_out"]:
        ff_out = Config.pypka_params["ff_structure_out"]
        if ff_out == "gromos_cph":
            ff_out = "gromos"
        os.system(
            "python2 {0} {1} Hs.pqr --ff {3} --ffout {3} "
            "--drop-water -v --chain >> {2} 2>&1 ".format(
                pdb2pqr_path, inputpdbfile, logfile, ff_out
            )
        )

    # log.redirectOutput("stop", logfile)
    # log.redirectErr("stop", errfile)

    if Config.pypka_params["f_structure_out"]:
        with open("Hs.pqr") as f:
            for line in f:
                if line.startswith("ATOM "):
                    (
                        aname,
                        anumb,
                        resname,
                        chain,
                        resnumb,
                        x,
                        y,
                        z,
                        charge,
                        radius,
                    ) = read_pqr_line(line)

                    if (
                        resnumb in chains_res["A"]
                        and resname in AMBER_Hs
                        and aname in AMBER_Hs[resname]
                        and aname not in AMBER_mainchain_Hs
                    ):
                        continue
                    elif aname[0] == "H" and aname not in ("H1", "H2", "H3"):
                        if not resnumb in mainchain_Hs:
                            mainchain_Hs[resnumb] = []
                        mainchain_Hs[resnumb].append(
                            (aname, anumb, resname, chain, x, y, z)
                        )

    CYS_bridges = {}
    with open("LOG_pdb2pqr") as f:
        for line in f:
            if "patched with CYX" in line:
                parts = line.split("patched")[0].replace("PATCH INFO: ", "").split()
                resname, chain, resnumb = parts
                chain = chain.replace("_", " ")
                if not chain in CYS_bridges:
                    CYS_bridges[chain] = []
                cys_res_numb = int(parts[-1])
                if cys_res_numb not in CYS_bridges[chain]:
                    CYS_bridges[chain].append(cys_res_numb)

    for chain, molecule in molecules.items():
        if chain in CYS_bridges:
            molecule.saveCYSBridges(CYS_bridges[chain])

    new_pdb_text = ""
    removed_pdb_text = ""
    removed_pdb_lines = []
    # ntr_trigger = True
    resnumb_max = 0
    chains = list(molecules.keys())

    with open(inputpqr) as f:
        for line in f:
            if "ATOM" in line[:4]:
                (
                    aname,
                    anumb,
                    resname,
                    original_chain,
                    resnumb,
                    x,
                    y,
                    z,
                    charge,
                    radius,
                ) = read_pqr_line(line)

                if original_chain == "_":
                    chain = " "
                else:
                    chain = original_chain

                termini_trigger = False
                if chain in chains:
                    molecule = molecules[chain]
                    NTR_numb = molecule.NTR
                    CTR_numb = molecule.CTR

                    sites_numbs = molecule.sites.keys()

                    aname, resname = correct_names(
                        resnumb, resname, aname, sites_numbs, NTR_numb, CTR_numb
                    )
                    resnumb_max = resnumb

                    if resnumb in (NTR_numb, CTR_numb):
                        termini_trigger = True

                if (
                    aname in ("O1", "O2", "OT1", "OT2", "H1", "H2", "H3")
                    and not termini_trigger
                    and resname in PROTEIN_RESIDUES
                ):
                    if aname == "O1":
                        aname = "O"
                    elif aname == "H1":
                        aname = "H"
                    else:
                        continue

                if line[26] != " ":
                    resnumb += TERMINAL_OFFSET

                new_line = new_pqr_line(
                    anumb,
                    aname,
                    resname,
                    resnumb,
                    x,
                    y,
                    z,
                    charge,
                    radius,
                    chain=original_chain,
                )
                if chain in molecules:
                    new_pdb_text += new_line
                elif aname not in ("O1", "O2", "OT1", "OT2", "H1", "H2", "H3"):
                    if resname in ("SER", "THR") and aname == "HG1":
                        aname = "HG"
                    removed_pdb_lines.append(new_line)

    resnumb_old = resnumb_max + 1
    for line in removed_pdb_lines:
        (
            aname,
            anumb_old,
            resname,
            chain,
            resnumb,
            x,
            y,
            z,
            charge,
            radius,
        ) = read_pqr_line(line)
        anumb += 1
        resnumb += resnumb_old
        while resnumb < resnumb_max:
            resnumb += resnumb_old
        removed_pdb_text += new_pqr_line(
            anumb, aname, resname, resnumb, x, y, z, charge, radius
        )
        resnumb_max = resnumb
    #            if ntr_trigger and :
    #                config.tit_mole._NTR = resnumb

    # chains = copy(chains_res['A'])
    # for res in chains:
    #    if str(res) > config.terminal_offset:
    #        print((res, chains_res['A'][res]))
    #        del chains_res['A'][res]
    # chains_res['A'][config.tit_mole._NTR] = 'NTR'
    # chains_res['A'][config.tit_mole._CTR] = 'CTR'

    with open("cleaned.pqr", "w") as f_new:
        f_new.write(new_pdb_text)

    with open("removed.pqr", "w") as f_new:
        f_new.write(removed_pdb_text)

    sites_addHtaut = ""
    for chain in molecules:
        for res in chains_res[chain]:
            if chains_res[chain][res] == "NTR" or (
                chain in CYS_bridges and res in CYS_bridges[chain]
            ):
                continue
            sites_addHtaut += "{0}-{1}-{2},".format(
                res, chains_res[chain][res], chain.replace(" ", "_")
            )

    if len(sites_addHtaut) > 0 and sites_addHtaut[-1] == ",":
        sites_addHtaut = sites_addHtaut[:-1]

    logfile = "LOG_addHtaut"
    # log.redirectErr("start", logfile)

    script_dir = Config.pypka_params["script_dir"]
    os.system(
        "{}/addHtaut_{} cleaned.pqr {} > {} 2> {}".format(
            script_dir,
            Config.pypka_params["ff_family"],
            sites_addHtaut,
            outputpqr,
            logfile,
        )
    )

    # log.redirectErr("stop", logfile)
    log.checkDelPhiErrors(logfile, "addHtaut")

    with open(outputpqr) as f:
        content = f.read()
    with open(outputpqr, "w") as f_new:
        f_new.write(content + removed_pdb_text)

    with open(pdb_filename) as f:
        box = None
        for line in f:
            if line.startswith("CRYST1"):
                tmp = line.split()[1:4]
                box = (float(tmp[0]), float(tmp[1]), float(tmp[2]))
        if not box:
            box = (1.0, 1.0, 1.0)

    # pdb2gro(outputpqr, "TMP.gro", chains_res, box, pqr=True, fix_termini=False)

    with open(outputpqr) as f, open("TMP.pdb", "w") as fnew:
        counter = 0
        new_pdb_text = (
            "CRYST1  {:3.3f}  {:3.3f}  {:3.3f}  "
            "60.00  60.00  90.00 P 1           1\n".format(box[0], box[1], box[2])
        )
        for line in f:
            counter += 1
            (
                aname,
                anumb_old,
                resname,
                chain,
                resnumb,
                x,
                y,
                z,
                charge,
                radius,
            ) = read_pqr_line(line)

            if chain == "_":
                chain = " "

            new_pdb_text += new_pdb_line(
                counter, aname, resname, resnumb, x, y, z, chain=chain
            )
        fnew.write(new_pdb_text)

    keep_membrane = False
    keep_ions = False
    if Config.delphi_params["pbc_dim"] == 2:
        keep_membrane = True

    if Config.pypka_params["keep_ions"]:
        keep_ions = True
    if keep_ions or keep_membrane:
        add_non_protein(
            pdb_filename, "TMP.pdb", keep_membrane=keep_membrane, keep_ions=keep_ions
        )

    tmpfiles = (
        "LOG_pdb2pqr",
        "LOG_pdb2pqr_err",
        "clean.pqr",
        "cleaned.pqr",
        "cleaned_tau.pqr",
        "input_clean.pdb",
        "removed.pqr",
        "Hs.pqr",
    )
    for filename in tmpfiles:
        if not Config.debug and os.path.isfile(filename):
            os.remove(filename)