Skip to content

report_helpers

utils.report.report_helpers

Helper methods for building standardized report sections.

utils.report.report_helpers.add_applied_documents

add_applied_documents(report: Report, docs: Sequence[Any]) -> None

Add applied code documents section to the report.

report : Report The report object to which the calculation steps will be added. docs : Sequence[Any] The list of applied code documents.

Source code in blueprints/utils/report/report_helpers.py
13
14
15
16
17
18
19
20
21
22
23
24
def add_applied_documents(report: Report, docs: Sequence[Any]) -> None:
    """
    Add applied code documents section to the report.

    report : Report
        The report object to which the calculation steps will be added.
    docs : Sequence[Any]
        The list of applied code documents.
    """
    report.add_heading("Applied code documents")
    report.add_paragraph("The following documents were applied in this check:")
    report.add_list(docs)

utils.report.report_helpers.add_applied_forces

add_applied_forces(
    report: Report, forces: ResultInternalForce1D, n: int = 2
) -> None

Add applied forces section to the report.

report : Report The report object to which the calculation steps will be added. forces : ResultInternalForce1D The internal forces object. n : int, optional Number of decimals (default is 2).

Source code in blueprints/utils/report/report_helpers.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def add_applied_forces(report: Report, forces: ResultInternalForce1D, n: int = 2) -> None:
    """
    Add applied forces section to the report.

    report : Report
        The report object to which the calculation steps will be added.
    forces : ResultInternalForce1D
        The internal forces object.
    n : int, optional
        Number of decimals (default is 2).
    """
    force_labels = {
        "n": "Normal force $N$ [kN]",
        "vz": "Shear force $V_z$ [kN]",
        "vy": "Shear force $V_y$ [kN]",
        "my": "Bending moment $M_y$ [kNm]",
        "mz": "Bending moment $M_z$ [kNm]",
        "mx": "Torsion $T$ [kNm]",
    }

    report.add_heading("Applied internal forces")
    report.add_paragraph("The following internal forces were applied in this check:")
    rows = []
    for force_attr in ["n", "vy", "vz", "mx", "my", "mz"]:
        value = getattr(forces, force_attr, None)
        if value is not None:
            label = force_labels[force_attr] if force_labels and force_attr in force_labels else force_attr.upper()
            rows.append([label, f"{value:.{n}f}"])
    report.add_table(headers=["Internal Force", "Value"], rows=rows)

utils.report.report_helpers.add_material_steel_info

add_material_steel_info(
    report: Report, steel_cross_section: SteelCrossSection, n: int = 2
) -> None

Add material and steel info to the report.

report : Report The report object to which the calculation steps will be added. steel_cross_section : SteelCrossSection The steel cross section object. n : int, optional Number of decimals (default is 2).

Source code in blueprints/utils/report/report_helpers.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def add_material_steel_info(report: Report, steel_cross_section: SteelCrossSection, n: int = 2) -> None:
    """
    Add material and steel info to the report.

    report : Report
        The report object to which the calculation steps will be added.
    steel_cross_section : SteelCrossSection
        The steel cross section object.
    n : int, optional
        Number of decimals (default is 2).
    """
    report.add_heading("Applied material and profile")
    report.add_paragraph("The following material properties were used in this check:")
    mat = steel_cross_section.material
    report.add_table(
        headers=["Property", "Value"],
        rows=[
            ["Material", str(getattr(mat, "name", mat))],
            ["Yield Strength $f_y$", f"{getattr(steel_cross_section, 'yield_strength', 0):.{n}f} MPa"],
            ["Ultimate Strength $f_u$", f"{getattr(steel_cross_section, 'ultimate_strength', 0):.{n}f} MPa"],
            ["Elastic Modulus $E$", f"{getattr(mat, 'e_modulus', 0):.{n}f} MPa"],
        ],
    )

utils.report.report_helpers.add_section_properties

add_section_properties(
    report: Report,
    section_properties: object,
    profile: object = None,
    n: int = 2,
    properties: Sequence[str] = ("area",),
) -> None

Add section properties to the report.

report : Report The report object to which the calculation steps will be added. section_properties : object The section properties object. profile : object, optional Optional profile object for name. n : int, optional Number of decimals (default is 2). properties : Sequence[str], optional List of property names to include (default is ("area",)).

