class SettingsConfig(Form): """ The root Form of the whole settings inputs tree. This collects all settings from EpiViz-AT and adds default values when they are missing. A representation of the configuration form we expect to receive from EpiViz. The hope is that this form will do as much validation and precondition checking as is feasible within the constraint that it must be able to validate a full EpiViz parameter document in significantly less than one second. This is because it will be used as part of a web service which gates EpiViz submissions and must return in near real time. The Configuration class is the root of the form. Example ------- >>> import json >>> input_data = json.loads(json_blob) >>> form = SettingsConfig(input_data) >>> errors = form.validate_and_normalize() """ model: Model = Model(display="Model", validation_priority=5) policies: Policies = Policies(display="Policies") gbd_round_id: IntField = IntField(display="GBD Round ID") random_effect: FormList = FormList(Smoothing, nullable=True, display="Random effects") rate: FormList = FormList(Smoothing, display="Rates") country_covariate: FormList = FormList(CountryCovariate, display="Country covariates") study_covariate: FormList = FormList(StudyCovariate, display="Study covariates", nullable=True) eta: Eta = Eta(validation_priority=5) students_dof: StudentsDOF = StudentsDOF(validation_priority=5) log_students_dof: StudentsDOF = StudentsDOF(validation_priority=5) location_set_version_id: IntField = IntField(default=429, nullable=True) csmr_cod_output_version_id: IntField = IntField() csmr_mortality_output_version_id: Dummy = Dummy() min_cv: FormList = FormList(MinCV, display="Minimum coefficient of variation", nullable=False) min_cv_by_rate: FormList = FormList( MinCVRate, display="Minimum coefficient of variation by rate", nullable=True) re_bound_location: FormList = FormList(RandomEffectBound) derivative_test: DerivativeTest = DerivativeTest(display="Derivative test") max_num_iter: FixedRandomInt = FixedRandomInt( display="Max ipopt iterations") print_level: FixedRandomInt = FixedRandomInt(display="Print level") accept_after_max_steps: FixedRandomInt = FixedRandomInt( display="Max backtracking") tolerance: FixedRandomFloat = FixedRandomFloat( display="Desired relative convergence tolerance") data_cv_by_integrand: FormList = FormList(DataCV) data_eta_by_integrand: FormList = FormList(DataEta) data_density_by_integrand: FormList = FormList(DataDensity) config_version: StrField = StrField(nullable=True, display="Settings version")
class CountryCovariate(Form): country_covariate_id = IntField(display="Covariate") measure_id = IntField(display="Measure") mulcov_type = OptionField(["rate_value", "meas_value", "meas_std"], display="Multiplier type") transformation = IntField(display="Transformation") age_time_specific = IntField(display="Age and Time specific") age_grid = StringListField(constructor=float, nullable=True, display="Age grid") time_grid = StringListField(constructor=float, nullable=True, display="Time grid") default = SmoothingPriorGroup(display="Defaults") mulstd = SmoothingPriorGroup(nullable=True, display="MulStd") detail = FormList(SmoothingPrior, nullable=True, display="Detail") custom_age_grid = Dummy() custom_time_grid = Dummy()
class StudyCovariate(Form): study_covariate_id: IntField = IntField(display="Covariate") measure_id: StrField = StrField(display="Measure") mulcov_type: OptionField = OptionField( ["rate_value", "meas_value", "meas_noise"], display="Multiplier type") transformation: IntField = IntField(display="Transformation") age_time_specific: IntField = IntField(display="Age and Time specific") age_grid: StringListField = StringListField(constructor=float, nullable=True, display="Age grid") time_grid: StringListField = StringListField(constructor=float, nullable=True, display="Time grid") default: SmoothingPriorGroup = SmoothingPriorGroup(display="Defaults") mulstd: SmoothingPriorGroup = SmoothingPriorGroup(nullable=True, display="MulStd") detail: FormList = FormList(SmoothingPrior, nullable=True, display="Detail") custom_age_grid: Dummy = Dummy() custom_time_grid: Dummy = Dummy()
class SettingsConfig(Form): """ The root Form of the whole settings inputs tree. Example: >>> import json >>> input_data = json.loads(json_blob) >>> form = SettingsConfig(input_data) >>> errors = form.validate_and_normalize() """ model = Model(display="Model", validation_priority=5) policies = Policies(display="Policies") gbd_round_id = IntField(display="GBD Round ID") random_effect = FormList(Smoothing, nullable=True, display="Random effects") rate = FormList(Smoothing, display="Rates") country_covariate = FormList(CountryCovariate, display="Country covariates") study_covariate = FormList(StudyCovariate, display="Study covariates", nullable=True) eta = Eta(validation_priority=5) students_dof = StudentsDOF(validation_priority=5) log_students_dof = StudentsDOF(validation_priority=5) location_set_version_id = IntField(default=429, nullable=True) csmr_cod_output_version_id = IntField() csmr_mortality_output_version_id = Dummy() min_cv = FormList(MinCV, display="Minimum coefficient of variation", nullable=False) min_cv_by_rate = FormList( MinCVRate, display="Minimum coefficient of variation by rate", nullable=True) re_bound_location = FormList(RandomEffectBound) derivative_test = DerivativeTest(display="Derivative test") max_num_iter = FixedRandomInt(display="Max ipopt iterations") print_level = FixedRandomInt(display="Print level") accept_after_max_steps = FixedRandomInt(display="Max backtracking") tolerance = FixedRandomFloat( display="Desired relative convergence tolerance") data_cv_by_integrand = FormList(DataCV) data_eta_by_integrand = FormList(DataEta) data_density_by_integrand = FormList(DataDensity) config_version = StrField(nullable=True, display="Settings version")
class Smoothing(Form): rate = OptionField(["pini", "iota", "rho", "chi", "omega"], "Rate") location = IntField(nullable=True) age_grid = StringListField(constructor=float, nullable=True, display="Age grid") time_grid = StringListField(constructor=float, nullable=True, display="Time grid") default = SmoothingPriorGroup(display="Defaults") mulstd = SmoothingPriorGroup(nullable=True, display="MulStd") detail = FormList(SmoothingPrior, nullable=True, display="Detail") age_time_specific = IntField(display="Age and Time specific", nullable=True) custom_age_grid = Dummy() custom_time_grid = Dummy() def _full_form_validation(self, root): errors = [] if self.rate == "pini": if not self.is_field_unset("age_grid") and len(self.age_grid) != 1: errors.append("Pini must have exactly one age point") else: age_grid = self.age_grid or root.model.default_age_grid if len(age_grid) > 1 and self.default.is_field_unset("dage"): errors.append( "You must supply a default age diff prior if the " "smoothing has extent over age") time_grid = self.time_grid or root.model.default_time_grid if len(time_grid) > 1 and self.default.is_field_unset("dtime"): errors.append( "You must supply a default time diff prior if the smoothing " "has extent over time") if self._container._name == "rate": # This validation only makes sense for Fixed Effects not # Random Effects # TODO This repeats validation logic in cascade.model.rates but I # don't see a good way to bring that in here is_negative = True is_positive = True for prior in ( [self.default.value] + [p for p in self.detail or [] if p.prior_type == "value"]): is_negative = is_negative and prior.min == 0 and prior.max == 0 is_positive = is_positive and prior.min > 0 if prior.min < 0: errors.append( "Rates must be constrained to be >= 0 at all points. " "Add or correct the lower bound") break if self.rate in ["iota", "rho"]: if not (is_negative or is_positive): errors.append( f"Rate {self.rate} must be either fully positive or " f"constrained to zero") return errors
class MyOuterForm(Form): inner_form = MyInnerForm() nothing_here = Dummy()
class MyInnerForm(Form): inner_sanctum = MyInnerSanctum() nothing_here_either = Dummy()