Skip to content

Commit

Permalink
Merge pull request #185 from metrumresearchgroup/develop
Browse files Browse the repository at this point in the history
release 2.3.0 merging to master
  • Loading branch information
shairozan authored Sep 10, 2020
2 parents c607c86 + 0907950 commit d1dd901
Show file tree
Hide file tree
Showing 20 changed files with 666 additions and 220 deletions.
18 changes: 16 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ steps:
- if [ -d /tmp/${DRONE_BUILD_NUMBER}/babylontest ] ; then rm -rf /tmp/${DRONE_BUILD_NUMBER}/babylontest; fi
- name: Build Babylon
commands:
- mkdir -p /tmp/${DRONE_BUILD_NUMBER} ; git rev-parse HEAD > /tmp/${DRONE_BUILD_NUMBER}/bbi_hash
- go build -o bbi cmd/bbi/main.go
- ./bbi version
- name: Get BabylonTest
Expand All @@ -30,7 +31,15 @@ steps:
commands:
- git clone https://github.com/metrumresearchgroup/babylontest.git /tmp/${DRONE_BUILD_NUMBER}/babylontest
- cd /tmp/${DRONE_BUILD_NUMBER}/babylontest
- mkdir -p /tmp/${DRONE_BUILD_NUMBER} ; git rev-parse HEAD > /tmp/${DRONE_BUILD_NUMBER}/babylontest_hash
- if [ ! -z $BABYLONTEST_BRANCH ]; then git checkout $BABYLONTEST_BRANCH; fi
- name: Copy commit hashes to s3
commands:
- printf "[\n" > /tmp/${DRONE_BUILD_NUMBER}/commits.json
- printf " {\"repo\":\"metrumresearchgroup/babylon\", \"commit\":\"$(cat /tmp/${DRONE_BUILD_NUMBER}/bbi_hash)\"},\n" >> /tmp/${DRONE_BUILD_NUMBER}/commits.json
- printf " {\"repo\":\"metrumresearchgroup/babylontest\", \"commit\":\"$(cat /tmp/${DRONE_BUILD_NUMBER}/babylontest_hash)\"}\n" >> /tmp/${DRONE_BUILD_NUMBER}/commits.json
- printf "]\n" >> /tmp/${DRONE_BUILD_NUMBER}/commits.json
- aws s3 cp /tmp/${DRONE_BUILD_NUMBER}/commits.json s3://mrg-validation/babylon/${DRONE_BUILD_NUMBER}/commits.json
- name: Test
environment:
<<: *sge_environment
Expand All @@ -57,9 +66,13 @@ steps:
- cd /tmp/${DRONE_BUILD_NUMBER}/babylontest
- export ROOT_EXECUTION_DIR=/data/${DRONE_BUILD_NUMBER}
- export BABYLON_GRID_NAME_PREFIX="drone_${DRONE_BUILD_NUMBER}"
#Run test suite and copy results to s3
- bbi init --dir /opt/NONMEM
- go test ./... -v --json --timeout 30m | tee test_output.json
- go test ./... -v --json -timeout 30m | tee test_output.json
- aws s3 cp test_output.json s3://mrg-validation/babylon/${DRONE_BUILD_NUMBER}/results.json
#Check for test failures and clean up
- chmod +x failure_detector.sh
- ./failure_detector.sh test_output.json
- rm -rf /data/${DRONE_BUILD_NUMBER}
- rm -rf /tmp/${DRONE_BUILD_NUMBER}/babylontest
- name: Cleanup on failure
Expand Down Expand Up @@ -102,7 +115,8 @@ steps:
- mkdir testoutput
- mkdir rendered
- aws s3 cp s3://mrg-validation/babylon/${DRONE_BUILD_NUMBER}/results.json testoutput/results.json
- ./gpv --scenarioFile validation.json --testsDirectory testoutput --outputDirectory rendered
- aws s3 cp s3://mrg-validation/babylon/${DRONE_BUILD_NUMBER}/commits.json commits.json
- ./gpv --scenarioFile validation.json --commitsFile commits.json --testsDirectory testoutput --outputDirectory rendered
- aws s3 cp rendered/specification.md s3://mrg-validation/babylon/${DRONE_TAG}/specification.md
- aws s3 cp rendered/testing_and_validation.md s3://mrg-validation/babylon/${DRONE_TAG}/testing_and_validation.md
- aws s3 cp rendered/traceability_matrix.md s3://mrg-validation/babylon/${DRONE_TAG}/traceability_matrix.md
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
.idea
dist
babylon.log
babylon.yaml
babylon.yaml
main
55 changes: 55 additions & 0 deletions cmd/covcor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright © 2016 Devin Pastoor <[email protected]>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"encoding/json"
"fmt"
parser "github.com/metrumresearchgroup/babylon/parsers/nmparser"
log "github.com/sirupsen/logrus"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const covcorLongDescription string = `load .cov and .cor output from model(s), for example:
bbi nonmem covcor run001/run001
bbi nonmem covcor run001/run001.cov
`
// runCmd represents the run command
var covcorCmd = &cobra.Command{
Use: "covcor",
Short: "load .cov and .cor output from a model run",
Long: covcorLongDescription,
Run: covcor,
}

