File indexing completed on 2026-04-09 07:50:03
0001
0002
0003 import numpy as np
0004 import os, re, logging
0005 log = logging.getLogger(__name__)
0006 from collections import OrderedDict as odict
0007 from opticks.sysrap.stag import stag
0008 tag = stag()
0009
0010 class U4Stack_item(object):
0011 @classmethod
0012 def Placeholder(cls):
0013 return cls(-1,"placeholder","ERROR" )
0014
0015 def __init__(self, code, name, note=""):
0016 self.code = code
0017 self.name = name
0018 self.note = note
0019
0020 def __repr__(self):
0021 return "%2d : %10s : %s " % (self.code, self.name, self.note)
0022
0023 class U4Stack(object):
0024 PATH = "$OPTICKS_PREFIX/include/u4/U4Stack.h"
0025 enum_ptn = re.compile("^\s*(\w+)\s*=\s*(.*?),*\s*?$")
0026 ttos_ptn = re.compile("^\s*case stag_(\w+):\s*stack = U4Stack_(\w+)\s*.*$")
0027
0028 def __init__(self, path=PATH):
0029 path = os.path.expandvars(path)
0030 lines = open(path, "r").read().splitlines()
0031 self.path = path
0032 self.lines = lines
0033 self.items = []
0034 self.parse()
0035
0036 def parse(self):
0037 self.code2item = odict()
0038 self.name2item = odict()
0039 self.tag2stack = odict()
0040 self.stack2tag = odict()
0041
0042 for line in self.lines:
0043 enum_match = self.enum_ptn.match(line)
0044 ttos_match = self.ttos_ptn.match(line)
0045 if enum_match:
0046 name, val = enum_match.groups()
0047 pfx = "U4Stack_"
0048 assert name.startswith(pfx)
0049 sname = name[len(pfx):]
0050 code = int(val)
0051
0052 item = U4Stack_item(code, sname, "")
0053 self.items.append(item)
0054 self.code2item[code] = item
0055 self.name2item[sname] = item
0056 log.debug(" name %20s sname %10s val %5s code %2d " % (name, sname, val, code))
0057
0058 elif ttos_match:
0059 tag_name, stack_name = ttos_match.groups()
0060
0061 stack_item = self.name2item.get(stack_name, None)
0062 tag_item = tag.name2item.get(tag_name, None)
0063
0064 stack_code = stack_item.code if not stack_item is None else -1
0065 tag_code = tag_item.code if not tag_item is None else -1
0066
0067 if stack_code > 0 and tag_code > 0:
0068 self.tag2stack[tag_code] = stack_code
0069 self.stack2tag[stack_code] = tag_code
0070 pass
0071 log.info(" tag_name %15s stack_name %50s stack_item %r tag_item %r" % (tag_name, stack_name, stack_item, tag_item ))
0072 else:
0073 pass
0074 log.debug(" skip : %s " % line )
0075 pass
0076 pass
0077
0078 def label(self, st, fl=None):
0079 """
0080 In [8]: print(stack.label(bt[53]))
0081 0 : 2 : ScintDiscreteReset :
0082 1 : 6 : BoundaryDiscreteReset :
0083 2 : 4 : RayleighDiscreteReset :
0084 3 : 3 : AbsorptionDiscreteReset :
0085 4 : 8 : BoundaryBurn_SurfaceReflectTransmitAbsorb :
0086 5 : 7 : BoundaryDiDiTransCoeff :
0087
0088 6 : 2 : ScintDiscreteReset :
0089 7 : 6 : BoundaryDiscreteReset :
0090 8 : 4 : RayleighDiscreteReset :
0091 9 : 3 : AbsorptionDiscreteReset :
0092 10 : 8 : BoundaryBurn_SurfaceReflectTransmitAbsorb :
0093 11 : 7 : BoundaryDiDiTransCoeff :
0094
0095 12 : 2 : ScintDiscreteReset :
0096 13 : 6 : BoundaryDiscreteReset :
0097 14 : 4 : RayleighDiscreteReset :
0098 15 : 3 : AbsorptionDiscreteReset :
0099
0100 16 : 2 : ScintDiscreteReset :
0101 17 : 6 : BoundaryDiscreteReset :
0102 18 : 8 : BoundaryBurn_SurfaceReflectTransmitAbsorb :
0103 19 : 7 : BoundaryDiDiTransCoeff :
0104 ## HUH: ONLY 2 RESET NOT NORMAL 4 ? WHY ?
0105 ## COULD BE PRECEEDING ZERO STEP OR SMTH LIKE THAT
0106
0107 20 : 2 : ScintDiscreteReset :
0108 21 : 6 : BoundaryDiscreteReset :
0109 22 : 4 : RayleighDiscreteReset :
0110 23 : 3 : AbsorptionDiscreteReset :
0111 """
0112 if not fl is None:
0113 assert st.shape == fl.shape
0114 pass
0115 lines = []
0116 num_zero = 0
0117 for i in range(len(st)):
0118 code = st[i]
0119 flat = fl[i] if not fl is None else None
0120 item = self(code)
0121 it = repr(item)
0122 assert code == item.code
0123 if code == st[0] and i > 0:
0124 lines.append("")
0125 pass
0126 label = "%2d : %s " % (i, it) if fl is None else "%2d : %10.4f : %s" % (i, flat, it)
0127 lines.append(label)
0128 if item.code == 0:
0129 num_zero += 1
0130 pass
0131 if num_zero == 2: break
0132 pass
0133 return "\n".join(lines)
0134
0135 def __call__(self, code):
0136 return self.code2item.get(code,U4Stack_item.Placeholder())
0137
0138 def __str__(self):
0139 return "\n".join(self.lines)
0140
0141 def __repr__(self):
0142 return "\n".join(list(map(repr,self.items)))
0143
0144 def is_one2one_mapping(self):
0145 """
0146 In [5]: stack.tag2stack
0147 Out[5]: OrderedDict([(1, 3), (2, 4), (3, 5), (4, 6), (5, 7), (6, 8), (7, 9)])
0148
0149 In [6]: stack.stack2tag
0150 Out[6]: OrderedDict([(3, 1), (4, 2), (5, 3), (6, 4), (7, 5), (8, 6), (9, 7)])
0151 """
0152 t2s = self.tag2stack
0153 s2t = self.stack2tag
0154 if len(t2s) != len(s2t): return False
0155
0156 for t in t2s.keys():
0157 s = t2s[t]
0158 t1 = s2t[s]
0159 print(" t2s : t %2d s %2d t1 %2d " % (t,s,t1))
0160 assert t == t1
0161 pass
0162 for s in s2t.keys():
0163 t = s2t[s]
0164 s1 = t2s[t]
0165 print(" s2t : s %2d t %2d s1 %2d " % (s,t,s1))
0166 assert s == s1
0167 pass
0168 return True
0169
0170 def dump_tag2stack(self):
0171 lines = []
0172 lines.append("U4Stack.py:dump_tag2stack")
0173 for t,s in self.tag2stack.items():
0174 line = "%-80r : %-80r " % (tag(t), self(s))
0175 lines.append(line)
0176 pass
0177 return "\n".join(lines)
0178
0179 def dump_stack2tag(self):
0180 lines = []
0181 lines.append("U4Stack.py:dump_stack2tag")
0182 for s,t in self.stack2tag.items():
0183 line = "%-80r : %-80r " % (self(s), tag(t))
0184 lines.append(line)
0185 pass
0186 return "\n".join(lines)
0187
0188 def make_stack2tag_mapped(self, arr):
0189 """
0190 :param arr: array assumed to contain stack enum integers
0191 :return arr_s2t: array with all B:stack enum integers mapped into A:tag enum integers
0192 """
0193 s2t = self.stack2tag
0194 arr_s2t = arr.copy()
0195 for s in s2t.keys():arr_s2t[np.where(arr==s)] = s2t[s]
0196 return arr_s2t
0197
0198 def make_tag2stack_mapped(self, arr):
0199 """
0200 :param arr: array assumed to containing tag enum integers
0201 :return arr_t2s: array with all A:tag enum integers mapped into B:stack enum integers
0202 """
0203 t2s = self.tag2stack
0204 arr_t2s = arr.copy()
0205 for t in t2s.keys():arr_t2s[np.where(arr==t)] = t2s[t]
0206 return arr_t2s
0207
0208
0209
0210 if __name__ == '__main__':
0211 logging.basicConfig(level=logging.INFO)
0212 stack = U4Stack()
0213
0214 print(repr(stack))
0215
0216 st = np.array([[2, 6, 4, 3, 8, 7, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
0217 [2, 6, 4, 3, 8, 7, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
0218 [2, 6, 4, 3, 8, 7, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8)
0219
0220 print(stack.label(st[0,:10]))
0221
0222 print(stack.dump_tag2stack())
0223 print(stack.dump_stack2tag())
0224
0225 assert stack.is_one2one_mapping() == True
0226
0227
0228
0229
0230