Skip to content

transformer_builder

This module contains classes for building transformers.

ClusteringBasedTransformerLoadMapper

Bases: TransformerLoadMapper

Uses clustering algorithms to figure out transformer location.

Refer to base class for attributes passed to base class.

Attributes:

Name Type Description
ht_kv float

High tension side kV

lt_kv float

Low tension side kV

num_phase NumPhase

NumPhase instance

ht_conn TransformerConnection

TransformerConnection instance for high tension side

lt_conn TransformerConnection

TransformerConnection instance for low tension side

ht_phase Phase

Phase instance for high tension side

lt_phase Phase

Phase instance for low tension side

clustering_object Clustering

Clustering instance

Source code in shift\transformer_builder.py
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
class ClusteringBasedTransformerLoadMapper(TransformerLoadMapper):
    """Uses clustering algorithms to figure out transformer location.

    Refer to base class for attributes passed to base class.

    Attributes:
        ht_kv (float): High tension side kV
        lt_kv (float): Low tension side kV
        num_phase (NumPhase): NumPhase instance
        ht_conn (TransformerConnection): TransformerConnection
            instance for high tension side
        lt_conn (TransformerConnection): TransformerConnection
            instance for low tension side
        ht_phase (Phase): Phase instance for high tension side
        lt_phase (Phase): Phase instance for low tension side
        clustering_object (Clustering): Clustering instance
    """

    def __init__(
        self,
        loads: List[Load],
        clustering_object: Clustering,
        diversity_factor_func: Callable[[float], float],
        ht_kv: float,
        lt_kv: float,
        ht_conn: TransformerConnection,
        lt_conn: TransformerConnection,
        ht_phase: Phase,
        lt_phase: Phase,
        num_phase: NumPhase,
        catalog_type="all",
        power_factor: float = 1.0,
        adjustment_factor: float = 1.25,
        planned_avg_annual_growth: float = 2,
        actual_avg_annual_growth: float = 4,
        actual_years_in_operation: float = 15,
        planned_years_in_operation: float = 10,
    ):

        """Constructor for `ClusteringBasedTransformerLoadMapper` class.

        Args:
            ht_kv (float): High tension side kV
            lt_kv (float): Low tension side kV
            num_phase (NumPhase): NumPhase instance
            ht_conn (TransformerConnection): TransformerConnection
                instance for high tension side
            lt_conn (TransformerConnection): TransformerConnection
                instance for low tension side
            ht_phase (Phase): Phase instance for high tension side
            lt_phase (Phase): Phase instance for low tension side
            clustering_object (Clustering): Clustering instance

        Raises:
            ZeroKVError: If kv specified is zero
            NegativeKVError: If kv specified is negative
            HTkVlowerthanLTkVError: If high tension kv used
                is less than low tension kv
        """

        super().__init__(
            loads,
            diversity_factor_func,
            adjustment_factor,
            planned_avg_annual_growth,
            actual_avg_annual_growth,
            actual_years_in_operation,
            planned_years_in_operation,
            power_factor,
            catalog_type,
        )

        self.clustering_object = clustering_object
        self.ht_kv = ht_kv
        self.lt_kv = lt_kv
        self.num_phase = num_phase
        self.ht_conn = ht_conn
        self.lt_conn = lt_conn
        self.ht_phase = ht_phase
        self.lt_phase = lt_phase

        for kv in [self.ht_kv, self.lt_kv]:
            if kv == 0:
                raise ZeroKVError
            if kv < 0:
                raise NegativeKVError

        if self.ht_kv < self.lt_kv:
            raise HTkVlowerthanLTkVError(self.ht_kv, self.lt_kv)

    def get_transformer_load_mapping(self) -> dict:
        """Refer to base class for more details."""

        # Prepare the data for clustering
        x_array = np.array(
            [[load.longitude, load.latitude] for load in self.loads]
        )

        # Perform clustering operation based on x_data
        clusters = self.clustering_object.get_clusters(x_array)

        # Mapping cluster centre to loads """
        cluster_to_customers = {tuple(c): [] for c in clusters["centre"]}
        for label, load in zip(clusters["labels"], self.loads):
            centre = tuple(clusters["centre"][label])
            cluster_to_customers[centre].append(load)

        # Container to store all the transformers with all the mapping
        self.transformers = {}
        for xfmr, t_loads in cluster_to_customers.items():

            # Now let's initialize the transformer with it's proper values
            catalog_used = self.get_catalog_object(
                t_loads, self.ht_kv, self.lt_kv
            )
            trans = Transformer()
            trans.latitude = xfmr[1]
            trans.longitude = xfmr[0]
            trans.name = f"{xfmr[0]}_{xfmr[1]}_transformer"
            trans.primary_kv = self.ht_kv
            trans.secondary_kv = self.lt_kv
            trans.pct_r = catalog_used["percentage_resistance"]
            trans.xhl = catalog_used["percentage_reactance"]
            trans.pct_noloadloss = catalog_used["percentage_no_load_loss"]
            trans.num_phase = self.num_phase
            trans.primary_con = self.ht_conn
            trans.kva = catalog_used["kva"]
            trans.secondary_con = self.lt_conn
            trans.primary_phase = self.ht_phase
            trans.secondary_phase = self.lt_phase
            self.transformers[trans] = t_loads
        return self.transformers

