Ejemplo n.º 1
0
def alignmol(mol):
    masses = []
    coordinates = [a.coords for a in mol.atoms]
    totalMass = 0
    for atom in mol:
        m = 1
        if options.useweights:
            m = atom.atomicmass
        masses.append(m)
        totalMass += m

    coordinates = numpy.array(coordinates)
    masses = numpy.array(masses)
    trans = -numpy.sum(coordinates * masses[:, numpy.newaxis],
                       axis=0) / totalMass
    mol.OBMol.Translate(openbabel.vector3(*trans))
    coordinates += trans
    #this is shamelessly stolen from the mdanalysis package
    inertia = calcI(masses, coordinates)

    eigenval, eigenvec = eig(inertia)
    # Sort
    indices = numpy.argsort(eigenval)
    # Return transposed in more logical form. See Issue 33.
    principalAxes = eigenvec[:, indices].T
    if det(principalAxes) < 0:
        principalAxes = -principalAxes  #remove reflection !!Is this correct?? Kabasch wiki says negate just one row, but this is Kabasch...

    xrot = openbabel.double_array([1, 0, 0, 0, -1, 0, 0, 0, -1])
    yrot = openbabel.double_array([-1, 0, 0, 0, 1, 0, 0, 0, -1])
    zrot = openbabel.double_array([-1, 0, 0, 0, -1, 0, 0, 0, 1])
    ident = openbabel.double_array([1, 0, 0, 0, 1, 0, 0, 0, 1])

    rotmat = openbabel.double_array(principalAxes.flatten())
    mol.OBMol.Rotate(rotmat)

    coordinates = [a.coords for a in mol.atoms]  #should be modified
    (a, b) = calcSplitMoments(coordinates, 1)
    if (a < b):
        mol.OBMol.Rotate(xrot)
#    print a,b
    (a, b) = calcSplitMoments(coordinates, 0)
    if (a < b):
        mol.OBMol.Rotate(yrot)


#    print a,b
    return
Ejemplo n.º 2
0
def shiftAndCalculateReactionCoordinate(mol,nOfAtoms,reactionCoordinate,vector,h,coords=None): # this function is called many times
    if coords==None:
        tmp = openbabel.doubleArray_frompointer(mol.GetCoordinates())
        coords = [ tmp[i] for i in xrange(3*nOfAtoms) ]
    coords = addVec(coords,multVec(h,vector))
    mol.SetCoordinates(openbabel.double_array(coords))
    return reactionCoordinate(mol)
Ejemplo n.º 3
0
def separateFragments(pymol, dist=3.0):
    mol = pymol.OBMol
    nAtom = len(pymol.atoms)
    unvisited = set(range(1, nAtom + 1))
    q = deque([1])
    fragments = [set()]
    while q or unvisited:
        if q:
            curr = q.popleft()
            unvisited.remove(curr)
            fragments[-1].add(curr)
        else:
            curr = unvisited.pop()
            fragments.append({curr})
        atom = mol.GetAtom(curr)
        for nbr in ob.OBAtomAtomIter(atom):
            nbrNum = nbr.GetIdx()
            if nbrNum in unvisited:
                q.append(nbrNum)
    coords = []
    for atom in pymol:
        coords.append(list(atom.coords))
    nFragments = len(fragments)
    delta = -(nFragments - 1) * dist / 2.0
    for fragment in fragments:
        for atomIdx in fragment:
            x, y, z = coords[atomIdx - 1]
            coords[atomIdx - 1] = [x + delta, y + delta, z + delta]
        delta += dist
    coords = [item for sublist in coords for item in sublist]
    c_coords = ob.double_array(coords)
    mol.SetCoordinates(c_coords)
