diff --git a/dataset/dataset.go b/dataset/dataset.go index dffaf51..435edde 100644 --- a/dataset/dataset.go +++ b/dataset/dataset.go @@ -207,7 +207,10 @@ func (t *Target) SetupHaddock3Scenario(wd string, s input.Scenario) (runner.Job, } // Generate the run.toml file - it will handle the restraints - _, _ = t.WriteRunToml(sPath, s.Parameters.General, s.Parameters.Modules) + _, err := t.WriteRunToml(sPath, s.Parameters.General, s.Parameters.Modules) + if err != nil { + return runner.Job{}, err + } j := runner.Job{ ID: t.ID + "_" + s.Name, @@ -252,6 +255,12 @@ func (t *Target) WriteRunToml(projectDir string, general map[string]interface{}, } runTomlString += "]\n\n" + fnameArray := [][]string{ + t.Restraints, + t.Toppar, + t.MiscPDB, + } + // NOTE: THE ORDER OF THE MODULES IS IMPORTANT!! // Range over the modules in the order they are defined v := reflect.ValueOf(mod) @@ -282,27 +291,19 @@ func (t *Target) WriteRunToml(projectDir string, general map[string]interface{}, } runTomlString += "[" + m + "]\n" for k, v := range field.Interface().(map[string]interface{}) { + + // Find the file to be used as fname if strings.Contains(k, "_fname") { - // Identify the fname parameters based on the pattern, considering - // word boundaries - pattern := regexp.MustCompile(`\b` + v.(string) + `\b`) - - // Find the restraints that match the pattern - for _, r := range t.Restraints { - if pattern.MatchString(r) { - runTomlString += k + " = \"../data/" + filepath.Base(r) + "\"\n" - } - } - // Find the Toppar that matches the pattern - for _, r := range t.Toppar { - if pattern.MatchString(r) { - runTomlString += k + " = \"../data/" + filepath.Base(r) + "\"\n" + pattern := regexp.MustCompile(v.(string)) + + for _, fArr := range fnameArray { + fname, err := utils.FindFname(fArr, pattern) + if err != nil { + return "", err } - } - // Find if a MiscPDB that matches the pattern - for _, r := range t.MiscPDB { - if pattern.MatchString(r) { - runTomlString += k + " = \"../data/" + filepath.Base(r) + "\"\n" + // If fname is not empty, add it to the TOML file + if fname != "" { + runTomlString += k + " = \"../data/" + filepath.Base(fname) + "\"\n" } } diff --git a/dataset/dataset_test.go b/dataset/dataset_test.go index e573a8e..f118296 100644 --- a/dataset/dataset_test.go +++ b/dataset/dataset_test.go @@ -526,7 +526,7 @@ func TestSetupHaddock3Scenario(t *testing.T) { "some-param": "some-value", }, Rigidbody: map[string]interface{}{ - "ambig_fname": "_ti.tbl", + "ambig_fname": "_ti", }, }, }, @@ -576,6 +576,22 @@ func TestSetupHaddock3Scenario(t *testing.T) { t.Errorf("Scenario was not written to disk") } + // Fail to setup a scenario in which multiple patterns match + target = Target{ + ID: "1abc", + Receptor: []string{"dummy.pdb", "dummy.pdb"}, + ReceptorList: "pdb-files.txt", + Ligand: []string{"dummy.pdb", "dummy.pdb"}, + LigandList: "pdb-files.txt", + Restraints: []string{"1abc_ti.tbl", "1abc_ti5.tbl"}, + Toppar: []string{"custom.top", "custom.param"}, + } + + _, err = target.SetupHaddock3Scenario(wd, s) + if err == nil { + t.Errorf("Failed to detect wrong scenario") + } + } func TestTarget_SetupHaddock24Scenario(t *testing.T) { diff --git a/example/example_haddock30.yml b/example/example_haddock30.yml index 1d7f3f3..c807002 100644 --- a/example/example_haddock30.yml +++ b/example/example_haddock30.yml @@ -1,11 +1,11 @@ general: - executable: /trinity/login/rodrigo/repos/haddock-runner/example/haddock3.sh + executable: /home/rodrigo/repos/haddock-runner/example/haddock3.sh max_concurrent: 4 - haddock_dir: /trinity/login/rodrigo/repos/haddock3 + haddock_dir: /home/rodrigo/repos/haddock3 receptor_suffix: _r_u ligand_suffix: _l_u - input_list: /trinity/login/rodrigo/repos/haddock-runner/example/input_list.txt - work_dir: /trinity/login/rodrigo/repos/haddock-runner/bm-goes-here + input_list: /home/rodrigo/repos/haddock-runner/example/input_list.txt + work_dir: /home/rodrigo/repos/haddock-runner/bm-goes-here scenarios: - name: true-interface @@ -20,20 +20,20 @@ scenarios: autohis: true rigidbody: sampling: 10 - ambig_fname: _ti - unambig_fname: _unambig - ligand_top_fname: _custom_top - ligand_param_fname: _custom_param + ambig_fname: _ti.tbl + unambig_fname: _unambig.tbl + ligand_top_fname: _ligand.top + ligand_param_fname: _ligand.param seletop: select: 2 flexref: - ambig_fname: _ti - unambig_fname: _unambig - ligand_top_fname: _custom_top - ligand_param_fname: _custom_param + ambig_fname: _ti.tbl + unambig_fname: _unambig.tbl + ligand_top_fname: _ligand.top + ligand_param_fname: _ligand.param emref: caprieval: - reference_fname: _ref + reference_fname: _ref.pdb - name: center-of-mass parameters: diff --git a/utils/utils.go b/utils/utils.go index 49d01e5..99da0f4 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -201,3 +201,20 @@ func ContainsCG(s string) bool { s = strings.ToLower(s) return regexp.MustCompile(`cg`).MatchString(s) } + +// FindFname checks the array of strings for a pattern, returns an error if multiple files match +func FindFname(arr []string, pattern *regexp.Regexp) (string, error) { + + var fname string + for _, f := range arr { + if pattern.MatchString(f) { + if fname != "" { + err := errors.New("multiple files match the pattern: `" + pattern.String() + "` please use a more specific pattern") + return "", err + } + fname = f + } + } + + return fname, nil +} diff --git a/utils/utils_test.go b/utils/utils_test.go index 48b96e9..383d93b 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -4,6 +4,7 @@ import ( "flag" "os" "reflect" + "regexp" "testing" ) @@ -314,3 +315,20 @@ func TestContainsCG(t *testing.T) { t.Errorf("Failed to detect cg") } } + +func TestFindFname(t *testing.T) { + + testArr := []string{"abc", "bcd", "cde"} + pattern := regexp.MustCompile("abc") + _, err := FindFname(testArr, pattern) + if err != nil { + t.Errorf("Failed to find name: %s", err) + } + + pattern = regexp.MustCompile("cd") + _, err = FindFname(testArr, pattern) + if err == nil { + t.Errorf("Failed to detect multiple files") + } + +}