rda-python-icoads 1.0.7__tar.gz → 1.0.9__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 rda-python-icoads might be problematic. Click here for more details.

Files changed (35) hide show
  1. rda_python_icoads-1.0.9/MANIFEST.in +6 -0
  2. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/PKG-INFO +1 -1
  3. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/pyproject.toml +20 -3
  4. rda_python_icoads-1.0.9/src/rda_python_icoads/R3.0-stat_doc.pdf +0 -0
  5. rda_python_icoads-1.0.9/src/rda_python_icoads/checkicoads.py +222 -0
  6. rda_python_icoads-1.0.9/src/rda_python_icoads/cleanicoads.py +175 -0
  7. rda_python_icoads-1.0.9/src/rda_python_icoads/counticoads.py +153 -0
  8. rda_python_icoads-1.0.9/src/rda_python_icoads/fillicoads.py +138 -0
  9. rda_python_icoads-1.0.9/src/rda_python_icoads/fillinventory.py +149 -0
  10. rda_python_icoads-1.0.9/src/rda_python_icoads/fillitable.py +289 -0
  11. rda_python_icoads-1.0.9/src/rda_python_icoads/fillmonth.py +94 -0
  12. rda_python_icoads-1.0.9/src/rda_python_icoads/msg +457 -0
  13. rda_python_icoads-1.0.9/src/rda_python_icoads/msg3.0_subset_readme.txt +94 -0
  14. rda_python_icoads-1.0.9/src/rda_python_icoads/msg3_subset.py +345 -0
  15. rda_python_icoads-1.0.9/src/rda_python_icoads/msg_download.py +211 -0
  16. rda_python_icoads-1.0.9/src/rda_python_icoads/msgsubset.f +612 -0
  17. rda_python_icoads-1.0.9/src/rda_python_icoads/writeicoads.py +169 -0
  18. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads.egg-info/PKG-INFO +1 -1
  19. rda_python_icoads-1.0.9/src/rda_python_icoads.egg-info/SOURCES.txt +30 -0
  20. rda_python_icoads-1.0.9/src/rda_python_icoads.egg-info/entry_points.txt +12 -0
  21. rda_python_icoads-1.0.7/MANIFEST.in +0 -2
  22. rda_python_icoads-1.0.7/src/rda_python_icoads.egg-info/SOURCES.txt +0 -16
  23. rda_python_icoads-1.0.7/src/rda_python_icoads.egg-info/entry_points.txt +0 -2
  24. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/LICENSE +0 -0
  25. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/README.md +0 -0
  26. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/setup.cfg +0 -0
  27. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads/PgIMMA.py +0 -0
  28. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads/README_R3.0_Subset.html +0 -0
  29. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads/__init__.py +0 -0
  30. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads/imma1_subset.py +0 -0
  31. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads/rdimma1_csv.f +0 -0
  32. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads.egg-info/dependency_links.txt +0 -0
  33. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads.egg-info/requires.txt +0 -0
  34. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/src/rda_python_icoads.egg-info/top_level.txt +0 -0
  35. {rda_python_icoads-1.0.7 → rda_python_icoads-1.0.9}/tests/test_icoads.py +0 -0
@@ -0,0 +1,6 @@
1
+ include src/rda_python_icoads/README_R3.0_Subset.html
2
+ include src/rda_python_icoads/rdimma1_csv.f
3
+ include src/rda_python_icoads/msg
4
+ include src/rda_python_icoads/R3.0-stat_doc.pdf
5
+ include src/rda_python_icoads/msg3.0_subset_readme.txt
6
+ include src/rda_python_icoads/msgsubset.f
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rda_python_icoads
3
- Version: 1.0.7
3
+ Version: 1.0.9
4
4
  Summary: RDA python package to manage RDA ICOADS datasets
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-icoads
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "rda_python_icoads"
9
- version = "1.0.7"
9
+ version = "1.0.9"
10
10
  authors = [
11
11
  { name="Zaihua Ji", email="zji@ucar.edu" },
12
12
  ]
@@ -30,10 +30,27 @@ include-package-data = true
30
30
  where = ["src"]
31
31
 
32
32
  [tool.setuptools.package-data]
