buildstock-fetch 1.2.0__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of buildstock-fetch might be problematic. Click here for more details.

buildstock_fetch/main.py CHANGED
@@ -3,6 +3,7 @@ import json
3
3
  import tempfile
4
4
  import zipfile
5
5
  from dataclasses import asdict, dataclass
6
+ from datetime import timedelta
6
7
  from importlib.resources import files
7
8
  from pathlib import Path
8
9
  from typing import Optional, Union
@@ -81,14 +82,7 @@ METADATA_DIR = Path(
81
82
  str(files("buildstock_fetch").joinpath("data").joinpath("building_data").joinpath("combined_metadata.parquet"))
82
83
  )
83
84
  RELEASE_JSON_FILE = Path(str(files("buildstock_fetch").joinpath("data").joinpath("buildstock_releases.json")))
84
- LOAD_CURVE_COLUMN_AGGREGATION = Path(
85
- str(
86
- files("buildstock_fetch")
87
- .joinpath("data")
88
- .joinpath("load_curve_column_map")
89
- .joinpath("2024_resstock_load_curve_columns.csv")
90
- )
91
- )
85
+ LOAD_CURVE_COLUMN_AGGREGATION = Path(str(files("buildstock_fetch").joinpath("data").joinpath("load_curve_column_map")))
92
86
  WEATHER_FILE_DIR = Path(str(files("buildstock_fetch").joinpath("data").joinpath("weather_station_map")))
93
87
 
94
88
 
