From c76507c79dab072cdc4258d470aff13a02abb8e6 Mon Sep 17 00:00:00 2001 From: Devin Pastoor Date: Mon, 26 Aug 2019 17:25:32 -0400 Subject: [PATCH] refactor: adjust to capturing all estimation methods lst parsing will still only get the last method, as will default to the ext file, and lst will be a general fallback. references #8 #18 #19 #20 #22 --- parsers/nmparser/parse_lst_file.go | 8 +++-- parsers/nmparser/parse_parameter_comments.go | 7 ---- parsers/nmparser/structs.go | 37 +++++++++++++------- parsers/nmparser/summary.go | 15 ++++---- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/parsers/nmparser/parse_lst_file.go b/parsers/nmparser/parse_lst_file.go index 626796f4..417578e6 100644 --- a/parsers/nmparser/parse_lst_file.go +++ b/parsers/nmparser/parse_lst_file.go @@ -135,9 +135,11 @@ func ParseLstEstimationFile(lines []string) ModelOutput { // TODO re-replace parameter data from lst result := ModelOutput{ RunDetails: ParseRunDetails(lines), - FinalParametersData: ParametersData{ - Estimates: finalParameterEst, - StdErr: finalParameterStdErr, + ParametersData: []ParametersData{ + ParametersData{ + Estimates: finalParameterEst, + StdErr: finalParameterStdErr, + }, }, ParameterStructures: parameterStructures, ParameterNames: parameterNames, diff --git a/parsers/nmparser/parse_parameter_comments.go b/parsers/nmparser/parse_parameter_comments.go index cb3ee73f..13c3ce38 100644 --- a/parsers/nmparser/parse_parameter_comments.go +++ b/parsers/nmparser/parse_parameter_comments.go @@ -4,13 +4,6 @@ import ( "strings" ) -// ParameterNames containst the names of model parameters -type ParameterNames struct { - Theta []string - Omega []string - Sigma []string -} - // ParseThetaComments will parse out the names from theta parameters func ParseThetaComments(lines []string) []string { parsedLines := FormatThetaBlock(CleanThetaBlock(lines)) diff --git a/parsers/nmparser/structs.go b/parsers/nmparser/structs.go index 1edccc19..b1019b4e 100644 --- a/parsers/nmparser/structs.go +++ b/parsers/nmparser/structs.go @@ -1,26 +1,38 @@ package parser +// ParameterNames containst the names of model parameters +type ParameterNames struct { + Theta []string `json:"theta,omitempty"` + Omega []string `json:"omega,omitempty"` + Sigma []string `json:"sigma,omitempty"` +} + // ParametersResult contains data about the parameter values for a model type ParametersResult struct { - Theta []float64 - Omega []float64 - Sigma []float64 + Theta []float64 `json:"theta,omitempty"` + Omega []float64 `json:"omega,omitempty"` + Sigma []float64 `json:"sigma,omitempty"` } type RandomEffectResult struct { - Omega []float64 - Sigma []float64 + Omega []float64 `json:"omega,omitempty"` + Sigma []float64 `json:"sigma,omitempty"` } type ParametersData struct { - Estimates ParametersResult `json:"final_parameter_estimates,omitempty"` - StdErr ParametersResult `json:"final_parameter_std_err,omitempty"` + Estimates ParametersResult `json:"estimates,omitempty"` + StdErr ParametersResult `json:"std_err,omitempty"` // indicates this line contains the OMEGA and SIGMA elements in // standard deviation/correlation format - RandomEffectSD RandomEffectResult + RandomEffectSD RandomEffectResult `json:"random_effect_sd,omitempty"` // indicates this line contains the standard errors to the OMEGA and // SIGMA elements in standard deviation/correlation format - RandomEffectSDSE RandomEffectResult - Fixed bool + RandomEffectSDSE RandomEffectResult `json:"random_effect_sdse,omitempty"` + Fixed bool `json:"fixed,omitempty"` +} + +type RunHeuristics struct { + HasZeroGradient bool `json:"has_zero_gradient,omitempty"` + MinimizationSuccessful bool `json:"minimization_successful,omitempty"` } // RunDetails contains key information about logistics of the model run @@ -89,8 +101,9 @@ type OfvDetails struct { // ModelOutput is the output struct from a lst file type ModelOutput struct { - RunDetails RunDetails `json:"run_details,omitempty"` - FinalParametersData ParametersData + RunDetails RunDetails `json:"run_details,omitempty"` + RunHeuristics RunHeuristics `json:"run_heuristics,omitempty"` + ParametersData []ParametersData `json:"parameters_data,omitempty"` ParameterStructures ParameterStructures `json:"parameter_structures,omitempty"` ParameterNames ParameterNames `json:"parameter_names,omitempty"` OFV OfvDetails `json:"ofv,omitempty"` diff --git a/parsers/nmparser/summary.go b/parsers/nmparser/summary.go index 48eb5074..4e0cc853 100644 --- a/parsers/nmparser/summary.go +++ b/parsers/nmparser/summary.go @@ -21,15 +21,16 @@ func (results ModelOutput) Summary() bool { } thetaTable := termtables.CreateTable() thetaTable.AddHeaders("Theta", "Name", "Estimate", "StdErr (RSE)") - if len(results.FinalParametersData.Estimates.Theta) != len(results.FinalParametersData.StdErr.Theta) { + finalEstimationMethodIndex := len(results.ParametersData) - 1 + if len(results.ParametersData[finalEstimationMethodIndex].Estimates.Theta) != len(results.ParametersData[finalEstimationMethodIndex].StdErr.Theta) { // if the standard errors aren't there, we should // instead make an equal length slice so that looping to build the table won't blow // up with an index out of bounds error - results.FinalParametersData.StdErr.Theta = make([]float64, len(results.FinalParametersData.Estimates.Theta)) + results.ParametersData[finalEstimationMethodIndex].StdErr.Theta = make([]float64, len(results.ParametersData[finalEstimationMethodIndex].Estimates.Theta)) } - for i := range results.FinalParametersData.Estimates.Theta { - numResult := results.FinalParametersData.Estimates.Theta[i] - seResult := results.FinalParametersData.StdErr.Theta[i] + for i := range results.ParametersData[finalEstimationMethodIndex].Estimates.Theta { + numResult := results.ParametersData[finalEstimationMethodIndex].Estimates.Theta[i] + seResult := results.ParametersData[finalEstimationMethodIndex].StdErr.Theta[i] var rse float64 if seResult != 0 && numResult != 0 { rse = math.Abs(seResult / numResult * 100) @@ -66,10 +67,10 @@ func (results ModelOutput) Summary() bool { omegaTable := termtables.CreateTable() omegaTable.AddHeaders("Omega", "Eta", "Estimate", "ShrinkageSD (%)") diagIndices := GetDiagonalElements(results.ParameterStructures.Omega) - for i := range results.FinalParametersData.Estimates.Omega { + for i := range results.ParametersData[finalEstimationMethodIndex].Estimates.Omega { omegaIndex, _ := omegaIndices[i] if results.ParameterStructures.Omega[i] != 0 { - val := results.FinalParametersData.Estimates.Omega[i] + val := results.ParametersData[finalEstimationMethodIndex].Estimates.Omega[i] var shrinkage float64 var etaName string userEtaIndex := funk.IndexOfInt(diagIndices, i)