working json document type

This commit is contained in:
2022-08-29 11:20:28 +02:00
parent b52fa6d9bd
commit 9f32dd657c
2 changed files with 70 additions and 88 deletions

View File

@@ -35,8 +35,9 @@ This contains a Widget to handle FixTargetFrames and fiducials, calculate final
import logging import logging
_log=logging.getLogger(__name__) _log=logging.getLogger(__name__)
import os, pickle, json, yaml,base64 import json, base64 #, os, pickle, yaml
import numpy as np import numpy as np
import pyqtUsrObj as UsrGO
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5.QtCore import Qt, QFileInfo, pyqtSignal, pyqtSlot from PyQt5.QtCore import Qt, QFileInfo, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
@@ -75,29 +76,31 @@ class MyJsonEncoder(json.JSONEncoder):
#return obj.tolist() #return obj.tolist()
elif isinstance(obj, set): elif isinstance(obj, set):
return list(obj) return list(obj)
if type(obj) not in (dict,list,str,int): elif type(obj) not in (dict,list,str,int):
_log.error('dont know how to json') try:
return repr(obj) return obj.obj2json(self)
except AttributeError:
_log.error('dont know how to json')
return repr(obj)
return json.JSONEncoder.default(self, obj) return json.JSONEncoder.default(self, obj)
def MyJsonDecoder(dct): def MyJsonDecoder(dct):
if isinstance(dct, dict) and '__ndarray__' in dct: if isinstance(dct, dict):
if '__class__' in dct:
cls=dct.pop('__class__')
cls=UsrGO.__dict__[cls]
obj=cls.__new__(cls)
obj.__init__(**dct)
#try:
# obj.json2obj(dct)
#except AttributeError:
# obj.__init__(**dct)
return obj
elif '__ndarray__' in dct:
data = base64.b64decode(dct['__ndarray__']) data = base64.b64decode(dct['__ndarray__'])
return np.frombuffer(data[:-1], dct['dtype']).reshape(dct['shape']) return np.frombuffer(data[:-1], dct['dtype']).reshape(dct['shape'])
return dct return dct
def yaml_repr_numpy(dumper, data):
return dumper.represent_scalar(u'!np_array', u'%s' % repr(data))
yaml.add_representer(np.ndarray, yaml_repr_numpy)
def yaml_cnstr_numpy(loader, node):
value = loader.construct_scalar(node)
a=eval(value[6:-1])
return np.array(a)
yaml.add_constructor(u'!np_array', yaml_cnstr_numpy)
class MarkerDelegate(QItemDelegate): class MarkerDelegate(QItemDelegate):
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
@@ -263,8 +266,8 @@ class WndFixTarget(QWidget):
#data_folder = cfg.value("folders/last_prelocation_folder", def_folder) #data_folder = cfg.value("folders/last_prelocation_folder", def_folder)
data_folder='' data_folder=''
if filename is None: if filename is None:
filename, _ = QFileDialog.getOpenFileName(self,"Load yaml data file",None, filename, _ = QFileDialog.getOpenFileName(self,"Load data file",None,
"yaml files (*.yaml);;json files (*.json);;pickle files (*.pkl);;text files (*.txt);;all files (*)",) "json files (*.json);;yaml files (*.yaml);;pickle files (*.pkl);;text files (*.txt);;all files (*)",)
if not filename: # cancelled dialog if not filename: # cancelled dialog
return return
@@ -350,8 +353,8 @@ class WndFixTarget(QWidget):
#data_folder = settings.value("folders/last_prelocation_folder") #data_folder = settings.value("folders/last_prelocation_folder")
data_folder='' data_folder=''
if filename is None: if filename is None:
filename, _ = QFileDialog.getSaveFileName(self,"Soad yaml data file",data_folder, filename, _ = QFileDialog.getSaveFileName(self,"Save data file",data_folder,
"yaml files (*.yaml);;json files (*.json);;pickle files (*.pkl);;text files (*.txt);;all files (*)",) "json files (*.json);;yaml files (*.yaml);;pickle files (*.pkl);;text files (*.txt);;all files (*)",)
if not filename: if not filename:
return return
@@ -370,7 +373,7 @@ class WndFixTarget(QWidget):
yaml.dump(self._data, f) yaml.dump(self._data, f)
elif ext=='json': elif ext=='json':
with open(filename, 'w') as f: with open(filename, 'w') as f:
json.dump(self._data, f,cls=MyJsonEncoder) json.dump(self._data, f,cls=MyJsonEncoder, indent=2)#separators=(',', ':')
print(self._data) print(self._data)
def delete_selected(self): def delete_selected(self):
@@ -725,7 +728,6 @@ void itemSelectionChanged()
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
import pyqtUsrObj as UsrGO
class Monster(yaml.YAMLObject): class Monster(yaml.YAMLObject):
yaml_tag = u'!Monster' yaml_tag = u'!Monster'

