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
45
46
47
48
49
50
51
52
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
54
55
56
57
58
59
60
61
62
63
@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
65
66
67
68
69
70
71
72
73
@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
75
76
77
78
79
80
81
82
83
84
@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
86
87
88
89
90
91
92
93
94
@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
 96
 97
 98
 99
100
101
102
103
104
105
@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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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
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
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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
45
46
47
48
49
50
51
52
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
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
45
46
47
48
49
50
51
52
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
332
333
334
335
336
337
338
339
340
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
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
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
364
365
366
367
368
369
370
371
372
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
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
401
402
403
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
405
406
407
408
409
410
411
412
413
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
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
@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}")