__init__(loads, clustering_object, diversity_factor_func, ht_kv, lt_kv, ht_conn, lt_conn, ht_phase, lt_phase, num_phase, catalog_type='all', power_factor=1.0, adjustment_factor=1.25, planned_avg_annual_growth=2, actual_avg_annual_growth=4, actual_years_in_operation=15, planned_years_in_operation=10)

Constructor for ClusteringBasedTransformerLoadMapper class.

Parameters:

Name Type Description Default
ht_kv float

High tension side kV

required
lt_kv float

Low tension side kV

required
num_phase NumPhase

NumPhase instance

required
ht_conn TransformerConnection

TransformerConnection instance for high tension side

required
lt_conn TransformerConnection

TransformerConnection instance for low tension side

required
ht_phase Phase

Phase instance for high tension side

required
lt_phase Phase

Phase instance for low tension side

required
clustering_object Clustering

Clustering instance

required

Raises:

Type Description
ZeroKVError

If kv specified is zero

NegativeKVError

If kv specified is negative

HTkVlowerthanLTkVError

If high tension kv used is less than low tension kv

Source code in shift\transformer_builder.py
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
def __init__(
    self,
    loads: List[Load],
    clustering_object: Clustering,
    diversity_factor_func: Callable[[float], float],
    ht_kv: float,
    lt_kv: float,
    ht_conn: TransformerConnection,
    lt_conn: TransformerConnection,
    ht_phase: Phase,
    lt_phase: Phase,
    num_phase: NumPhase,
    catalog_type="all",
    power_factor: float = 1.0,
    adjustment_factor: float = 1.25,
    planned_avg_annual_growth: float = 2,
    actual_avg_annual_growth: float = 4,
    actual_years_in_operation: float = 15,
    planned_years_in_operation: float = 10,
):

    """Constructor for `ClusteringBasedTransformerLoadMapper` class.

    Args:
        ht_kv (float): High tension side kV
        lt_kv (float): Low tension side kV
        num_phase (NumPhase): NumPhase instance
        ht_conn (TransformerConnection): TransformerConnection
            instance for high tension side
        lt_conn (TransformerConnection): TransformerConnection
            instance for low tension side
        ht_phase (Phase): Phase instance for high tension side
        lt_phase (Phase): Phase instance for low tension side
        clustering_object (Clustering): Clustering instance

    Raises:
        ZeroKVError: If kv specified is zero
        NegativeKVError: If kv specified is negative
        HTkVlowerthanLTkVError: If high tension kv used
            is less than low tension kv
    """

    super().__init__(
        loads,
        diversity_factor_func,
        adjustment_factor,
        planned_avg_annual_growth,
        actual_avg_annual_growth,
        actual_years_in_operation,
        planned_years_in_operation,
        power_factor,
        catalog_type,
    )

    self.clustering_object = clustering_object
    self.ht_kv = ht_kv
    self.lt_kv = lt_kv
    self.num_phase = num_phase
    self.ht_conn = ht_conn
    self.lt_conn = lt_conn
    self.ht_phase = ht_phase
    self.lt_phase = lt_phase

    for kv in [self.ht_kv, self.lt_kv]:
        if kv == 0:
            raise ZeroKVError
        if kv < 0:
            raise NegativeKVError

    if self.ht_kv < self.lt_kv:
        raise HTkVlowerthanLTkVError(self.ht_kv, self.lt_kv)

get_transformer_load_mapping()

Refer to base class for more details.