View File

@@ -18,7 +18,10 @@ from pyqtgraph.Qt import QtCore, QtGui
import numpy as np import numpy as np
from PyQt5.QtGui import QPolygon,QPolygonF from PyQt5.QtGui import QPolygon,QPolygonF
from PyQt5.QtCore import Qt,QPointF,QLineF from PyQt5.QtCore import Qt,QPointF,QLineF
import yaml
def itr2str(itr):
return '('+', '.join(tuple(map(lambda x:f'{x:.6g}', itr)))+')'
def obj_tree(obj,p=''): def obj_tree(obj,p=''):
obj_info(obj,p) obj_info(obj,p)
@@ -159,23 +162,19 @@ class Fiducial(pg.ROI):
tr.setMatrix(tr.m11(), tr.m12(), tr.m13(), tr.m21(), -tr.m22(), tr.m23(), tr.m31(), tr.m32(), tr.m33()) tr.setMatrix(tr.m11(), tr.m12(), tr.m13(), tr.m21(), -tr.m22(), tr.m23(), tr.m31(), tr.m32(), tr.m33())
p.setTransform(tr) p.setTransform(tr)
def __repr__(self): def __repr__(self):
s=f'{self.__class__.__name__}:(pos:{tuple(self.pos())}, size:{tuple(self.size())}, xyz:{self._xyz}}}' pos='('+', '.join(tuple(map(lambda x: f'{x:.6g}',self.pos())))+')'
s=f'{self.__class__.__name__}:(pos:{itr2str(self.pos())}, size:{itr2str(self.size())}, xyz:{itr2str(self._xyz)}}}'
return s return s
@staticmethod def obj2json(self,encoder):
def yaml_repr(dumper, data): jsn= {
m={'pos':(data.pos()),'size':(data.size()),'xyz':(map(float,data._xyz))} '__class__':self.__class__.__name__,
return dumper.represent_mapping(u'!Fiducial', m) 'pos':tuple(self.pos()),
'size':tuple(self.size()),
@staticmethod 'xyz':tuple(self._xyz),
def yaml_cnstr(loader, node): }
m=loader.construct_mapping(node) return jsn
return Fiducial(**m)
yaml.add_representer(Fiducial, Fiducial.yaml_repr)
yaml.add_constructor(u'!Fiducial', Fiducial.yaml_cnstr)
class Grid(pg.ROI): class Grid(pg.ROI):
@@ -241,26 +240,18 @@ class Grid(pg.ROI):
#p.drawRect(0, 0, 1, 1) #p.drawRect(0, 0, 1, 1)
def __repr__(self): def __repr__(self):
s=f'{self.__class__.__name__}:(pos:{tuple(self.pos())}, size:{tuple(self.size())}, cnt:{self._cnt}, ficucialScale:{self._fidScl}}}' s=f'{self.__class__.__name__}:(pos:{itr2str(self.pos())}, size:{itr2str(self.size())}, cnt:{self._cnt}, ficucialScale:{self._fidScl}}}'
return s return s
@staticmethod def obj2json(self,encoder):
def yaml_repr(dumper, data): jsn= {
#s=f'{{"pos":{tuple(data.pos())}, "size":{tuple(data.size())}, "cnt":{data._cnt}, "ficucialScale":{data._fidScl}}}' '__class__':self.__class__.__name__,
#return dumper.represent_scalar(u'!Grid', s) 'pos':tuple(self.pos()),
m={'pos':list(data.pos()),'size':list(data.size()),'cnt':list(data._cnt), 'ficucialScale':data._fidScl} 'size':tuple(self.size()),
return dumper.represent_mapping(u'!Grid', m) 'cnt':self._cnt,
'ficucialScale':self._fidScl
@staticmethod }
def yaml_cnstr(loader, node): return jsn
# value = loader.construct_scalar(node)
# kwargs=eval(value)
# return Grid(**kwargs)
m=loader.construct_mapping(node)
return Grid(**m)
yaml.add_representer(Grid, Grid.yaml_repr)
yaml.add_constructor(u'!Grid', Grid.yaml_cnstr)
class Path(pg.ROI): class Path(pg.ROI):
@@ -319,28 +310,24 @@ class Path(pg.ROI):
fid=self._fiducial fid=self._fiducial
for i in range(fid.shape[0]): for i in range(fid.shape[0]):
x,y=fid[i,:]#;print(x,y) x,y=fid[i,:] #;print(x,y)
lh=QLineF(x-5*rx,y,x+5*rx,y) lh=QLineF(x-5*rx,y,x+5*rx,y)
lv=QLineF(x, y-5*ry, x, y+5*ry) lv=QLineF(x, y-5*ry, x, y+5*ry)
p.drawLines(lh,lv) p.drawLines(lh,lv)
def __repr__(self): def __repr__(self):
s=f'{self.__class__.__name__}:(pos:{tuple(self.pos())}, size:{tuple(self.size())}, cnt:{self._cnt}, ficucialScale:{self._fidScl}}}' s=f'{self.__class__.__name__}:(pos:{itr2str(self.pos())}, size:{itr2str(self.size())}, cnt:{self._cnt}, ficucialScale:{self._fidScl}}}'
return s return s
@staticmethod def obj2json(self,encoder):
def yaml_repr(dumper, data): jsn= {
m={'pos':list(data.pos()),'size':list(data.size()),'cnt':data._cnt, 'ficucialScale':data._fidScl} '__class__':self.__class__.__name__,
return dumper.represent_mapping(u'!Path', m) 'pos':tuple(self.pos()),
'fiducial': repr(self._fiducial),
@staticmethod 'path': repr(self._path),
def yaml_cnstr(loader, node): 'ficucialScale':self._fidScl
m=loader.construct_mapping(node) }
return Path(**m) return jsn
yaml.add_representer(Path, Path.yaml_repr)
yaml.add_constructor(u'!Path', Path.yaml_cnstr)
class FixTargetFrame(pg.ROI): class FixTargetFrame(pg.ROI):
'''fixed target frame''' '''fixed target frame'''
@@ -440,7 +427,7 @@ class FixTargetFrame(pg.ROI):
p0=np.array(p0) p0=np.array(p0)
for p1 in ((-120,-120),(120,-120),(0,0),(-120,120),(120,120),): for p1 in ((-120,-120),(120,-120),(0,0),(-120,120),(120,120),):
p1=np.array(p1) p1=np.array(p1)
x, y=p0+p1 ;print(x,y) x, y=p0+p1 #;print(x,y)
lh=QLineF(x-rx, y, x+rx, y) lh=QLineF(x-rx, y, x+rx, y)
lv=QLineF(x, y-ry, x, y+ry) lv=QLineF(x, y-ry, x, y+ry)
p.drawLines(lh, lv) p.drawLines(lh, lv)
@@ -448,24 +435,17 @@ class FixTargetFrame(pg.ROI):
assert('unknown feducial type') assert('unknown feducial type')
def __repr__(self): def __repr__(self):
s=f'{self.__class__.__name__}:(pos:{tuple(self.pos())}, size:{tuple(self.size())}, dscr:{self._dscr}}}' s=f'{self.__class__.__name__}:(pos:{itr2str(self.pos())}, size:{itr2str(self.size())}, dscr:{self._dscr}}}'
return s return s
@staticmethod def obj2json(self,encoder):
def yaml_repr(dumper, data): jsn= {
#m={'pos':list(data.pos()),'size':list(data.size()),'dscr':repr(data._dscr)} '__class__':self.__class__.__name__,
m={'pos':list(data.pos()),'size':list(data.size())} 'pos':tuple(self.pos()),
return dumper.represent_mapping(u'!FixTargetFrame', m) 'size':tuple(self.size()),
'dscr': self._dscr
@staticmethod }
def yaml_cnstr(loader, node): return jsn
m=loader.construct_mapping(node)
#m['dscr']=eval(m['dscr'])
return FixTargetFrame(**m)
yaml.add_representer(FixTargetFrame, FixTargetFrame.yaml_repr)
yaml.add_constructor(u'!FixTargetFrame', FixTargetFrame.yaml_cnstr)
class TxtROI(pg.ROI): class TxtROI(pg.ROI):