@@ -752,10 +746,19 @@ def _create_aggregation_expressions(load_curve: pl.DataFrame, column_aggregation
752
746
  return agg_exprs
753
747
 
754
748
 
755
- def _aggregate_load_curve_aggregate(load_curve: pl.DataFrame, aggregate_time_step: str) -> pl.DataFrame:
756
- """Aggregate the 15-minute load curve to specified time step based on aggregation rules."""
749
+ def _aggregate_load_curve_aggregate(
750
+ load_curve: pl.DataFrame, aggregate_time_step: str, release_year: str
751
+ ) -> pl.DataFrame:
752
+ """Aggregate the 15-minute load curve to specified time step based on aggregation rules.
753
+
754
+ Removes the last row to ensure complete aggregation periods.
755
+ """
757
756
  # Read the aggregation rules from CSV
758
- aggregation_rules = pl.read_csv(LOAD_CURVE_COLUMN_AGGREGATION)
757
+ if release_year == "2024":
758
+ load_curve_map = LOAD_CURVE_COLUMN_AGGREGATION.joinpath("2024_resstock_load_curve_columns.csv")
759
+ elif release_year == "2022":
760
+ load_curve_map = LOAD_CURVE_COLUMN_AGGREGATION.joinpath("2022_resstock_load_curve_columns.csv")
761
+ aggregation_rules = pl.read_csv(load_curve_map)
759
762
 
760
763
  # Create a dictionary mapping column names to their aggregation functions
761
764
  column_aggregations = dict(zip(aggregation_rules["name"], aggregation_rules["Aggregate_function"]))
@@ -768,6 +771,13 @@ def _aggregate_load_curve_aggregate(load_curve: pl.DataFrame, aggregate_time_ste
768
771
  # Convert timestamp to datetime if it's not already
769
772
  load_curve = load_curve.with_columns(pl.col("timestamp").cast(pl.Datetime))
770
773
 
774
+ # We want to subtract 15 minutes because the original load curve provides information
775
+ # for the previous 15 minutes for each timestamp. For example, the first timestamp is 00:00:15,
776
+ # and the columns correspond to consumption from 00:00:00 to 00:00:15. When aggregating,
777
+ # we want the 00:00:00 timestamp to correspond to the consumption from 00:00:00 to whenever the
778
+ # next timestamp is.
779
+ load_curve = load_curve.with_columns((pl.col("timestamp") - timedelta(minutes=15)).alias("timestamp"))
780
+
771
781
  # Get the grouping key configuration
772
782
  grouping_key, format_string = _get_time_step_grouping_key(aggregate_time_step)
773
783
 
@@ -787,7 +797,7 @@ def _aggregate_load_curve_aggregate(load_curve: pl.DataFrame, aggregate_time_ste
787
797
 
788
798
 
789
799
  def _download_and_process_aggregate(
790
- url: str, output_file: Path, progress: Progress, task_id: TaskID, aggregate_time_step: str
800
+ url: str, output_file: Path, progress: Progress, task_id: TaskID, aggregate_time_step: str, release_year: str
791
801
  ) -> int:
792
802
  """Download aggregate time step load curve to temporary file, process with Polars, and save result."""
793
803
  # Get file size first for progress tracking
@@ -822,7 +832,7 @@ def _download_and_process_aggregate(
822
832
 
823
833
  # Process with Polars
824
834
  load_curve_15min = pl.read_parquet(temp_path)
825
- load_curve_aggregate = _aggregate_load_curve_aggregate(load_curve_15min, aggregate_time_step)
835
+ load_curve_aggregate = _aggregate_load_curve_aggregate(load_curve_15min, aggregate_time_step, release_year)
826
836
 
827
837
  # Save processed file to final destination
828
838
  load_curve_aggregate.write_parquet(output_file)
@@ -1040,7 +1050,9 @@ def download_aggregate_time_step_load_curve_with_progress(
1040
1050
 
1041
1051
  # Download with progress tracking if progress object is provided
1042
1052
  if progress and task_id is not None:
1043
- _download_and_process_aggregate(download_url, output_file, progress, task_id, aggregate_time_step)
1053
+ _download_and_process_aggregate(
1054
+ download_url, output_file, progress, task_id, aggregate_time_step, bldg_id.release_year
1055
+ )
1044
1056
  else:
1045
1057
  # For non-progress downloads, still use temp file approach for consistency
1046
1058
  with tempfile.NamedTemporaryFile(delete=False, suffix=".parquet") as temp_file:
@@ -1052,7 +1064,9 @@ def download_aggregate_time_step_load_curve_with_progress(
1052
1064
 
1053
1065
  # Process with Polars
1054
1066
  load_curve_15min = pl.read_parquet(temp_path)
1055
- load_curve_aggregate = _aggregate_load_curve_aggregate(load_curve_15min, aggregate_time_step)
1067
+ load_curve_aggregate = _aggregate_load_curve_aggregate(
1068
+ load_curve_15min, aggregate_time_step, bldg_id.release_year
1069
+ )
1056
1070
 
1057
1071
  # Save processed file to final destination
1058
1072
  load_curve_aggregate.write_parquet(output_file)
@@ -1715,8 +1729,10 @@ def fetch_bldg_data(
1715
1729
  total_files += len(unique_metadata_urls) # Add metadata file
1716
1730
  if file_type_obj.load_curve_15min:
1717
1731
  total_files += len(bldg_ids) # Add 15-minute load curve files
1732
+ if file_type_obj.load_curve_hourly:
1733
+ total_files += len(bldg_ids) # Add hourly load curve files
1718
1734
  if file_type_obj.load_curve_monthly:
1719
- total_files += len(bldg_ids) # Add 15-minute load curve files
1735
+ total_files += len(bldg_ids) # Add monthly load curve files
1720
1736
  if file_type_obj.load_curve_annual:
1721
1737
  total_files += len(bldg_ids) # Add annual load curve files
1722
1738
  if file_type_obj.weather:
@@ -1788,6 +1804,19 @@ def _execute_downloads(
1788
1804
  bldg_ids, output_dir, max_workers, progress, downloaded_paths, failed_downloads, console
1789
1805
  )
1790
1806
 
1807
+ if file_type_obj.load_curve_hourly:
1808
+ aggregate_time_step = "hourly"
1809
+ _download_aggregate_load_curves_parallel(
1810
+ bldg_ids,
1811
+ output_dir,
1812
+ aggregate_time_step,
1813
+ max_workers,
1814
+ progress,
1815
+ downloaded_paths,
1816
+ failed_downloads,
1817
+ console,
1818
+ )
1819
+
1791
1820
  if file_type_obj.load_curve_monthly:
1792
1821
  aggregate_time_step = "monthly"
1793
1822
  _download_aggregate_load_curves_parallel(
@@ -29,7 +29,7 @@ app = typer.Typer(
29
29
  BUILDSTOCK_RELEASES_FILE = str(files("buildstock_fetch").joinpath("data").joinpath("buildstock_releases.json"))
30
30
 
31
31
  # File types that haven't been implemented yet
32
- UNAVAILABLE_FILE_TYPES = ["load_curve_hourly", "load_curve_daily"]
32
+ UNAVAILABLE_FILE_TYPES = ["load_curve_daily"]
33
33
 
34
34
 
35
35
  class InvalidProductError(Exception):
@@ -125,6 +125,14 @@ def _get_release_versions_options(
125
125
  )
126
126
  available_release_versions = list({parsed_releases[release]["release_version"] for release in available_releases})
127
127
 
128
+ if (
129
+ product_type == "resstock"
130
+ and weather_file == "tmy3"
131
+ and release_year == "2024"
132
+ and "1" in available_release_versions
133
+ ):
134
+ available_release_versions.remove("1")
135
+
128
136
  # Define the desired order: "2", "1.1", "1"
129
137
  display_order = ["2", "1.1", "1"]
130
138
 
@@ -785,9 +793,6 @@ def _process_data_download(inputs: dict[str, Union[str, list[str]]]) -> None:
785
793
  if isinstance(output_dir, list):
786
794
  output_dir = output_dir[0] if output_dir else "."
787
795
 
788
- print(selected_bldg_ids)
789
- print(available_weather_states)
790
- print(file_type_tuple)
791
796
  fetch_bldg_data(
792
797
  selected_bldg_ids, file_type_tuple, Path(output_dir), weather_states=available_weather_states
793
798
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: buildstock-fetch
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: This library simplifies downloading building characteristics and load curve data from NREL's ResStock and ComStock projects.
5
5
  Author-email: Switchbox <hello@switch.box>
6
6
  Project-URL: Homepage, https://switchbox-data.github.io/buildstock-fetch/
@@ -1,7 +1,7 @@
1
1
  buildstock_fetch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  buildstock_fetch/__main__.py,sha256=wEPNJ-s7F6KcRQ_4B5Xh08uqvYZHno5F2R8DU0BMBtk,80
3
- buildstock_fetch/main.py,sha256=J3C44xYW1MVe9CAtcJfyNwDeoJJ-XNRFVv7lAcmxH-0,72445
4
- buildstock_fetch/main_cli.py,sha256=Qg2cXRuzMpMpm-eH567UrEY3HIoLYQtSLRWDYMNr6Y0,31813
3
+ buildstock_fetch/main.py,sha256=6NAYxs_5yW0PpNgPdCgmaJJUqgSF-InrMO8xZJe4npQ,73839
4
+ buildstock_fetch/main_cli.py,sha256=3zKJ5sXG2QGmAs--kZPQy1qhLEnaw5gvi4RoH_q65dI,31891
5
5
  buildstock_fetch/data/buildstock_releases.json,sha256=rHbNkWtTi6VXFim7xtvhwFWQUvtqvcbCfjtvRjkWV-4,10853
6
6
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=comstock/release_year=2021/weather_file=amy2018/release_version=1/state=AK/d1454abff0d94c8090af7b3e923c473b-0.parquet,sha256=nG6H3oGyDzPk1B15YmFd_U81PsA14uABqqwK7P30nKE,7059
7
7
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=comstock/release_year=2021/weather_file=amy2018/release_version=1/state=AK/dcd864cc169b4695be2b9775b1a054ae-0.parquet,sha256=fsREWV9g4fsA3cIWqyPnXVwd7FsJxED2btYpmyOvnbQ,7163
@@ -1600,9 +1600,9 @@ buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/r
1600
1600
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/release_year=2024/weather_file=tmy3/release_version=2/state=WY/d1454abff0d94c8090af7b3e923c473b-0.parquet,sha256=bWuUnd02XJXYXkHqiXQuIidtm1be5yHmrz1-iFZ14ao,22304
1601
1601
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/release_year=2024/weather_file=tmy3/release_version=2/state=WY/dcd864cc169b4695be2b9775b1a054ae-0.parquet,sha256=EC1DGLtXqwF1slnnbuTJyQZF0Ox5hoDRDxgaF_SpN8g,21727
1602
1602
  buildstock_fetch/data/weather_station_map/weather_station_map.parquet,sha256=igNrx-UGH20CqPcjANTDrrMyj6Z4_JcXIg2aaCNhFRg,346990
1603
- buildstock_fetch-1.2.0.dist-info/licenses/LICENSE,sha256=TJeh2yvO8__8Rbamd8r48-zvlFCINAsu9nOo5QdMRX8,1066
1604
- buildstock_fetch-1.2.0.dist-info/METADATA,sha256=6Px9cA0FJ9O16wBWSUQ9EKEDXNVG3tuMd-uMhaJmOv4,7607
1605
- buildstock_fetch-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1606
- buildstock_fetch-1.2.0.dist-info/entry_points.txt,sha256=C7zPk3BSLcI47ymvYKI05nvfRJMEXz4BPIIDKsjePn8,54
1607
- buildstock_fetch-1.2.0.dist-info/top_level.txt,sha256=-PGb2C-Tb3O-wPqUHSOBrvJqRzNHgY_KTbTsXaHIo5M,17
1608
- buildstock_fetch-1.2.0.dist-info/RECORD,,
1603
+ buildstock_fetch-1.3.0.dist-info/licenses/LICENSE,sha256=TJeh2yvO8__8Rbamd8r48-zvlFCINAsu9nOo5QdMRX8,1066
1604
+ buildstock_fetch-1.3.0.dist-info/METADATA,sha256=Ifx3dv3sp1coZB7-umz3kdpk3NEILXnZSjTdrIRYFOg,7607
1605
+ buildstock_fetch-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1606
+ buildstock_fetch-1.3.0.dist-info/entry_points.txt,sha256=C7zPk3BSLcI47ymvYKI05nvfRJMEXz4BPIIDKsjePn8,54
1607
+ buildstock_fetch-1.3.0.dist-info/top_level.txt,sha256=-PGb2C-Tb3O-wPqUHSOBrvJqRzNHgY_KTbTsXaHIo5M,17
1608
+ buildstock_fetch-1.3.0.dist-info/RECORD,,