Source code in shift\transformer_builder.py
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
def get_transformer_load_mapping(self) -> dict:
    """Refer to base class for more details."""

    # Prepare the data for clustering
    x_array = np.array(
        [[load.longitude, load.latitude] for load in self.loads]
    )

    # Perform clustering operation based on x_data
    clusters = self.clustering_object.get_clusters(x_array)

    # Mapping cluster centre to loads """
    cluster_to_customers = {tuple(c): [] for c in clusters["centre"]}
    for label, load in zip(clusters["labels"], self.loads):
        centre = tuple(clusters["centre"][label])
        cluster_to_customers[centre].append(load)

    # Container to store all the transformers with all the mapping
    self.transformers = {}
    for xfmr, t_loads in cluster_to_customers.items():

        # Now let's initialize the transformer with it's proper values
        catalog_used = self.get_catalog_object(
            t_loads, self.ht_kv, self.lt_kv
        )
        trans = Transformer()
        trans.latitude = xfmr[1]
        trans.longitude = xfmr[0]
        trans.name = f"{xfmr[0]}_{xfmr[1]}_transformer"
        trans.primary_kv = self.ht_kv
        trans.secondary_kv = self.lt_kv
        trans.pct_r = catalog_used["percentage_resistance"]
        trans.xhl = catalog_used["percentage_reactance"]
        trans.pct_noloadloss = catalog_used["percentage_no_load_loss"]
        trans.num_phase = self.num_phase
        trans.primary_con = self.ht_conn
        trans.kva = catalog_used["kva"]
        trans.secondary_con = self.lt_conn
        trans.primary_phase = self.ht_phase
        trans.secondary_phase = self.lt_phase
        self.transformers[trans] = t_loads
    return self.transformers

SingleTransformerBuilder

Bases: TransformerLoadMapper

Class for managing building of single transformer used to build substation transformer.

Refer to base class for attributes passed to base class.

Attributes:

Name Type Description
ht_kv float

High tension side kV

lt_kv float

Low tension side kV

num_phase NumPhase

NumPhase instance

ht_conn TransformerConnection

TransformerConnection instance for high tension side

lt_conn TransformerConnection

TransformerConnection instance for low tension side

ht_phase Phase

Phase instance for high tension side

lt_phase Phase

Phase instance for low tension side

longitude float

Longitude property of transformer

latitude float

Latitude property of transformer

Source code in shift\transformer_builder.py
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
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
401
402
class SingleTransformerBuilder(TransformerLoadMapper):
    """Class for managing building of single transformer
    used to build substation transformer.

    Refer to base class for attributes passed to base class.

    Attributes:
        ht_kv (float): High tension side kV
        lt_kv (float): Low tension side kV
        num_phase (NumPhase): NumPhase instance
        ht_conn (TransformerConnection): TransformerConnection
            instance for high tension side
        lt_conn (TransformerConnection): TransformerConnection
            instance for low tension side
        ht_phase (Phase): Phase instance for high tension side
        lt_phase (Phase): Phase instance for low tension side
        longitude (float): Longitude property of transformer
        latitude (float): Latitude property of transformer
    """

    def __init__(
        self,
        loads: List[Load],
        longitude: float,
        latitude: float,
        diversity_factor_func: Callable[[float], float],
        ht_kv: float,
        lt_kv: float,
        ht_conn: TransformerConnection,
        lt_conn: TransformerConnection,
        ht_phase: Phase,
        lt_phase: Phase,
        num_phase: NumPhase,
        catalog_type="all",
        power_factor: float = 1.0,
        adjustment_factor: float = 1.25,
        planned_avg_annual_growth: float = 2,
        actual_avg_annual_growth: float = 4,
        actual_years_in_operation: float = 15,
        planned_years_in_operation: float = 10,
    ) -> None:
        """Constructor for `SingleTransformerBuilder` class.

        Args:
            ht_kv (float): High tension side kV
            lt_kv (float): Low tension side kV
            num_phase (NumPhase): NumPhase instance
            ht_conn (TransformerConnection): TransformerConnection
                instance for high tension side
            lt_conn (TransformerConnection): TransformerConnection
                instance for low tension side
            ht_phase (Phase): Phase instance for high tension side
            lt_phase (Phase): Phase instance for low tension side
            longitude (float): Longitude property of transformer
            latitude (float): Latitude property of transformer

        Raises:
            ZeroKVError: If kv specified is zero
            NegativeKVError: If kv specified is negative
            HTkVlowerthanLTkVError: If high tension kv used
                is less than low tension kv
        """

        super().__init__(
            loads,
            diversity_factor_func,
            adjustment_factor,
            planned_avg_annual_growth,
            actual_avg_annual_growth,
            actual_years_in_operation,
            planned_years_in_operation,
            power_factor,
            catalog_type,
        )

        self.ht_kv = ht_kv
        self.lt_kv = lt_kv
        self.num_phase = num_phase
        self.ht_conn = ht_conn
        self.lt_conn = lt_conn
        self.ht_phase = ht_phase
        self.lt_phase = lt_phase
        self.longitude = longitude
        self.latitude = latitude

        for kv in [self.ht_kv, self.lt_kv]:
            if kv == 0:
                raise ZeroKVError
            if kv < 0:
                raise NegativeKVError

        if self.ht_kv < self.lt_kv:
            raise HTkVlowerthanLTkVError(self.ht_kv, self.lt_kv)

    def get_transformer_load_mapping(self) -> dict:
        """Refer to base class for more details."""

        self.transformers = {}
        catalog_used = self.get_catalog_object(
            self.loads, self.ht_kv, self.lt_kv
        )
        trans = Transformer()
        trans.latitude = self.latitude
        trans.longitude = self.longitude
        trans.name = f"{self.longitude}_{self.latitude}_transformer"
        trans.primary_kv = self.ht_kv
        trans.secondary_kv = self.lt_kv
        trans.pct_r = catalog_used["percentage_resistance"]
        trans.xhl = catalog_used["percentage_reactance"]
        trans.pct_noloadloss = catalog_used["percentage_no_load_loss"]
        trans.num_phase = self.num_phase
        trans.primary_con = self.ht_conn
        trans.kva = catalog_used["kva"]
        trans.secondary_con = self.lt_conn
        trans.primary_phase = self.ht_phase
        trans.secondary_phase = self.lt_phase
        self.transformers[trans] = self.loads

        return self.transformers

