pypromice 1.4.0__tar.gz → 1.4.2__tar.gz

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 pypromice might be problematic. Click here for more details.

Files changed (59) hide show
  1. {pypromice-1.4.0/src/pypromice.egg-info → pypromice-1.4.2}/PKG-INFO +2 -2
  2. {pypromice-1.4.0 → pypromice-1.4.2}/setup.py +2 -2
  3. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/bufr_to_csv.py +9 -2
  4. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/L2toL3.py +1 -0
  5. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/aws.py +10 -1
  6. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/resample.py +51 -3
  7. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/utilities/git.py +8 -7
  8. {pypromice-1.4.0 → pypromice-1.4.2/src/pypromice.egg-info}/PKG-INFO +2 -2
  9. {pypromice-1.4.0 → pypromice-1.4.2}/LICENSE.txt +0 -0
  10. {pypromice-1.4.0 → pypromice-1.4.2}/MANIFEST.in +0 -0
  11. {pypromice-1.4.0 → pypromice-1.4.2}/README.md +0 -0
  12. {pypromice-1.4.0 → pypromice-1.4.2}/setup.cfg +0 -0
  13. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/__init__.py +0 -0
  14. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/get/__init__.py +0 -0
  15. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/get/get.py +0 -0
  16. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/get/get_promice_data.py +0 -0
  17. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/__init__.py +0 -0
  18. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/bufr_utilities.py +0 -0
  19. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/create_bufr_files.py +0 -0
  20. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/get_bufr.py +0 -0
  21. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/make_metadata_csv.py +0 -0
  22. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/positions_seed.csv +0 -0
  23. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/postprocess/real_time_utilities.py +0 -0
  24. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/L0toL1.py +0 -0
  25. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/L1toL2.py +0 -0
  26. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/__init__.py +0 -0
  27. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/get_l2.py +0 -0
  28. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/get_l2tol3.py +0 -0
  29. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/join_l2.py +0 -0
  30. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/join_l3.py +0 -0
  31. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/load.py +0 -0
  32. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/utilities.py +0 -0
  33. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/value_clipping.py +0 -0
  34. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/process/write.py +0 -0
  35. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/__init__.py +0 -0
  36. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/github_data_issues.py +0 -0
  37. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/percentiles/__init__.py +0 -0
  38. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/percentiles/compute_thresholds.py +0 -0
  39. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/percentiles/outlier_detector.py +0 -0
  40. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/percentiles/thresholds.csv +0 -0
  41. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/qc/persistence.py +0 -0
  42. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/resources/__init__.py +0 -0
  43. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/resources/file_attributes.csv +0 -0
  44. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/resources/variable_aliases_GC-Net.csv +0 -0
  45. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/resources/variables.csv +0 -0
  46. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/station_configuration.py +0 -0
  47. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/__init__.py +0 -0
  48. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/get_l0tx.py +0 -0
  49. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/get_msg.py +0 -0
  50. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/get_watsontx.py +0 -0
  51. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/payload_formats.csv +0 -0
  52. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/payload_types.csv +0 -0
  53. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/tx/tx.py +0 -0
  54. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice/utilities/__init__.py +0 -0
  55. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice.egg-info/SOURCES.txt +0 -0
  56. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice.egg-info/dependency_links.txt +0 -0
  57. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice.egg-info/entry_points.txt +0 -0
  58. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice.egg-info/requires.txt +0 -0
  59. {pypromice-1.4.0 → pypromice-1.4.2}/src/pypromice.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypromice
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: PROMICE/GC-Net data processing toolbox
5
5
  Home-page: https://github.com/GEUS-Glaciology-and-Climate/pypromice
6
6
  Author: GEUS Glaciology and Climate
@@ -15,7 +15,7 @@ Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Topic :: Scientific/Engineering
17
17
  Classifier: Operating System :: OS Independent
18
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.txt
21
21
  Requires-Dist: numpy~=1.23
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="pypromice",
8
- version="1.4.0",
8
+ version="1.4.2",
9
9
  author="GEUS Glaciology and Climate",
10
10
  description="PROMICE/GC-Net data processing toolbox",
11
11
  long_description=long_description,
