Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Primitives, enum and CIM_datatype #39

Merged

Conversation

HUG0-D
Copy link
Contributor

@HUG0-D HUG0-D commented Oct 21, 2024

Enum classes

Correctly defining classes with defined values, using Enum. (Issue: #38 )
Examples: UnitSymbol or UnitMultiplier

Primitives classes

The current model generates classes for primitives, which are then rarely used to define the other classes.
Instead of creating individual classes for each primitives, a generic Primitive class is created.
Examples:
Float = Primitive(name="Float", type=float, profiles=[Profile.EQBD, Profile.OP, Profile.SSH, Profile.EQ, Profile.DY, Profile.DL, Profile.SV, Profile.SC, ])

Common CIMDatatype class

The current model generates datatypes that are then never used in the cim classes (example: CurrentFlow).
Instead of creating multiple unused classes with the same attributes (multiplier, unit, value), this pr creates a generic CIMDatatype class. (Issue: #38 )
Examples:
CurrentFlow = CIMDatatype(name="CurrentFlow", type=float, symbol=UnitSymbol.A, multiplier=UnitMultiplier.none, profiles=[Profile.SSH,Profile.EQ,Profile.SV,Profile.SC,])

Annotation of the data type

As said above, the newly created datatypes are added as annotation (data_type) when creating the other classes.

@dataclass
class CurrentLimit(OperationalLimit):
    """
    Operational limit on current.

    normalValue: The normal value for limit on current flow. The attribute shall be a positive value or zero.
    value: Limit on current flow. The attribute shall be a positive value or zero.
    """

    normalValue : float = Field(default=0.0, data_type = CurrentFlow, json_schema_extra={"in_profiles":[Profile.EQ, ]}) 

    value : float = Field(default=0.0, data_type = CurrentFlow, json_schema_extra={"in_profiles":[Profile.SSH, ]}) 



    @cached_property
    def possible_profiles(self)->set[BaseProfile]:
        """
        A resource can be used by multiple profiles. This is the set of profiles
        where this element can be found.
        """
        return { Profile.EQ, Profile.SSH,  }

@HUG0-D HUG0-D force-pushed the enum-datatypes-implementation branch 2 times, most recently from 26640c4 to a0d0068 Compare October 28, 2024 11:37
@m-mirz m-mirz self-assigned this Nov 8, 2024
Copy link
Contributor

@m-mirz m-mirz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine apart from the failing formatting check. Thanks!

@HUG0-D HUG0-D requested a review from m-mirz November 11, 2024 08:39
@chicco785
Copy link
Collaborator

@HUG0-D not necessarily linked to this PR, but it seems we have lot of annotations that may be redundant in attributes:

"""
Generated from the CGMES files via cimgen: https://github.com/sogno-platform/cimgen
"""

from functools import cached_property
from typing import Optional

from pydantic import Field
from pydantic.dataclasses import dataclass

from ..utils.profile import BaseProfile, Profile
from .Conductor import Conductor
from .Conductance import Conductance
from .Susceptance import Susceptance
from .Resistance import Resistance
from .Reactance import Reactance
from .Temperature import Temperature


@dataclass
class ACLineSegment(Conductor):
    """
    A wire or combination of wires, with consistent electrical characteristics, building a single electrical system,
      used to carry alternating current between points in the power system. For symmetrical, transposed 3ph lines,
      it is sufficient to use  attributes of the line segment, which describe impedances and admittances for the
      entire length of the segment.  Additionally impedances can be computed by using length and associated per
      length impedances. The BaseVoltage at the two ends of ACLineSegments in a Line shall have the same
      BaseVoltage.nominalVoltage. However, boundary lines  may have slightly different BaseVoltage.nominalVoltages
      and  variation is allowed. Larger voltage difference in general requires use of an equivalent branch.

    b0ch: Zero sequence shunt (charging) susceptance, uniformly distributed, of the entire line section.
    bch: Positive sequence shunt (charging) susceptance, uniformly distributed, of the entire line section.  This value
      represents the full charging over the full length of the line.
    g0ch: Zero sequence shunt (charging) conductance, uniformly distributed, of the entire line section.
    gch: Positive sequence shunt (charging) conductance, uniformly distributed, of the entire line section.
    r: Positive sequence series resistance of the entire line section.
    r0: Zero sequence series resistance of the entire line section.
    shortCircuitEndTemperature: Maximum permitted temperature at the end of SC for the calculation of minimum short-
      circuit currents. Used for short circuit data exchange according to IEC 60909
    x: Positive sequence series reactance of the entire line section.
    x0: Zero sequence series reactance of the entire line section.
    """

    b0ch: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Susceptance,
		},
    )

    bch: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Susceptance,
		},
    )

    g0ch: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Conductance,
		},
    )

    gch: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Conductance,
		},
    )

    r: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Resistance,
		},
    )

    r0: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Resistance,
		},
    )

    shortCircuitEndTemperature: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Temperature,
		},
    )

    x: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Reactance,
		},
    )

    x0: float = Field(
        default=0.0,
        json_schema_extra={
            "in_profiles": [
                Profile.EQ,
            ],
            "is_used": True,
            "is_class_attribute": False,
            "is_enum_attribute": False,
            "is_list_attribute": False,
            "is_primitive_attribute": False,
            "is_cim_datatype": True,
            "cim_data_type": Reactance,
		},
    )

    @cached_property
    def possible_profiles(self) -> set[BaseProfile]:
        """
        A resource can be used by multiple profiles. This is the set of profiles
        where this element can be found.
        """
        return {
            Profile.EQ,
        }

    @cached_property
    def recommended_profile(self) -> BaseProfile:
        """
        This is the profile with most of the attributes.
        It should be used to write the data to as few as possible files.
        """
        return Profile.EQ

  • "is_enum_attribute": False could be defined clearly by the linked type;
  • "is_primitive_attribute": False, "is_cim_datatype": True, "cim_data_type": Reactance,: seems overlapping.
  • When "is_list_attribute": True, we have anyhow pydantic annotations stating that:
  Cut: list = Field(
        default_factory=list,

@m-mirz m-mirz requested a review from tom-hg57 November 14, 2024 13:48
@m-mirz
Copy link
Contributor

m-mirz commented Nov 14, 2024

@HUG0-D I have noticed that you have two "rebase branch" commits in this PR. Why do these commits exist? Usually there should not be a new commit introduced by the rebase process. I am referring to 01729ef and bdd09b4

@HUG0-D
Copy link
Contributor Author

HUG0-D commented Nov 15, 2024

@m-mirz thank you for pointing that out! This was my first time using rebase, and I realize now that I might not have followed the correct process, which led to those extra “rebase branch” commits. I tried to handle some merge conflicts manually, and doing so, I think I mistakenly created those additional commits.

@HUG0-D HUG0-D force-pushed the enum-datatypes-implementation branch from 21f2a5d to 8759e25 Compare November 15, 2024 15:19
@HUG0-D
Copy link
Contributor Author

HUG0-D commented Nov 15, 2024

@m-mirz During the rebase process, I encountered several issues that resulted in a messy commit history. To ensure the PR is clean and easy to review, I created a new branch from main and reapplied my changes with a clean commit structure.

The functionality and content of the PR remain the same as before, but now the history is more streamlined. Please let me know if you have any questions or concerns.

Thanks for your understanding!

cimgen/languages/modernpython/lang_pack.py Outdated Show resolved Hide resolved
cimgen/cimgen.py Outdated Show resolved Hide resolved
cimgen/cimgen.py Outdated Show resolved Hide resolved
@tom-hg57
Copy link
Collaborator

it seems we have lot of annotations that may be redundant in attributes:

Most of these annotations comes from my PR #36 to provide information about the disjoint attribute types. Now, including "datatype" there are 5 disjoint attribute types:

  1. is_class_attribute
  2. is_enum_attribute
  3. is_datatype_attribute
  4. is_list_attribute
  5. is_primitive_attribute

Maybe a single "attribute_type" (class, enum, ...) would be less noisy. But these booleans could easily used in chevron templates.

Signed-off-by: HUG0-D <[email protected]>
…e_class", "is_a_cim_datatype" --> "is_a_datatype_class", "is_cim_datatype" --> "is_datatype_attribute"

Signed-off-by: HUG0-D <[email protected]>
@HUG0-D HUG0-D force-pushed the enum-datatypes-implementation branch from 73ff2ac to 2c3d74c Compare November 18, 2024 13:39
@HUG0-D HUG0-D requested a review from tom-hg57 November 18, 2024 14:26
@tom-hg57
Copy link
Collaborator

I know it's not caused by your changes, but I think this import in base.py is wrong:
from pycgmes.utils.constants import NAMESPACES

This should be:
from .utils.constants import NAMESPACES

In the same way "pycgmes" should be removed from chevron_writer.py.

And the comment in cimpy_cgmesProfile_template.mustache should be changed to:
All CGMES objects requiring a Profile are actually asking for a BaseProfile.

cimgen/languages/modernpython/lang_pack.py Outdated Show resolved Hide resolved
cimgen/languages/modernpython/lang_pack.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@guillaume-alliander guillaume-alliander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some python comments.

cimgen/languages/modernpython/lang_pack.py Outdated Show resolved Hide resolved
cimgen/languages/modernpython/lang_pack.py Outdated Show resolved Hide resolved
cimgen/languages/modernpython/lang_pack.py Outdated Show resolved Hide resolved
Remove need for os library

Signed-off-by: HUG0-D <[email protected]>
@m-mirz m-mirz merged commit 13af877 into sogno-platform:master Nov 23, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants