buildstock-fetch 1.4.3__py3-none-any.whl → 1.4.5__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.

@@ -0,0 +1 @@
1
+ __version__ = "1.4.5"
@@ -1,4 +1,104 @@
1
1
  {
2
+ "com_2024_amy2018_1": {
3
+ "upgrade_descriptions": {
4
+ "0": "Baseline",
5
+ "1": "Variable Speed HP RTU, Electric Backup",
6
+ "2": "Variable Speed HP RTU, Original Heating Fuel Backup",
7
+ "3": "Variable Speed HP RTU, Electric Backup, Energy Recovery",
8
+ "5": "VRF with DOAS",
9
+ "6": "VRF with 25pct Upsizing Allowance",
10
+ "7": "DOAS HP Minisplits",
11
+ "8": "HP Boiler, Electric Backup",
12
+ "9": "HP Boiler, Gas Backup",
13
+ "10": "Air Side Economizers for AHUs",
14
+ "11": "Demand Control Ventilation",
15
+ "12": "Energy Recovery for AHUs",
16
+ "13": "Advanced RTU Controls",
17
+ "14": "Unoccupied AHU Control",
18
+ "15": "Hydronic Water-to-Water Geothermal Heat Pump",
19
+ "16": "Packaged Water-to-Air Geothermal Heat Pump",
20
+ "17": "Console Water-to-Air Geothermal Heat Pump",
21
+ "18": "Comprehensive Geothermal Heat Pump Package, Hydronic GHP, Packaged GHP, or Console GHP",
22
+ "19": "Demand Flexibility, Thermostat Control, Load Shed",
23
+ "20": "Demand Flexibility, Thermostat Control, Load Shift",
24
+ "21": "LED Lighting",
25
+ "22": "Electric Kitchen Equipment",
26
+ "23": "Wall Insulation",
27
+ "24": "Roof Insulation",
28
+ "25": "Secondary Windows",
29
+ "26": "Window Film",
30
+ "27": "New Windows",
31
+ "28": "Package 1, Wall & Roof Insulation + New Windows",
32
+ "29": "Package 2, LED Lighting + Variable Speed HP RTU or HP Boilers",
33
+ "31": "Package 4, Package 1 + Package 2",
34
+ "32": "Package 5, Variable Speed HP RTU or HP Boilers + Economizer + DCV + Energy Recovery"
35
+ }
36
+ },
37
+ "com_2024_amy2018_2": {
38
+ "upgrade_descriptions": {
39
+ "0": "Baseline",
40
+ "1": "HP RTU E Backup",
41
+ "2": "HP RTU OF Backup",
42
+ "3": "HP RTU + ER",
43
+ "4": "HP RTU Std Perf",
44
+ "5": "Std Perf w Roof",
45
+ "6": "Std Perf 32F Lockout",
46
+ "7": "CCHPC",
47
+ "8": "VRF with DOAS",
48
+ "9": "VRF with 25pct Upsizing Allowance",
49
+ "10": "DOAS HP Minisplits",
50
+ "11": "HP Boiler E Backup",
51
+ "12": "HP Boiler G Backup",
52
+ "13": "Economizer",
53
+ "14": "DCV",
54
+ "15": "Energy Recovery",
55
+ "16": "Advanced RTU Controls",
56
+ "17": "Unoccupied AHU Control",
57
+ "18": "Ideal Thermal Loads",
58
+ "19": "Hydronic GHP",
59
+ "20": "Packaged GHP",
60
+ "21": "Console GHP",
61
+ "22": "Comprehensive GHP",
62
+ "23": "tstat_shed",
63
+ "24": "tstat_shift",
64
+ "25": "light_shed",
65
+ "26": "light_emission",
66
+ "27": "LED Lighting",
67
+ "28": "Electric Kitchen Equipment",
68
+ "29": "Wall Insulation",
69
+ "30": "Roof Insulation",
70
+ "31": "Secondary Windows",
71
+ "32": "Window Film",
72
+ "33": "New Windows",
73
+ "34": "Package 1",
74
+ "35": "Package 2",
75
+ "36": "Package 3",
76
+ "37": "Package 4",
77
+ "38": "Package 5",
78
+ "39": "Package 6"
79
+ }
80
+ },
81
+ "res_2024_amy2018_2": {
82
+ "upgrade_descriptions": {
83
+ "0": "Baseline",
84
+ "1": "ENERGY STAR heat pump with elec backup",
85
+ "2": "High efficiency cold-climate heat pump with elec backup",
86
+ "3": "Ultra high efficiency heat pump with elec backup",
87
+ "4": "ENERGY STAR heat pump with existing system as backup",
88
+ "5": "Geothermal heat pump",
89
+ "6": "ENERGY STAR heat pump with elec backup + Light Touch Envelope",
90
+ "7": "High efficiency cold-climate heat pump with elec backup + Light Touch Envelope",
91
+ "8": "Ultra high efficiency heat pump with elec backup + Light Touch Envelope",
92
+ "9": "ENERGY STAR heat pump with existing system as backup + Light Touch Envelope",
93
+ "10": "Geothermal heat pump + Light Touch Envelope",
94
+ "11": "ENERGY STAR heat pump with elec backup + Light Touch Envelope + Full Appliance Electrification with Efficiency",
95
+ "12": "High efficiency cold-climate heat pump with elec backup + Light Touch Envelope + Full Appliance Electrification with Efficiency",
96
+ "13": "Ultra high efficiency heat pump with elec backup + Light Touch Envelope + Full Appliance Electrification with Efficiency",
97
+ "14": "ENERGY STAR heat pump with existing system as backup + Light Touch Envelope + Full Appliance Electrification with Efficiency",
98
+ "15": "Geothermal heat pump + Light Touch Envelope + Full Appliance Electrification with Efficiency",
99
+ "16": "Envelope Only - Light Touch Envelope"
100
+ }
101
+ },
2
102
  "res_2024_tmy3_2": {
3
103
  "upgrade_descriptions": {
4
104
  "0": "Baseline",
buildstock_fetch/main.py CHANGED
@@ -722,7 +722,7 @@ def _process_single_metadata_file(metadata_file: Path) -> None:
722
722
 
723
723
  # Use streaming operations to avoid loading entire file into memory
724
724
  # Create a temporary file to write the filtered data
725
- with tempfile.NamedTemporaryFile(delete=False, suffix=".parquet") as temp_file:
725
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".parquet", dir=metadata_file.parent) as temp_file:
726
726
  temp_file_path = temp_file.name
727
727
 
728
728
  try:
@@ -161,7 +161,9 @@ def _get_upgrade_ids_options(release_name: str) -> list[str]:
161
161
  "upgrade_descriptions"
162
162
  ]
163
163
  available_upgrade_ids = [
164
- f"{upgrade_id}: {upgrade_descriptions[upgrade_id]}" for upgrade_id in available_upgrade_ids
164
+ f"{upgrade_id}: {upgrade_descriptions[upgrade_id]}"
165
+ for upgrade_id in available_upgrade_ids
166
+ if upgrade_id in upgrade_descriptions
165
167
  ]
166
168
 
167
169
  return cast(list[str], available_upgrade_ids)
@@ -399,15 +401,26 @@ def _run_interactive_mode() -> dict[str, Union[str, list[str]]]:
399
401
  )