__init__(loads, longitude, latitude, diversity_factor_func, ht_kv, lt_kv, ht_conn, lt_conn, ht_phase, lt_phase, num_phase, catalog_type='all', power_factor=1.0, adjustment_factor=1.25, planned_avg_annual_growth=2, actual_avg_annual_growth=4, actual_years_in_operation=15, planned_years_in_operation=10)

Constructor for SingleTransformerBuilder class.

Parameters:

Name Type Description Default
ht_kv float

High tension side kV

required
lt_kv float

Low tension side kV

required
num_phase NumPhase

NumPhase instance

required
ht_conn TransformerConnection

TransformerConnection instance for high tension side

required
lt_conn TransformerConnection

TransformerConnection instance for low tension side

required
ht_phase Phase

Phase instance for high tension side

required
lt_phase Phase

Phase instance for low tension side

required
longitude float

Longitude property of transformer

required
latitude float

Latitude property of transformer

required

Raises:

Type Description
ZeroKVError

If kv specified is zero

NegativeKVError

If kv specified is negative

HTkVlowerthanLTkVError

If high tension kv used is less than low tension kv

Source code in shift\transformer_builder.py
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
def __init__(
    self,
    loads: List[Load],
    longitude: float,
    latitude: float,
    diversity_factor_func: Callable[[float], float],
    ht_kv: float,
    lt_kv: float,
    ht_conn: TransformerConnection,
    lt_conn: TransformerConnection,
    ht_phase: Phase,
    lt_phase: Phase,
    num_phase: NumPhase,
    catalog_type="all",
    power_factor: float = 1.0,
    adjustment_factor: float = 1.25,
    planned_avg_annual_growth: float = 2,
    actual_avg_annual_growth: float = 4,
    actual_years_in_operation: float = 15,
    planned_years_in_operation: float = 10,
) -> None:
    """Constructor for `SingleTransformerBuilder` class.

    Args:
        ht_kv (float): High tension side kV
        lt_kv (float): Low tension side kV
        num_phase (NumPhase): NumPhase instance
        ht_conn (TransformerConnection): TransformerConnection
            instance for high tension side
        lt_conn (TransformerConnection): TransformerConnection
            instance for low tension side
        ht_phase (Phase): Phase instance for high tension side
        lt_phase (Phase): Phase instance for low tension side
        longitude (float): Longitude property of transformer
        latitude (float): Latitude property of transformer

    Raises:
        ZeroKVError: If kv specified is zero
        NegativeKVError: If kv specified is negative
        HTkVlowerthanLTkVError: If high tension kv used
            is less than low tension kv
    """

    super().__init__(
        loads,
        diversity_factor_func,
        adjustment_factor,
        planned_avg_annual_growth,
        actual_avg_annual_growth,
        actual_years_in_operation,
        planned_years_in_operation,
        power_factor,
        catalog_type,
    )

    self.ht_kv = ht_kv
    self.lt_kv = lt_kv
    self.num_phase = num_phase
    self.ht_conn = ht_conn
    self.lt_conn = lt_conn
    self.ht_phase = ht_phase
    self.lt_phase = lt_phase
    self.longitude = longitude
    self.latitude = latitude

    for kv in [self.ht_kv, self.lt_kv]:
        if kv == 0:
            raise ZeroKVError
        if kv < 0:
            raise NegativeKVError

    if self.ht_kv < self.lt_kv:
        raise HTkVlowerthanLTkVError(self.ht_kv, self.lt_kv)