Ejemplo n.º 4
0
def alignmol(mol):
    masses = []    
    coordinates = [ a.coords for a in mol.atoms]
    totalMass = 0
    for atom in mol:
        m = 1
        if options.useweights:
            m = atom.atomicmass
        masses.append(m)
        totalMass += m
    
    coordinates = numpy.array(coordinates)
    masses = numpy.array(masses)
    trans = -numpy.sum(coordinates * masses[:, numpy.newaxis], axis=0) / totalMass
    mol.OBMol.Translate(openbabel.vector3(*trans))
    coordinates += trans
    #this is shamelessly stolen from the mdanalysis package
    inertia = calcI(masses, coordinates)

    eigenval, eigenvec = eig(inertia)
        # Sort
    indices = numpy.argsort(eigenval)
        # Return transposed in more logical form. See Issue 33.
    principalAxes = eigenvec[:,indices].T
    if det(principalAxes) < 0:
        principalAxes = -principalAxes #remove reflection !!Is this correct?? Kabasch wiki says negate just one row, but this is Kabasch...

    xrot = openbabel.double_array([1,0,0,0,-1,0,0,0,-1])
    yrot = openbabel.double_array([-1,0,0,0,1,0,0,0,-1])
    zrot = openbabel.double_array([-1,0,0,0,-1,0,0,0,1])
    ident = openbabel.double_array([1,0,0,0,1,0,0,0,1])
    
    rotmat = openbabel.double_array(principalAxes.flatten())
    mol.OBMol.Rotate(rotmat)

    coordinates = [ a.coords for a in mol.atoms] #should be modified
    (a,b) = calcSplitMoments(coordinates, 1)
    if(a < b):
        mol.OBMol.Rotate(xrot)
#    print a,b
    (a,b) = calcSplitMoments(coordinates, 0)
    if(a < b):
        mol.OBMol.Rotate(yrot)  
#    print a,b
    return
Ejemplo n.º 5
0
def set_xyz(x,coords):
    """
    Parameters:
    mol : Open babel mol object, or anything that can be converted to mol object with get_mol.
    coords : One-d array of natom floats
    """
    mol = get_mol(x)
    mol.OBMol.SetCoordinates(openbabel.double_array(coords))
    return mol
Ejemplo n.º 6
0
 def rotate(mol, theta, phi):
     m_theta = np.array([[1.0, 0.0, 0.0],
                         [0.0, math.cos(theta), -math.sin(theta)],
                         [0.0, math.sin(theta), math.cos(theta)]])
     m_phi = np.array([[math.cos(phi), 0.0, math.sin(phi)],
                       [0.0, 1.0, 0.0],
                       [-math.sin(phi), 0.0, math.cos(phi)]])
     m = np.dot(m_phi, m_theta)
     m_list = list(itertools.chain(*m))
     mol.Rotate(ob.double_array(m_list))
     return mol
Ejemplo n.º 7
0
def shiftAndCalculateReactionCoordinate(
        mol,
        nOfAtoms,
        reactionCoordinate,
        vector,
        h,
        coords=None):  # this function is called many times
    if coords == None:
        tmp = openbabel.doubleArray_frompointer(mol.GetCoordinates())
        coords = [tmp[i] for i in xrange(3 * nOfAtoms)]
    coords = addVec(coords, multVec(h, vector))
    mol.SetCoordinates(openbabel.double_array(coords))
    return reactionCoordinate(mol)
Ejemplo n.º 8
0
    def AndersenIntegrator(self,mol,relevantCoordinates,ff,h,reactionCoordinate,timeStep,timeStep2,nuTimesTimeStep):
        currCoords = self.coords[-1]
        currVelocity = self.velocity[-1]
        currAcc = self.acceleration[-1]
        
        # calculating next position:  
        nextCoords = self.nOfAtomsX3*[0]
        for i in xrange(self.nOfAtomsX3):
            nextCoords[i] = currCoords[i] + timeStep*currVelocity[i] + currAcc[i]*timeStep2/2 # nie jestem pewien tego currAcc
        
        for i in xrange(self.nOfAtomsX3):
            currVelocity[i] = currVelocity[i] + 0.5*timeStep*currAcc[i] # that's the ACTUAL currentVelocity
            
        mol.SetCoordinates( openbabel.double_array(nextCoords) )   
        energy = self.calculateGradU(ff,mol)
        gradKsi = calcGrad(mol,relevantCoordinates,reactionCoordinate,h)
        self.calculateZksi( gradKsi )
        
        Zksi = self.Zksi[-1]
        gradU = self.gradU[-1]
  
        if Zksi==0: constraintLambda = 0
        else: constraintLambda = (scalarTrippleProduct(self.invMasses,gradKsi,gradU)-calcVectorHessianVectorProduct(mol,reactionCoordinate,h,currVelocity)) / Zksi
        
        ###########################
        #constraintLambda = 0 # if set to 0 it will be a simple Andersen dynamics simulation
        ###########################

        currAcc = self.nOfAtomsX3*[0]                                
        for i in xrange(self.nOfAtomsX3):
            currAcc[i] = (-gradU[i] + constraintLambda*gradKsi[i])/self.masses[i] # TODO: upewnij sie, ze tu jest dzielenie przez mase
            
        # second velocity half-step
        for i in xrange(self.nOfAtomsX3):
            currVelocity[i] = currVelocity[i] + 0.5*timeStep*currAcc[i] # that's the ACTUAL currentVelocity

        # Andersen thermostat
        for i in xrange(self.nOfAtoms):
            if random.random()<nuTimesTimeStep:
                for j in xrange(3): currVelocity[3*i+j] = random.gauss(0,self.AndersenSigmas[3*i+j])
                       
        self.setNonVelocityAtribute(self.coords,nextCoords)
        self.setNonVelocityAtribute(self.acceleration,currAcc)
        self.setNonVelocityAtribute(self.gradU,gradU)
        self.velocity[3] = currVelocity  
        
        return energy
