Skip to content

Report

Data models for report production.

ActivityColumnMetric dataclass

ActivityColumnMetric(activity, metric_column, metric_type=MetricType.NOT_SET, expression='')

This class provides granular control of the metric applied in each activity's column.

is_valid

is_valid()

Checks if the activity column metric is valid.

Returns:

Type Description
bool

True if the activity column metric is valid else False.

Source code in src/cplus_plugin/models/report.py
def is_valid(self) -> bool:
    """Checks if the activity column metric is valid.

    :returns: True if the activity column metric is
    valid else False.
    :rtype: bool
    """
    if self.activity is None or self.metric_column is None:
        return False

    if self.metric_type == MetricType.NOT_SET:
        return False

    if not self.expression:
        return False

    return True

ActivityContextInfo dataclass

ActivityContextInfo(activity, area)

Contains information about an activity for use in an expression context.

BaseReportContext dataclass

BaseReportContext(template_path, name, project_file, feedback)

Common context information for generating a scenario report.

MetricColumn dataclass

MetricColumn(name, header, expression, alignment=QtCore.Qt.AlignHCenter, auto_calculated=False, format_as_number=True, number_formatter=QgsFallbackNumericFormat)

This class contains information required to create custom columns for the activity table in a scenario analysis report.

create_default_column staticmethod

create_default_column(name, header, expression='')

Creates a default metric column.

:py:attr:~format_as_number is set to True and :py:attr:~number_formatter is set to two decimals places with a thousands' comma separator.

Parameters:

Name Type Description Default
name str

Unique column name.

required
header str

Label that will be used in the activity metrics table.

required
expression str

Column expression. Default is an empty string.

''

Returns:

Type Description
MetricColumn

Metric column object.

Source code in src/cplus_plugin/models/report.py
@staticmethod
def create_default_column(
    name: str, header: str, expression: str = ""
) -> "MetricColumn":
    """Creates a default metric column.

    :py:attr:`~format_as_number` is set to True and
    :py:attr:`~number_formatter` is set to two decimals
    places with a thousands' comma separator.

    :param name: Unique column name.
    :type name: str

    :param header: Label that will be used in the
    activity metrics table.
    :type header: str

    :param expression: Column expression. Default is an
    empty string.
    :type expression: str

    :returns: Metric column object.
    :rtype: MetricColumn
    """
    number_formatter = MetricColumn.default_formatter()

    column = MetricColumn(name, header, expression)
    column.number_formatter = number_formatter

    return column

default_formatter staticmethod

default_formatter()

Returns a default number formatter with two decimals places and a comma for thousands' separator.

Returns:

Type Description
QgsNumericFormat

Basic number formatter.

Source code in src/cplus_plugin/models/report.py
@staticmethod
def default_formatter() -> QgsNumericFormat:
    """Returns a default number formatter with two
    decimals places and a comma for thousands'
    separator.

    :returns: Basic number formatter.
    :rtype: QgsNumericFormat
    """
    number_formatter = QgsBasicNumericFormat()
    number_formatter.setThousandsSeparator(",")
    number_formatter.setShowTrailingZeros(True)
    number_formatter.setNumberDecimalPlaces(2)

    return number_formatter

to_qgs_column

to_qgs_column()

Convenience function that converts this object to a QgsLayoutTableColumn for use in a QgsLayoutTable.

Returns:

Type Description
QgsLayoutTableColumn

A layout column object containing the heading, horizontal alignment and width specified.

Source code in src/cplus_plugin/models/report.py
def to_qgs_column(self) -> QgsLayoutTableColumn:
    """Convenience function that converts this object to a
    QgsLayoutTableColumn for use in a QgsLayoutTable.

    :returns: A layout column object containing the heading,
    horizontal alignment and width specified.
    :rtype: QgsLayoutTableColumn
    """
    layout_column = QgsLayoutTableColumn(self.header)
    layout_column.setHAlignment(self.alignment)
    layout_column.setWidth(0)

    return layout_column

MetricConfiguration dataclass

MetricConfiguration(metric_columns, activity_metrics)

Container for metric column and activity column metric data models.

activities property

activities

Gets the activity models in the configuration.

Returns:

Type Description
typing.List[Activity]

Activity models in the configuration.

create staticmethod

create()

Creates an empty metric configuration.

Returns:

Type Description
MetricConfiguration

An empty metric configuration.

Source code in src/cplus_plugin/models/report.py
@staticmethod
def create() -> "MetricConfiguration":
    """Creates an empty metric configuration.

    :returns: An empty metric configuration.
    :rtype: MetricConfiguration
    """
    return MetricConfiguration([], [[]])