get_transformer_load_mapping()

Refer to base class for more details.

Source code in shift\transformer_builder.py
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
def get_transformer_load_mapping(self) -> dict:
    """Refer to base class for more details."""

    self.transformers = {}
    catalog_used = self.get_catalog_object(
        self.loads, self.ht_kv, self.lt_kv
    )
    trans = Transformer()
    trans.latitude = self.latitude
    trans.longitude = self.longitude
    trans.name = f"{self.longitude}_{self.latitude}_transformer"
    trans.primary_kv = self.ht_kv
    trans.secondary_kv = self.lt_kv
    trans.pct_r = catalog_used["percentage_resistance"]
    trans.xhl = catalog_used["percentage_reactance"]
    trans.pct_noloadloss = catalog_used["percentage_no_load_loss"]
    trans.num_phase = self.num_phase
    trans.primary_con = self.ht_conn
    trans.kva = catalog_used["kva"]
    trans.secondary_con = self.lt_conn
    trans.primary_phase = self.ht_phase
    trans.secondary_phase = self.lt_phase
    self.transformers[trans] = self.loads

    return self.transformers

TransformerLoadMapper

Bases: ABC

Interface for getting transformer load mapping.

Attributes:

Name Type Description
loads List[Load]

List of loads

diversity_factor_func Callable

Callable to compute diversity factor

adjustment_factor float

Adjustment factor for adjusting kva

planned_avg_annual_growth float

Planned average annual load growth rate in percentage

actual_avg_annual_growth float

Actual average annual load growth rate in percentage

actual_years_in_operation float

Actual years in operation

planned_years_in_operation float

Planned years in operation

power_factor float

Power factor used to compute kva

catalog_type str

Catalog type used for choosing transformer

trans_catalog pd.DataFrame

Dataframe containing transformer catalogs