@@ -29,7 +29,7 @@ setuptools.setup(
29
29
  package_dir={"": "src"},
30
30
  include_package_data = True,
31
31
  packages=setuptools.find_packages(where="src"),
32
- python_requires=">=3.8",
32
+ python_requires=">=3.10",
33
33
  package_data={
34
34
  "pypromice.tx": ["payload_formats.csv", "payload_types.csv"],
35
35
  "pypromice.qc.percentiles": ["thresholds.csv"],
@@ -1,15 +1,22 @@
1
1
  import argparse
2
2
  from pathlib import Path
3
3
 
4
+ import pandas as pd
5
+
4
6
  from pypromice.postprocess.bufr_utilities import read_bufr_file
5
7
 
6
8
 
7
9
  def main():
8
10
  parser = argparse.ArgumentParser("BUFR to CSV converter")
9
- parser.add_argument("path", type=Path)
11
+ parser.add_argument("path", type=Path, nargs='+')
10
12
  args = parser.parse_args()
11
13
 
12
- print(read_bufr_file(args.path).to_csv())
14
+ paths = []
15
+ for path in args.path:
16
+ paths += list(path.parent.glob(path.name))
17
+
18
+ df = pd.concat([read_bufr_file(path) for path in paths])
19
+ print(df.to_csv())
13
20
 
14
21
 
15
22
  if __name__ == "__main__":
@@ -254,6 +254,7 @@ def process_surface_height(ds, data_adjustments_dir, station_config={}):
254
254
 
255
255
  ds['z_surf_combined'] = np.maximum(ds['z_surf_combined'], ds['z_ice_surf'])
256
256
  ds['snow_height'] = np.maximum(0, ds['z_surf_combined'] - ds['z_ice_surf'])
257
+ ds['z_ice_surf'] = ds['z_ice_surf'].where(ds.snow_height.notnull())
257
258
  elif ds.attrs['site_type'] in ['accumulation', 'bedrock']:
258
259
  # Handle accumulation and bedrock site types
259
260
  ds['z_ice_surf'] = ('time', ds['z_surf_1'].data * np.nan)
@@ -55,7 +55,15 @@ class AWS(object):
55
55
  """
56
56
  assert os.path.isfile(config_file), "cannot find " + config_file
57
57
  assert os.path.isdir(inpath), "cannot find " + inpath
58
- logger.info("AWS object initialising...")
58
+ logger.info(
59
+ "AWS("
60
+ f"config_file={config_file},"
61
+ f" inpath={inpath},"
62
+ f" data_issues_repository={data_issues_repository},"
63
+ f" var_file={var_file},"
64
+ f" meta_file={meta_file}"
65
+ ")"
66
+ )
59
67
 
60
68
  # Load config, variables CSF standards, and L0 files
61
69
  self.config = self.loadConfig(config_file, inpath)
@@ -73,6 +81,7 @@ class AWS(object):
73
81
  l0_data_root=inpath_hash,
74
82
  data_issues=data_issues_hash,
75
83
  )
84
+ logger.debug('Source information: %s', source_dict)
76
85
  self.meta["source"] = json.dumps(source_dict)
77
86
 
78
87
  # Load config file
@@ -32,8 +32,46 @@ def resample_dataset(ds_h, t):
32
32
  ds_d : xarray.Dataset
33
33
  L3 AWS dataset resampled to the frequency defined by t
34
34
  '''
35
- df_d = ds_h.to_dataframe().resample(t).mean()
35
+ # Convert dataset to DataFrame
36
+ df_d = ds_h.to_dataframe()
36
37
 
38
+ # Identify non-numeric columns
39
+ non_numeric_cols = df_d.select_dtypes(exclude=['number']).columns
40
+
41
+ # Log a warning and drop non-numeric columns
42
+ if len(non_numeric_cols) > 0:
43
+ for col in non_numeric_cols:
44
+ unique_values = df_d[col].unique()
45
+ logger.warning(f"Dropping column '{col}' because it is of type '{df_d[col].dtype}' and contains unique values: {unique_values}")
46
+
47
+ df_d = df_d.drop(columns=non_numeric_cols)
48
+ # Resample the DataFrame
49
+ df_d = df_d.resample(t).mean()
50
+
51
+ # taking the 10 min data and using it as instantaneous values:
52
+ is_10_minutes_timestamp = (ds_h.time.diff(dim='time') / np.timedelta64(1, 's') == 600)
53
+ if (t == '60min') and is_10_minutes_timestamp.any():
54
+ cols_to_update = ['p_i', 't_i', 'rh_i', 'rh_i_cor', 'wspd_i', 'wdir_i','wspd_x_i','wspd_y_i']
55
+ timestamp_10min = ds_h.time.where(is_10_minutes_timestamp, drop=True).to_index()
56
+ timestamp_round_hour = df_d.index
57
+ timestamp_to_update = timestamp_round_hour.intersection(timestamp_10min)
58
+
59
+ for col in cols_to_update:
60
+ if col not in df_d.columns:
61
+ df_d[col] = np.nan
62
+ else:
63
+ # if there are already instantaneous values in the dataset
64
+ # we want to keep them as they are
65
+ # removing timestamps where there is already t_i filled from a TX file
66
+ missing_instantaneous = ds_h.reindex(time=timestamp_to_update)[col].isnull()
67
+ timestamp_to_update = timestamp_to_update[missing_instantaneous]
68
+ df_d.loc[timestamp_to_update, col] = ds_h.reindex(
69
+ time= timestamp_to_update
70
+ )[col.replace('_i','_u')].values
71
+ if col == 'p_i':
72
+ df_d.loc[timestamp_to_update, col] = df_d.loc[timestamp_to_update, col].values-1000
73
+
74
+
37
75
  # recalculating wind direction from averaged directional wind speeds
38
76
  for var in ['wdir_u','wdir_l']:
39
77
  boom = var.split('_')[1]
@@ -60,9 +98,19 @@ def resample_dataset(ds_h, t):
60
98
  if var+'_cor' in df_d.keys():
61
99
  df_d[var+'_cor'] = (p_vap.to_series().resample(t).mean() \
62
100
  / es_cor.to_series().resample(t).mean())*100
101
+
102
+ # passing each variable attribute to the ressample dataset
103
+ vals = []
104
+ for c in df_d.columns:
105
+ if c in ds_h.data_vars:
106
+ vals.append(xr.DataArray(
107
+ data=df_d[c], dims=['time'],
108
+ coords={'time':df_d.index}, attrs=ds_h[c].attrs))
109
+ else:
110
+ vals.append(xr.DataArray(
111
+ data=df_d[c], dims=['time'],
112
+ coords={'time':df_d.index}, attrs=None))
63
113
 
64
- vals = [xr.DataArray(data=df_d[c], dims=['time'],
65
- coords={'time':df_d.index}, attrs=ds_h[c].attrs) for c in df_d.columns]
66
114
  ds_d = xr.Dataset(dict(zip(df_d.columns,vals)), attrs=ds_h.attrs)
67
115
  return ds_d
68
116
 
@@ -7,12 +7,16 @@ import logging
7
7
  logger = logging.getLogger(__name__)
8
8
 
9
9
 
10
- def get_commit_hash_and_check_dirty(file_path) -> str:
11
- repo_path = Path(file_path).parent
10
+ def get_commit_hash_and_check_dirty(file_path: str | Path) -> str:
11
+ if isinstance(file_path, str):
12
+ file_path = Path(file_path)
13
+ if file_path.is_dir():
14
+ repo_path = file_path
15
+ else:
16
+ repo_path = file_path.parent
12
17
 
13
18
  try:
14
19
  # Ensure the file path is relative to the repository
15
- relative_file_path = os.path.relpath(file_path, repo_path)
16
20
 
17
21
  # Get the latest commit hash for the file
18
22
  commit_hash = (
@@ -25,8 +29,6 @@ def get_commit_hash_and_check_dirty(file_path) -> str:
25
29
  "-n",
26
30
  "1",
27
31
  "--pretty=format:%H",
28
- #"--",
29
- #relative_file_path,
30
32
  ],
31
33
  stderr=subprocess.STDOUT,
32
34
  )
@@ -49,12 +51,11 @@ def get_commit_hash_and_check_dirty(file_path) -> str:
49
51
 
50
52
  if is_dirty:
51
53
  logger.warning(f"Warning: The file {file_path} is dirty compared to the last commit. {commit_hash}")
52
- return 'unknown'
54
+ return f'{commit_hash} (dirty)'
53
55
  if commit_hash == "":
54
56
  logger.warning(f"Warning: The file {file_path} is not under version control.")
55
57
  return 'unknown'
56
58
 
57
- print(f"Commit hash: {commit_hash}")
58
59
  return commit_hash
59
60
  except subprocess.CalledProcessError as e:
60
61
  logger.warning(f"Error: {e.output.decode('utf-8')}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pypromice
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: PROMICE/GC-Net data processing toolbox
5
5
  Home-page: https://github.com/GEUS-Glaciology-and-Climate/pypromice
6
6
  Author: GEUS Glaciology and Climate
@@ -15,7 +15,7 @@ Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Topic :: Scientific/Engineering
17
17
  Classifier: Operating System :: OS Independent
18
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.txt
21
21
  Requires-Dist: numpy~=1.23
File without changes
File without changes
File without changes
File without changes