find

find(activity_id, name_header)

Returns a matching activity column metric model for the activity with the given UUID and the corresponding metric column name or header label.

Parameters:

Name Type Description Default
activity_id str

The activity's unique identifier.

required
name_header str

The metric column name or header to match.

required

Returns:

Type Description
typing.Optional[ActivityColumnMetric]

Matching column metric or None if not found.

Source code in src/cplus_plugin/models/report.py
def find(
    self, activity_id: str, name_header: str
) -> typing.Optional[ActivityColumnMetric]:
    """Returns a matching activity column metric model
    for the activity with the given UUID and the corresponding
    metric column name or header label.

    :param activity_id: The activity's unique identifier.
    :type activity_id: str

    :param name_header: The metric column name or header to match.
    :type name_header: str

    :returns: Matching column metric or None if not found.
    :rtype: typing.Optional[ActivityColumnMetric]
    """

    def _search_list(model_list: typing.List, activity_identifier: str, name: str):
        for model in model_list:
            if isinstance(model, list):
                yield from _search_list(model, activity_identifier, name)
            else:
                if str(model.activity.uuid) == activity_identifier and (
                    model.metric_column.name == name
                    or model.metric_column.name == name
                ):
                    yield model

    match = next(_search_list(self.activity_metrics, activity_id, name_header), -1)

    return match if match != -1 else None

is_valid

is_valid()

Checks the validity of the configuration.

It verifies if the number of metric columns matches the column mappings for activity metrics.

Returns:

Type Description
bool

True if the configuration is valid, else False.

Source code in src/cplus_plugin/models/report.py
def is_valid(self) -> bool:
    """Checks the validity of the configuration.

    It verifies if the number of metric columns matches the
    column mappings for activity metrics.

    :returns: True if the configuration is valid, else False.
    :rtype: bool
    """
    column_metrics_len = 0
    if len(self.activity_metrics) > 0:
        column_metrics_len = len(self.activity_metrics[0])

    return len(self.metric_columns) == column_metrics_len

MetricConfigurationProfile dataclass

MetricConfigurationProfile(name, config)

Profile with unique identifiers for a metrics configuration.

id property

id

Gets a cleaned profile name that has been stripped of spaces, special characters and in lower case.

Returns:

Type Description
str

Cleaned version of the name attribute.

is_valid

is_valid()

Checks if the profile is valid.

Checks if the name is specified or if the metric configuration is valid.

Returns:

Type Description
bool

True if the profile is valid else False.

Source code in src/cplus_plugin/models/report.py
def is_valid(self) -> bool:
    """Checks if the profile is valid.

    Checks if the name is specified or if the metric
    configuration is valid.

    :returns: True if the profile is valid else False.
    :rtype: bool
    """
    if not self.name.strip() or not self.config.is_valid():
        return False

    return True

MetricEvalResult dataclass

MetricEvalResult(success, value)

Result of evaluating a metric.

MetricProfileCollection dataclass

MetricProfileCollection(current_profile='', profiles=list())

Collection of MetricConfigurationProfile objects.

identifiers property

identifiers

Gets a collection of profile IDs and corresponding names.

Invalid profiles are excluded from the collection.

Returns:

Type Description
dict

A collection of profile IDs and corresponding names.

add_profile

add_profile(profile)

Add a metric profile to the collection.

It checks if there is an existing profile with a similar ID and if the profile is valid.

Parameters:

Name Type Description Default
profile MetricConfigurationProfile

Metric profile to be added to the collection.

required

Returns:

Type Description
bool

True if the metric profile was successfully added else False if the profile is invalid or there exists one with a similar ID in the collection.

Source code in src/cplus_plugin/models/report.py
def add_profile(self, profile: MetricConfigurationProfile) -> bool:
    """Add a metric profile to the collection.

    It checks if there is an existing profile with a
    similar ID and if the profile is valid.

    :param profile: Metric profile to be added to the collection.
    :type profile: MetricConfigurationProfile

    :returns: True if the metric profile was successfully added else
    False if the profile is invalid or there exists one with a
    similar ID in the collection.
    :rtype: bool
    """
    if not profile.is_valid() or self.profile_exists(profile.id):
        return False

    self.profiles.append(profile)

    return True

get_current_profile

get_current_profile()

Helper function that retrieves the current metric profile if it has been specified in the attribute.

Returns:

Type Description
MetricConfigurationProfile

Current metric profile object or None if not specified or not found in the collection.

