20
20
import uuid
21
21
import warnings
22
22
from collections import defaultdict
23
+ from collections .abc import Iterable
23
24
from io import IOBase , StringIO
24
25
from itertools import chain
25
26
from math import isclose
26
- from typing import IO , Iterable , Literal , Optional , Tuple , Union
27
+ from typing import IO , ClassVar , Literal
27
28
28
- from typing_extensions import ClassVar
29
+ import numpy as np
30
+ from sigfig import round
29
31
30
32
ReportingFrequency = Literal ["Annual" , "Monthly" , "Daily" , "Hourly" , "Timestep" ]
31
33
@@ -205,13 +207,13 @@ def __set_on_dependencies(self, key, value):
205
207
if key in self ._independant_vars :
206
208
self ._reset_dependant_vars (key )
207
209
key = f"_{ key } "
208
- super (IDF , self ).__setattr__ (key , value )
210
+ super ().__setattr__ (key , value )
209
211
210
212
def __init__ (
211
213
self ,
212
- idfname : Optional [ Union [ str , IO , Path ]] = None ,
214
+ idfname : str | IO | Path | None = None ,
213
215
epw = None ,
214
- as_version : Union [ str , EnergyPlusVersion ] = None ,
216
+ as_version : str | EnergyPlusVersion = None ,
215
217
annual = False ,
216
218
design_day = False ,
217
219
expandobjects = False ,
@@ -230,7 +232,7 @@ def __init__(
230
232
output_directory = None ,
231
233
outputtype = "standard" ,
232
234
encoding = None ,
233
- iddname : Optional [ Union [ str , IO , Path ]] = None ,
235
+ iddname : str | IO | Path | None = None ,
234
236
reporting_frequency : ReportingFrequency = "Monthly" ,
235
237
** kwargs ,
236
238
):
@@ -617,7 +619,7 @@ def output_suffix(self, value):
617
619
self ._output_suffix = value
618
620
619
621
@property
620
- def idfname (self ) -> Union [ Path , StringIO ] :
622
+ def idfname (self ) -> Path | StringIO :
621
623
"""Path: The path of the active (parsed) idf model."""
622
624
if self ._idfname is None :
623
625
if self .as_version is None :
@@ -834,7 +836,7 @@ def sim_id(self) -> str:
834
836
835
837
# endregion
836
838
@property
837
- def sim_info (self ) -> Optional [ DataFrame ] :
839
+ def sim_info (self ) -> DataFrame | None :
838
840
"""DataFrame: Unique number generated for a simulation."""
839
841
if self .sql_file is not None :
840
842
with sqlite3 .connect (self .sql_file ) as conn :
@@ -845,7 +847,7 @@ def sim_info(self) -> Optional[DataFrame]:
845
847
return None
846
848
847
849
@property
848
- def sim_timestamp (self ) -> Union [ str , Series ] :
850
+ def sim_timestamp (self ) -> str | Series :
849
851
"""Return the simulation timestamp or "Never" if not ran yet."""
850
852
if self .sim_info is None :
851
853
return "Never"
@@ -1488,7 +1490,7 @@ def savecopy(self, filename, lineendings="default", encoding="latin-1"):
1488
1490
Returns:
1489
1491
Path: The new file path.
1490
1492
"""
1491
- super (IDF , self ).save (filename , lineendings , encoding )
1493
+ super ().save (filename , lineendings , encoding )
1492
1494
return Path (filename )
1493
1495
1494
1496
def copy (self ):
@@ -1515,7 +1517,7 @@ def save(self, lineendings="default", encoding="latin-1", **kwargs):
1515
1517
Returns:
1516
1518
IDF: The IDF model
1517
1519
"""
1518
- super (IDF , self ).save (filename = self .idfname , lineendings = lineendings , encoding = encoding )
1520
+ super ().save (filename = self .idfname , lineendings = lineendings , encoding = encoding )
1519
1521
log (f"saved '{ self .name } ' at '{ self .idfname } '" )
1520
1522
return self
1521
1523
@@ -1538,7 +1540,7 @@ def saveas(self, filename, lineendings="default", encoding="latin-1", inplace=Fa
1538
1540
Returns:
1539
1541
IDF: A new IDF object based on the new location file.
1540
1542
"""
1541
- super (IDF , self ).save (filename = filename , lineendings = lineendings , encoding = encoding )
1543
+ super ().save (filename = filename , lineendings = lineendings , encoding = encoding )
1542
1544
1543
1545
import inspect
1544
1546
@@ -1719,7 +1721,6 @@ def wwr(self, azimuth_threshold=10, round_to=10):
1719
1721
1720
1722
def roundto (x , to = 10.0 ):
1721
1723
"""Round up to closest `to` number."""
1722
- from builtins import round
1723
1724
1724
1725
if to and not math .isnan (x ):
1725
1726
return int (round (x / to )) * to
@@ -1754,7 +1755,6 @@ def roundto(x, to=10.0):
1754
1755
1755
1756
# Create dataframe with wall_area, window_area and wwr as columns and azimuth
1756
1757
# as indexes
1757
- from sigfig import round
1758
1758
1759
1759
df = (
1760
1760
pd .DataFrame ({"wall_area" : total_surface_area , "window_area" : total_window_area })
@@ -1763,8 +1763,15 @@ def roundto(x, to=10.0):
1763
1763
)
1764
1764
df .wall_area = df .wall_area .apply (round , decimals = 1 )
1765
1765
df .window_area = df .window_area .apply (round , decimals = 1 )
1766
- df ["wwr" ] = (df .window_area / df .wall_area ).fillna (0 ).apply (round , 2 )
1767
- df ["wwr_rounded_%" ] = (df .window_area / df .wall_area * 100 ).fillna (0 ).apply (lambda x : roundto (x , to = round_to ))
1766
+ df ["wwr" ] = (
1767
+ (df .window_area / df .wall_area ).replace ([np .inf , - np .inf ], np .nan ).fillna (0 ).apply (round , decimals = 2 )
1768
+ )
1769
+ df ["wwr_rounded_%" ] = (
1770
+ (df .window_area / df .wall_area * 100 )
1771
+ .replace ([np .inf , - np .inf ], np .nan )
1772
+ .fillna (0 )
1773
+ .apply (lambda x : roundto (x , to = round_to ))
1774
+ )
1768
1775
return df
1769
1776
1770
1777
def space_heating_profile (
@@ -1897,7 +1904,7 @@ def custom_profile(
1897
1904
log (f"Retrieved { name } in { time .time () - start_time :,.2f} seconds" )
1898
1905
return series
1899
1906
1900
- def newidfobject (self , key , ** kwargs ) -> Optional [ EpBunch ] :
1907
+ def newidfobject (self , key , ** kwargs ) -> EpBunch | None :
1901
1908
"""Define EpBunch object and add to model.
1902
1909
1903
1910
The function will test if the object exists to prevent duplicates.
@@ -2040,7 +2047,7 @@ def anidfobject(self, key: str, aname: str = "", **kwargs) -> EpBunch:
2040
2047
abunch = obj2bunch (self .model , self .idd_info , obj )
2041
2048
if aname :
2042
2049
warnings .warn (
2043
- "The aname parameter should no longer be used (%s )." % aname ,
2050
+ f "The aname parameter should no longer be used ({ aname } )." ,
2044
2051
UserWarning ,
2045
2052
)
2046
2053
namebunch (abunch , aname )
@@ -2247,7 +2254,7 @@ def set_wwr(
2247
2254
# reviewed as of 2021-11-10.
2248
2255
2249
2256
try :
2250
- ggr : Optional [ Idf_MSequence ] = self .idfobjects ["GLOBALGEOMETRYRULES" ][0 ]
2257
+ ggr : Idf_MSequence | None = self .idfobjects ["GLOBALGEOMETRYRULES" ][0 ]
2251
2258
except IndexError :
2252
2259
ggr = None
2253
2260
@@ -2275,12 +2282,12 @@ def set_wwr(
2275
2282
continue
2276
2283
# remove all subsurfaces
2277
2284
for ss in wall_subsurfaces :
2278
- self .rename (ss .key .upper (), ss .Name , "%s window" % wall .Name )
2285
+ self .rename (ss .key .upper (), ss .Name , f" { wall .Name } window" )
2279
2286
self .removeidfobject (ss )
2280
2287
coords = window_vertices_given_wall (wall , wwr )
2281
2288
window = self .newidfobject (
2282
2289
"FENESTRATIONSURFACE:DETAILED" ,
2283
- Name = "%s window" % wall .Name ,
2290
+ Name = f" { wall .Name } window" ,
2284
2291
Surface_Type = "Window" ,
2285
2292
Construction_Name = construction or "" ,
2286
2293
Building_Surface_Name = wall .Name ,
@@ -2492,7 +2499,7 @@ def coords_are_truly_relative(self):
2492
2499
all_zone_origin_at_0 = False
2493
2500
return ggr_asks_for_relative and not all_zone_origin_at_0
2494
2501
2495
- def rotate (self , angle : Optional [ float ] = None , anchor : Tuple [float , float , float ] | None = None ):
2502
+ def rotate (self , angle : float | None = None , anchor : tuple [float , float , float ] | None = None ):
2496
2503
"""Rotate the IDF counterclockwise around `anchor` by the angle given (degrees).
2497
2504
2498
2505
IF angle is None, rotates to Direction_of_Relative_North specified in Zone
@@ -2512,7 +2519,7 @@ def rotate(self, angle: Optional[float] = None, anchor: Tuple[float, float, floa
2512
2519
2513
2520
anchor = Vector3D (* anchor )
2514
2521
# Rotate the building
2515
- super (IDF , self ).rotate (angle , anchor = anchor )
2522
+ super ().rotate (angle , anchor = anchor )
2516
2523
log (f"Geometries rotated by { angle } degrees around " f"{ anchor or 'building centroid' } " )
2517
2524
2518
2525
# after building is rotate, change the north axis and zone direction to zero.
@@ -2522,14 +2529,14 @@ def rotate(self, angle: Optional[float] = None, anchor: Tuple[float, float, floa
2522
2529
# Mark the model as rotated
2523
2530
self .rotated = True
2524
2531
2525
- def translate (self , vector : Tuple [float , float , float ]):
2532
+ def translate (self , vector : tuple [float , float , float ]):
2526
2533
"""Move the IDF in the direction given by a vector."""
2527
2534
if isinstance (vector , tuple ):
2528
2535
from geomeppy .geom .vectors import Vector2D
2529
2536
2530
2537
vector = Vector2D (* vector )
2531
2538
2532
- super (IDF , self ).translate (vector = vector )
2539
+ super ().translate (vector = vector )
2533
2540
self .translated = True
2534
2541
2535
2542
@property
@@ -2612,13 +2619,13 @@ def _process_csv(file, working_dir, simulname):
2612
2619
tables_out .makedirs_p ()
2613
2620
file .copy (tables_out / "%s_%s.csv" % (file .basename ().stripext (), simulname ))
2614
2621
return
2615
- log ("try to store file %s in DataFrame" % file )
2622
+ log (f "try to store file { file } in DataFrame" )
2616
2623
try :
2617
2624
df = pd .read_csv (file , sep = "," , encoding = "us-ascii" )
2618
2625
except ParserError :
2619
2626
pass
2620
2627
else :
2621
- log ("file %s stored" % file )
2628
+ log (f "file { file } stored" )
2622
2629
return df
2623
2630
2624
2631
0 commit comments