Source code in blueprints/utils/report/report_helpers.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def add_section_properties(
    report: Report,
    section_properties: object,
    profile: object = None,
    n: int = 2,
    properties: Sequence[str] = ("area",),
) -> None:
    """
    Add section properties to the report.

    report : Report
        The report object to which the calculation steps will be added.
    section_properties : object
        The section properties object.
    profile : object, optional
        Optional profile object for name.
    n : int, optional
        Number of decimals (default is 2).
    properties : Sequence[str], optional
        List of property names to include (default is ("area",)).
    """
    # Mini dictionary of common property labels used in section reports
    # please note: sectionproperties uses x-y coordinates, while Blueprints y-z as in structural analysis
    property_labels = {
        # mm^2
        "area": "Area $A$ in $mm^{2}$",
        "a_sx": "Shear area $A_{sy}$ in $mm^{2}$",
        "a_sy": "Shear area $A_{sz}$ in $mm^{2}$",
        # mm
        "perimeter": "Perimeter $P$ in $mm$",
        # kg/m
        "mass": "Mass $W$ in $kg/m$",
        # mm^3
        "zxx_plus": "Section modulus $W_{y,el+}$ in $mm^{3}$",
        "zxx_minus": "Section modulus $W_{y,el-}$ in $mm^{3}$",
        "zyy_plus": "Section modulus $W_{z,el+}$ in $mm^{3}$",
        "zyy_minus": "Section modulus $W_{z,el-}$ in $mm^{3}$",
        "sxx": "Plastic section modulus $W_{y,pl}$ in $mm^{3}$",
        "syy": "Plastic section modulus $W_{z,pl}$ in $mm^{3}$",
        # mm^4
        "ixx_c": "Second moment of area $I_{y}$ in $mm^{4}$",
        "iyy_c": "Second moment of area $I_{z}$ in $mm^{4}$",
        "j": "Torsion constant $I_{T}$ in $mm^{4}$",
    }

    report.add_paragraph("The following section properties were used in this check:")
    rows = []
    if profile is not None:
        rows.append(["Profile", str(getattr(profile, "name", profile))])
    for prop in properties:
        label = property_labels[prop] if property_labels and prop in property_labels else prop.capitalize()
        value = getattr(section_properties, prop, None)
        if value is None:
            rows.append([label, "Not calculated"])
        else:
            value_str = f"{value:.{n}f}" if isinstance(value, float) else str(value)
            rows.append([label, value_str])

    report.add_table(headers=["Property", "Value"], rows=rows)

utils.report.report_helpers.add_unity_check_summary

add_unity_check_summary(
    report: Report,
    calculations: dict[str, Optional[CheckProtocol] | CheckResult],
    n: int = 2,
) -> None

Add a summary table of unity checks to the report.

report : Report The report object to which the calculation steps will be added. calculations : dict[str, "CheckProtocol" | CheckResult] Iterable of (check_name, check_instance) pairs where check_instance can be either a CheckProtocol object or a CheckResult object (e.g., dict.items() or list of tuples). n : int, optional Number of decimals (default is 2).

Source code in blueprints/utils/report/report_helpers.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
def add_unity_check_summary(report: Report, calculations: dict[str, Optional["CheckProtocol"] | CheckResult], n: int = 2) -> None:
    """
    Add a summary table of unity checks to the report.

    report : Report
        The report object to which the calculation steps will be added.
    calculations : dict[str, "CheckProtocol" | CheckResult]
        Iterable of (check_name, check_instance) pairs where check_instance can be either
        a CheckProtocol object or a CheckResult object (e.g., dict.items() or list of tuples).
    n : int, optional
        Number of decimals (default is 2).
    """
    report.add_heading("Utilization summary")
    rows = []
    overall_ok = True
    for check_name, check in calculations.items():
        if check is None:
            continue
        if isinstance(check, CheckResult):
            continue

        res = check.result()
        uc = getattr(res, "unity_check", None)
        utilization = f"{uc:.{n}f}" if uc is not None else "Not calculated"
        status = "OK" if getattr(res, "is_ok", False) else "NOT OK"
        if not getattr(res, "is_ok", False):
            overall_ok = False
        rows.append([check_name.capitalize(), utilization, status])
    if len(rows) == 0:
        report.add_paragraph("No checks were performed.")
        return
    report.add_table(headers=["Check", "Utilization", "Status"], rows=rows)
    report.add_paragraph(f"Overall result: {'OK' if overall_ok else 'NOT OK'}", bold=True)