Using the CdaExporter Class =========================== .. toctree:: :maxdepth: 2 :caption: Contents: .. role:: py(code) :language: python Exporting Configuration ----------------------- The configuration information for exporting SHEF data from a CWMS database is stored much like the SHEF loading configuration. However, instead of having one import time series group, you can create as many time series groups as necessary under the ``SHEF Export`` time series category, and assign the time series to be exported to the groups. Note that this allows for a single time series to be a member of more than one export group. .. dropdown:: Why use sparate time series categoreies & groups for loading and unloading? 1. It allows for SHEF text for a specific location and parameter to be loaded into one time series and unloaded from another one. This allows loading into a "raw" (not screened or validated) time series and unloading from a "revised" (screeened and validiated) time series - although, in this scenario, the SHEF text *should* have different type and source (TS) codes. 2. Using multiple groups for export allows the :py:`CdaExporter` to export by group name instead of having to export multiple time series identifiers to unload SHEF text for specific purposes As in the SHEF loading configuration, assigned time series use the ``Alias`` field to hold the SHEF unloading configuration. The information must be of the format ``...:Units=`` where: * ```` is the location identifer in the SHEF text * ```` is the SHEF phyical element code in the SHEF text * ```` is the SHEF type and source code concatenated with the SHEF extremum code [1]_ in the SHEF text * ```` is the SHEF duration numeric value corresponding to the duration code in the SHEF text * ```` is the unit of the values in the SHEF text For information on SHEF codes, see the `SHEF Code Manual `_ Groups ------ As stated above, the :py:`CdaExporter` can export by group where the group name is the name of a time series group under the ``SHEF Export`` time series category. The group operations available are: * :py:`get_groups() -> dict[str, str]` returns a dictionary whose keys are the defined group names and whose values are the description in the CWMS database for each group * :py:`get_time_series(group: str) -> list[str]` returns a list of time series identifiers assigned to the specified group Other ----- * :py:`get_unit(tsid: str) -> Optional[str]` returns the SHEF unit for the time series as specified in alias field of the time series group assignment. Examples -------- An exmple configuration and a Python script using it to unload data is shown below. Note that some non-standard SHEF PE codes are used, so an annotated SHEF file is created that has extra information. .. figure:: images/cda-exporter-config.png :alt: Application screenshot :width: 100% :align: left CWMS-Vue with SHEF unloading configuration info (double-click to see larger image). .. code-block:: python # export_arbuckle.py import os from datetime import datetime, timedelta from shef.exporters import CdaExporter exporter = CdaExporter(os.getenv("cda_url_root"), "SWT") exporter.start_time = datetime.now() - timedelta(hours=6) exporter.end_time = datetime.now() group_name = "ARBU" assert group_name in exporter.get_groups() # ------------------------------------------------------------------ # # Generate SHEF data for time series in group "ARBU" (Arbuckle Lake) # # ------------------------------------------------------------------ # # Create a file with just SHEF data (no indication of missing data) # # ------------------------------------------------------------------ # with open("Arbuckle.shef", "w") as f: exporter.set_output(f) exporter.export(group_name) # -------------------------------------------- # # Create an annotated SHEF file that includes: # # 1. Source time series IDs # # 2. SHEF units # # 3. Indication of missing data # # -------------------------------------------- # with open("Arbuckle-annotated.shef", "w") as f: exporter.set_output(f) for tsid in exporter.get_time_series(group_name): f.write(f":\n: {tsid}, unit={exporter.get_unit(tsid)}\n:\n") shef = exporter.get_export(tsid) f.write(shef if shef else "\n\n") .. dropdown:: Arbuckle.shef :: .E ARBO2 20251124 Z DH060000/LSHPZZ/DIH01 .E1 73.3261/73.3737/73.3499/73.3737/73.3737/73.3737/ .E ARBO2 20251124 Z DH060000/PCHPZZ/DIH01 .E1 38.85/38.99/39.05/39.06/39.06/39.08/ .E ARBO2 20251124 Z DH060000/HPHPZZ/DIH01 .E1 872.39/872.41/872.4/872.41/872.41/872.41/ .E ARBO2 20251124 Z DH060000/VBHPZZ/DIH01 .E1 13.05/13.05/13.05/13.05/13.05/13.05/ .E ARBO2 20251124 Z DH060000/YHHPZZ/DIH01 .E1 12.97/12.97/12.97/12.97/12.97/12.97/ .E ARBO2 20251124 Z DH060000/YLHPZZ/DIH01 .E1 100/100/100/100/100/100/ .E ARBO2 20251124 Z DH060000/YDHPZZ/DIH01 .E1 62.571/62.571/62.571/62.571/62.571/62.571/ .E ARBO2 20251124 Z DH060000/YMHPZZ/DIH01 .E1 2.54375/2.67419/2.609/2.67419/2.67419/2.67419/ .E ARBO2 20251124 Z DH060000/YEHPZZ/DIH01 .E1 0.92712/0.97466/0.9509/0.97466/0.97466/0.97466/ .. dropdown:: Arbuckle-annotated.shef :: : : ARBU.Stor.Inst.1Hour.0.Ccp-Rev, unit=kaf : .E ARBO2 20251124 Z DH060000/LSHPZZ/DIH01 .E1 73.3261/73.3737/73.3499/73.3737/73.3737/73.3737/ : : ARBU.Precip-Cuml.Inst.1Hour.0.Ccp-Rev, unit=in : .E ARBO2 20251124 Z DH060000/PCHPZZ/DIH01 .E1 38.85/38.99/39.05/39.06/39.06/39.08/ : : ARBU.Elev.Inst.1Hour.0.Ccp-Rev, unit=ft : .E ARBO2 20251124 Z DH060000/HPHPZZ/DIH01 .E1 872.39/872.41/872.4/872.41/872.41/872.41/ : : ARBU.Volt-Battery.Inst.1Hour.0.Ccp-Rev, unit=volt : .E ARBO2 20251124 Z DH060000/VBHPZZ/DIH01 .E1 13.05/13.05/13.05/13.05/13.05/13.05/ : : ARBU.Volt-Battery Load.Inst.1Hour.0.Ccp-Rev, unit=volt : .E ARBO2 20251124 Z DH060000/YHHPZZ/DIH01 .E1 12.97/12.97/12.97/12.97/12.97/12.97/ : : ARBU.Precip-Cuml Alt.Inst.1Hour.0.Ccp-Rev, unit=in : : : ARBU.%-Conservation Pool Full.Inst.1Hour.0.Ccp-Rev, unit=% : .E ARBO2 20251124 Z DH060000/YLHPZZ/DIH01 .E1 100/100/100/100/100/100/ : : ARBU.Stor-Conservation Pool.Inst.1Hour.0.Ccp-Rev, unit=kaf : .E ARBO2 20251124 Z DH060000/YDHPZZ/DIH01 .E1 62.571/62.571/62.571/62.571/62.571/62.571/ : : ARBU.%-Flood Pool Full.Inst.1Hour.0.Ccp-Rev, unit=% : .E ARBO2 20251124 Z DH060000/YMHPZZ/DIH01 .E1 2.54375/2.67419/2.609/2.67419/2.67419/2.67419/ : : ARBU.Stor-Flood Pool.Inst.1Hour.0.Ccp-Rev, unit=kaf : .E ARBO2 20251124 Z DH060000/YEHPZZ/DIH01 .E1 0.92712/0.97466/0.9509/0.97466/0.97466/0.97466/ .. [1] Use ``Z`` unless you know the values represent some extremum (min or max over a time period), in which case consult the `SHEF Code Manual `_.