NASA Logo
Ocean Color Science Software

ocssw V2022
build_ADT_json.py
Go to the documentation of this file.
1 from typing import Dict, List
2 import json
3 import os
4 # Builds ADT json files for l2gen SST from RSMAS txt trees.
5 # Txt trees are availible (for now ) only for VIIRS J1
6 if __name__ == "__main__":
7  # attributes
8  corr_map: Dict[str, str] = {"sst2b": "SST", "sst3b": "SST3", "sst2bmsst3b": "d_SST_SST3", "dm3750": "BT37_MAXMIN",
9  "m3750": "BT37", "sd.sst": "SST_STD",
10  "dm8550": "BT85_MAXMIN", "dm11000": "BT11", "dm12000": "BT12",
11  "dm3750m12000": "d_BT37_BT12",
12  "dm3750m11000": "d_BT37_BT11", "dm11000m12000": "d_BT11_BT12", "m8550": "BT85",
13  "lat": "lat", "lon": "lon", "anc.wv": "wv", "sd.m3750": "BT37_STD",
14  "sd.m11000": "BT11_STD", "sd.m12000": "SST_STD", "Tdeflong": "Tdeflong",
15  "maxm8550": "BT85_MAX", "minm8550": "BT85_MIN", "m.rho1380": "RHOCIRRUS",
16  "dm.rho678": "RHOred_MAXMIN", "m.rho678": "RHOred", " minm.rho678": "RHOred_MIN",
17  "maxm.rho678": "RHOred_MAX", "maxm.rho748": "RHO07_MAX", "minm.rho748": "RHO07_MIN",
18  "minm.rho1610": "RHO16_MIN", "maxm.rho1610": "RHO16_MAX",
19  "minm.rho1380": "RHOCIRRUS_MIN", "maxm.rho1380": "RHOCIRRUS_MAX", "m.rho1610": "RHO16",
20  "dm.rho1610": "RHO16_MAXMIN",
21  "dm.rho1380": "RHOCIRRUS_MAXMIN", "m.rho748": "RHO07", "maxm.rho.1380": "RHOCIRRUS_MAX"}
22 
23 
24  class Tree:
25  def __init__(self):
26  self.children: List[Tree] = []
27  self.threshold = None
28  self.addTreesum = None
29  self.testname = None
30  self.node_type = None
31 
32  def add_children(self, children):
33  self.children = children
34 
35  def set_threshold(self, thresholds: Dict[str, float]):
36  self.threshold = thresholds
37 
38  def set_treesum(self, treesum):
39  self.addTreesum = treesum
40 
41  def set_testname(self, name):
42  self.testname = name
43 
44  def traverse(self):
45  # print(self.testname, end="; ")
46  # print(self.node_type, end="; ")
47  # print(self.threshold, end="; ")
48  # print(self.addTreesum)
49  for child in self.children:
50  child.traverse()
51 
52 
53  def build_my_tree(input_tree: Tree):
54  names = {}
55  for i, child in enumerate(input_tree.children):
56  if child.testname in names:
57  names[child.testname].append(i)
58  else:
59  names[child.testname] = [i]
60  new_children: List[Tree] = []
61  for name, indexes in names.items():
62  new_children.append(Tree())
63  new_children[-1].testname = name
64  new_children[-1].children = [input_tree.children[indexes[0]], input_tree.children[indexes[1]]]
65  new_children[-1].threshold = input_tree.children[indexes[0]].threshold
66  input_tree.children[indexes[0]].testname = "true"
67  input_tree.children[indexes[1]].testname = "false"
68  input_tree.children[indexes[0]].threshold = None
69  input_tree.children[indexes[1]].threshold = None
70  input_tree.children = new_children
71  for child in new_children:
72  for dec in child.children:
73  build_my_tree(dec)
74  pass
75 
76 
77  def count_order(line: str, pattern="| "):
78  pat_len = len(pattern)
79  count = 0
80  conc: str = ""
81  while conc == line[:count * pat_len]:
82  conc += pattern
83  count += 1
84  return count - 1
85  pass
86 
87 
88  def traverse_list(lines: List[str], i: int, tree: Tree):
89  pattern = "| "
90  # print("current node = ", lines[i][:-1], tree.testname)
91  if (i > len(lines) - 2):
92  # print("No children ", i)
93  return i
94  current_order = count_order(lines[i], pattern)
95  j = i
96  while j < len(lines) - 1:
97  next_line = lines[j + 1]
98  next_order = count_order(next_line, pattern)
99  if next_order > current_order:
100  tree.children.append(Tree())
101  test_name = next_line[next_order * len(pattern):].split()[0]
102  test_order = next_line[next_order * len(pattern):].split()[1]
103  test_threshold = float(next_line[next_order * len(pattern):].split()[2][:-1])
104  test_treesum = float(next_line[next_order * len(pattern):].split()[3])
105  # print(
106  # f"rootname = {tree.testname}, childrenlen = {len(tree.children)},"
107  # f" childname = {test_name}, childorder = {next_order}, test_order = {test_order}, test_threshold = {test_threshold}, test_treesum = {test_treesum} ")
108  tree.children[-1].testname = test_name
109  tree.children[-1].threshold = test_threshold
110  tree.children[-1].addTreesum = test_treesum
111  tree.children[-1].node_type = "threshold_max" if test_order == "<" else "threshold_min"
112  j = traverse_list(lines, j + 1, tree.children[-1])
113  else:
114  return j
115  return j
116  pass
117 
118 
119  def trim_word(inp_str: str):
120  index = inp_str.find(")")
121  return inp_str[index + 1:]
122 
123 
124  def create_dict_from_tree(tree: Tree, json):
125  arr = []
126  test_name = ""
127  for _ in range(len(tree.children)):
128  arr.append({})
129  if tree.testname == "decision_tree":
130  test_name = "decision_tree"
131  if len(arr) > 0:
132  json[test_name] = {"children": arr}
133  elif tree.testname != "true" and tree.testname != "false":
134  thresholds = [{"threshold_max": tree.threshold}]
135  test_name_or = trim_word(tree.testname)
136  if test_name_or in corr_map:
137  test_name = corr_map[test_name_or]
138  else:
139  print(f"{test_name_or} NOT FOUND")
140  raise SystemExit('Wrong Keyword')
141  json[test_name] = {"thresholds": thresholds, "children": arr}
142  else:
143  test_name = tree.testname
144  if len(arr) > 0:
145  json[test_name] = {"addTreesum": tree.addTreesum, "children": arr}
146  else:
147  json[test_name] = {"addTreesum": tree.addTreesum}
148  for i, child in enumerate(tree.children):
149  create_dict_from_tree(child, json[test_name]["children"][i])
150  pass
151 
152 
153  def get_the_tree(path_inp_file, out_path):
154  # path_inp_file: str = "/Users/avsemeno/Downloads/NOAA20_R2022_SST_delivery/NOAA_20_ADtree_no_glint_R2022.0_results.txt" #/Users/avsemeno/Downloads/NOAA20_R2022_SST_delivery/NOAA_20_ADtree_mod_glint_R2022.0_results.txt" # /Users/avsemeno/Downloads/NOAA20_R2022_SST_delivery/NOAA_20_ADtree_night_R2022.0_results.txt"
155  data = []
156  append = False
157  with open(path_inp_file, "r") as file:
158  lines = file.readlines()
159  for line in lines:
160  if line == ": 0\n":
161  append = True
162  if "Legend" in line:
163  append = False
164  if append:
165  data.append(line)
166  adt = Tree()
167  adt.testname = "decision_tree"
168  traverse_list(data, 0, adt)
169  build_my_tree(adt)
170  adt.traverse()
171  jsonf = {}
172  create_dict_from_tree(adt, jsonf)
173  # print(jsonf)
174 
175  with open(out_path, "w") as outfile:
176  json.dump(jsonf, outfile, indent=4)
177  return jsonf
178 
179 
180  ocdata = os.environ.get('OCDATAROOT')
181  if ocdata == None:
182  raise SystemExit('OCDATAROOT not found')
183  path_no_glint = os.path.join(ocdata, "viirs", "j1", "cal", "NOAA_20_ADtree_no_glint_R2022.0_results.txt")
184  path_glint = os.path.join(ocdata, "viirs", "j1", "cal", "NOAA_20_ADtree_mod_glint_R2022.0_results.txt")
185  path_night = os.path.join(ocdata, "viirs", "j1", "cal", "NOAA_20_ADtree_night_R2022.0_results.txt")
186  tree_no_glint = get_the_tree(path_no_glint, "no_glint_day.json")
187  tree_glint = get_the_tree(path_glint, "glint_day.json")
188  adt_night = {"version": "v6.R2022"}
189  tree_night = get_the_tree(path_night, "night.json")
190  adt_night["decision_tree"] = tree_night["decision_tree"]
191  adt_full = {"version": "v6.R2022", "decision_tree": {"children": [
192  {"solz": {"thresholds": [{"threshold_min": 85.0}],
193  "children": [{"true": tree_night["decision_tree"]}, {"false": {"children": [
194  {"glintcoef": {"thresholds": [{"threshold_max": 0.005}],
195  "children": [{"true": tree_no_glint["decision_tree"]},
196  {"false": tree_glint["decision_tree"]}]}}]}}]}}]}}
197 
198  with open("cloud_mask_sst.json", "w") as outfile:
199  json.dump(adt_full, outfile, indent=2)
200  with open("cloud_mask_sst3.json", "w") as outfile:
201  json.dump(adt_night, outfile, indent=4)
202  pass
def build_my_tree(Tree input_tree)
def create_dict_from_tree(Tree tree, json)
def set_treesum(self, treesum)
def count_order(str line, pattern="| ")
def trim_word(str inp_str)
def add_children(self, children)
void print(std::ostream &stream, const char *format)
Definition: PrintDebug.hpp:38
def get_the_tree(path_inp_file, out_path)
def set_threshold(self, Dict[str, float] thresholds)
def traverse_list(List[str] lines, int i, Tree tree)
def set_testname(self, name)