Changeset c416a17 in sasview for src/sas/sasgui/guiframe/data_manager.py
- Timestamp:
- May 26, 2017 7:41:44 AM (7 years ago)
- Branches:
- ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- c1e380e
- Parents:
- 6964d44 (diff), 7132e49 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/data_manager.py
r630155bd rc416a17 2 2 #This software was developed by the University of Tennessee as part of the 3 3 #Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 4 #project funded by the US National Science Foundation. 4 #project funded by the US National Science Foundation. 5 5 # 6 6 #See the license text in license.txt … … 9 9 ################################################################################ 10 10 """ 11 This module manages all data loaded into the application. Data_manager makes 12 available all data loaded for the current perspective. 13 14 All modules "creating Data" posts their data to data_manager . 11 This module manages all data loaded into the application. Data_manager makes 12 available all data loaded for the current perspective. 13 14 All modules "creating Data" posts their data to data_manager . 15 15 Data_manager make these new data available for all other perspectives. 16 16 """ 17 import logging 17 18 import os 18 import copy 19 import logging 20 import json 21 from StringIO import StringIO 19 import copy 22 20 23 21 from sas.sasgui.guiframe.data_state import DataState … … 28 26 import time 29 27 30 # used for import/export 31 import numpy as np 32 from sas.sascalc.dataloader.data_info import Sample, Source, Vector 33 from sas.sasgui.plottools.plottables import Plottable, Theory1D, Fit1D, Text, Chisq, View 28 logger = logging.getLogger(__name__) 34 29 35 30 class DataManager(object): … … 40 35 """ 41 36 Store opened path and data object created at the loading time 42 :param auto_plot: if True the datamanager sends data to plotting 43 plugin. 37 :param auto_plot: if True the datamanager sends data to plotting 38 plugin. 44 39 :param auto_set_data: if True the datamanager sends to the current 45 40 perspective … … 57 52 n_count = 0 58 53 for value in self.stored_data.values(): 59 n_count += 1 54 n_count += 1 60 55 _str += "State No %s \n" % str(n_count) 61 56 _str += str(value) + "\n" 62 57 return _str 63 58 64 59 def create_gui_data(self, data, path=None): 65 60 """ 66 61 Receive data from loader and create a data to use for guiframe 67 62 """ 68 63 69 64 if issubclass(Data2D, data.__class__): 70 new_plot = Data2D(image=None, err_image=None) 71 else: 72 new_plot = Data1D(x=[], y=[], dx=None, dy=None) 65 new_plot = Data2D(image=None, err_image=None) # For now, isSesans for 2D data is always false 66 else: 67 new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=data.isSesans) 68 69 70 #elif data.meta_data['loader'] == 'SESANS': 71 # new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=True) 72 #else: 73 # new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None) #SESANS check??? 73 74 74 75 new_plot.copy_from_datainfo(data) … … 89 90 if title.strip() == "": 90 91 title = file_name 91 92 92 93 if new_plot.filename.strip() == "": 93 94 new_plot.filename = file_name 94 95 95 96 new_plot.name = name 96 97 new_plot.title = title … … 115 116 ## name of the data allow to differentiate data when plotted 116 117 name = parse_name(name=name, expression="_") 117 118 118 max_char = name.find("[") 119 119 if max_char < 0: 120 120 max_char = len(name) 121 121 name = name[0:max_char] 122 123 122 if name not in self.data_name_dict: 124 123 self.data_name_dict[name] = 0 … … 127 126 name = name + " [" + str(self.data_name_dict[name]) + "]" 128 127 return name 129 130 128 129 131 130 def add_data(self, data_list): 132 131 """ 133 receive a list of 132 receive a list of 134 133 """ 135 134 for id, data in data_list.iteritems(): … … 137 136 msg = "Data manager already stores %s" % str(data.name) 138 137 msg += "" 139 logg ing.info(msg)138 logger.info(msg) 140 139 data_state = self.stored_data[id] 141 140 data_state.data = data … … 151 150 if prev_data.id not in self.stored_data.keys(): 152 151 return None, {} 153 data_state = self.stored_data[prev_data.id] 152 data_state = self.stored_data[prev_data.id] 154 153 self.stored_data[new_data.id] = data_state.clone() 155 154 self.stored_data[new_data.id].data = new_data 156 155 if prev_data.id in self.stored_data.keys(): 157 del self.stored_data[prev_data.id] 156 del self.stored_data[prev_data.id] 158 157 return prev_data.id, {new_data.id: self.stored_data[new_data.id]} 159 158 160 159 def update_theory(self, theory, data_id=None, state=None): 161 160 """ … … 165 164 uid = theory.id 166 165 if uid in self.stored_data.keys(): 167 data_state = self.stored_data[uid] 166 data_state = self.stored_data[uid] 168 167 else: 169 168 data_state = DataState() … … 172 171 self.stored_data[uid] = data_state 173 172 return {uid: self.stored_data[uid]} 174 175 173 176 174 def get_message(self): … … 196 194 if search_id in theory_list.keys(): 197 195 _selected_theory_list[search_id] = theory_list[search_id] 198 196 199 197 return _selected_data, _selected_theory_list 200 201 198 199 202 200 def freeze(self, theory_id): 203 201 """ … … 229 227 return selected_theory 230 228 231 232 229 def delete_data(self, data_id, theory_id=None, delete_all=False): 233 230 """ … … 239 236 del self.data_name_dict[data_state.data.name] 240 237 del self.stored_data[d_id] 241 242 238 self.delete_theory(data_id, theory_id) 243 239 if delete_all: … … 264 260 if id in self.stored_data: 265 261 del self.stored_data[id] 266 267 262 268 263 def get_by_name(self, name_list=None): … … 301 296 """ 302 297 return self.stored_data 303 304 def assign(self, other):305 self.stored_data = other.stored_data306 self.message = other.message307 self.data_name_dict = other.data_name_dict308 self.count = other.count309 self.list_of_id = other.list_of_id310 self.time_stamp = other.time_stamp311 312 def save_to_writable(self, fp):313 """314 save content of stored_data to fp (a .write()-supporting file-like object)315 """316 317 def add_type(dict, type):318 dict['__type__'] = type.__name__319 return dict320 321 def jdefault(o):322 """323 objects that can't otherwise be serialized need to be converted324 """325 # tuples and sets (TODO: default JSONEncoder converts tuples to lists, create custom Encoder that preserves tuples)326 if isinstance(o, (tuple, set)):327 content = { 'data': list(o) }328 return add_type(content, type(o))329 330 # "simple" types331 if isinstance(o, (Sample, Source, Vector)):332 return add_type(o.__dict__, type(o))333 if isinstance(o, (Plottable, View)):334 return add_type(o.__dict__, type(o))335 336 # DataState337 if isinstance(o, DataState):338 # don't store parent339 content = o.__dict__.copy()340 content.pop('parent')341 return add_type(content, type(o))342 343 # ndarray344 if isinstance(o, np.ndarray):345 buffer = StringIO()346 np.save(buffer, o)347 buffer.seek(0)348 content = { 'data': buffer.read().decode('latin-1') }349 return add_type(content, type(o))350 351 # not supported352 logging.info("data cannot be serialized to json: %s" % type(o))353 return None354 355 json.dump(self.stored_data, fp, indent=2, sort_keys=True, default=jdefault)356 357 358 def load_from_readable(self, fp):359 """360 load content from tp to stored_data (a .read()-supporting file-like object)361 """362 363 supported = [364 tuple, set,365 Sample, Source, Vector,366 Plottable, Data1D, Data2D, Theory1D, Fit1D, Text, Chisq, View,367 DataState, np.ndarray]368 369 lookup = dict((cls.__name__, cls) for cls in supported)370 371 class TooComplexException(Exception):372 pass373 374 def simple_type(cls, data, level):375 class Empty(object):376 def __init__(self):377 for key, value in data.iteritems():378 setattr(self, key, generate(value, level))379 380 # create target object381 o = Empty()382 o.__class__ = cls383 384 return o385 386 def construct(type, data, level):387 try:388 cls = lookup[type]389 except KeyError:390 logging.info('unknown type: %s' % type)391 return None392 393 # tuples and sets394 if cls in (tuple, set):395 # convert list to tuple/set396 return cls(generate(data['data'], level))397 398 # "simple" types399 if cls in (Sample, Source, Vector):400 return simple_type(cls, data, level)401 if issubclass(cls, Plottable) or (cls == View):402 return simple_type(cls, data, level)403 404 # DataState405 if cls == DataState:406 o = simple_type(cls, data, level)407 o.parent = None # TODO: set to ???408 return o409 410 # ndarray411 if cls == np.ndarray:412 buffer = StringIO()413 buffer.write(data['data'].encode('latin-1'))414 buffer.seek(0)415 return np.load(buffer)416 417 logging.info('not implemented: %s, %s' % (type, cls))418 return None419 420 def generate(data, level):421 if level > 16: # recursion limit (arbitrary number)422 raise TooComplexException()423 else:424 level += 1425 426 if isinstance(data, dict):427 try:428 type = data['__type__']429 except KeyError:430 # if dictionary doesn't have __type__ then it is assumed to be just an ordinary dictionary431 o = {}432 for key, value in data.iteritems():433 o[key] = generate(value, level)434 return o435 436 return construct(type, data, level)437 438 if isinstance(data, list):439 return [generate(item, level) for item in data]440 441 return data442 443 new_stored_data = {}444 for id, data in json.load(fp).iteritems():445 try:446 new_stored_data[id] = generate(data, 0)447 except TooComplexException:448 logging.info('unable to load %s' % id)449 450 self.stored_data = new_stored_data
Note: See TracChangeset
for help on using the changeset viewer.