Initial Commit with 4.2 Version of Drug Bank Data

This commit is contained in:
Sarah Jamie Lewis 2019-10-27 18:45:04 -07:00
commit 4c4c9dace8
6 changed files with 231 additions and 0 deletions

1
drugs.4.2.db Normal file

File diff suppressed because one or more lines are too long

92
drugs.go Normal file
View File

@ -0,0 +1,92 @@
package drugs
import (
"encoding/json"
"github.com/sahilm/fuzzy"
"io/ioutil"
"strings"
)
type DrugInteraction struct {
ID string
}
type PathWay struct {
ID string
Drugs []string
}
type Salt struct {
ID string
Name string
}
type DrugDatabase struct {
drugs []DrugInfo
index map[string]int
keys []string
}
type Classification struct {
Description string
DirectParent string
Kingdom string
SuperClass string
Class string
SubClass string
}
type DrugInfo struct {
ID string
Name string
DrugType string
HalfLife string
Description string
Classification Classification
Indication string
Toxicity string
MechanismOfAction string
Pharmacodynamics string
Absorption string
Interactions []DrugInteraction
Salts []Salt
Groups map[string]bool
Pathways []PathWay
}
func (dd * DrugDatabase) generateIndex() {
dd.index = make(map[string]int)
for i,drug := range dd.drugs {
dd.index[strings.ToLower(drug.ID)] = i
dd.index[strings.ToLower(drug.Name)] = i
dd.keys = append(dd.keys, strings.ToLower(drug.ID))
dd.keys = append(dd.keys, strings.ToLower(drug.Name))
}
}
func (dd * DrugDatabase) Lookup(query string) (DrugInfo) {
index,ok := dd.index[strings.ToLower(query)]
if ok {
return dd.drugs[index]
}
matches := fuzzy.Find(query, dd.keys)
for _,match := range matches {
return dd.drugs[dd.index[match.Str]]
}
return DrugInfo{}
}
func LoadDatabaseJSON(path string) DrugDatabase {
data,err := ioutil.ReadFile(path)
if err == nil {
var db []DrugInfo
err := json.Unmarshal(data, &db)
if err == nil {
var ddb DrugDatabase
ddb.drugs = db
ddb.generateIndex()
return ddb
}
}
return DrugDatabase{}
}

20
drugs_test.go Normal file
View File

@ -0,0 +1,20 @@
package drugs
import (
"testing"
)
func TestQueryDatabase(t *testing.T) {
drugsdb := LoadDatabase("./drugbank.xml")
t.Logf("Query by ID: %v", drugsdb.QueryDatabaseByID("DB00083"))
t.Logf("Query by ID: %v", drugsdb.QueryDatabaseByName("Ibuprofen"))
for i := 50; i < 60; i++ {
t.Logf("Query by Name: %v", drugsdb.QueryDatabaseByIndex(i))
}
}
func TestQueryJson(t *testing.T) {
ddb := LoadDatabaseJSON("./drugs.4.2.db")
t.Logf("Query by ID: %v", ddb.Lookup("DB00083"))
t.Logf("Query by ID: %v", ddb.Lookup("ibupren"))
}

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module git.openprivacy.ca/sarah/sigil/cmd/sigilbot/drugs
go 1.12
require (
github.com/antchfx/xmlquery v1.1.0
github.com/antchfx/xpath v1.1.0 // indirect
github.com/sahilm/fuzzy v0.1.0
golang.org/x/net v0.0.0-20191027233614-53de4c7853b5 // indirect
)

12
go.sum Normal file
View File

@ -0,0 +1,12 @@
github.com/antchfx/xmlquery v1.1.0 h1:vj0kZ1y3Q6my4AV+a9xbWrMYzubw+84zuiKgvfV8vb8=
github.com/antchfx/xmlquery v1.1.0/go.mod h1:/+CnyD/DzHRnv2eRxrVbieRU/FIF6N0C+7oTtyUtCKk=
github.com/antchfx/xpath v1.1.0 h1:mJTvYpiHvxNQRD4Lbfin/FodHVCHh2a5KrOFr4ZxMOI=
github.com/antchfx/xpath v1.1.0/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20191027233614-53de4c7853b5 h1:IX2aat8xHKk1JAYuDPcTTEMfRaGQh2eHrTcrlp3KJi0=
golang.org/x/net v0.0.0-20191027233614-53de4c7853b5/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

