cloudnetpy 1.56.13__py3-none-any.whl → 1.56.14__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.
@@ -498,30 +498,58 @@ def _read_toa5(filename: str | PathLike) -> dict[str, list]:
498
498
  return data
499
499
 
500
500
 
501
- def _read_typ_op4a(filename: str | PathLike) -> dict[str, list]:
501
+ def _read_typ_op4a(lines: list[str]) -> dict[str, list]:
502
502
  """Read output of "CS/PA" command. The output starts with line "TYP OP4A"
503
503
  followed by one line per measured variable in format: <number>:<value>.
504
504
  Output ends with characters: <ETX><CR><LF><NUL>. Lines are separated by
505
505
  <CR><LF>.
506
506
  """
507
507
  data = {}
508
- with open(filename, encoding="latin1", errors="ignore") as file:
509
- for line in file:
510
- if ":" not in line:
511
- continue
512
- key, value = line.strip().split(":", maxsplit=1)
513
- # Skip datetime and 16-bit values.
514
- if key in ("19", "30", "31", "32", "33"):
515
- continue
516
- varname = TELEGRAM.get(int(key))
517
- if varname is None:
518
- continue
519
- parser = PARSERS.get(varname, next)
520
- tokens = value.split(";")
521
- data[varname] = [parser(iter(tokens))]
508
+ for line in lines:
509
+ if ":" not in line:
510
+ continue
511
+ key, value = line.strip().split(":", maxsplit=1)
512
+ # Skip datetime and 16-bit values.
513
+ if key in ("19", "30", "31", "32", "33"):
514
+ continue
515
+ varname = TELEGRAM.get(int(key))
516
+ if varname is None:
517
+ continue
518
+ parser = PARSERS.get(varname, next)
519
+ tokens = value.split(";")
520
+ data[varname] = [parser(iter(tokens))]
522
521
  return data
523
522
 
524
523
 
