Results

What a run produced, and how to name a quantity without knowing where it lives.

Two classes. ResponseCatalog maps the short names cdadt reports under – total_fuel, MTOW, takeoff_field_length – onto the paths those quantities live at inside the black box, so that a case file can write objective: {name: total_fuel} instead of mission.loiter.fuel_burn_integ.fuel_burn_final. The catalog is built from the discipline classes themselves, so a response added to a discipline is addressable in a case file immediately and nothing has to be kept in step by hand.

SizingResults is the answer: every response of every discipline, read on every run rather than whichever few a caller thought to ask for. Reading the whole set is what makes a run report complete, and what makes two runs comparable without re-running either.

class cdadt.results.ResponseCatalog(disciplines=None)[source]

Bases: object

Every response the disciplines of a study report, by short name.

Parameters:

disciplines (sequence of type or Discipline, optional) – Discipline classes or instances to catalogue. Default: the airframe disciplines plus performance.

Raises:

ValueError – If two disciplines report different quantities under the same name. Names are how a case file addresses a response, so they have to be unique across the study.

Examples

>>> catalog = ResponseCatalog()
>>> catalog.path("total_fuel")
'mission.loiter.fuel_burn_integ.fuel_burn_final'
>>> catalog.units("takeoff_field_length")
'ft'
response(name)[source]

Return one catalogued response.

Raises:

KeyError – If nothing reports it, listing what is available.

Parameters:

name (str)

Return type:

Response

path(name)[source]

Return the black-box path of a response, or name itself if it is already a path.

A case file may name either. Anything the catalog does not know is passed through unchanged, so a raw path always works and the black box gives the error if it is wrong.

Parameters:

name (str)

Return type:

str

units(name)[source]

Return the units of a response, or None for a raw path or a dimensionless one.

Parameters:

name (str)

Return type:

str | None

owner(name)[source]

Return the name of the discipline that reports name.

Parameters:

name (str)

Return type:

str

class cdadt.results.SizingResults(values, missing=None, model='', num_nodes=0)[source]

Bases: object

Everything one converged run produced.

Parameters:
  • values (mapping) – discipline name -> {response name -> value}.

  • missing (mapping, optional) – discipline name -> optional response names the black box did not publish. Recorded rather than dropped: a report that silently omits a quantity reads as a report that found nothing to say about it.

  • model (str, optional) – The module:Class string of the black box that produced these numbers.

  • num_nodes (int, optional) – Analysis points per phase the run used.

Examples

>>> results["total_fuel"]
18597.3...
>>> results.by_discipline["weights"]["MTOW"]
78345.6...
property by_discipline: Mapping[str, Mapping[str, Any]]

Return the results grouped by discipline.

property missing: Mapping[str, tuple[str, ...]]

Return the optional responses the black box did not publish, by discipline.

property model: str

The black box that produced these numbers.

property num_nodes: int

Analysis points per phase the run used.

scalars()[source]

Return only the single-valued results, as floats.

Vector results – throttle histories and the like – are omitted, because the things a report tabulates and an optimizer constrains are scalars.

Return type:

dict[str, float]

to_dict()[source]

Return a plain, serializable dictionary of the whole run.

Return type:

dict[str, Any]

report(catalog=None)[source]

Return the run as a table, grouped by discipline.

Parameters:

catalog (ResponseCatalog, optional) – Used for units. Defaults to a catalogue of the standard disciplines.

Return type:

str

classmethod collect(box, disciplines)[source]

Read every discipline’s responses out of a converged box.

Parameters:
Return type:

SizingResults