33
- "rda_python_icoads" = ["README_R3.0_Subset.html", "rdimma1_csv.f"]
33
+ "rda_python_icoads" = [
34
+ "README_R3.0_Subset.html",
35
+ "rdimma1_csv.f",
36
+ "msg",
37
+ "R3.0-stat_doc.pdf",
38
+ "msg3.0_subset_readme.txt",
39
+ "msgsubset.f",
40
+ ]
34
41
 
35
42
  [project.urls]
36
43
  "Homepage" = "https://github.com/NCAR/rda-python-icoads"
37
44
 
38
45
  [project.scripts]
39
- imma1_subset = "rda_python_icoads.imma1_subset:main"
46
+ "imma1_subset" = "rda_python_icoads.imma1_subset:main"
47
+ "msg3_subset" = "rda_python_icoads.msg3_subset:main"
48
+ "checkicoads" = "rda_python_icoads.checkicoads:main"
49
+ "cleanicoads" = "rda_python_icoads.cleanicoads:main"
50
+ "counticoads" = "rda_python_icoads.counticoads:main"
51
+ "fillicoads" = "rda_python_icoads.fillicoads:main"
52
+ "fillinventory" = "rda_python_icoads.fillinventory:main"
53
+ "fillitable" = "rda_python_icoads.fillitable:main"
54
+ "fillmonth" = "rda_python_icoads.fillmonth:main"
55
+ "msg_download" = "rda_python_icoads.msg_download:main"
56
+ "writeicoads" = "rda_python_icoads.writeicoads:main"
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env python3
2
+ #
3
+ ##################################################################################
4
+ #
5
+ # Title : checkicoads
6
+ # Author : Zaihua Ji, zji@ucar.edu
7
+ # Date : 12/30/2020
8
+ # 2025-03-03 transferred to package rda_python_icoads from
9
+ # https://github.com/NCAR/rda-icoads.git
10
+ # Purpose : check and compare ICOADS data files and IVADDB records
11
+ #
12
+ # Github : https://github.com/NCAR/rda-python-icoads.git
13
+ #
14
+ ##################################################################################
15
+
16
+ import sys
17
+ import os
18
+ import re
19
+ from os import path as op
20
+ from rda_python_common import PgLOG
21
+ from rda_python_common import PgDBI
22
+ from rda_python_common import PgUtil
23
+ from rda_python_common import PgOPT
24
+ from rda_python_common import PgSIG
25
+ from . import PgIMMA
26
+
27
+ PVALS = {
28
+ 'bdate' : None,
29
+ 'edate' : None,
30
+ 'bmdate' : [],
31
+ 'emdate' : [],
32
+ 'fname' : [],
33
+ 'flag' : [], # 1 - file exists, 2 - db records exist, 3 - both
34
+ 'mproc' : 10,
35
+ 'fpattern' : "IMMA1_R3.0.0_<YYYY-MM>",
36
+ 'readall' : 0
37
+ }
38
+
39
+ #
40
+ # main function to run dsarch
41
+ #
42
+ def main():
43
+
44
+ option = ''
45
+ argv = sys.argv[1:]
46
+
47
+ for arg in argv:
48
+ if arg == "-b":
49
+ PgLOG.PGLOG['BCKGRND'] = 1
50
+ elif arg == "-a":
51
+ PVALS['readall'] = 1
52
+ elif arg == "-f":
53
+ option = 'f'
54
+ elif arg == "-m":
55
+ option = 'm'
56
+ elif re.match(r'^-', arg):
57
+ PgLOG.pglog(arg + ": Invalid Option", PgLOG.LGWNEX)
58
+ elif option:
59
+ if option == 'f':
60
+ PVALS['fpattern'] = arg
61
+ elif option == 'm':
62
+ PVALS['mproc'] = arg
63
+ option = ''
64
+ elif not PVALS['bdate']:
65
+ PVALS['bdate'] = arg
66
+ elif not PVALS['edate']:
67
+ PVALS['edate'] = arg
68
+ else:
69
+ PgLOG.pglog(arg + ": Invalid parameter", PgLOG.LGWNEX)
70
+
71
+ PgLOG.PGLOG['LOGFILE'] = "icoads.log"
72
+ PgDBI.ivaddb_dbname()
73
+
74
+ if not (PVALS['bdate'] and PVALS['edate']):
75
+ pgrec = PgDBI.pgget("cntldb.inventory", "min(date) bdate, max(date) edate", '', PgLOG.LGEREX)
76
+ print("Usage: checkicoads [-a] [-m mproc] [-f FilePattern] BeginDate EndDate")
77
+ print(" Default FilePattern is " + PVALS['fpattern'])
78
+ print(" Option -a - read all attms, including multi-line ones, such as IVAD and REANQC")
79
+ print(" Option -m - start up to given number of processes, one for each month (Default to 10)")
80
+ print(" Set BeginDate and EndDate between '{}' and '{}'".format(pgrec['bdate'], pgrec['edate']))
81
+ sys.exit(0)
82
+
83
+ if PgUtil.diffdate(PVALS['bdate'], PVALS['edate']) > 0:
84
+ tmpdate = PVALS['bdate']
85
+ PVALS['bdate'] = PVALS['edate']
86
+ PVALS['edate'] = tmpdate
87
+
88
+ PgLOG.cmdlog("checkicoads {}".format(' '.join(argv)))
89
+ check_imma_data()
90
+ PgLOG.cmdlog()
91
+ sys.exit(0)
92
+
93
+ #
94
+ # check imma data
95
+ #
96
+ def check_imma_data():
97
+
98
+ mcnt = init_months()
99
+ if mcnt == 1: PVALS['mproc'] = 1
100
+ if PVALS['mproc'] > 1:
101
+ PgSIG.start_none_daemon('writeicoads', '', PgLOG.PGLOG['CURUID'], PVALS['mproc'], 300, 1)
102
+
103
+ for midx in range(mcnt):
104
+ fname = PVALS['fname'][midx]
105
+ if op.isfile(fname +".cnt"): continue # monthly file counted already
106
+ if PVALS['mproc'] > 1:
107
+ stat = PgSIG.start_child("checkicoads_{}".format(midx), PgLOG.LOGWRN, 1) # try to start a child process
108
+ if stat <= 0:
109
+ sys.exit(1) # something wrong
110
+ elif PgSIG.PGSIG['PPID'] > 1:
111
+ check_imma_file(fname, midx)
112
+ sys.exit(0) # stop child process
113
+ else:
114
+ PgDBI.pgdisconnect(0) # disconnect database for reconnection
115
+ continue # continue for next midx
116
+ else:
117
+ check_imma_file(fname, midx)
118
+
119
+ if PVALS['mproc'] > 1: PgSIG.check_child(None, 0, PgLOG.LOGWRN, 1)
120
+
121
+ dump_final_counts()
122
+
123
+ #
124
+ # compare icoads records from given file name and IVADDB
125
+ #
126
+ def check_imma_file(fname, midx):
127
+
128
+ PgLOG.pglog("Count IMMA records in File '{}'".format(fname), PgLOG.WARNLG)
129
+ flag = PVALS['flag'][midx]
130
+
131
+ acnts = [0]*PgIMMA.TABLECOUNT
132
+ acounts = [0]*PgIMMA.TABLECOUNT
133
+
134
+ if flag&1:
135
+ IMMA = open(fname, 'r')
136
+ line = IMMA.readline()
137
+ while line:
138
+ if PVALS['readall'] and re.match(r'^98', line):
139
+ PgIMMA.get_imma_multiple_counts(line, acnts)
140
+ else:
141
+ PgIMMA.get_imma_counts(line, acnts)
142
+ line.IMMA.readline()
143
+ IMMA.close()
144
+ for i in range(PgIMMA.TABLECOUNT): acounts[i] = acnts[i]
145
+
146
+ if flag&2:
147
+ PgLOG.pglog("Count IMMA records in in IVADDB", PgLOG.WARNLG)
148
+ cdate = bdate = PVALS['bmdate'][midx]
149
+ edate = PVALS['emdate'][midx]
150
+ while cdate <= edate:
151
+ acnts = PgIMMA.count_imma_records(cdate, 0, PVALS['readall'])
152
+ cdate = PgUtil.adddate(cdate, 0, 0, 1)
153
+ if acnts:
154
+ for i in range(PgIMMA.TABLECOUNT): acounts[i] -= acnts[i]
155
+
156
+ dump_monthly_counts(fname, acounts)
157
+
158
+ #
159
+ # dump monthly counts
160
+ #
161
+ def dump_monthly_counts(fname, acounts):
162
+
163
+ oname = fname + ".cnt"
164
+ IMMA = open(oname, 'w')
165
+ IMMA.write("{}, {}\n".format(fname, ', '.join(acounts)))
166
+ IMMA.close()
167
+
168
+ #
169
+ # concat all monthly counts into one
170
+ #
171
+ def dump_final_counts():
172
+
173
+ fname = "ICOADS_DIFF_COUNTS.csv"
174
+
175
+ IMMA = open(fname, 'w')
176
+ IMMA.write("FileName, {}\n".format(', '.join(PgIMMA.IMMA_NAMES)))
177
+ IMMA.close()
178
+ PgLOG.pgsystem("cat *.cnt >> " + fname)
179
+
180
+ #
181
+ # initialize the month list
182
+ #
183
+ def init_months():
184
+
185
+ seps = ["<" , ">"]; # temporal pattern delimiters
186
+ match = "[^" + seps[1] + "]+"
187
+
188
+ ms = re.search(r'{}({}){}'.format(seps[0], match, seps[1]), PVALS['fpattern'])
189
+ if ms:
190
+ tpattern = ms.group(1)
191
+ treplace = "{}{}{}".format(seps[0], tpattern, seps[1])
192
+ else:
193
+ PgLOG.pglog(PVALS['fpattern'] + ": Not temporal pattern found to get month list", PgLOG.LGEREX)
194
+
195
+ bdate = PVALS['bdate']
196
+ done = midx = 0
197
+ while True:
198
+ edate = PgUtil.enddate(bdate, 0, 'M')
199
+ if PgUtil.diffdate(PVALS['edate'], edate) <= 0:
200
+ edate = PVALS['edate']
201
+ done = 1
202
+ mdate = PgUtil.format_date(bdate, tpattern)
203
+ fname = PVALS['fpattern'].replace(treplace, mdate)
204
+ flag = 0
205
+ if op.isfile(fname): flag += 1
206
+ if PgDBI.pgget("cntldb.inventory", "", "date BETWEEN '{}' AND '{}'".format(bdate, edate), PgLOG.LGEREX):
207
+ flag += 2
208
+ if flag:
209
+ PVALS['bmdate'].append(bdate)
210
+ PVALS['emdate'].append(edate)
211
+ PVALS['fname'].append(fname)
212
+ PVALS['flag'].append(flag)
213
+ midx += 1
214
+ if done: break
215
+ bdate = PgUtil.adddate(edate, 0, 0, 1)
216
+
217
+ return midx
218
+
219
+ #
220
+ # call main() to start program
221
+ #
222
+ if __name__ == "__main__": main()
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env python3
2
+ #
3
+ ##################################################################################
4
+ #
5
+ # Title : cleanicoads
6
+ # Author : Zaihua Ji, zji@ucar.edu
7
+ # Date : 12/30/2020
8
+ # 2025-03-03 transferred to package rda_python_icoads from
9
+ # https://github.com/NCAR/rda-icoads.git
10
+ # Purpose : clean up one or all IMMA1 attms in IVADDB for given period
11
+ #
12
+ # Github : https://github.com/NCAR/rda-python-icoads.git
13
+ #
14
+ ##################################################################################
15
+
16
+ import sys
17
+ import os
18
+ import re
19
+ from os import path as op
20
+ from rda_python_common import PgLOG
21
+ from rda_python_common import PgDBI
22
+ from rda_python_common import PgUtil
23
+ from . import PgIMMA
24
+
25
+ PVALS = {
26
+ 'bdate' : None,
27
+ 'edate' : None,
28
+ 'aname' : None,
29
+ 'tinfo' : {},
30
+ 'tcnt' : 0,
31
+ 'dcnd' : None,
32
+ 'uatti' : '',
33
+ 'names' : None
34
+ }
35
+
36
+ #
37
+ # main function to run dsarch
38
+ #
39
+ def main():
40
+
41
+ option = ''
42
+ files = []
43
+ leaduid = 0
44
+ chkexist = 0
45
+ readall = 0
46
+ argv = sys.argv[1:]
47
+
48
+ for arg in argv:
49
+ if arg == "-b":
50
+ PgLOG.PGLOG['BCKGRND'] = 1
51
+ elif arg == "-a":
52
+ option = 'a'
53
+ elif re.match(r'^-', arg):
54
+ PgLOG.pglog(arg + ": Invalid Option", PgLOG.LGWNEX)
55
+ elif option:
56
+ PVALS['aname'] = arg
57
+ option = ''
58
+ elif not PVALS['bdate']:
59
+ PVALS['bdate'] = arg
60
+ elif not PVALS['edate']:
61
+ PVALS['edate'] = arg
62
+ else:
63
+ PgLOG.pglog(arg + ": Invalid parameter", PgLOG.LGWNEX)
64
+
65
+ if not PVALS['bdate']:
66
+ print("Usage: cleanicoads [-a ATTNAME] BDATE EDATE")
67
+ print(" Option -a - clean a single attm for given attm name")
68
+ PgLOG.pgexit()
69
+
70
+ PgLOG.PGLOG['LOGFILE'] = "icoads.log"
71
+ PgDBI.ivaddb_dbname()
72
+ PgLOG.cmdlog("cleanicoads {}".format(' '.join(argv)))
73
+ set_table_info()
74
+ clean_imma_data()
75
+ PgLOG.cmdlog()
76
+ PgLOG.pgexit()
77
+
78
+ #
79
+ # set the table index list
80
+ #
81
+ def set_table_info():
82
+
83
+ table = "cntldb.inventory"
84
+ if PVALS['edate']:
85
+ PVALS['dcnd'] = "date BETWEEN '{}' AND '{}'".format(PVALS['bdate'], PVALS['edate'])
86
+ else:
87
+ PVALS['dcnd'] = "date >= '{}'".format(PVALS['bdate'])
88
+
89
+ PVALS['tinfo'] = PgDBI.pgmget(table, "tidx, min(miniidx) bidx, max(maxiidx) eidx", PVALS['dcnd'] + " GROUP BY tidx", PgLOG.LGEREX)
90
+ PVALS['tcnt'] = len(PVALS['tinfo']['tidx']) if PVALS['tinfo'] else 0
91
+
92
+ if not PVALS['tcnt']:
93
+ PgLOG.pglog("{}: No data found in IVADDB for {}".format(table, PVALS['dcnd']), PgLOG.LGEREX)
94
+
95
+ #
96
+ # clean up imma data
97
+ #
98
+ def clean_imma_data():
99
+
100
+ table = "cntldb.inventory"
101
+
102
+ for i in range(PVALS['tcnt']):
103
+ tidx = PVALS['tinfo']['tidx'][i]
104
+ cnd = "iidx BETWEEN {} AND {}".format(PVALS['tinfo']['bidx'][i], PVALS['tinfo']['eidx'][i])
105
+ if PVALS['aname']:
106
+ clean_one_attm_for_tidx(PVALS['aname'], tidx, cnd)
107
+ else:
108
+ clean_imma_data_for_tidx(tidx, cnd)
109
+
110
+ cnt = PgDBI.pgdel(table, PVALS['dcnd'], PgLOG.LGEREX)
111
+ s = 's' if cnt > 1 else ''
112
+ PgLOG.pglog("{}: {} record{} deleted for {}".format(table, cnt, s, PVALS['dcnd']), PgLOG.LOGWRN)
113
+
114
+ #
115
+ # clean up imma data for table index
116
+ #
117
+ def clean_imma_data_for_tidx(tidx, cnd):
118
+
119
+ PgLOG.pglog("Clean IMMA data for table index {}...".format(tidx), PgLOG.LOGWRN)
120
+
121
+ for i in range(PgIMMA.TABLECOUNT):
122
+ aname = PgIMMA.IMMA_NAMES[i]
123
+ clean_one_attm_for_tidx(aname, tidx, cnd)
124
+
125
+ #
126
+ # clean up one attm data for table index
127
+ #
128
+ def clean_one_attm_for_tidx(aname, tidx, cnd):
129
+
130
+ table = "{}_{}".format(aname, tidx)
131
+ if not PgDBI.pgcheck(table): return 0 # not record to delete
132
+
133
+ if aname == 'iuida': clean_itidx_for_tidx(table, cnd)
134
+
135
+ cnt = PgDBI.pgdel(table, cnd, PgLOG.LGEREX)
136
+ s = 's' if cnt > 1 else ''
137
+ PgLOG.pglog("{}: {} record{} deleted for {}".format(table, cnt, s, cnd), PgLOG.LOGWRN)
138
+
139
+ cnt = PgDBI.pgget(table, "", "", PgLOG.LGEREX)
140
+ clean_iattm_for_tidx(aname, tidx, cnt)
141
+
142
+ #
143
+ # clean up table itidx for table index
144
+ #
145
+ def clean_itidx_for_tidx(table, cnd):
146
+
147
+ tname = "cntldb.itidx"
148
+ uids = PgDBI.pgmget(table, "distinct (substring(uid, 1, 2)) uida", cnd, PgLOG.LGEREX)
149
+ ucnt = len(uids['uida']) if uids else 0
150
+ for i in range(ucnt):
151
+ table = "{}_{}".format(tname, uids['uida'][i].lower())
152
+ if not PgDBI.pgcheck(table): continue
153
+ cnt = PgDBI.pgdel(table, cnd, PgLOG.LOGWRN)
154
+ s = 's' if cnt > 1 else ''
155
+ PgLOG.pglog("{}: {} record{} deleted".format(table, cnt, s), PgLOG.LOGWRN)
156
+
157
+ #
158
+ # clean up table iattm for table index
159
+ #
160
+ def clean_iattm_for_tidx(aname, tidx, cnt):
161
+
162
+ table = "cntldb.iattm"
163
+ cnd = "attm = '{}' AND tidx = {}".format(aname, tidx)
164
+ pgrec = {'count' : cnt}
165
+ PgDBI.pgupdt(table, pgrec, cnd, PgLOG.LGWNEX)
166
+ PgLOG.pglog("{}: Set count to {} for {}".format(table, cnt, cnd), PgLOG.LOGWRN)
167
+
168
+ table += "_daily"
169
+ cnd += " AND " + PVALS['dcnd']
170
+ PgDBI.pgdel(table, PVALS['dcnd'], PgLOG.LGWNEX)
171
+
172
+ #
173
+ # call main() to start program
174
+ #
175
+ if __name__ == "__main__": main()
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env python3
2
+ #
3
+ ##################################################################################
4
+ #
5
+ # Title : counticoads
6
+ # Author : Zaihua Ji, zji@ucar.edu
7
+ # Date : 12/30/2020
8
+ # 2025-03-03 transferred to package rda_python_icoads from
9
+ # https://github.com/NCAR/rda-icoads.git
10
+ # Purpose : read ICOADS data from IVADDB and count out daily, monthly or year records
11
+ # by attms
12
+ #
13
+ # Github : https://github.com/NCAR/rda-python-icoads.git
14
+ #
15
+ ##################################################################################
16
+
17
+ import sys
18
+ import re
19
+ from rda_python_common import PgLOG
20
+ from rda_python_common import PgDBI
21
+ from rda_python_common import PgUtil
22
+ from . import PgIMMA
23
+
24
+ PVALS = {
25
+ 'bdate' : None,
26
+ 'edate' : None,
27
+ 'bpdate' : [],
28
+ 'epdate' : [],
29
+ 'period' : [],
30
+ 'group' : None,
31
+ 'names' : None
32
+ }
33
+
34
+ #
35
+ # main function to run dsarch
36
+ #
37
+ def main():
38
+
39
+ option = ''
40
+ argv = sys.argv[1:]
41
+ for arg in argv:
42
+ if arg == "-b":
43
+ PgLOG.PGLOG['BCKGRND'] = 1
44
+ elif arg == "-g":
45
+ option = 'g'
46
+ elif re.match(r'^-', arg):
47
+ PgLOG.pglog(arg + ": Invalid Option", PgLOG.LGWNEX)
48
+ elif option:
49
+ PVALS['group'] = arg
50
+ option = ''
51
+ elif not PVALS['bdate']:
52
+ PVALS['bdate'] = arg
53
+ elif not PVALS['edate']:
54
+ PVALS['edate'] = arg
55
+ else:
56
+ PgLOG.pglog(arg + ": Invalid parameter", PgLOG.LGWNEX)
57
+
58
+ PgDBI.ivaddb_dbname()
59
+ if not (PVALS['bdate'] and PVALS['edate'] and re.match(r'^(daily|monthly|yearly)$', PVALS['group'])):
60
+ pgrec = PgDBI.pgget("cntldb.inventory", "min(date) bdate, max(date) edate", '', PgLOG.LGEREX)
61
+ print("Usage: counticoads -g GroupBy (daily|monthly|yearly) BeginDate EndDate")
62
+ print(" Group by Daily, Monthly or Yearly is mandatory")
63
+ print(" Set BeginDate and EndDate between '{} and '{}'".format(pgrec['bdate'], pgrec['edate']))
64
+ sys.exit(0)
65
+
66
+ if PgUtil.diffdate(PVALS['bdate'], PVALS['edate']) > 0:
67
+ tmpdate = PVALS['bdate']
68
+ PVALS['bdate'] = PVALS['edate']
69
+ PVALS['edate'] = tmpdate
70
+
71
+ PgLOG.PGLOG['LOGFILE'] = "icoads.log"
72
+ PgLOG.cmdlog("counticoads {}".format(' '.format(argv)))
73
+ PVALS['names'] = '/'.join(PgIMMA.IMMA_NAMES)
74
+ fname = "ICOADS_COUNTS_{}_{}-{}.txt" .format(PVALS['group'].upper(), PVALS['bdate'], PVALS['edate'])
75
+ IMMA = open(fname, 'w')
76
+ IMMA.write("{}, {}\n".format(PVALS['group'], ', '.join(PgIMMA.IMMA_NAMES)))
77
+ count_imma_data(IMMA)
78
+ IMMA.close()
79
+
80
+ PgLOG.cmdlog()
81
+ sys.exit(0)
82
+
83
+ #
84
+ # count imaa data
85
+ #
86
+ def count_imma_data(IMMA):
87
+
88
+ pcnt = init_periods()
89
+ tcounts = [0]*PgIMMA.TABLECOUNT
90
+
91
+ for pidx in range(pcnt):
92
+ acnts = count_period_imma(pidx)
93
+ IMMA.write("{}' {}\n".format(PVALS['period'][pidx], ', '.join(acnts)))
94
+ for i in range(PgIMMA.TABLECOUNT): tcounts[i] += acnts[i]
95
+
96
+ if pcnt > 1:
97
+ IMMA.write("Total, {}\n".format(', '.join(tcounts)))
98
+ PgLOG.pglog("{}({}) for {} {} periods".format('/'.join(tcounts), PVALS['names'], pcnt, PVALS['group']), PgLOG.LOGWRN)
99
+
100
+
101
+
102
+ #
103
+ # read icoads record from given file name and save them into RDADB
104
+ #
105
+ def count_period_imma(pidx):
106
+
107
+ PgLOG.pglog("count IMMA1 records for {} period {} from IVADDB".format(PVALS['group'], PVALS['period'][pidx]), PgLOG.WARNLG)
108
+ acounts = [0]*PgIMMA.TABLECOUNT
109
+ date = PVALS['bpdate'][pidx]
110
+ while date <= PVALS['epdate'][pidx]:
111
+ acnts = PgIMMA.count_imma_records(date)
112
+ if acnts:
113
+ for i in range(PgIMMA.TABLECOUNT): acounts[i] += acnts[i]
114
+ date = PgUtil.adddate(date, 0, 0, 1)
115
+
116
+ PgLOG.pglog("{}({}) for {} period {}".format('/'.join(acounts), PVALS['names'], PVALS['group'], PVALS['period'][pidx]), PgLOG.LOGWRN)
117
+ return acounts
118
+
119
+ #
120
+ # initialize (daily|monthly|yearly) periods
121
+ #
122
+ def init_periods():
123
+
124
+ bdate = PVALS['bdate']
125
+ if PVALS['group'] == "yearly":
126
+ dfmt = "YYYY"
127
+ eflg = "Y"
128
+ elif PVALS['group'] == 'monthly':
129
+ dfmt = "YYYY-MM"
130
+ eflg = "M"
131
+ else: # must be daily
132
+ dfmt = "YYYY-MM-DD"
133
+ eflg = ""
134
+
135
+ pcnt = 0
136
+ while True:
137
+ pcnt += 1
138
+ PVALS['bpdate'].append(bdate)
139
+ PVALS['period'].append(PgUtil.format_date(bdate, dfmt))
140
+ edate = PgUtil.enddate(bdate, 0, eflg) if eflg else bdate
141
+ if PgUtil.diffdate(PVALS['edate'], edate) > 0:
142
+ PVALS['epdate'].append(edate)
143
+ bdate = PgUtil.adddate(edate, 0, 0, 1)
144
+ else:
145
+ PVALS['epdate'].append(PVALS['edate'])
146
+ break
147
+
148
+ return pcnt
149
+
150
+ #
151
+ # call main() to start program
152
+ #
153
+ if __name__ == "__main__": main()