96
xmldrugdatabase.go Normal file
View File

@ -0,0 +1,96 @@
package drugs
import (
"github.com/antchfx/xmlquery"
"os"
"strconv"
)
func LoadDatabase(path string) XMLDrugsDatabase {
f, err := os.Open(path)
if err == nil {
doc, err := xmlquery.Parse(f)
if err == nil {
return XMLDrugsDatabase{doc}
}
}
return XMLDrugsDatabase{}
}
func populate_druginfo(node *xmlquery.Node) (di DrugInfo) {
di.ID = node.SelectElement("drugbank-id").InnerText()
di.Name = node.SelectElement("name").InnerText()
di.HalfLife = node.SelectElement("half-life").InnerText()
di.Description = node.SelectElement("description").InnerText()
di.Indication = node.SelectElement("indication").InnerText()
di.Pharmacodynamics = node.SelectElement("pharmacodynamics").InnerText()
di.Toxicity = node.SelectElement("toxicity").InnerText()
di.Absorption = node.SelectElement("absorption").InnerText()
di.MechanismOfAction = node.SelectElement("mechanism-of-action").InnerText()
interactions := node.SelectElement("drug-interactions").SelectElements("drug-interaction")
for _, interaction := range interactions {
di.Interactions = append(di.Interactions, DrugInteraction{interaction.SelectElement("drugbank-id").InnerText()})
}
di.DrugType = node.SelectAttr("type")
classification := node.SelectElement("classification")
if classification != nil {
di.Classification = Classification{
classification.SelectElement("description").InnerText(),
classification.SelectElement("direct-parent").InnerText(),
classification.SelectElement("kingdom").InnerText(),
classification.SelectElement("superclass").InnerText(),
classification.SelectElement("class").InnerText(),
classification.SelectElement("subclass").InnerText()}
}
groups := node.SelectElement("groups").SelectElements("group")
di.Groups = make(map[string]bool)
for _, group := range groups {
di.Groups[group.InnerText()] = true
}
salts := node.SelectElement("salts").SelectElements("salt")
for _, salt := range salts {
di.Salts = append(di.Salts, Salt{salt.SelectElement("drugbank-id").InnerText(),
salt.SelectElement("name").InnerText()})
}
pathways := node.SelectElement("pathways").SelectElements("pathway")
for _, pathway := range pathways {
pathwaysdrugs := []string{}
drugs := pathway.SelectElement("drugs").SelectElements("drug")
for _,drug := range drugs {
pathwaysdrugs = append(pathwaysdrugs, drug.SelectElement("drugbank-id").InnerText())
}
di.Pathways = append(di.Pathways, PathWay{pathway.SelectElement("smpdb-id").InnerText(), pathwaysdrugs})
}
return
}
type XMLDrugsDatabase struct {
root *xmlquery.Node
}
func (dd XMLDrugsDatabase) QueryDatabaseByID(ID string) (di DrugInfo) {
result := xmlquery.FindOne(dd.root, "//drugbank/drug[./drugbank-id='"+ID+"']")
return populate_druginfo(result)
}
func (dd XMLDrugsDatabase) QueryDatabaseByIndex(index int) (di DrugInfo) {
result := xmlquery.FindOne(dd.root, "//drugbank/drug["+strconv.Itoa(index)+"]")
return populate_druginfo(result)
}
func (dd XMLDrugsDatabase) QueryDatabaseByName(name string) (di DrugInfo) {
result := xmlquery.Find(dd.root, "//drugbank/drug[./name='"+name+"']")
if len(result) < 1 {
return
}
return populate_druginfo(result[0])
}