File indexing completed on 2026-04-09 07:48:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 """
0022 histype.py: HisType
0023 ========================
0024
0025 ::
0026
0027
0028 LV=box histype.py
0029
0030 histype.py --det PmtInBox --tag 10 --src torch
0031 histype.py --det dayabay --tag 1 --src torch
0032
0033
0034 ::
0035
0036 export OPTICKS_ANA_DEFAULTS="det=tboolean-box,src=torch,tag=1,pfx=."
0037
0038 cd /tmp
0039 OPTICKS_EVENT_BASE=tboolean-box histype.py
0040
0041 ::
0042
0043
0044 In [21]: from opticks.ana.histype import HisType
0045
0046 In [22]: histype = HisType()
0047
0048 In [25]: histype.code("TO BT AB")
0049 Out[25]: 1229
0050
0051 In [26]: ab.a.seqhis
0052 Out[26]:
0053 A()sliced
0054 A([36045, 36045, 2237, ..., 36045, 36045, 36045], dtype=uint64)
0055
0056 In [27]: ab.a.seqhis.shape
0057 Out[27]: (100000,)
0058
0059 In [29]: np.where(ab.a.seqhis == histype.code("TO BT AB"))[0]
0060 Out[29]: array([ 2084, 4074, 15299, 20870, 25748, 26317, 43525, 51563, 57355, 61602, 65894, 71978, 77062, 78744, 79117, 86814])
0061
0062 In [30]: np.where(ab.a.seqhis == histype.code("TO BT AB"))[0].shape
0063 Out[30]: (16,)
0064
0065
0066 """
0067 import os, datetime, logging, sys
0068 log = logging.getLogger(__name__)
0069 import numpy as np
0070
0071 from opticks.ana.base import PhotonCodeFlags
0072 from opticks.ana.seq import SeqType, SeqTable, SeqAna
0073 from opticks.ana.nbase import count_unique_sorted
0074 from opticks.ana.nload import A
0075
0076 class HisType(SeqType):
0077 @classmethod
0078 def Convert(cls, q):
0079 """
0080 :param q: uint64 (100000, 2) : 2*64 bits (32 nibbles) of history : for 32 points of history
0081 :return qq: int8 (100000, 32)
0082
0083 Place nibbles from q (2 uint64) into qq (32 int8) doubling bits as NumPy lacks an int4 dtype
0084
0085 HMM: would be simpler if NumPy had uint128 dtype
0086
0087 ::
0088
0089 q = xf.seq[:,0]
0090 s = HisType.Convert(q)
0091 ss = ht.aflags[s].view("|S%d" % (3*32))
0092
0093 n = np.sum( seqnib_(q), axis=1 )
0094
0095 np.c_[ss, n, np.arange(len(ss))]
0096
0097 In [36]: np.c_[ss, n, np.arange(len(ss))][n > 16]
0098 Out[36]:
0099 array([[b'TO BT BT BT BT SR SR SR BT BT BT BT BT BT BT BT SA ', b'17', b'204'],
0100 [b'TO BR BT BT BT BT SR SR SR BT BT BT BT BT BT BR BT BT BT BT SA ', b'21', b'921'],
0101 [b'TO BR BR BT BT BT BT SR SR BT BR BT SR SR SR BT BT BT BT BT BT ', b'21', b'925']], dtype='|S96')
0102
0103 """
0104 qq = np.zeros( (len(q), 32), dtype=np.int8 )
0105 for i in np.arange(16): qq[:,i] = ( q[:,0] >> np.uint64(4*i) ) & 0xf
0106 for i in np.arange(16): qq[:,16+i] = ( q[:,1] >> np.uint64(4*i) ) & 0xf
0107 return qq
0108
0109 def __init__(self):
0110 flags = PhotonCodeFlags()
0111 SeqType.__init__(self, flags, flags.abbrev)
0112
0113 def seqhis(self, q):
0114 """
0115 :param q: uint64 (100000, 2)
0116 :return s: "|S96" (100000, 1)
0117
0118 ht.aflags array([b' ', b'CK ', b'SI ', b'MI ', b'AB ', ... , b'TO ', b'NA ', b'EX ', b'EC ', ..., dtype='|S3')
0119
0120 """
0121 qq = self.Convert(q)
0122 return self.aflags[qq].view("|S%d" % (32*3) )
0123
0124
0125 def test_HistoryTable(ht, seqhis):
0126 log.info("[")
0127
0128
0129
0130 for seq in ht.labels:
0131 seqs = [seq]
0132 s_seqhis = list(map(lambda _:seqhis == af.code(_), seqs ))
0133 psel = np.logical_or.reduce(s_seqhis)
0134
0135 n = len(seqhis[psel])
0136 assert n == ht.label2count.get(seq)
0137 print("%10s %s " % (n, seq ))
0138 pass
0139 log.info("]")
0140
0141 def test_roundtrip(af):
0142 log.info("[")
0143 x=0x8cbbbcd
0144 l = af.label(x)
0145 c = af.code(l)
0146 print("%x %s %x " % ( x,l,c ))
0147 assert x == c
0148 log.info("]")
0149
0150
0151 def test_load_SeqTable(ok, af):
0152 try:
0153 ph = A.load_("ph",ok.src,ok.tag,ok.det, pfx=ok.pfx)
0154 except IOError as err:
0155 log.fatal(err)
0156 sys.exit(0)
0157
0158 log.info("loaded ph %s %s shape %s " % (ph.path, ph.stamp, repr(ph.shape)))
0159
0160 seqhis = ph[:,0,0]
0161
0162 cu = count_unique_sorted(seqhis)
0163
0164 ht = SeqTable(cu, af, smry=True)
0165
0166
0167 test_HistoryTable(ht, seqhis)
0168
0169
0170
0171 def test_HisType(af):
0172 log.info("[")
0173 print(af)
0174 print("af.abbrev.name2abbr",af.abbrev.name2abbr)
0175 print("af.flags.names",af.flags.names)
0176 print("af.flags.codes",af.flags.codes)
0177 print("af.abbr2code",af.abbr2code)
0178 log.info("]")
0179
0180
0181 if __name__ == '__main__':
0182 from opticks.ana.main import opticks_main
0183 ok = opticks_main()
0184
0185 af = HisType()
0186
0187
0188
0189
0190
0191 test_load_SeqTable(ok, af)
0192
0193
0194
0195
0196
0197
0198