Skip to content

cable_spec_parsers

CableSpecParser

CableSpecParser(cable_specs: Series)

Bases: ABC

Abstract base class for parsing cable specification rows into structured input schemas.

Parameters:

Name Type Description Default
cable_specs Series

Cable specification row from the source cable table.

required
Source code in cable_thermal_model/cable/cable_spec_parsers.py
42
43
44
45
46
47
48
49
def __init__(self, cable_specs: pd.Series):
    """Initialize parser with raw cable specification row.

    Args:
        cable_specs: Cable specification row from the source cable table.

    """
    self.cable_specs = cable_specs

get_internal_oil_duct_input abstractmethod

get_internal_oil_duct_input() -> (
    InternalOilDuctInputSchema | None
)

Build internal oil duct schema.

Returns:

Type Description
InternalOilDuctInputSchema | None

InternalOilDuctInputSchema | None: Oil duct schema when applicable, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
51
52
53
54
55
56
57
58
59
60
@abstractmethod
def get_internal_oil_duct_input(self) -> InternalOilDuctInputSchema | None:
    """Build internal oil duct schema.

    Returns:
        InternalOilDuctInputSchema | None: Oil duct schema when applicable,
            otherwise `None`.

    """
    pass

get_conductor_input abstractmethod

get_conductor_input() -> ConductorInputSchema

Build conductor schema for the current cable specs.

Returns:

Name Type Description
ConductorInputSchema ConductorInputSchema

Conductor layer schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
62
63
64
65
66
67
68
69
70
@abstractmethod
def get_conductor_input(self) -> ConductorInputSchema:
    """Build conductor schema for the current cable specs.

    Returns:
        ConductorInputSchema: Conductor layer schema.

    """
    pass

get_conductor_screen_input abstractmethod

get_conductor_screen_input() -> (
    ConductorScreenInputSchema | None
)

Build optional conductor screen schema.

Returns:

Type Description
ConductorScreenInputSchema | None

ConductorScreenInputSchema | None: Conductor screen schema when applicable, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
72
73
74
75
76
77
78
79
80
81
@abstractmethod
def get_conductor_screen_input(self) -> ConductorScreenInputSchema | None:
    """Build optional conductor screen schema.

    Returns:
        ConductorScreenInputSchema | None: Conductor screen schema when
            applicable, otherwise `None`.

    """
    pass

get_insulation_input abstractmethod

get_insulation_input() -> InsulationInputSchema

Build insulation schema for the current cable specs.

Returns:

Name Type Description
InsulationInputSchema InsulationInputSchema

Insulation layer schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
83
84
85
86
87
88
89
90
91
@abstractmethod
def get_insulation_input(self) -> InsulationInputSchema:
    """Build insulation schema for the current cable specs.

    Returns:
        InsulationInputSchema: Insulation layer schema.

    """
    pass

get_insulation_screen_input abstractmethod

get_insulation_screen_input() -> (
    InsulationScreenInputSchema | None
)

Build optional insulation screen schema.

Returns:

Type Description
InsulationScreenInputSchema | None

InsulationScreenInputSchema | None: Insulation screen schema when applicable, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
 93
 94
 95
 96
 97
 98
 99
100
101
102
@abstractmethod
def get_insulation_screen_input(self) -> InsulationScreenInputSchema | None:
    """Build optional insulation screen schema.

    Returns:
        InsulationScreenInputSchema | None: Insulation screen schema when
            applicable, otherwise `None`.

    """
    pass

get_screen_input

get_screen_input() -> ScreenInputSchema | None

Build optional metallic screen input schema.

Returns:

Type Description
ScreenInputSchema | None