400
402
 
401
403
  # Retrieve upgrade ids
402
- selected_upgrade_ids = _handle_cancellation(
404
+ upgrade_options = _get_upgrade_ids_options(selected_release_name)
405
+ selected_upgrade_ids_raw = _handle_cancellation(
403
406
  questionary.checkbox(
404
407
  "Select upgrade ids:",
405
- choices=_get_upgrade_ids_options(selected_release_name),
406
- instruction="Use spacebar to select/deselect options, enter to confirm",
408
+ choices=upgrade_options,
409
+ instruction="Use spacebar to select/deselect options, 'a' to select all, 'i' to invert selection, enter to confirm",
407
410
  validate=lambda answer: "You must select at least one upgrade id" if len(answer) == 0 else True,
408
411
  ).ask()
409
412
  )
410
413
 
414
+ # Extract upgrade ID integers from the selected options
415
+ selected_upgrade_ids = []
416
+ for option in selected_upgrade_ids_raw:
417
+ if ":" in option:
418
+ # Extract the integer before the colon
419
+ upgrade_id = option.split(":")[0].strip()
420
+ selected_upgrade_ids.append(upgrade_id)
421
+ else:
422
+ selected_upgrade_ids.append(option)
423
+
411
424
  # Retrieve state
412
425
  selected_states: list[str] = cast(
413
426
  list[str],
@@ -658,6 +671,58 @@ def _get_user_download_choice(bldg_ids: list) -> list:
658
671
  return selected_bldg_ids
659
672
 
660
673
 
674
+ def _select_bldg_ids_for_sample(bldg_ids: list, sample: Union[str, None]) -> list:
675
+ """Return building IDs sampled per (state, upgrade_id) pair.
676
+
677
+ - Group by (state, upgrade_id)
678
+ - If sample is "all"/"a": return all IDs from each group
679
+ - If sample is an integer string N: return first N from each group
680
+ - Invalid or non-positive sample returns an empty list
681
+ """
682
+ if sample is None:
683
+ return []
684
+
685
+ # Group building IDs by (state, upgrade_id)
686
+ state_upgrade_groups: dict[tuple[str, str], list] = {}
687
+ for bldg_id in bldg_ids:
688
+ key = (bldg_id.state, bldg_id.upgrade_id)
689
+ if key not in state_upgrade_groups:
690
+ state_upgrade_groups[key] = []
691
+ state_upgrade_groups[key].append(bldg_id)
692
+
693
+ sample_str = str(sample).strip().lower()
694
+ if sample_str in ("all", "a"):
695
+ selected_all: list = []
696
+ for group_ids in state_upgrade_groups.values():
697
+ selected_all.extend(group_ids)
698
+ console.print(f"[green]Selected all {len(selected_all)} building IDs across all state/upgrade pairs.[/green]")
699
+ return selected_all
700
+
701
+ try:
702
+ sample_size = int(sample_str)
703
+ except ValueError:
704
+ console.print(f"[red]Invalid value for --sample: {sample}. Use an integer, 'all', or 'a'.[/red]")
705
+ return []
706
+
707
+ if sample_size <= 0:
708
+ console.print("[yellow]Sample size must be greater than 0.[/yellow]")
709
+ return []
710
+
711
+ # Select first N from each (state, upgrade_id) group
712
+ selected_per_group: list = []
713
+ for (state, upgrade_id), group_ids in state_upgrade_groups.items():
714
+ take = min(sample_size, len(group_ids))
715
+ selected_per_group.extend(group_ids[:take])
716
+ console.print(
717
+ f"[green]Sampling {take} building IDs for State {state}, Upgrade {upgrade_id} (of {len(group_ids)} available).[/green]"
718
+ )
719
+
720
+ if not selected_per_group and len(bldg_ids) > 0:
721
+ console.print("[yellow]No building IDs selected after sampling per group.[/yellow]")
722
+
723
+ return selected_per_group
724
+
725
+
661
726
  def _validate_required_inputs(inputs: dict[str, Union[str, list[str]]]) -> Union[str, bool]:
662
727
  """Validate that all required inputs are provided."""
663
728
  if not all([
@@ -765,7 +830,7 @@ RELEASE_YEAR_OPTION = typer.Option(None, "--release_year", "-y", help="Release y
765
830
  WEATHER_FILE_OPTION = typer.Option(None, "--weather_file", "-w", help='"tmy3", "amy2012", "amy2018"')
766
831
  RELEASE_VERSION_OPTION = typer.Option(None, "--release_version", "-r", help="1, 1.1, or 2")
767
832
  STATES_OPTION = typer.Option(
768
- None, "--states", "-s", help="List of states (multiple can be provided, inside quotes and separated by spaces)"
833
+ None, "--states", "-st", help="List of states (multiple can be provided, inside quotes and separated by spaces)"
769
834
  )
770
835
  FILE_TYPE_OPTION = typer.Option(
771
836
  None,
@@ -777,6 +842,12 @@ UPGRADE_ID_OPTION = typer.Option(
777
842
  None, "--upgrade_id", "-u", help="Upgrade IDs (multiple can be provided, inside quotes and separated by spaces)"
778
843
  )
779
844
  OUTPUT_DIRECTORY_OPTION = typer.Option(None, "--output_directory", "-o", help='e.g., "data" or "../output"')
845
+ SAMPLE_OPTION = typer.Option(
846
+ None,
847
+ "--sample",
848
+ "-sm",
849
+ help="Number of building IDs to download across all upgrades (only applies to direct inputs)",
850
+ )
780
851
  VERSION_OPTION = typer.Option(False, "--version", "-v", help="Show version information and exit")
781
852
 
782
853
 
@@ -824,7 +895,8 @@ def _process_direct_inputs(
824
895
  file_type: str,
825
896
  upgrade_id: str,
826
897
  output_directory: str,
827
- ) -> dict[str, Union[str, list[str]]]:
898
+ sample: Union[str, None] = None,
899
+ ) -> tuple[dict[str, Union[str, list[str]]], Union[str, None]]:
828
900
  """Process direct command line inputs."""
829
901
  states_list = states.split() if states else []
830
902
  upgrade_ids_list = upgrade_id.split() if upgrade_id else ["0"]
@@ -850,10 +922,10 @@ def _process_direct_inputs(
850
922
  console.print(f"\n[red]Invalid product: {direct_inputs['product']}[/red]")
851
923
  raise typer.Exit(1) from None
852
924
 
853
- return direct_inputs
925
+ return direct_inputs, sample
854
926
 
855
927
 
856
- def _process_data_download(inputs: dict[str, Union[str, list[str]]]) -> None:
928
+ def _process_data_download(inputs: dict[str, Union[str, list[str]]], sample: Union[str, None] = None) -> None:
857
929
  """Process data download based on available file types."""
858
930
  available_file_types, unavailable_file_types = _check_unavailable_file_types(inputs)
859
931
  if "weather" in inputs["file_type"]:
@@ -865,8 +937,12 @@ def _process_data_download(inputs: dict[str, Union[str, list[str]]]) -> None:
865
937
  # Fetch the building ids and download data
866
938
  bldg_ids = _fetch_all_building_ids(inputs)
867
939
 
868
- # Ask user about download choice
869
- selected_bldg_ids = _get_user_download_choice(bldg_ids)
940
+ # If sample is provided (direct input mode), use it to sample building IDs
941
+ if sample is not None:
942
+ selected_bldg_ids = _select_bldg_ids_for_sample(bldg_ids, sample)
943
+ else:
944
+ # Ask user about download choice (interactive mode)
945
+ selected_bldg_ids = _get_user_download_choice(bldg_ids)
870
946
 
871
947
  if selected_bldg_ids:
872
948
  file_type_tuple = (
@@ -895,6 +971,7 @@ def main_callback(
895
971
  file_type: str = FILE_TYPE_OPTION,
896
972
  upgrade_id: str = UPGRADE_ID_OPTION,
897
973
  output_directory: str = OUTPUT_DIRECTORY_OPTION,
974
+ sample: str = SAMPLE_OPTION,
898
975
  version: bool = VERSION_OPTION,
899
976
  ) -> None:
900
977
  """
@@ -908,14 +985,23 @@ def main_callback(
908
985
  # If no arguments provided, run interactive mode
909
986
  if not any([product, release_year, weather_file, release_version, states, file_type]):
910
987
  inputs = _run_interactive_mode_wrapper()
988
+ sample_value = None
911
989
  else:
912
- inputs = _process_direct_inputs(
913
- product, release_year, weather_file, release_version, states, file_type, upgrade_id, output_directory
990
+ inputs, sample_value = _process_direct_inputs(
991
+ product,
992
+ release_year,
993
+ weather_file,
994
+ release_version,
995
+ states,
996
+ file_type,
997
+ upgrade_id,
998
+ output_directory,
999
+ sample,
914
1000
  )
915
1001
 
916
1002
  # Process the data
917
1003
  _print_data_processing_info(inputs)
918
- _process_data_download(inputs)
1004
+ _process_data_download(inputs, sample_value)
919
1005
 
920
1006
 
921
1007
  app.command()(main_callback)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: buildstock-fetch
3
- Version: 1.4.3
3
+ Version: 1.4.5
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,9 +1,9 @@
1
- buildstock_fetch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1
+ buildstock_fetch/__init__.py,sha256=Fv2JHnR-ADpzdVitwHAsUrkhe-BpoDkmx7MxtXxlm1k,22
2
2
  buildstock_fetch/__main__.py,sha256=wEPNJ-s7F6KcRQ_4B5Xh08uqvYZHno5F2R8DU0BMBtk,80
3
- buildstock_fetch/main.py,sha256=yZ8xoYWnoyeTIDMXzVnbQt57a2NAZS7bEPRDtj_SuiU,90887
4
- buildstock_fetch/main_cli.py,sha256=ZZ6Yn7rBfXguCiUSszKlB0L-FY88ZJM_HXLC8o1EGNc,36311
3
+ buildstock_fetch/main.py,sha256=zvVfr_fPqC83B3i0S860WFPJOB0SbDZ_LLfaL9IGtMs,90913
4
+ buildstock_fetch/main_cli.py,sha256=4RbIvWjy5VT4BiqfEE3_tXGnGh18M5L4QkMV7SA6vyk,39571
5
5
  buildstock_fetch/data/buildstock_releases.json,sha256=XL-D1Xdix59sFGbS6vKFiGhQakhhPrwn14N-Tgt9iuk,11620
6
- buildstock_fetch/data/buildstock_upgrades_lookup.json,sha256=CCc2dV6voD8r6WpBBq9zoxhVQGAPcUGmAoFyKoUcUpo,1486
6
+ buildstock_fetch/data/buildstock_upgrades_lookup.json,sha256=Nt2R_p-7JN0S-MpGrQQqwAzvEtRRx-PmGqgWrUvHTDw,5801
7
7
  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
8
8
  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
9
9
  buildstock_fetch/data/building_data/combined_metadata.parquet/product=comstock/release_year=2021/weather_file=amy2018/release_version=1/state=AL/d1454abff0d94c8090af7b3e923c473b-0.parquet,sha256=jiTG48ly-LZwfwAL3THdfRzHDG1qEogoxO7P78U4WOU,41201
@@ -1603,9 +1603,9 @@ buildstock_fetch/data/building_data/combined_metadata.parquet/product=resstock/r
1603
1603
  buildstock_fetch/data/load_curve_column_map/2022_resstock_load_curve_columns.csv,sha256=9UoTPlvxR3RqsxH8i4tI75lLtdSAT-HbAFxwlzvAYNY,7339
1604
1604
  buildstock_fetch/data/load_curve_column_map/2024_resstock_load_curve_columns.csv,sha256=TIxqsE-iVHE5tYq9oPSgBxIVbd5qfyDcJG_eTqds9aY,7471
1605
1605
  buildstock_fetch/data/weather_station_map/weather_station_map.parquet,sha256=igNrx-UGH20CqPcjANTDrrMyj6Z4_JcXIg2aaCNhFRg,346990
1606
- buildstock_fetch-1.4.3.dist-info/licenses/LICENSE,sha256=TJeh2yvO8__8Rbamd8r48-zvlFCINAsu9nOo5QdMRX8,1066
1607
- buildstock_fetch-1.4.3.dist-info/METADATA,sha256=7TaxdMpRmwemxFqaneiJ09sXgPzlcuc_xBUIPGdzTn4,8323
1608
- buildstock_fetch-1.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1609
- buildstock_fetch-1.4.3.dist-info/entry_points.txt,sha256=C7zPk3BSLcI47ymvYKI05nvfRJMEXz4BPIIDKsjePn8,54
1610
- buildstock_fetch-1.4.3.dist-info/top_level.txt,sha256=-PGb2C-Tb3O-wPqUHSOBrvJqRzNHgY_KTbTsXaHIo5M,17
1611
- buildstock_fetch-1.4.3.dist-info/RECORD,,
1606
+ buildstock_fetch-1.4.5.dist-info/licenses/LICENSE,sha256=TJeh2yvO8__8Rbamd8r48-zvlFCINAsu9nOo5QdMRX8,1066
1607
+ buildstock_fetch-1.4.5.dist-info/METADATA,sha256=wfDXp8KQNXGzGwyOCbRILkX2VOlxmwdwPOgvkfQN57c,8323
1608
+ buildstock_fetch-1.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1609
+ buildstock_fetch-1.4.5.dist-info/entry_points.txt,sha256=C7zPk3BSLcI47ymvYKI05nvfRJMEXz4BPIIDKsjePn8,54
1610
+ buildstock_fetch-1.4.5.dist-info/top_level.txt,sha256=-PGb2C-Tb3O-wPqUHSOBrvJqRzNHgY_KTbTsXaHIo5M,17
1611
+ buildstock_fetch-1.4.5.dist-info/RECORD,,