Ejemplo n.º 9
0
def make_structure(request):
    def makeResidue(mol, idx, aaatoms):
        res = mol.NewResidue()
        res.SetNum(idx)
        for atom in ob.OBMolAtomIter(mol):
            if atom.GetIdx() not in aaatoms:
                res.AddAtom(atom)

    aminoacids = request.GET.getlist("as")
    color = request.GET.get("rescol", "#3EC1CD")

    mol = ob.OBMol()
    conv = ob.OBConversion()
    pattern = ob.OBSmartsPattern()
    pattern.Init("[NX3][$([CX4H1]([*])),$([CX4H2])][CX3](=[OX1])[OX2]")
    builder = ob.OBBuilder()
    conv.SetInAndOutFormats("sdf", "svg")
    conv.AddOption("d", ob.OBConversion.OUTOPTIONS)
    conv.AddOption("b", ob.OBConversion.OUTOPTIONS, "none")
    conv.ReadString(mol, str(Substrate.objects.get(pk=int(aminoacids[0])).structure))
    pattern.Match(mol)
    mollist = pattern.GetUMapList()[0]
    oatom = mol.GetAtom(mollist[4])
    catom = mol.GetAtom(mollist[2])
    firstnatom = mol.GetAtom(mollist[0])
    makeResidue(mol, 0, mollist)

    i = 1
    for aa in aminoacids[1:]:
        mol2 = ob.OBMol()
        conv.ReadString(mol2, str(Substrate.objects.get(pk=int(aa)).structure))
        pattern.Match(mol2)
        mollist = pattern.GetUMapList()[0]
        makeResidue(mol2, i, mollist)

        molnatoms = mol.NumAtoms()
        mol += mol2

        natom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[0]).GetIdx())

        builder.Connect(mol, catom.GetIdx(), natom.GetIdx())

        foatom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[4]).GetIdx())
        catom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[2]).GetIdx())
        mol.DeleteHydrogens(oatom)
        mol.DeleteAtom(oatom)

        natom.SetImplicitValence(3)
        mol.DeleteHydrogens(natom)
        mol.AddHydrogens(natom)
        oatom = foatom

        i += 1

    nidx = firstnatom.GetIdx()
    oidx =  oatom.GetIdx()
    builder.Build(mol)
    natom = mol.GetAtom(nidx)
    oatom = mol.GetAtom(oidx)
    for res in ob.OBResidueIter(mol):
        for atom in ob.OBResidueAtomIter(res):
            for bond in ob.OBAtomBondIter(atom):
                data = ob.OBPairData()
                data.SetAttribute("color")
                data.SetValue(color)
                bond.CloneData(data)
    mol.DeleteHydrogens()
    gen2d = ob.OBOp.FindType("gen2d")
    gen2d.Do(mol)

    opp = oatom.GetY() - natom.GetY()
    adj = oatom.GetX() - natom.GetX()
    angle = abs(math.atan(opp / adj))
    if opp > 0 and adj > 0:
        pass
    elif opp > 0 and adj < 0:
        angle = math.pi - angle
    elif opp < 0 and adj < 0:
        angle = math.pi + angle
    elif opp < 0 and adj > 0:
        angle = 2 * math.pi - angle
    angle = -angle
    mol.Rotate(ob.double_array([math.cos(angle), -math.sin(angle), 0,
                                math.sin(angle), math.cos(angle),  0,
                                0,               0,                1]))
    svg = conv.WriteString(mol)
    # need to get rid of square aspect ratio
    delstart = svg.find("width")
    delend = svg.find("svg", delstart)
    delend = svg.find("viewBox", delend)
    svgend = svg.rfind("</g>")
    svg = svg[0:delstart] + svg[delend:svgend]
    return HttpResponse(svg, mimetype="image/svg+xml")