ScreenInputSchema | None: Screen layer schema when present, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
def get_screen_input(self) -> ScreenInputSchema | None:
    """Build optional metallic screen input schema.

    Returns:
        ScreenInputSchema | None: Screen layer schema when present,
            otherwise `None`.

    """
    material = CableScreenMaterial(self.cable_specs["Sheath material"])
    if material == CableScreenMaterial.NONE.value:
        return None

    return ScreenInputSchema(
        material=material,
        inner_radius=None,
        thickness=float(self.cable_specs["t_she"]) / 1e3,  # convert to meters
        outer_radius=float(self.cable_specs["D_she_ext"]) / 2 / 1e3,  # convert to meters
        conducting_surface_area=float(self.cable_specs["A_she"]) / 1e6,  # convert to square meters
        screen_type=CableScreenType(self.cable_specs["Sheath/cable type"]),
    )

get_bedding_input

get_bedding_input() -> BeddingInputSchema | None

Build optional bedding layer input schema.

Returns:

Type Description
BeddingInputSchema | None

BeddingInputSchema | None: Bedding layer schema when present, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
def get_bedding_input(self) -> BeddingInputSchema | None:
    """Build optional bedding layer input schema.

    Returns:
        BeddingInputSchema | None: Bedding layer schema when present,
            otherwise `None`.

    """
    material = CableBeddingMaterial(self.cable_specs["Bedding material"])
    if material == CableBeddingMaterial.NONE.value:
        return None
    thickness = float(self.cable_specs["t_2"]) / 1e3  # convert to meters
    if np.isclose(thickness, 0):
        return None

    return BeddingInputSchema(
        material=material,
        inner_radius=None,
        thickness=thickness,
        outer_radius=None,
    )

get_armour_input

get_armour_input() -> ArmourInputSchema | None

Build optional armour layer input schema.

Returns:

Type Description
ArmourInputSchema | None

ArmourInputSchema | None: Armour layer schema when present, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
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
def get_armour_input(self) -> ArmourInputSchema | None:
    """Build optional armour layer input schema.

    Returns:
        ArmourInputSchema | None: Armour layer schema when present,
            otherwise `None`.

    """
    material = CableArmourMaterial(self.cable_specs["Arm material"])
    if material == CableArmourMaterial.NONE.value:
        return None

    conducting_surface_area = float(self.cable_specs["A_tape"]) / 1e6
    if conducting_surface_area <= 0:
        d_wire = float(self.cable_specs["d_wire"]) / 1e3  # convert to meters
        n_wireOrTape = float(self.cable_specs["n_wireOrTape"])
        conducting_surface_area = np.pi / 4 * d_wire**2 * n_wireOrTape

    return ArmourInputSchema(
        material=material,
        inner_radius=float(self.cable_specs["D_arm_int"]) / 2 / 1e3,  # convert to meters
        thickness=None,
        outer_radius=float(self.cable_specs["D_arm_ext"]) / 2 / 1e3,  # convert to meters
        conducting_surface_area=conducting_surface_area,  # convert to square meters
    )

get_sheath_input

get_sheath_input() -> SheathInputSchema

Build outer sheath layer input schema.

Returns:

Name Type Description
SheathInputSchema SheathInputSchema

Sheath layer schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
def get_sheath_input(self) -> SheathInputSchema:
    """Build outer sheath layer input schema.

    Returns:
        SheathInputSchema: Sheath layer schema.

    """
    material = CableSheathMaterial(self.cable_specs["Cable serving material"])

    return SheathInputSchema(
        material=material,
        inner_radius=None,
        thickness=None,
        outer_radius=float(self.cable_specs["D_ext"]) / 2 / 1e3,  # convert to meters
    )

get_cable_constructional_input

get_cable_constructional_input() -> (
    CableConstructionalInputSchema
)

Compose full cable constructional schema from parsed fields.

Returns:

Name Type Description
CableConstructionalInputSchema CableConstructionalInputSchema