524
+ def _read_fmi(content: str):
525
+ """Read format used by Finnish Meteorological Institute and University of
526
+ Helsinki:
527
+ - "[YYYY-MM-DD HH:MM:SS\n"
528
+ - output of "CS/PA" command without non-printable characters at the end
529
+ - "]\n"
530
+ """
531
+ output: dict[str, Any] = defaultdict(list)
532
+ for m in re.finditer(
533
+ r"\[(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+) "
534
+ r"(?P<hour>\d+):(?P<minute>\d+):(?P<second>\d+)"
535
+ r"(?P<output>[^\]]*)\]",
536
+ content,
537
+ ):
538
+ for key, value in _read_typ_op4a(m["output"].splitlines()).items():
539
+ output[key].append(value)
540
+ output["_datetime"].append(
541
+ datetime.datetime(
542
+ int(m["year"]),
543
+ int(m["month"]),
544
+ int(m["day"]),
545
+ int(m["hour"]),
546
+ int(m["minute"]),
547
+ int(m["second"]),
548
+ )
549
+ )
550
+ return output
551
+
552
+
525
553
  def _read_parsivel(
526
554
  filenames: Iterable[str | PathLike],
527
555
  telegram: Sequence[int | None] | None = None,
@@ -530,17 +558,20 @@ def _read_parsivel(
530
558
  combined_data = defaultdict(list)
531
559
  for filename in filenames:
532
560
  with open(filename, encoding="latin1", errors="ignore") as file:
533
- lines = file.read().splitlines()
561
+ content = file.read()
562
+ lines = content.splitlines()
534
563
  if not lines:
535
564
  msg = f"File '{filename}' is empty"
536
565
  raise DisdrometerDataError(msg)
537
566
  if "TOA5" in lines[0]:
538
567
  data = _read_toa5(filename)
539
568
  elif "TYP OP4A" in lines[0]:
540
- data = _read_typ_op4a(filename)
569
+ data = _read_typ_op4a(lines)
541
570
  elif "Date" in lines[0]:
542
571
  headers = _parse_headers(lines[0])
543
572
  data = _read_rows(headers, lines[1:])
573
+ elif "[" in lines[0]:
574
+ data = _read_fmi(content)
544
575
  elif telegram is not None:
545
576
  headers = _parse_telegram(telegram)
546
577
  data = _read_rows(headers, lines)
@@ -166,7 +166,7 @@ DEFINITIONS = {
166
166
  "Value 5: Good radar echo only.\n"
167
167
  "Value 6: No radar echo but known attenuation.\n"
168
168
  "Value 7: Radar echo corrected for liquid attenuation using microwave\n"
169
- " radiometer data."
169
+ " radiometer data.\n"
170
170
  "Value 8: Radar ground clutter.\n"
171
171
  "Value 9: Lidar clear-air molecular scattering."
172
172
  ),
cloudnetpy/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 56
3
- PATCH = 13
3
+ PATCH = 14
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloudnetpy
3
- Version: 1.56.13
3
+ Version: 1.56.14
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -8,7 +8,7 @@ cloudnetpy/metadata.py,sha256=Bcu1a9UyUq61jomuZ0_6hYIOzf61e5qCXeiwLm46ikw,5040
8
8
  cloudnetpy/output.py,sha256=jD1pfBb4OQhVOrlhPEk-8FAi4bUW7zjAL468r6BPkJg,14586
9
9
  cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  cloudnetpy/utils.py,sha256=yY5a5HLuAks2uzA4XbbqsGFEmXoyqECn_TjD3sMa0lI,27193
11
- cloudnetpy/version.py,sha256=bpWyAessbgr5f46ROxR4dNxoCHjQ47qyZBv3TvLVaEU,73
11
+ cloudnetpy/version.py,sha256=Fa0L-CaTgGkRxlnKqX3a-6es2Ei1Q8LSXzXmGmFXq7w,73
12
12
  cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
13
13
  cloudnetpy/categorize/atmos.py,sha256=cax3iRmvr7S-VkUZqz0JCfAN3WEsUVbGfH4zSHy1APo,12384
14
14
  cloudnetpy/categorize/atmos_utils.py,sha256=wndpwJxc2-QnNTkV8tc8I11Vs_WkNz9sVMX1fuGgUC4,3777
@@ -48,7 +48,7 @@ cloudnetpy/instruments/vaisala.py,sha256=E6PaK26lHprqOJUCEDZPZQu83Qan9n_THudTFQM
48
48
  cloudnetpy/instruments/weather_station.py,sha256=IMJHGXfMhb4jJw_i66oGDCkeeRn3_eko8zVehu6Fte0,5970
49
49
  cloudnetpy/instruments/disdrometer/__init__.py,sha256=lyjwttWvFvuwYxEkusoAvgRcbBmglmOp5HJOpXUqLWo,93
50
50
  cloudnetpy/instruments/disdrometer/common.py,sha256=nWlVqwvlxei4wJaubBN6NoNsAOpnEqDHvKCPjrAb6Go,15701
51
- cloudnetpy/instruments/disdrometer/parsivel.py,sha256=QVd5DTDWvBIAEfXgo_3gbjoU8yL2co2e5Z5BqoqNkjc,19887
51
+ cloudnetpy/instruments/disdrometer/parsivel.py,sha256=7clC_RS1vbHQ9xY5kHp0pShSRk9mnRwnWHMx42MJJSU,20766
52
52
  cloudnetpy/instruments/disdrometer/thies.py,sha256=h7EwZ9tn47UUMiYqDQ68vkXv4q0rEqX1ZeFXd7XJYNg,5050
53
53
  cloudnetpy/model_evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  cloudnetpy/model_evaluation/file_handler.py,sha256=oUGIblcEWLLv16YKUch-M5KA-dGRAcuHa-9anP3xtX4,6447
@@ -94,7 +94,7 @@ cloudnetpy/plotting/__init__.py,sha256=lg9Smn4BI0dVBgnDLC3JVJ4GmwoSnO-qoSd4ApvwV
94
94
  cloudnetpy/plotting/plot_meta.py,sha256=NWI8ECKMypN5YyM9XKCAp1WEthbFlKMvilxqXmYSEK4,14631
95
95
  cloudnetpy/plotting/plotting.py,sha256=2NhSl_4gcLxOSlUEGPnwBNc0mUCmPracaguHo9kL51A,30714
96
96
  cloudnetpy/products/__init__.py,sha256=2hRb5HG9hNrxH1if5laJkLeFeaZCd5W1q3hh4ewsX0E,273
97
- cloudnetpy/products/classification.py,sha256=J_FOMUSyxvFaT-hvdKVVcKPtuQ0u3V9PsV5xaIKzMjg,7843
97
+ cloudnetpy/products/classification.py,sha256=0E9OUGR3uLCsS1nORwQu0SqW0_8uX7n6LlRcVhtzKw4,7845
98
98
  cloudnetpy/products/der.py,sha256=HAdPvbJySEqkIwDrdZDPnli_wnN2qwm72_D1a82ZWIs,12398
99
99
  cloudnetpy/products/drizzle.py,sha256=BY2HvJeWt_ps6KKCGXwUUNRTy78q0cQM8bOCCoj8TWA,10803
100
100
  cloudnetpy/products/drizzle_error.py,sha256=4GwlHRtNbk9ks7bGtXCco-wXbcDOKeAQwKmbhzut6Qk,6132
@@ -106,8 +106,8 @@ cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe5
106
106
  cloudnetpy/products/mwr_tools.py,sha256=PRm5aCULccUehU-Byk55wYhhEHseMjoAjGBu5TSyHao,4621
107
107
  cloudnetpy/products/product_tools.py,sha256=E8CSijBY8cr70BH2JFa0lGQ-RzI9EcHQ0Fzt8CQ8rY4,10442
108
108
  docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
109
- cloudnetpy-1.56.13.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
110
- cloudnetpy-1.56.13.dist-info/METADATA,sha256=U0Jsf1FLCoaqvQag9FAToXdPB7YD6EGBNEMPHb4h0_4,5734
111
- cloudnetpy-1.56.13.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
112
- cloudnetpy-1.56.13.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
113
- cloudnetpy-1.56.13.dist-info/RECORD,,
109
+ cloudnetpy-1.56.14.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
110
+ cloudnetpy-1.56.14.dist-info/METADATA,sha256=nSphTgk88JFpj2s5KJX9SLUFuHkKBIcLvUcm0ZC2w8E,5734
111
+ cloudnetpy-1.56.14.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
112
+ cloudnetpy-1.56.14.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
113
+ cloudnetpy-1.56.14.dist-info/RECORD,,