Ejemplo n.º 10
0
    # generate .top and write
    fcontent = gen_top(args.force_field,
                       os.path.splitext(args.dfrfile)[0] + ".itp")
    with open("topology.top", "w") as f:
        f.write(fcontent)

    # get the molecule diameter
    mol.OBMol.Center()
    maxd = 0.0
    for atom in mol:
        x, y, z = atom.coords
        r = sqrt(x * x + y * y + z * z)
        if r > maxd:
            maxd = r

    # modify the unit cell and translate the molecule to the center of box
    boxsize = maxd + 100.0
    cell = openbabel.OBUnitCell()
    cell.SetData(boxsize, boxsize, boxsize, 90.0, 90.0, 90.0)
    mol.OBMol.CloneData(cell)

    disp = boxsize / 2.0
    arr = openbabel.vector3(openbabel.double_array([disp, disp, disp]))
    mol.OBMol.Translate(arr)

    # write .gro
    mol.write("gro",
              os.path.splitext(args.txtfile)[0] + ".gro",
              overwrite=True)
Ejemplo n.º 11
0
    def AndersenIntegrator(self, mol, relevantCoordinates, ff, h,
                           reactionCoordinate, timeStep, timeStep2,
                           nuTimesTimeStep):
        currCoords = self.coords[-1]
        currVelocity = self.velocity[-1]
        currAcc = self.acceleration[-1]

        # calculating next position:
        nextCoords = self.nOfAtomsX3 * [0]
        for i in xrange(self.nOfAtomsX3):
            nextCoords[
                i] = currCoords[i] + timeStep * currVelocity[i] + currAcc[
                    i] * timeStep2 / 2  # nie jestem pewien tego currAcc

        for i in xrange(self.nOfAtomsX3):
            currVelocity[i] = currVelocity[i] + 0.5 * timeStep * currAcc[
                i]  # that's the ACTUAL currentVelocity

        mol.SetCoordinates(openbabel.double_array(nextCoords))
        energy = self.calculateGradU(ff, mol)
        gradKsi = calcGrad(mol, relevantCoordinates, reactionCoordinate, h)
        self.calculateZksi(gradKsi)

        Zksi = self.Zksi[-1]
        gradU = self.gradU[-1]

        if Zksi == 0: constraintLambda = 0
        else:
            constraintLambda = (
                scalarTrippleProduct(self.invMasses, gradKsi, gradU) -
                calcVectorHessianVectorProduct(mol, reactionCoordinate, h,
                                               currVelocity)) / Zksi

        ###########################
        #constraintLambda = 0 # if set to 0 it will be a simple Andersen dynamics simulation
        ###########################

        currAcc = self.nOfAtomsX3 * [0]
        for i in xrange(self.nOfAtomsX3):
            currAcc[i] = (
                -gradU[i] + constraintLambda * gradKsi[i]) / self.masses[
                    i]  # TODO: upewnij sie, ze tu jest dzielenie przez mase

        # second velocity half-step
        for i in xrange(self.nOfAtomsX3):
            currVelocity[i] = currVelocity[i] + 0.5 * timeStep * currAcc[
                i]  # that's the ACTUAL currentVelocity

        # Andersen thermostat
        for i in xrange(self.nOfAtoms):
            if random.random() < nuTimesTimeStep:
                for j in xrange(3):
                    currVelocity[3 * i + j] = random.gauss(
                        0, self.AndersenSigmas[3 * i + j])

        self.setNonVelocityAtribute(self.coords, nextCoords)
        self.setNonVelocityAtribute(self.acceleration, currAcc)
        self.setNonVelocityAtribute(self.gradU, gradU)
        self.velocity[3] = currVelocity

        return energy