Fully assembled constructional input schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
def get_cable_constructional_input(self) -> CableConstructionalInputSchema:
    """Compose full cable constructional schema from parsed fields.

    Returns:
        CableConstructionalInputSchema: Fully assembled constructional
            input schema.

    """
    return CableConstructionalInputSchema(
        number_of_conductors=CableConductorCount(self.cable_specs["Number of conductors"]),
        oil_duct_input=self.get_internal_oil_duct_input(),
        conductor_input=self.get_conductor_input(),
        conductor_screen_input=self.get_conductor_screen_input(),
        insulation_input=self.get_insulation_input(),
        insulation_screen_input=self.get_insulation_screen_input(),
        screen_input=self.get_screen_input(),
        bedding_input=self.get_bedding_input(),
        armour_input=self.get_armour_input(),
        sheath_input=self.get_sheath_input(),
    )

SingleCoreSpecParser

SingleCoreSpecParser(cable_specs: Series)

Bases: CableSpecParser

Parser for single-core cable specifications.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
42
43
44
45
46
47
48
49
def __init__(self, cable_specs: pd.Series):
    """Initialize parser with raw cable specification row.

    Args:
        cable_specs: Cable specification row from the source cable table.

    """
    self.cable_specs = cable_specs

get_internal_oil_duct_input

get_internal_oil_duct_input() -> (
    InternalOilDuctInputSchema | None
)

Build optional internal oil duct schema for single-core cables.

Returns:

Type Description
InternalOilDuctInputSchema | None

InternalOilDuctInputSchema | None: Oil duct schema when a duct is defined, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
def get_internal_oil_duct_input(self) -> InternalOilDuctInputSchema | None:
    """Build optional internal oil duct schema for single-core cables.

    Returns:
        InternalOilDuctInputSchema | None: Oil duct schema when a duct is
            defined, otherwise `None`.

    """
    if self.cable_specs["d_int_cond"] > 0.0:
        return InternalOilDuctInputSchema(
            material=CableOilMaterial.Oil,
            inner_radius=None,
            thickness=None,
            outer_radius=float(self.cable_specs["d_int_cond"]) / 2 / 1e3,  # convert to meters
        )
    else:
        return None

get_conductor_input

get_conductor_input() -> ConductorInputSchema

Build conductor input schema for a single-core cable.

Returns:

Name Type Description
ConductorInputSchema ConductorInputSchema

Conductor layer schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def get_conductor_input(self) -> ConductorInputSchema:
    """Build conductor input schema for a single-core cable.

    Returns:
        ConductorInputSchema: Conductor layer schema.

    """
    shape = CableConductorShape(self.cable_specs["Shape"])
    if shape == CableConductorShape.Round and self.cable_specs["d_int_cond"] > 0.0:
        shape = CableConductorShape.Hollow
    return ConductorInputSchema(
        material=CableConductorMaterial(self.cable_specs["Material"]),
        shape=shape,
        surface_type=CableConductorSurfaceType(self.cable_specs["Type"]),
        outer_radius=float(self.cable_specs["d_cond"]) / 2 / 1e3,  # convert to meters
        inner_radius=None,
        thickness=None,
        conducting_surface_area=float(self.cable_specs["A_cond"]) / 1e6,  # convert to square meters
    )

get_conductor_screen_input

get_conductor_screen_input() -> (
    ConductorScreenInputSchema | None
)

Build optional conductor screen schema for single-core cables.

Returns:

Type Description
ConductorScreenInputSchema | None

ConductorScreenInputSchema | None: Screen schema when thickness is positive, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
def get_conductor_screen_input(self) -> ConductorScreenInputSchema | None:
    """Build optional conductor screen schema for single-core cables.

    Returns:
        ConductorScreenInputSchema | None: Screen schema when thickness is
            positive, otherwise `None`.

    """
    thickness = self._compute_conductor_instulation_screen_thickness()
    if thickness <= 0:
        return None

    material = CableConductorInsulationScreenMaterial(self.cable_specs["Conductor/isolation screen"])
    return ConductorScreenInputSchema(
        material=material,
        inner_radius=None,
        thickness=thickness,  # convert to meters
        outer_radius=None,
    )

get_insulation_input

get_insulation_input() -> InsulationInputSchema