Source code in shift\transformer_builder.py
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 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
142
143
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
class TransformerLoadMapper(ABC):
    """Interface for getting transformer load mapping.

    Attributes:
        loads (List[Load]): List of loads
        diversity_factor_func (Callable): Callable to compute diversity factor
        adjustment_factor (float): Adjustment factor for adjusting kva
        planned_avg_annual_growth (float): Planned average annual load
            growth rate in percentage
        actual_avg_annual_growth (float): Actual average annual load
            growth rate in percentage
        actual_years_in_operation (float): Actual years in operation
        planned_years_in_operation (float): Planned years in operation
        power_factor (float): Power factor used to compute kva
        catalog_type (str): Catalog type used for choosing transformer
        trans_catalog (pd.DataFrame): Dataframe containing transformer catalogs
    """

    def __init__(
        self,
        loads: List[Load],
        diversity_factor_func: Callable[[float], float],
        adjustment_factor: float = 1.25,
        planned_avg_annual_growth: float = 2,
        actual_avg_annual_growth: float = 4,
        actual_years_in_operation: float = 15,
        planned_years_in_operation: float = 10,
        power_factor: float = 0.9,
        catalog_type: str = "all",
    ) -> None:
        """Constructor for `TransformerLoadMapper` class.

        Args:
            loads (List[Load]): List of loads
            diversity_factor_func (Callable[[float], float]): Callable to
                compute diversity factor
            adjustment_factor (float): Adjustment factor for adjusting kva
            planned_avg_annual_growth (float): Planned average annual load
                growth rate in percentage
            actual_avg_annual_growth (float): Actual average annual load
                growth rate in percentage
            actual_years_in_operation (float): Actual years in operation
            planned_years_in_operation (float): Planned years in operation
            power_factor (float): Power factor used to compute kva
            catalog_type (str): Catalog type used for choosing transformer

        Raises:
            PercentageNotInRangeError: If invalid percentage is used
            OperationYearNotInRange: If invalid operation year is used
            AdjustmentFactorNotInRangeError: If invalid adjustment
                factor is used
            PowerFactorNotInRangeError: If invalid power factor is used
            EmptyCatalog: If catalog is empty for given type
        """

        self.loads = loads
        self.diversity_factor_func = diversity_factor_func
        self.planned_avg_annual_growth = planned_avg_annual_growth
        self.actual_avg_annual_growth = actual_avg_annual_growth
        self.actual_years_in_operation = actual_years_in_operation
        self.planned_years_in_operation = planned_years_in_operation
        self.power_factor = power_factor

        if (
            self.planned_avg_annual_growth < MIN_PERCENTAGE
            or self.planned_avg_annual_growth > MAX_PERCENTAGE
        ):
            raise PercentageNotInRangeError(self.planned_avg_annual_growth)

        if (
            self.actual_avg_annual_growth < MIN_PERCENTAGE
            or self.actual_avg_annual_growth > MAX_PERCENTAGE
        ):
            raise PercentageNotInRangeError(self.actual_avg_annual_growth)

        if (
            self.actual_years_in_operation < MIN_YEAR_OPERATION
            or self.actual_years_in_operation > MAX_YEAR_OPERATION
        ):
            raise OperationYearNotInRange(self.actual_years_in_operation)

        if (
            self.planned_years_in_operation < MIN_YEAR_OPERATION
            or self.planned_years_in_operation > MAX_YEAR_OPERATION
        ):
            raise OperationYearNotInRange(self.planned_years_in_operation)

        self.adjustment_factor = adjustment_factor
        if (
            self.adjustment_factor < MIN_ADJUSTMENT_FACTOR
            or self.adjustment_factor > MAX_ADJUSTMENT_FACTOR
        ):
            raise AdjustmentFactorNotInRangeError(self.adjustment_factor)

        if (
            self.power_factor < MIN_POWER_FACTOR
            or self.power_factor > MAX_POWER_FACTOR
        ):
            raise PowerFactorNotInRangeError(self.power_factor)

        self.trans_catalog = pd.read_excel(TRANSFORMER_CATALOG_FILE)

        df_validator(TRANSFORMER_CATALAOG_SCHEMA, self.trans_catalog)
        if catalog_type != "all":
            self.trans_catalog = self.trans_catalog.loc[
                self.trans_catalog["type"] == type
            ]
            if self.trans_catalog.empty:
                raise EmptyCatalog(
                    f"Catalog of type {type} not found in transformer.xlsx file"
                )

    def compute_transformer_kva_capacity(
        self, non_coincident_peak: float, num_of_customers: int
    ) -> float:
        """Method for computing transformer capacity.

        Args:
            non_coincident_peak (float): Non coincident peak
            num_of_customers (int): Number of customers

        Returns:
            float: Transformer size
        """

        # Initial step is to compute maximum diversified demand
        div_factor = (
            self.diversity_factor_func(num_of_customers)
            if num_of_customers > 1
            else 1
        )
        max_diversified_demand = non_coincident_peak / div_factor
        max_diversified_kva = (
            max_diversified_demand * self.adjustment_factor / self.power_factor
        )

        original_max_diversified_kva = max_diversified_kva / math.pow(
            1 + self.actual_avg_annual_growth / 100,
            self.actual_years_in_operation,
        )
        trafo_size = original_max_diversified_kva * math.pow(
            1 + self.planned_avg_annual_growth / 100,
            self.planned_years_in_operation,
        )
        return trafo_size

    @abstractmethod
    def get_transformer_load_mapping(self) -> dict:
        """Abstract method for returning transformer to loads mapping."""
        pass

    def get_catalog_object(
        self, t_loads: List[Load], ht_kv: float, lt_kv: float
    ) -> dict:
        """Method for getting transformet catalog.

        Args:
            t_loads (List[Load]): List of `Load` instances
            ht_kv (float): High tension kV
            lt_kv (float): Low tension kv

        Raises:
            EmptyCatalog: If transformer catalog is not found

        Returns:
            dict: Transformer record
        """

        # Get maximum diversified demand (kW) and adjusted kW
        sum_of_noncoincident_peaks = sum(l.kw for l in t_loads)
        kva = self.compute_transformer_kva_capacity(
            sum_of_noncoincident_peaks, len(t_loads)
        )

        # Filter by capacity above kva capacity
        catalog = self.trans_catalog[self.trans_catalog["kva"] >= kva]
        if not catalog.empty:

            # Filter by high voltage
            catalog = catalog[catalog["ht_kv"] >= ht_kv]
            if not catalog.empty:

                # Filter by low voltage
                catalog = catalog[catalog["lt_kv"] >= lt_kv]

                if not catalog.empty:
                    catalog_used = catalog.loc[
                        catalog["kva"].idxmin()
                    ].to_dict()
                else:
                    raise EmptyCatalog(
                        "Catalog does not exist for transformer of"
                        + " capacity above or equal to"
                        + f"{kva} kVA with high tension voltage above or "
                        + f"equal to {ht_kv} and "
                        + f"above or equal to low tension voltage{lt_kv}"
                    )

            else:
                raise EmptyCatalog(
                    "Catalog does not exist for transformer of "
                    + "capacity greater than "
                    + f"{kva} kVA with high tension voltage greater "
                    + f"than or equal to {ht_kv}"
                )

        else:
            raise EmptyCatalog(
                "Catalog does not exist for transformer"
                + "of capacity above or equal to {kva} kVA"
            )

        return catalog_used

