File indexing completed on 2026-04-09 07:48:49
0001
0002 """
0003 NPMeta.py
0004 ===========
0005
0006 Parsing metadata lines from NP.hh
0007
0008 Currently have two copies of this source at::
0009
0010 ~/np/npmeta.py
0011 ~/opticks/ana/npmeta.py
0012
0013 The np repository version is regarded as the
0014 primary and is occasionally copied together with
0015 NP.hh NPFold.h headers via::
0016
0017 cd ~/np
0018 ./cp.sh
0019
0020 """
0021
0022 import os, logging
0023 from collections import OrderedDict as odict
0024 import numpy as np
0025 log = logging.getLogger(__name__)
0026
0027
0028 class NPMetaCompare(object):
0029 def __init__(self, am, bm):
0030
0031 ak = list(filter(None,am.d.keys()))
0032 bk = list(filter(None,bm.d.keys()))
0033 kk = ak if ak == bk else list(set(list(ak)+list(bk)))
0034 skk = np.array( list(map(lambda _:"%30s"%_, kk )), dtype="|S30" )
0035 tab = np.zeros( [len(kk),2], dtype="|U25" )
0036 lines = []
0037
0038 hfmt = "%-30s : %7s : %7s : %7s : %7s : %s "
0039 vfmt = "%-30s : %7d : %7d : %7.3f : %7.3f : %7.3f"
0040 lines.append(hfmt % ("key", "a", "b", "a/b", "b/a", "(a-b)^2/(a+b)" ))
0041
0042 for i, k in enumerate(kk):
0043
0044 if k == "": continue
0045 al = am.d.get(k,[])
0046 bl = bm.d.get(k,[])
0047
0048 av = al[0] if len(al) == 1 else 0
0049 bv = bl[0] if len(bl) == 1 else 0
0050
0051
0052
0053
0054
0055
0056 tab[i,0] = av
0057 tab[i,1] = bv
0058 pass
0059
0060 stab = np.c_[skk, tab]
0061
0062
0063 self.ak = ak
0064 self.bk = bk
0065 self.am = am
0066 self.bm = bm
0067 self.kk = kk
0068 self.skk = skk
0069 self.tab = tab
0070 self.lines = lines
0071 self.stab = stab
0072
0073 def __str__(self):
0074 return "\n".join(self.lines)
0075
0076 def __repr__(self):
0077 lines = []
0078 lines.append("skk")
0079 return "\n".join(lines)
0080
0081
0082 class NPMeta(object):
0083 ENCODING = "utf-8"
0084 @classmethod
0085 def Compare(cls, am, bm):
0086 cfm = NPMetaCompare(am,bm)
0087 return cfm
0088
0089 @classmethod
0090 def AsDict_OLD(cls, lines):
0091 d = odict()
0092 key = ""
0093 d[key] = []
0094 for line in lines:
0095 dpos = line.find(":")
0096 if dpos > -1:
0097 key = line[:dpos]
0098 d[key] = []
0099 val = line[dpos+1:]
0100 else:
0101 val = line
0102 pass
0103 d[key].append(val)
0104 pass
0105 return d
0106
0107 @classmethod
0108 def AsDict(cls, lines):
0109 d = odict()
0110 for line in lines:
0111 dpos = line.find(":")
0112 if dpos == -1: continue
0113 key = line[:dpos]
0114 val = line[dpos+1:]
0115 d[key] = val
0116 pass
0117 return d
0118
0119
0120 @classmethod
0121 def Load(cls, path):
0122 name = os.path.basename(path)
0123 lines = open(path, "r").read().splitlines()
0124 return cls(lines)
0125
0126 @classmethod
0127 def LoadAsArray(cls, path):
0128 name = os.path.basename(path)
0129 lines = open(path, "r").read().splitlines()
0130 return np.array(lines)
0131
0132 def __init__(self, lines):
0133 self.lines = lines
0134 self.d = self.AsDict(lines)
0135
0136 def __len__(self):
0137 return len(self.lines)
0138
0139 def find(self, k, fallback=None):
0140 return self.d.get(k, fallback)
0141
0142 def __getattr__(self, k):
0143 if not k in self.d:
0144 raise AttributeError("No attribute %s " % k)
0145 return self.find(k)
0146
0147 def get_value(self,k,fallback=""):
0148 if not k in self.d:return fallback
0149 f = self.find(k, fallback)
0150 return f[0] if type(f) is list else f
0151
0152 def __getitem__(self, idx):
0153 """
0154 item access useful for simple lists of names, not metadata dicts
0155 """
0156 return self.lines[idx]
0157
0158 def oldfind(self, k_start, fallback=None, encoding=ENCODING):
0159 meta = self.meta
0160 ii = np.flatnonzero(np.char.startswith(meta, k_start.encode(encoding)))
0161 log.debug( " ii %s len(ii) %d " % (str(ii), len(ii)) )
0162 ret = fallback
0163 if len(ii) == 1:
0164 i = ii[0]
0165 line = meta[i].decode(encoding)
0166 ret = line[len(k_start):]
0167 log.debug(" line [%s] ret [%s] " % (line,ret) )
0168 else:
0169 log.debug("did not find line starting with %s or found more than 1" % k_start)
0170 pass
0171 return ret
0172
0173 def __repr__(self):
0174 return "\n".join(self.lines)
0175 def __str__(self):
0176 return repr(self.d)
0177
0178
0179 def has_key(self, k):
0180 return k in self.d
0181
0182 def keys(self):
0183 return self.d.keys()
0184
0185 def values(self):
0186 return self.d.values()
0187
0188 def smry(self, keys="red,green,blue"):
0189 kv = []
0190 for k in keys.split(","):
0191 if self.has_key(k):
0192 v = self.d[k]
0193 kv.append("%s:%s" % (k,v) )
0194 pass
0195 return " ".join(kv)
0196
0197 @classmethod
0198 def Summarize(cls, label):
0199 """
0200 Shorten stamp labels via heuristics of distinctive chars
0201 """
0202 smry = ""
0203 p = None
0204 for c in label:
0205 if p is None:
0206 smry += c
0207 elif c.isalnum() and p == "_":
0208 smry += c
0209 elif c.isupper() and p.islower():
0210 smry += c
0211 elif p == "P" and c in "ro":
0212 smry += c
0213 pass
0214 p = c
0215 pass
0216 return smry
0217
0218
0219
0220
0221
0222
0223 def test_load():
0224
0225 path = "/tmp/t_meta.txt"
0226 multiline = "hello:world\nmoi:red\nmidx:green\nmord:blue\niidx:grey\nTOPLINE:yellow\nBOTLINE:red\n"
0227 oneline = "hello:world\n"
0228 test = oneline
0229 open(path, "w").write(test)
0230
0231
0232 pm = NPMeta.Load(path)
0233
0234 moi = pm.find("moi:")
0235 midx = pm.find("midx:")
0236 mord = pm.find("mord:")
0237 iidx = pm.find("iidx:")
0238 print(" moi:[%s] midx:[%s] mord:[%s] iidx:[%s] " % (moi, midx, mord, iidx) )
0239
0240 TOPLINE = pm.find("TOPLINE:")
0241 BOTLINE = pm.find("BOTLINE:")
0242
0243 print(" TOPLINE:[%s] " % TOPLINE )
0244 print(" BOTLINE:[%s] " % BOTLINE )
0245
0246
0247
0248 if __name__ == '__main__':
0249 logging.basicConfig(level=logging.INFO)
0250
0251 lines = ['PV:nnvt_body_phys',
0252 'nnvt_inner1_phys',
0253 'nnvt_inner2_phys',
0254 'nnvt_tube_phy',
0255 'nnvt_edge_phy',
0256 'hama_body_phys',
0257 'nnvt_plate_phy',
0258 'hama_inner1_phys',
0259 'hama_inner2_phys',
0260 'hama_outer_edge_phy',
0261 'hama_plate_phy',
0262 'hama_dynode_tube_phy',
0263 'hama_inner_ring_phy',
0264 'MLV:nnvt_log',
0265 'nnvt_body_log',
0266 'nnvt_inner2_log',
0267 'hama_log',
0268 'hama_body_log',
0269 'hama_inner2_log']
0270
0271
0272 m = NPMeta(lines)
0273 print(m.d)
0274
0275
0276
0277
0278
0279
0280