Build insulation input schema for a single-core cable.

Returns:

Name Type Description
InsulationInputSchema InsulationInputSchema

Insulation layer schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
def get_insulation_input(self) -> InsulationInputSchema:
    """Build insulation input schema for a single-core cable.

    Returns:
        InsulationInputSchema: Insulation layer schema.

    """
    material = CableInsulationMaterial(self.cable_specs["Isolation material"])
    return InsulationInputSchema(
        material=material,
        nominal_phase_voltage=float(self.cable_specs["U_0"]),
        inner_radius=None,
        thickness=float(self.cable_specs["t1"]) / 1e3,  # convert to meters
        outer_radius=None,
    )

get_insulation_screen_input

get_insulation_screen_input() -> (
    InsulationScreenInputSchema | None
)

Build optional insulation screen schema for single-core cables.

Returns:

Type Description
InsulationScreenInputSchema | None

InsulationScreenInputSchema | None: Screen schema when thickness is positive, otherwise None.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
def get_insulation_screen_input(self) -> InsulationScreenInputSchema | None:
    """Build optional insulation screen schema for single-core cables.

    Returns:
        InsulationScreenInputSchema | None: Screen schema when thickness is
            positive, otherwise `None`.

    """
    thickness = self._compute_conductor_instulation_screen_thickness()
    if thickness <= 0:
        return None

    material = CableConductorInsulationScreenMaterial(self.cable_specs["Conductor/isolation screen"])
    return InsulationScreenInputSchema(
        material=material,
        inner_radius=None,
        thickness=thickness,
        outer_radius=None,
    )

ThreeCoreSpecParser

ThreeCoreSpecParser(cable_specs: Series)

Bases: CableSpecParser

Parser for three-core cable specifications.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
42
43
44
45
46
47
48
49
def __init__(self, cable_specs: pd.Series):
    """Initialize parser with raw cable specification row.

    Args:
        cable_specs: Cable specification row from the source cable table.

    """
    self.cable_specs = cable_specs

get_internal_oil_duct_input

get_internal_oil_duct_input() -> (
    InternalOilDuctInputSchema | None
)

Return oil duct schema for three-core cables.

Returns:

Type Description
InternalOilDuctInputSchema | None

InternalOilDuctInputSchema | None: Always None, because three-core cables are modeled without an internal oil duct layer.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
329
330
331
332
333
334
335
336
337
def get_internal_oil_duct_input(self) -> InternalOilDuctInputSchema | None:
    """Return oil duct schema for three-core cables.

    Returns:
        InternalOilDuctInputSchema | None: Always `None`, because three-core
            cables are modeled without an internal oil duct layer.

    """
    return None

get_conductor_input

get_conductor_input() -> ConductorInputSchema

Build conductor input schema for a three-core cable.

Returns:

Name Type Description
ConductorInputSchema ConductorInputSchema

Conductor layer schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def get_conductor_input(self) -> ConductorInputSchema:
    """Build conductor input schema for a three-core cable.

    Returns:
        ConductorInputSchema: Conductor layer schema.

    """
    shape = CableConductorShape(self.cable_specs["Shape"])

    return ConductorInputSchema(
        material=CableConductorMaterial(self.cable_specs["Material"]),
        shape=shape,
        surface_type=CableConductorSurfaceType(self.cable_specs["Type"]),
        outer_radius=None,
        inner_radius=None,
        thickness=None,
        conducting_surface_area=float(self.cable_specs["A_cond"]) / 1e6,  # convert to square meters
        single_conductor_radius=float(self.cable_specs["d_cond"]) / 2 / 1e3
        if shape == CableConductorShape.Round
        else None,  # convert to meters
    )

get_conductor_screen_input

get_conductor_screen_input() -> (
    ConductorScreenInputSchema | None
)

Return conductor screen schema for three-core cables.

Returns:

Type Description
ConductorScreenInputSchema | None