__init__(loads, diversity_factor_func, adjustment_factor=1.25, planned_avg_annual_growth=2, actual_avg_annual_growth=4, actual_years_in_operation=15, planned_years_in_operation=10, power_factor=0.9, catalog_type='all')

Constructor for TransformerLoadMapper class.

Parameters:

Name Type Description Default
loads List[Load]

List of loads

required
diversity_factor_func Callable[[float], float]

Callable to compute diversity factor

required
adjustment_factor float

Adjustment factor for adjusting kva

1.25
planned_avg_annual_growth float

Planned average annual load growth rate in percentage

2
actual_avg_annual_growth float

Actual average annual load growth rate in percentage

4
actual_years_in_operation float

Actual years in operation

15
planned_years_in_operation float

Planned years in operation

10
power_factor float

Power factor used to compute kva

0.9
catalog_type str

Catalog type used for choosing transformer

'all'

Raises:

Type Description
PercentageNotInRangeError

If invalid percentage is used

OperationYearNotInRange

If invalid operation year is used

AdjustmentFactorNotInRangeError

If invalid adjustment factor is used

PowerFactorNotInRangeError

If invalid power factor is used

EmptyCatalog

If catalog is empty for given type

Source code in shift\transformer_builder.py
 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
142
143
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
177
178
179
def __init__(
    self,
    loads: List[Load],
    diversity_factor_func: Callable[[float], float],
    adjustment_factor: float = 1.25,
    planned_avg_annual_growth: float = 2,
    actual_avg_annual_growth: float = 4,
    actual_years_in_operation: float = 15,
    planned_years_in_operation: float = 10,
    power_factor: float = 0.9,
    catalog_type: str = "all",
) -> None:
    """Constructor for `TransformerLoadMapper` class.

    Args:
        loads (List[Load]): List of loads
        diversity_factor_func (Callable[[float], float]): Callable to
            compute diversity factor
        adjustment_factor (float): Adjustment factor for adjusting kva
        planned_avg_annual_growth (float): Planned average annual load
            growth rate in percentage
        actual_avg_annual_growth (float): Actual average annual load
            growth rate in percentage
        actual_years_in_operation (float): Actual years in operation
        planned_years_in_operation (float): Planned years in operation
        power_factor (float): Power factor used to compute kva
        catalog_type (str): Catalog type used for choosing transformer

    Raises:
        PercentageNotInRangeError: If invalid percentage is used
        OperationYearNotInRange: If invalid operation year is used
        AdjustmentFactorNotInRangeError: If invalid adjustment
            factor is used
        PowerFactorNotInRangeError: If invalid power factor is used
        EmptyCatalog: If catalog is empty for given type
    """

    self.loads = loads
    self.diversity_factor_func = diversity_factor_func
    self.planned_avg_annual_growth = planned_avg_annual_growth
    self.actual_avg_annual_growth = actual_avg_annual_growth
    self.actual_years_in_operation = actual_years_in_operation
    self.planned_years_in_operation = planned_years_in_operation
    self.power_factor = power_factor

    if (
        self.planned_avg_annual_growth < MIN_PERCENTAGE
        or self.planned_avg_annual_growth > MAX_PERCENTAGE
    ):
        raise PercentageNotInRangeError(self.planned_avg_annual_growth)

    if (
        self.actual_avg_annual_growth < MIN_PERCENTAGE
        or self.actual_avg_annual_growth > MAX_PERCENTAGE
    ):
        raise PercentageNotInRangeError(self.actual_avg_annual_growth)

    if (
        self.actual_years_in_operation < MIN_YEAR_OPERATION
        or self.actual_years_in_operation > MAX_YEAR_OPERATION
    ):
        raise OperationYearNotInRange(self.actual_years_in_operation)

    if (
        self.planned_years_in_operation < MIN_YEAR_OPERATION
        or self.planned_years_in_operation > MAX_YEAR_OPERATION
    ):
        raise OperationYearNotInRange(self.planned_years_in_operation)

    self.adjustment_factor = adjustment_factor
    if (
        self.adjustment_factor < MIN_ADJUSTMENT_FACTOR
        or self.adjustment_factor > MAX_ADJUSTMENT_FACTOR
    ):
        raise AdjustmentFactorNotInRangeError(self.adjustment_factor)

    if (
        self.power_factor < MIN_POWER_FACTOR
        or self.power_factor > MAX_POWER_FACTOR
    ):
        raise PowerFactorNotInRangeError(self.power_factor)

    self.trans_catalog = pd.read_excel(TRANSFORMER_CATALOG_FILE)

    df_validator(TRANSFORMER_CATALAOG_SCHEMA, self.trans_catalog)
    if catalog_type != "all":
        self.trans_catalog = self.trans_catalog.loc[
            self.trans_catalog["type"] == type
        ]
        if self.trans_catalog.empty:
            raise EmptyCatalog(
                f"Catalog of type {type} not found in transformer.xlsx file"
            )

