-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmol_output.go
115 lines (108 loc) · 3.19 KB
/
mol_output.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
* mol_output.go, part of Bartender
*
*
*
* Copyright 2023 Raul Mera <rmeraa{at}academicos(dot)uta(dot)cl>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
*/
package main
import (
"fmt"
"strings"
chem "github.com/rmera/gochem"
"github.com/rmera/gochem/traj/dcd"
v3 "github.com/rmera/gochem/v3"
)
func MakePDB(coord *v3.Matrix, mol *chem.Molecule, beads []BeadCoord) {
nvsites := NVsites(beads)
binterval := 100.0 / (float64(len(beads)) - float64(nvsites))
bfacs := make([]float64, mol.Len())
for i, _ := range bfacs {
bfacs[i] = -1
}
mol2 := chem.NewTopology(0, 1, nil)
vsitesread := 0
var vscoord *v3.Matrix
if nvsites > 0 {
vscoord = v3.Zeros(nvsites)
}
finalcoord := v3.Zeros(coord.NVecs() + nvsites)
for i := 0; i < mol.Len(); i++ {
mol2.AppendAtom(mol.Atom(i))
}
for i, v := range beads {
c, in := v(coord, mol)
if in == nil {
vscoord.SetVecs(c, []int{vsitesread})
at := new(chem.Atom)
at.Symbol = "U"
at.Name = "U"
at.MolName = "VIR"
at.MolID = i + 1
mol2.AppendAtom(at)
bfacs = append(bfacs, 0.0) //This will fail if the virtual sites are not by the end of the beads slice.
vsitesread++
continue
}
for _, w := range in {
ifloat := float64(i)
at := mol.Atom(w)
at.MolID = i + 1
if bfacs[w] == -1 {
bfacs[w] = binterval * ifloat
} else {
bfacs[w] = (binterval*ifloat + bfacs[w]) / 2 //this is for atoms that are shared among beads. It will only help if the sharing beads come one after the other (say, if the atom is shared between beads 7 and 8, but not if the sharing beads are 8 and 10.
}
}
}
if vscoord != nil {
finalcoord.Stack(coord, vscoord)
chem.PDBFileWrite("Beads.pdb", finalcoord, mol2, bfacs)
return
}
chem.PDBFileWrite("Beads.pdb", coord, mol2, bfacs)
}
// Saves the multi-xyz trajectory in the file trajname to a DCD trajectory in the file fname.
// Since this is not really needed, it doesn't panic. Will just return an error to be printed by main.
func DCDSave(fname, trajname string) error {
if !strings.Contains(trajname, ".trj") {
return fmt.Errorf("Option only available for multi-xyz trajectories, such as those produced by xtb")
}
mol, err := chem.XYZFileRead(trajname)
if err != nil {
return err
}
dcd, err := dcd.NewWriter(fname, mol.Len())
coord := v3.Zeros(mol.Len())
for {
err = mol.Next(coord)
if err != nil {
break
}
err = dcd.WNext(coord)
if err != nil {
return err
}
}
if _, ok := err.(chem.LastFrameError); ok { //just means we read the whole thing.
return nil
}
return err
}