ConductorScreenInputSchema | None: Always None; three-core conductor-screen handling is embedded in insulation schema.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
361
362
363
364
365
366
367
368
369
def get_conductor_screen_input(self) -> ConductorScreenInputSchema | None:
    """Return conductor screen schema for three-core cables.

    Returns:
        ConductorScreenInputSchema | None: Always `None`; three-core
            conductor-screen handling is embedded in insulation schema.

    """
    return None

get_insulation_input

get_insulation_input() -> (
    ThreeCoreCableInsulationInputSchema
)

Build three-core specific insulation input schema.

Returns:

Name Type Description
ThreeCoreCableInsulationInputSchema ThreeCoreCableInsulationInputSchema

Insulation layer schema with three-core specific fields.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
def get_insulation_input(self) -> ThreeCoreCableInsulationInputSchema:
    """Build three-core specific insulation input schema.

    Returns:
        ThreeCoreCableInsulationInputSchema: Insulation layer schema with
            three-core specific fields.

    """
    material = CableInsulationMaterial(self.cable_specs["Isolation material"])

    if float(self.cable_specs["delta_1"]) > 0:
        conductor_screen_thickness = float(self.cable_specs["delta_1"]) / 1e3  # convert to meters
        conductor_screen_material = CableConductorInsulationScreenMaterial(
            self.cable_specs["Conductor/isolation screen"]
        )
    else:
        conductor_screen_thickness = None
        conductor_screen_material = None

    return ThreeCoreCableInsulationInputSchema(
        material=material,
        inner_radius=None,
        thickness=None,
        outer_radius=None,
        nominal_phase_voltage=float(self.cable_specs["U_0"]),
        diameter_over_stranded_conductors=float(self.cable_specs["Doga"]) / 1e3,  # convert to meters
        single_conductor_insulation_thickness=float(self.cable_specs["t1"]) / 1e3,  # convert to meters
        conductor_screen_material=conductor_screen_material,
        conductor_screen_thickness=conductor_screen_thickness,
    )

get_insulation_screen_input

get_insulation_screen_input() -> (
    InsulationScreenInputSchema | None
)

Return insulation screen schema for three-core cables.

Returns:

Type Description
InsulationScreenInputSchema | None

InsulationScreenInputSchema | None: Always None; three-core equivalent modeling does not create a separate layer.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
402
403
404
405
406
407
408
409
410
def get_insulation_screen_input(self) -> InsulationScreenInputSchema | None:
    """Return insulation screen schema for three-core cables.

    Returns:
        InsulationScreenInputSchema | None: Always `None`; three-core
            equivalent modeling does not create a separate layer.

    """
    return None

SpecParserFactory

Factory that returns the appropriate CableSpecParser for cable specification.

get_spec_parser staticmethod

get_spec_parser(cable_specs: Series) -> CableSpecParser

Create the parser matching conductor count in cable specs.

Parameters:

Name Type Description Default
cable_specs Series

Cable specification row from source table.

required

Returns:

Name Type Description
CableSpecParser CableSpecParser

Single-core or three-core parser instance.

Raises:

Type Description
ValueError

If number of conductors is unsupported.

Source code in cable_thermal_model/cable/cable_spec_parsers.py
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
@staticmethod
def get_spec_parser(cable_specs: pd.Series) -> CableSpecParser:
    """Create the parser matching conductor count in cable specs.

    Args:
        cable_specs: Cable specification row from source table.

    Returns:
        CableSpecParser: Single-core or three-core parser instance.

    Raises:
        ValueError: If number of conductors is unsupported.

    """
    number_of_conductors = CableConductorCount(cable_specs["Number of conductors"])
    if number_of_conductors == CableConductorCount.One:
        return SingleCoreSpecParser(cable_specs=cable_specs)
    elif number_of_conductors == CableConductorCount.Three:
        return ThreeCoreSpecParser(cable_specs=cable_specs)
    else:
        raise ValueError(f"Unsupported number of conductors: {number_of_conductors}")