compute_transformer_kva_capacity(non_coincident_peak, num_of_customers)

Method for computing transformer capacity.

Parameters:

Name Type Description Default
non_coincident_peak float

Non coincident peak

required
num_of_customers int

Number of customers

required

Returns:

Name Type Description
float float

Transformer size

Source code in shift\transformer_builder.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
def compute_transformer_kva_capacity(
    self, non_coincident_peak: float, num_of_customers: int
) -> float:
    """Method for computing transformer capacity.

    Args:
        non_coincident_peak (float): Non coincident peak
        num_of_customers (int): Number of customers

    Returns:
        float: Transformer size
    """

    # Initial step is to compute maximum diversified demand
    div_factor = (
        self.diversity_factor_func(num_of_customers)
        if num_of_customers > 1
        else 1
    )
    max_diversified_demand = non_coincident_peak / div_factor
    max_diversified_kva = (
        max_diversified_demand * self.adjustment_factor / self.power_factor
    )

    original_max_diversified_kva = max_diversified_kva / math.pow(
        1 + self.actual_avg_annual_growth / 100,
        self.actual_years_in_operation,
    )
    trafo_size = original_max_diversified_kva * math.pow(
        1 + self.planned_avg_annual_growth / 100,
        self.planned_years_in_operation,
    )
    return trafo_size

get_catalog_object(t_loads, ht_kv, lt_kv)

Method for getting transformet catalog.

Parameters:

Name Type Description Default
t_loads List[Load]

List of Load instances

required
ht_kv float

High tension kV

required
lt_kv float

Low tension kv

required

Raises:

Type Description
EmptyCatalog

If transformer catalog is not found

Returns:

Name Type Description
dict dict

Transformer record

Source code in shift\transformer_builder.py
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
def get_catalog_object(
    self, t_loads: List[Load], ht_kv: float, lt_kv: float
) -> dict:
    """Method for getting transformet catalog.

    Args:
        t_loads (List[Load]): List of `Load` instances
        ht_kv (float): High tension kV
        lt_kv (float): Low tension kv

    Raises:
        EmptyCatalog: If transformer catalog is not found

    Returns:
        dict: Transformer record
    """

    # Get maximum diversified demand (kW) and adjusted kW
    sum_of_noncoincident_peaks = sum(l.kw for l in t_loads)
    kva = self.compute_transformer_kva_capacity(
        sum_of_noncoincident_peaks, len(t_loads)
    )

    # Filter by capacity above kva capacity
    catalog = self.trans_catalog[self.trans_catalog["kva"] >= kva]
    if not catalog.empty:

        # Filter by high voltage
        catalog = catalog[catalog["ht_kv"] >= ht_kv]
        if not catalog.empty:

            # Filter by low voltage
            catalog = catalog[catalog["lt_kv"] >= lt_kv]

            if not catalog.empty:
                catalog_used = catalog.loc[
                    catalog["kva"].idxmin()
                ].to_dict()
            else:
                raise EmptyCatalog(
                    "Catalog does not exist for transformer of"
                    + " capacity above or equal to"
                    + f"{kva} kVA with high tension voltage above or "
                    + f"equal to {ht_kv} and "
                    + f"above or equal to low tension voltage{lt_kv}"
                )

        else:
            raise EmptyCatalog(
                "Catalog does not exist for transformer of "
                + "capacity greater than "
                + f"{kva} kVA with high tension voltage greater "
                + f"than or equal to {ht_kv}"
            )

    else:
        raise EmptyCatalog(
            "Catalog does not exist for transformer"
            + "of capacity above or equal to {kva} kVA"
        )

    return catalog_used

get_transformer_load_mapping() abstractmethod

Abstract method for returning transformer to loads mapping.

Source code in shift\transformer_builder.py
215
216
217
218
@abstractmethod
def get_transformer_load_mapping(self) -> dict:
    """Abstract method for returning transformer to loads mapping."""
    pass