diff --git a/frontend/src/components/IndividualModel/CDFTable.js b/frontend/src/components/IndividualModel/CDFTable.js index 38362208..d06069e3 100644 --- a/frontend/src/components/IndividualModel/CDFTable.js +++ b/frontend/src/components/IndividualModel/CDFTable.js @@ -11,12 +11,16 @@ class CDFTable extends Component { const {bmd_dist} = this.props; return ( + + + + - + diff --git a/frontend/src/components/IndividualModel/ContinuousDeviance.js b/frontend/src/components/IndividualModel/ContinuousDeviance.js index e5c30b04..6c692bef 100644 --- a/frontend/src/components/IndividualModel/ContinuousDeviance.js +++ b/frontend/src/components/IndividualModel/ContinuousDeviance.js @@ -20,11 +20,11 @@ class ContinuousDeviance extends Component { - + - + diff --git a/frontend/src/components/IndividualModel/ContinuousSummary.js b/frontend/src/components/IndividualModel/ContinuousSummary.js index 58acba62..30d211b5 100644 --- a/frontend/src/components/IndividualModel/ContinuousSummary.js +++ b/frontend/src/components/IndividualModel/ContinuousSummary.js @@ -19,7 +19,7 @@ class ContinuousSummary extends Component { - + @@ -40,7 +40,7 @@ class ContinuousSummary extends Component { - + @@ -50,7 +50,7 @@ class ContinuousSummary extends Component { - + diff --git a/frontend/src/components/IndividualModel/ContinuousTestOfInterest.js b/frontend/src/components/IndividualModel/ContinuousTestOfInterest.js index 6afca764..5058773a 100644 --- a/frontend/src/components/IndividualModel/ContinuousTestOfInterest.js +++ b/frontend/src/components/IndividualModel/ContinuousTestOfInterest.js @@ -22,7 +22,7 @@ class ContinuousTestOfInterest extends Component { - + @@ -30,7 +30,7 @@ class ContinuousTestOfInterest extends Component { LLR - + diff --git a/frontend/src/components/IndividualModel/DichotomousDeviance.js b/frontend/src/components/IndividualModel/DichotomousDeviance.js index cf7b7add..e948e2ff 100644 --- a/frontend/src/components/IndividualModel/DichotomousDeviance.js +++ b/frontend/src/components/IndividualModel/DichotomousDeviance.js @@ -26,10 +26,10 @@ class DichotomousDeviance extends Component { - + - + diff --git a/frontend/src/components/IndividualModel/DichotomousSummary.js b/frontend/src/components/IndividualModel/DichotomousSummary.js index b06b9aa5..be92923b 100644 --- a/frontend/src/components/IndividualModel/DichotomousSummary.js +++ b/frontend/src/components/IndividualModel/DichotomousSummary.js @@ -18,7 +18,7 @@ class DichotomousSummary extends Component { - + @@ -39,7 +39,7 @@ class DichotomousSummary extends Component { - + @@ -49,7 +49,7 @@ class DichotomousSummary extends Component { - + diff --git a/frontend/src/components/IndividualModel/GoodnessFit.js b/frontend/src/components/IndividualModel/GoodnessFit.js index 09ead3d8..b2413c18 100644 --- a/frontend/src/components/IndividualModel/GoodnessFit.js +++ b/frontend/src/components/IndividualModel/GoodnessFit.js @@ -6,87 +6,141 @@ import {Dtype} from "@/constants/dataConstants"; import {isLognormal} from "@/constants/modelConstants"; import {ff} from "@/utils/formatters"; -/* eslint-disable */ -const hdr_c_normal = [ - "Dose", "Size", "Observed Mean", "Calculated Mean", "Estimated Mean", - "Observed SD", "Calculated SD", "Estimated SD", "Scaled Residual", - ], - hdr_c_lognormal = [ - "Dose", "Size", "Observed Mean", "Calculated Median", "Estimated Median", - "Observed SD", "Calculated GSD", "Estimated GSD", "Scaled Residual", - ], - hdr_d = [ "Dose", "Size", "Observed", "Expected", "Estimated Probability", "Scaled Residual"]; -/* eslint-enable */ - @observer class GoodnessFit extends Component { - getHeaders(dtype, settings) { - if (dtype == Dtype.CONTINUOUS || dtype == Dtype.CONTINUOUS_INDIVIDUAL) { - const headers = isLognormal(settings.disttype) ? hdr_c_lognormal : hdr_c_normal; - return [headers, [10, 10, 10, 12, 12, 12, 10, 12, 12]]; - } - if (dtype == Dtype.DICHOTOMOUS) { - return [hdr_d, [17, 16, 16, 17, 17, 17]]; - } - throw Error("Unknown dtype"); + getDichotomousData() { + const {store} = this.props, + gof = store.modalModel.results.gof, + dataset = store.selectedDataset; + return { + headers: [ + "Dose", + "N", + "Observed", + "Expected", + "Estimated Probability", + "Scaled Residual", + ], + colwidths: [17, 16, 16, 17, 17, 17], + data: dataset.doses.map((dose, i) => { + return [ + dose, + dataset.ns[i], + dataset.incidences[i], + ff(gof.expected[i]), + ff(gof.expected[i] / dataset.ns[i]), + ff(gof.residual[i]), + ]; + }), + }; + } + + getContinuousNormalData(dtype) { + const {store} = this.props, + gof = store.modalModel.results.gof, + dataset = store.selectedDataset, + useFF = dtype === Dtype.CONTINUOUS_INDIVIDUAL; + return { + headers: [ + "Dose", + "N", + "Sample Mean", + "Model Fitted Mean", + "Sample SD", + "Model Fitted SD", + "Scaled Residual", + ], + colwidths: [1, 1, 1, 1, 1, 1, 1], + data: dataset.doses.map((dose, i) => { + return [ + dose, + dataset.ns[i], + useFF ? ff(gof.obs_mean[i]) : gof.obs_mean[i], + ff(gof.est_mean[i]), + useFF ? ff(gof.obs_sd[i]) : gof.obs_sd[i], + ff(gof.est_sd[i]), + ff(gof.residual[i]), + ]; + }), + }; + } + + getContinuousLognormalData(dtype) { + const {store} = this.props, + gof = store.modalModel.results.gof, + dataset = store.selectedDataset, + useFF = dtype === Dtype.CONTINUOUS_INDIVIDUAL; + return { + headers: [ + "Dose", + "N", + "Sample Mean", + "Approximate Sample Median", + "Model Fitted Median", + "Sample SD", + "Approximate Sample GSD", + "Model Fitted GSD", + "Scaled Residual", + ], + colwidths: [10, 10, 10, 12, 12, 12, 10, 12, 12], + data: dataset.doses.map((dose, i) => { + return [ + dose, + dataset.ns[i], + useFF ? ff(gof.obs_mean[i]) : gof.obs_mean[i], + ff(gof.calc_mean[i]), + ff(gof.est_mean[i]), + useFF ? ff(gof.obs_sd[i]) : gof.obs_sd[i], + ff(gof.calc_mean[i]), + ff(gof.est_sd[i]), + ff(gof.residual[i]), + ]; + }), + }; } render() { const {store} = this.props, settings = store.modalModel.settings, - gof = store.modalModel.results.gof, dataset = store.selectedDataset, - {dtype} = dataset, - headers = this.getHeaders(dtype, settings); + {dtype} = dataset; + + let data; + if (dtype == Dtype.DICHOTOMOUS) { + data = this.getDichotomousData(); + } else { + if (isLognormal(settings.disttype)) { + data = this.getContinuousLognormalData(dtype); + } else { + data = this.getContinuousNormalData(dtype); + } + } return (
CDF
PercentileCumulative Probability BMD
Likelihoods of InterestLikelihoods
ModelLog Likelihood-2* Log(Likelihood Ratio) # of Parameters AIC
SummaryModeling Summary
{ff(results.fit.aic)}
Log Likelihood-2* Log(Likelihood Ratio) {ff(results.fit.loglikelihood)}
{fractionalFormatter(p_value)}
Model DOFModel d.f. {ff(results.tests.dfs[3])}
Test of InterestTests of Mean and Variance Fits
TestTest DOFTest d.f. P-Value
ModelLog Likelihood-2* Log(Likelihood Ratio) # Parameters DevianceTest DOFTest d.f. P-Value
SummaryModeling Summary
{ff(results.fit.aic)}
Log Likelihood-2* Log(Likelihood Ratio) {ff(results.fit.loglikelihood)}
{fourDecimalFormatter(results.gof.p_value)}
Overall DOFOverall d.f. {ff(results.gof.df)}
- {headers[1].map((d, i) => ( + {data.colwidths.map((d, i) => ( ))} - + - {headers[0].map((d, i) => ( + {data.headers.map((d, i) => ( ))} - {dtype == Dtype.CONTINUOUS || dtype == Dtype.CONTINUOUS_INDIVIDUAL - ? gof.dose.map((item, i) => { - const useFF = dtype === Dtype.CONTINUOUS_INDIVIDUAL; - return ( - - - - - - - - - - - - ); - }) - : null} - {dtype == Dtype.DICHOTOMOUS - ? dataset.doses.map((dose, i) => { - return ( - - - - - - - - - ); - }) - : null} + {data.data.map((row, i) => { + return ( + + {row.map((cell, j) => ( + + ))} + + ); + })}
Goodness of FitGoodness of Fit
{d}
{item}{gof.size[i]}{useFF ? ff(gof.obs_mean[i]) : gof.obs_mean[i]}{ff(gof.calc_mean[i])}{ff(gof.est_mean[i])}{useFF ? ff(gof.obs_sd[i]) : gof.obs_sd[i]}{ff(gof.calc_sd[i])}{ff(gof.est_sd[i])}{ff(gof.residual[i])}
{dose}{dataset.ns[i]}{dataset.incidences[i]}{ff(gof.expected[i])}{ff(gof.expected[i] / dataset.ns[i])}{ff(gof.residual[i])}
{cell}
); diff --git a/frontend/src/components/IndividualModel/ModelDetailModal.js b/frontend/src/components/IndividualModel/ModelDetailModal.js index 85f985bc..e58e2e78 100644 --- a/frontend/src/components/IndividualModel/ModelDetailModal.js +++ b/frontend/src/components/IndividualModel/ModelDetailModal.js @@ -69,7 +69,7 @@ class ModelBody extends Component { - + @@ -82,7 +82,7 @@ class ModelBody extends Component { ) : null} {isContinuous ? ( - + diff --git a/frontend/src/components/IndividualModel/ModelOptionsTable.js b/frontend/src/components/IndividualModel/ModelOptionsTable.js index 690a7fe4..b60a2994 100644 --- a/frontend/src/components/IndividualModel/ModelOptionsTable.js +++ b/frontend/src/components/IndividualModel/ModelOptionsTable.js @@ -6,6 +6,7 @@ import {getLabel} from "@/common"; import TwoColumnTable from "@/components/common/TwoColumnTable"; import {Dtype} from "@/constants/dataConstants"; import {hasDegrees} from "@/constants/modelConstants"; +import {isHybridBmr} from "@/constants/optionsConstants"; import { continuousBmrOptions, dichotomousBmrOptions, @@ -39,7 +40,7 @@ class ModelOptionsTable extends Component { data = [ ["BMR Type", getLabel(model.settings.bmr_type, dichotomousBmrOptions)], ["BMR", ff(model.settings.bmr)], - ["Confidence Level", ff(1 - model.settings.alpha)], + ["Confidence Level (one sided)", ff(1 - model.settings.alpha)], hasDegrees.has(model.model_class.verbose) ? ["Degree", ff(model.settings.degree)] : null, @@ -53,8 +54,10 @@ class ModelOptionsTable extends Component { ["BMRF", ff(model.settings.bmr)], ["Distribution Type", getLabel(model.settings.disttype, distTypeOptions)], ["Direction", model.settings.is_increasing ? "Up" : "Down"], - ["Confidence Level", 1 - ff(model.settings.alpha)], - ["Tail Probability", ff(model.settings.tail_prob)], + ["Confidence Level (one sided)", 1 - ff(model.settings.alpha)], + isHybridBmr(model.settings.bmr_type) + ? ["Tail Probability", ff(model.settings.tail_prob)] + : null, hasDegrees.has(model.model_class.verbose) ? ["Degree", ff(model.settings.degree)] : null, @@ -66,7 +69,7 @@ class ModelOptionsTable extends Component { data = [ ["BMR Type", getLabel(model.settings.bmr_type, dichotomousBmrOptions)], ["BMR", ff(model.settings.bmr)], - ["Confidence Level", ff(1 - model.settings.alpha)], + ["Confidence Level (one sided)", ff(1 - model.settings.alpha)], ["Bootstrap Seed", model.settings.bootstrap_seed], ["Bootstrap Iterations", model.settings.bootstrap_iterations], [ diff --git a/frontend/src/components/IndividualModel/ModelParameters.js b/frontend/src/components/IndividualModel/ModelParameters.js index d70b58e8..49dcf060 100644 --- a/frontend/src/components/IndividualModel/ModelParameters.js +++ b/frontend/src/components/IndividualModel/ModelParameters.js @@ -10,60 +10,65 @@ import {parameterFormatter} from "@/utils/formatters"; class ModelParameters extends Component { render() { const {parameters} = this.props, - indexes = _.range(parameters.names.length); + indexes = _.range(parameters.names.length), + anyBounded = _.sum(parameters.bounded) > 0; return ( - - - - - - - - - - - - - - - - - - - - - - {indexes.map(i => { - const bounded = parameters.bounded[i]; - return ( - - - - - - - - ); - })} - -
Model Parameters
VariableEstimateStandard ErrorLower ConfidenceUpper Confidence
{parameters.names[i]} - {bounded ? ( - <> - Bounded - - - ) : ( - parameterFormatter(parameters.values[i]) - )} - {bounded ? "NA" : parameterFormatter(parameters.se[i])} - {bounded ? "NA" : parameterFormatter(parameters.lower_ci[i])} - - {bounded ? "NA" : parameterFormatter(parameters.upper_ci[i])} -
+ <> + + + + + + + + + + + + + + + + + + {indexes.map(i => { + const bounded = parameters.bounded[i]; + return ( + + + + + + ); + })} + +
Model Parameters
VariableEstimateStandard Error
{parameters.names[i]} + {bounded ? ( + <> + On Bound + + + ) : ( + parameterFormatter(parameters.values[i]) + )} + + {bounded + ? "Not Reported" + : parameterFormatter(parameters.se[i])} +
+ {anyBounded ? ( +

+ Standard errors estimates are not generated for parameters estimated on + corresponding bounds, although sampling error is present for all parameters, + as a rule. Standard error estimates may not be reliable as a basis for + confidence intervals or tests when one or more parameters are on bounds. +

+ ) : null} + ); } } diff --git a/frontend/src/components/Main/OptionsForm/OptionsFormList.js b/frontend/src/components/Main/OptionsForm/OptionsFormList.js index 075cafea..83ed7b14 100644 --- a/frontend/src/components/Main/OptionsForm/OptionsFormList.js +++ b/frontend/src/components/Main/OptionsForm/OptionsFormList.js @@ -23,7 +23,8 @@ class OptionsFormList extends Component { modelType = optionsStore.getModelType, optionsList = toJS(optionsStore.optionsList), distTypeHelpText = - "If lognormal is selected, only the Exponential and Hill models can be executed. Other models will be removed during the execution process and will not be shown in the outputs."; + "If lognormal is selected, only the Exponential and Hill models can be executed. Other models will be removed during the execution process and will not be shown in the outputs.", + tailProbabilityHelpText = "Only used for Hybrid models."; return (
@@ -36,8 +37,13 @@ class OptionsFormList extends Component { <> BMR Type BMRF - Tail Probability - Confidence Level + + Tail Probability + + + Confidence Level (one sided) Distribution +
Variance  @@ -50,14 +56,14 @@ class OptionsFormList extends Component { <> Risk Type BMR - Confidence Level + Confidence Level (one sided) ) : null} {modelType === MODEL_NESTED_DICHOTOMOUS ? ( <> Risk Type BMR - Confidence Level + Confidence Level (one sided) Litter Specific
diff --git a/frontend/src/components/Output/BayesianResultTable.js b/frontend/src/components/Output/BayesianResultTable.js index b71d7eaa..d41fd1a8 100644 --- a/frontend/src/components/Output/BayesianResultTable.js +++ b/frontend/src/components/Output/BayesianResultTable.js @@ -36,8 +36,8 @@ class BayesianResultTable extends Component { BMD BMDU Unnormalized Log Posterior Probability - Scaled Residual for Dose Group near BMD - Scaled Residual for Control Dose Group + Scaled Residual at Control + Scaled Residual near BMD @@ -63,8 +63,8 @@ class BayesianResultTable extends Component { {ff(model.results.bmd)} {ff(model.results.bmdu)} {ff(model.results.fit.bic_equiv)} - {ff(model.results.gof.roi)} {ff(model.results.gof.residual[0])} + {ff(model.results.gof.roi)} ); })} diff --git a/frontend/src/components/Output/FrequentistResultTable.js b/frontend/src/components/Output/FrequentistResultTable.js index ae3a8bdc..4420415c 100644 --- a/frontend/src/components/Output/FrequentistResultTable.js +++ b/frontend/src/components/Output/FrequentistResultTable.js @@ -242,8 +242,8 @@ class FrequentistRow extends Component { {ff(results.bmdu)} {fractionalFormatter(getPValue(dataset.dtype, results))} {ff(results.fit.aic)} - {ff(results.gof.roi)} {ff(results.gof.residual[0])} + {ff(results.gof.roi)} P-Value AIC - Scaled Residual for Dose Group near BMD - Scaled Residual for Control Dose Group + Scaled Residual at Control + Scaled Residual near BMD {store.recommendationEnabled ? (