func covcor(cmd *cobra.Command, args []string) {
if debug {
viper.Debug()
}

results, err := parser.GetCovCorOutput(args[0])
if err != nil {
log.Fatal(err)
}

jsonRes, _ := json.MarshalIndent(results, "", "\t")
fmt.Printf("%s\n", jsonRes)

}
func init() {
nonmemCmd.AddCommand(covcorCmd)
}
11 changes: 4 additions & 7 deletions cmd/nonmem.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,21 +167,18 @@ type NonMemModel struct {
Error error `json:"error"`
}

var nonmemLongDescription string = fmt.Sprintf("\n%s\n\n%s\n\n%s\n", runLongDescription, summaryLongDescription, covcorLongDescription)

// RunCmd represents the run command
var nonmemCmd = &cobra.Command{
Use: "nonmem",
Short: "nonmem a (set of) models locally or on the grid",
Long: `run nonmem model(s), for example:
bbi nonmem <local|sge> run001.mod
bbi nonmem --clean_lvl=1 <local|sge> run001.mod run002.mod
bbi nonmem run <local|sge> [001:006].mod // expand to run001.mod run002.mod ... run006.mod local
bbi nonmem run <local|sge> .// run all models in directory
`,
Long: nonmemLongDescription,
Run: nonmem,
}

func nonmem(cmd *cobra.Command, args []string) {
println(runLongDescription)
println(nonmemLongDescription)
}