Source code in src/cplus_plugin/models/report.py
def get_current_profile(self) -> typing.Optional[MetricConfigurationProfile]:
    """Helper function that retrieves the current metric profile if it has
    been specified in the attribute.

    :returns: Current metric profile object or None if not specified
    or not found in the collection.
    :rtype: MetricConfigurationProfile
    """
    if not self.current_profile:
        return None

    return self.get_profile(self.current_profile)

get_profile

get_profile(profile_id)

Gets a metric profile with the given ID.

Parameters:

Name Type Description Default
profile_id str

ID of the metric profile to retrieve.

required

Returns:

Type Description
MetricConfigurationProfile

Metric profile matching the given ID or None if not found.

Source code in src/cplus_plugin/models/report.py
def get_profile(
    self, profile_id: str
) -> typing.Optional[MetricConfigurationProfile]:
    """Gets a metric profile with the given ID.

    :param profile_id: ID of the metric profile to retrieve.
    :type profile_id: str

    :returns: Metric profile matching the given ID or None if
    not found.
    :rtype: MetricConfigurationProfile
    """
    profiles = [profile for profile in self.profiles if profile.id == profile_id]

    return profiles[0] if profiles else None

profile_exists

profile_exists(profile_id)

Checks if a profile with the given ID exists in the collection.

Returns:

Type Description
bool

True if the profile ID exists else False.

Source code in src/cplus_plugin/models/report.py
def profile_exists(self, profile_id: str) -> bool:
    """Checks if a profile with the given ID exists in the collection.

    :returns: True if the profile ID exists else False.
    :rtype: bool
    """
    return profile_id in self.identifiers

remove_profile

remove_profile(profile_id)

Remove a metric profile from the collection.

Returns:

Type Description
bool

True if the profile was successfully removed else False if the profile with the given ID does not exist in the collection.

Source code in src/cplus_plugin/models/report.py
def remove_profile(self, profile_id: str) -> bool:
    """Remove a metric profile from the collection.

    :returns: True if the profile was successfully removed else
    False if the profile with the given ID does not exist in
    the collection.
    :rtype: bool
    """
    if not self.profile_exists(profile_id):
        return False

    self.profiles = [
        profile for profile in self.profiles if profile.id != profile_id
    ]

    return True

MetricType

Bases: IntEnum

Type of metric or expression.

from_int staticmethod

from_int(int_enum)

Creates the metric type enum from the corresponding int equivalent.

Parameters:

Name Type Description Default
int_enum int

Integer representing the metric type.

required

Returns:

Type Description
MetricType

Metric type enum corresponding to the given int else unknown if not found.

Source code in src/cplus_plugin/models/report.py
@staticmethod
def from_int(int_enum: int) -> "MetricType":
    """Creates the metric type enum from the
    corresponding int equivalent.

    :param int_enum: Integer representing the metric type.
    :type int_enum: int

    :returns: Metric type enum corresponding to the given
    int else unknown if not found.
    :rtype: MetricType
    """
    if int_enum == 0:
        return MetricType.COLUMN
    elif int_enum == 1:
        return MetricType.CELL
    elif int_enum == 2:
        return MetricType.NOT_SET
    else:
        return MetricType.UNKNOWN

RepeatAreaDimension dataclass

RepeatAreaDimension(rows, columns, width, height)

Contains information for rendering repeat model items such as scenarios or activities in a CPlus repeat item.

ReportContext dataclass

ReportContext(template_path, name, project_file, feedback, scenario, scenario_output_dir, output_layer_name, custom_metrics)

Bases: BaseReportContext

Context information for generating a scenario analysis report.

ReportResult dataclass

ReportResult(success, scenario_id, output_dir, messages=tuple(), name='', base_file_name='')

Detailed result information from a report generation run.

pdf_path property

pdf_path

Returns the absolute path to the PDF file if the process completed successfully.

Caller needs to verify if the file actually exists in the given location.

:returns: Absolute path to the PDF file if the process completed successfully else an empty string.

ReportSubmitStatus dataclass

ReportSubmitStatus(status, feedback, identifier)

Result of report submission process.

ScenarioAreaInfo dataclass

ScenarioAreaInfo(name, identifier, area=dict())

Contains information on the result of calculating a scenario's area.

ScenarioComparisonReportContext dataclass

ScenarioComparisonReportContext(template_path, name, project_file, feedback, results, output_dir)

Bases: BaseReportContext

Contextual information related to the generation of scenario comparison report.


Last update: June 9, 2025
Back to top