Ejemplo n.º 12
0
def align_ligand(dummies, ligand):
  # fit dummy atoms of ligand to defined positions
  log.info('Aligning ligand dummy atoms to desired dummy atoms...')

  # 0.9 create local copy, as this function would otherwise modify the given ligand 
  aligned_ligand = openbabel.OBMol(ligand)
  
  # 1.0 get dummy atoms from ligand
  log.debug('... get dummy atoms of ligand')
  ligand_dummies = get_dummies(ligand)
  
  # 1.1 get translation vector from read-in position to origin
  log.info('... determing translation vector from read-in to origin')
  translation = ligand_dummies.Center(1)
  
  ## DEBUG
  #obconversion = openbabel.OBConversion()
  #obconversion.SetOutFormat("pdb")
  #obconversion.WriteFile(ligand_dummies,"ligand_dummies_centered.pdb")
  
  # 1.2 initialize OBAlign for alignment to final destination
  log.info('... doing the alignment for dummy atoms')
  aligner = openbabel.OBAlign(dummies, ligand_dummies)
  success=aligner.Align()
  
  if success == False:
    return None, None
    
  #log.info('... done.')
  rmsd=aligner.GetRMSD()
  log.debug('RMSD of alignment: ' + str(rmsd))

  ## 1.2.1 get Rotation Matrix for alignment 
  log.info('... determining the rotation matrix')
  rotation_matrix = aligner.GetRotMatrix()
  rot = openbabel.double_array([1,2,3,4,5,6,7,8,9])
  rotation_matrix.GetArray(rot)
  
  # .. only for debugging:
  arewedebugging = log.getLogger()
  if arewedebugging.isEnabledFor(logging.DEBUG):
    log.debug('--- rotation matrix ---')
    for i in range(0,9): log.debug(str(i)+ " : " + str(rot[i]))

  # 1.3 generate positioning vector 
  ## NB: centering would not work because of rotation!!
  ## update cooordinates to new value
  aligner.UpdateCoords(ligand_dummies)
  log.info('... generating positioning vector')
  positioning = openbabel.vector3()
  ## calculate the vector for positioning to destination
  n = 0
  for atom in openbabel.OBMolAtomIter(ligand_dummies):
    n += 1
    positioning += atom.GetVector()
  positioning /= n 

  # 1.4 move all ligand atoms to fit the pose the dummy atoms have been aligned to
  
  ## 1.4.1 generate inverted translation vector to translate ligand to origin
  translation_to_origin = translation
  translation_to_origin *= -1

  ## 1.4.2 generate inverted rotation matrix to reconstruct alignment results
  rotation_inversion = rotation_matrix.transpose()
  rot_inv = openbabel.double_array([1,2,3,4,5,6,7,8,9])
  rotation_inversion.GetArray(rot_inv)
    
  ## 1.4.3 apply translation to origin, rotation, and translation to final destination
  aligned_ligand.Translate(translation_to_origin)
  aligned_ligand.Rotate(rot_inv)
  aligned_ligand.Translate(positioning)
  
  ## 1.5 clean output ligand of dummy atoms, if desired
  if remove_dummies:
    log.info('Cleaning the ligand of unwanted dummies...')
    _temp_atom = []
    for atom in openbabel.OBMolAtomIter(aligned_ligand):
      #aligned_ligand.AddResidue(atom.GetResidue())
      #aligned_ligand.AddAtom(atom)
      if atom.GetAtomicNum() == 0:
	_temp_atom.append(atom)
    for a in _temp_atom:
      aligned_ligand.DeleteAtom(a)
  #else:
    #aligned_ligand = ligand

  log.info('... returning the aligned ligand.')
  return aligned_ligand, rmsd
Ejemplo n.º 13
0
print "x=%f; y=%f; z=%f" % (natom.GetX(), natom.GetY(), natom.GetZ())
print "x=%f; y=%f; z=%f" % (oatom.GetX(), oatom.GetY(), oatom.GetZ())

opp = oatom.GetY() - natom.GetY()
adj = oatom.GetX() - natom.GetX()
angle = abs(math.atan(opp / adj))
if opp > 0 and adj > 0:
    pass
elif opp > 0 and adj < 0:
    angle = math.pi - angle
elif opp < 0 and adj < 0:
    angle = math.pi + angle
elif opp < 0 and adj > 0:
    angle = 2 * math.pi - angle
print math.degrees(angle)
angle = -angle
mol.Rotate(ob.double_array([math.cos(angle), -math.sin(angle), 0,
                            math.sin(angle), math.cos(angle),  0,
                            0,               0,                1]))

svg = conv.WriteString(mol)
# need to get rid of square aspect ratio
delstart = svg.find("width")
delend = svg.find("svg", delstart)
delend = svg.find("viewBox", delend)
svgend = svg.rfind("</g>")
svg = svg[0:delstart] + svg[delend:svgend]
outf = file("test.svg", "w")
outf.write(svg)
outf.close()