Пример #1
0
def _fit_initial_charges(mol, args, atom_types):

    from htmd.charge import fitGasteigerCharges
    from htmd.parameterization.util import guessBondType

    logger.info('=== Initial atomic charge fitting ===')

    if args.charge_type == 'None':
        logger.info('Initial atomic charges are taken from {}'.format(
            args.filename))

    elif args.charge_type in ('Gasteiger', 'AM1-BCC', 'ESP'):
        if args.min_type == 'mm':
            logger.info('Method: Gasteiger')

            # TODO move to _prepare_molecule
            if np.any(mol.bondtype == "un"):
                logger.info('Guessing bond types')
                mol = guessBondType(mol)

            mol = fitGasteigerCharges(mol, atom_types=atom_types)

            # Print the initial charges
            logger.info('Initial atomic charges:')
            for name, charge in zip(mol.name, mol.charge):
                logger.info('   {:4s}: {:6.3f}'.format(name, charge))
            logger.info('Molecular charge: {:6.3f}'.format(np.sum(mol.charge)))

            charge = int(round(np.sum(mol.charge)))
            if args.charge != charge:
                raise RuntimeError(
                    'Molecular charge is set to {}, but Gasteiger atomic charges add up to {}.'
                    .format(args.charge, charge))

        elif args.min_type in ('None', 'qm'):
            logger.info('Initial atomic charges are not required')

        else:
            raise AssertionError()

    else:
        raise AssertionError()

    return mol
Пример #2
0
def _fit_charges(mol, args, qm, atom_types):

    from htmd.charge import fitGasteigerCharges, fitChargesWithAntechamber, fitESPCharges, symmetrizeCharges
    from htmd.parameterization.util import guessBondType, getFixedChargeAtomIndices, getDipole, _qm_method_name
    from htmd.parameterization.detect import detectEquivalentAtoms

    logger.info('=== Atomic charge fitting ===')
    logger.info('Method: {}'.format(args.charge_type))

    if args.charge_type == 'None':

        # TODO move to argument validation
        if len(args.fix_charge) > 0:
            logger.warning('Flag --fix-charge does not have effect!')

        logger.info('Atomic charges are taken from {}'.format(args.filename))

    elif args.charge_type == 'Gasteiger':

        # TODO move to argument validation
        if len(args.fix_charge) > 0:
            logger.warning('Flag --fix-charge does not have effect!')

        # TODO move to _prepare_molecule
        if np.any(mol.bondtype == "un"):
            logger.info('Guessing bond types')
            mol = guessBondType(mol)

        mol = fitGasteigerCharges(mol, atom_types=atom_types)

        charge = int(round(np.sum(mol.charge)))
        if args.charge != charge:
            raise RuntimeError(
                'Molecular charge is set to {}, but Gasteiger atomic charges add up to {}.'
                .format(args.charge, charge))

    elif args.charge_type == 'AM1-BCC':

        # TODO move to argument validation
        if len(args.fix_charge) > 0:
            logger.warning('Flag --fix-charge does not have effect!')

        mol = fitChargesWithAntechamber(mol, type='bcc', molCharge=args.charge)
        mol = symmetrizeCharges(mol)

    elif args.charge_type == 'ESP':

        # Detect equivalent atom groups
        logger.info('Equivalent atom groups:')
        atom_groups = [
            group for group in detectEquivalentAtoms(mol)[0] if len(group) > 1
        ]
        for atom_group in atom_groups:
            logger.info('    {}'.format(', '.join(mol.name[list(atom_group)])))

        # Select the atoms with fixed charges
        fixed_atom_indices = getFixedChargeAtomIndices(mol, args.fix_charge)

        # Create an ESP directory
        espDir = os.path.join(args.outdir, "esp", _qm_method_name(qm))
        os.makedirs(espDir, exist_ok=True)

        charge = int(round(np.sum(mol.charge)))
        if args.charge != charge:
            logger.warning(
                'Molecular charge is set to {}, but atomic charges add up to {}'
                ''.format(args.charge, charge))
            if len(args.fix_charge) > 0:
                raise RuntimeError(
                    'Flag --fix-charge cannot be used when atomic charges are inconsistent with passed '
                    'molecular charge {}'.format(args.charge))
            mol.charge[:] = args.charge / mol.numAtoms

        # Set random number generator seed
        if args.seed:
            np.random.seed(args.seed)

        # Fit ESP charges
        mol, extra = fitESPCharges(mol, qm, espDir, fixed=fixed_atom_indices)

        # Print QM dipole
        logger.info(
            'QM dipole: {:6.3f} {:6.3f} {:6.3f}; total: {:6.3f}'.format(
                *extra['qm_dipole']))

    else:
        raise ValueError()

    # Print MM dipole
    mm_dipole = getDipole(mol)
    logger.info('MM dipole: {:6.3f} {:6.3f} {:6.3f}; total: {:6.3f}'.format(
        *mm_dipole))

    # Print the new charges
    logger.info('Atomic charges:')
    for name, charge in zip(mol.name, mol.charge):
        logger.info('   {:4s}: {:6.3f}'.format(name, charge))
    logger.info('Molecular charge: {:6.3f}'.format(np.sum(mol.charge)))

    return mol