func init() {
Expand Down
11 changes: 0 additions & 11 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ var (
//Json indicates whether we should have a JSON tree of output
Json bool
preview bool
noExt bool
noGrd bool
noCov bool
noCor bool
noShk bool
executionWaitGroup sync.WaitGroup
)

Expand Down Expand Up @@ -98,12 +93,6 @@ func init() {
RootCmd.PersistentFlags().BoolVar(&Json, "json", false, "json tree of output, if possible")
viper.BindPFlag("json", RootCmd.PersistentFlags().Lookup("json")) //Bind to viper
RootCmd.PersistentFlags().BoolVarP(&preview, "preview", "p", false, "preview action, but don't actually run command")
//Used for Summary
RootCmd.PersistentFlags().BoolVarP(&noExt, "no-ext-file", "", false, "do not use ext file")
RootCmd.PersistentFlags().BoolVarP(&noGrd, "no-grd-file", "", false, "do not use grd file")
RootCmd.PersistentFlags().BoolVarP(&noCov, "no-cov-file", "", false, "do not use cov file")
RootCmd.PersistentFlags().BoolVarP(&noCor, "no-cor-file", "", false, "do not use cor file")
RootCmd.PersistentFlags().BoolVarP(&noShk, "no-shk-file", "", false, "do not use shk file")
}

// initConfig reads in config file and ENV variables if set.
Expand Down
133 changes: 123 additions & 10 deletions cmd/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,153 @@ package cmd
import (
"encoding/json"
"fmt"

parser "github.com/metrumresearchgroup/babylon/parsers/nmparser"
log "github.com/sirupsen/logrus"
"os"
"runtime"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var summaryTree bool
var (
summaryTree bool
noExt bool
noGrd bool
noShk bool
extFile string
)
const summaryLongDescription string = `summarize model(s), for example:
bbi nonmem summary run001/run001
bbi nonmem summary run001/run001.lst
bbi nonmem summary run001/run001.res
`

// runCmd represents the run command
var summaryCmd = &cobra.Command{
Use: "summary",
Short: "summarize the output of a model",
Long: `run model(s), for example:
nmu summarize run001.lst
`,
Short: "summarize the output of model(s)",
Long: summaryLongDescription,
Run: summary,
}

type jsonResults struct {
Results []parser.SummaryOutput
Errors []error
}

func summary(cmd *cobra.Command, args []string) {
if debug {
viper.Debug()
}
if len(args) == 1 {
results, err := parser.GetModelOutput(args[0], parser.NewModelOutputFile(extFile, noExt), !noGrd, !noShk, )
if err != nil {
log.Fatal(err)
}
if Json {
jsonRes, _ := json.MarshalIndent(results, "", "\t")
fmt.Printf("%s\n", jsonRes)
} else {
results.Summary()
}
return
}

// if we are going to parse multiple models, we need to reasonably handle failures. The objective
// will be to always return a json object if its json, and if not, error as soon as it hits a printed issue.
// As such, the idea will be to store results such they can be filtered
type result int
const (
SUCCESS result = 1
ERROR = 2
)
type modelResult struct {
Index int
Outcome result
Err error
Result parser.SummaryOutput
}

workers := runtime.NumCPU()
if workers < 4 {
workers = 4
}

results := parser.GetModelOutput(args[0], verbose, noExt, noGrd, noCov, noCor, noShk)
numModels := len(args)
if workers > numModels {
workers = numModels
}
models := make(chan int, numModels)
results := make(chan modelResult, numModels)
orderedResults := make([]modelResult, numModels)
var modelResults jsonResults

for w := 1; w <= workers; w++ {
go func(w int, modIndex <-chan int, results chan<- modelResult) {
for i := range modIndex {
r, err := parser.GetModelOutput(args[i], parser.NewModelOutputFile(extFile, noExt), !noGrd, !noShk, )
if err != nil {
results <- modelResult{
Index: i,
Outcome: ERROR,
Err: err,
Result: r,
}
} else {
results <- modelResult{
Index: i,
Outcome: SUCCESS,
Err: err,
Result: r,
}
}
}
}(w, models, results)
}
for m := 0; m < numModels; m++ {
models <- m
}
close(models)
for r := 0; r < numModels; r++ {
res := <-results
orderedResults[res.Index] = res
}
for _, res := range orderedResults {
if res.Outcome == SUCCESS {
modelResults.Results = append(modelResults.Results, res.Result)
} else if res.Outcome == ERROR {
modelResults.Errors = append(modelResults.Errors, res.Err)
}
}
if Json {
jsonRes, _ := json.MarshalIndent(results, "", "\t")
jsonRes, _ := json.MarshalIndent(modelResults, "", "\t")
fmt.Printf("%s\n", jsonRes)
} else {
results.Summary()
return
}


// not json lets print all successful models first then any errors
for i, res := range modelResults.Results {
res.Summary()
// add some spacing between models
if i != len(modelResults.Results) -1 {
fmt.Println("")
fmt.Println("")
}
}
for _, res := range modelResults.Errors {
log.Error(res)
}
if len(modelResults.Errors) > 0 {
os.Exit(1)
}
}
func init() {
nonmemCmd.AddCommand(summaryCmd)
//Used for Summary
summaryCmd.PersistentFlags().BoolVar(&noExt, "no-ext-file", false, "do not use ext file")
summaryCmd.PersistentFlags().BoolVar(&noGrd, "no-grd-file", false, "do not use grd file")
summaryCmd.PersistentFlags().BoolVar(&noShk, "no-shk-file", false, "do not use shk file")
summaryCmd.PersistentFlags().StringVar(&extFile, "ext-file", "", "name of custom ext-file")
}
Binary file removed main
Binary file not shown.
Loading

0 comments on commit d1dd901

Please sign in to comment.