forked from jmwoll/goccs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
goccs.go
124 lines (118 loc) · 4.5 KB
/
goccs.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
116
117
118
119
120
121
122
123
124
package main
// Copyright (C) 2017-2018 Jan Wollschläger <[email protected]>
// This file is part of goccs.
//
// goccs is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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, see <http://www.gnu.org/licenses/>.
import (
"flag"
"fmt"
)
func main() {
defaultStr := "unset"
approximationPtr := flag.String("approximation", "PA", "The approximation to use: Must be either 'PA' or 'EHS' (defaults to 'PA')")
xyzfilePtr := flag.String("xyzfile", defaultStr, "The xyzfile for which to calculate the CCS (alternatively, the xyzstring may be specified).")
xyzstringPtr := flag.String("xyzstring", defaultStr, "The xyzstring for which to calculate the CCS (alternatively, the xyzfile may be specified.)")
numrotamersPtr := flag.Int("num_rotamers", 0, "The number of rotamers to consider (defaults to '3000')")
trialsperrotamerPtr := flag.Int("trials_per_rotamer", 0, "The number of trials per rotamer (defaults to '10000' for PA and '10000' for EHS)")
parameters := flag.String("parameters", "siu_guo_2010", "The parameters to use. Either one of ['siu_guo_2010','mobcal'] or a JSON, e.g.:\n {'H': 1.23, 'C': 2.34, 'O': 3.45}")
processesPtr := flag.Int("processes", 10, "The number of processes to use (defaults to 10).")
processDetails := flag.Bool("process details", false, "Prints the CCS of each process.")
flag.Parse()
if *approximationPtr == "PA" {
fmt.Println("The projection approximation (PA) will be used for CCS calculations.")
} else {
if *approximationPtr == "EHS" {
fmt.Println("The exact hard sphere scattering approximation (EHS) will be used for CCS calculations.")
} else {
panic("unknown CCS approximation method must be one of ['PA','EHS']")
}
}
if *xyzfilePtr == defaultStr && *xyzstringPtr == defaultStr {
panic("Either xyzfile or xyzstring must be specified (at least one must be set).")
}
if *xyzfilePtr != defaultStr && *xyzstringPtr != defaultStr {
panic("Either xyzfile or xyzstring must be specified (not both).")
}
if *xyzfilePtr != defaultStr {
fmt.Println()
fmt.Print("the contents will be read from the xyzfile:")
fmt.Println(*xyzfilePtr)
}
if *xyzstringPtr != defaultStr {
fmt.Println()
fmt.Print("the contents will be read from the string:")
fmt.Println(*xyzstringPtr)
}
if *numrotamersPtr == 0 {
*numrotamersPtr = 3000
}
if *trialsperrotamerPtr == 0 {
if *approximationPtr == "PA" {
*trialsperrotamerPtr = 10000
} else {
*trialsperrotamerPtr = 10000
}
}
var loadedParams ParameterSet
if *parameters == "mobcal" || *parameters == "siu_guo_2010" {
if *approximationPtr == "EHS" {
loadedParams = EHSParametersforname(*parameters)
} else {
loadedParams = PAParametersforname(*parameters)
}
} else {
loadedParams = JSONtoParameterSet(*parameters)
}
var mol Molecule
if *xyzstringPtr != defaultStr {
mol = Loadxyzstring(*xyzstringPtr)
} else {
mol = Loadxyzfile(*xyzfilePtr)
}
if *processesPtr == 1 {
ccs := 0.0
if *approximationPtr == "PA" {
ccs = PACCS(mol, *trialsperrotamerPtr, *numrotamersPtr, loadedParams)
} else {
ccs = EHSCCS(mol, *trialsperrotamerPtr, *numrotamersPtr, loadedParams)
}
fmt.Println(ccs)
} else {
ccsChan := make(chan float64)
for i := 0; i < (*processesPtr); i++ {
if *approximationPtr == "PA" {
go parallelPACCS(mol, *trialsperrotamerPtr, (*numrotamersPtr)/(*processesPtr), loadedParams, ccsChan)
} else {
go parallelEHSCCS(mol, *trialsperrotamerPtr, (*numrotamersPtr)/(*processesPtr), loadedParams, ccsChan)
}
}
ccs := 0.0
for i := 0; i < (*processesPtr); i++ {
ccsChanVal := <-ccsChan
if *processDetails {
fmt.Print("->")
fmt.Println(ccsChanVal)
}
ccs += ccsChanVal
}
ccs = ccs / float64(*processesPtr)
fmt.Println(ccs)
}
}
func parallelPACCS(mol Molecule, trialperrot int, numrot int, params ParameterSet, ccsChan chan float64) {
ccsChan <- PACCS(mol, trialperrot, numrot, params)
}
func parallelEHSCCS(mol Molecule, trialperrot int, numrot int, params ParameterSet, ccsChan chan float64) {
ccsChan <- EHSCCS(mol, trialperrot, numrot, params)
}