Changeset 630155bd in sasview for src/sas/sasgui
- Timestamp:
- Oct 5, 2016 4:40:30 PM (8 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:
- 2366fb2, e207c3f
- Parents:
- d0ccd80f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/data_manager.py
rd85c194 r630155bd 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 os 18 import copy 17 19 import logging 18 import os19 import copy 20 import json 21 from StringIO import StringIO 20 22 21 23 from sas.sasgui.guiframe.data_state import DataState … … 26 28 import time 27 29 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 34 28 35 class DataManager(object): 29 36 """ … … 33 40 """ 34 41 Store opened path and data object created at the loading time 35 :param auto_plot: if True the datamanager sends data to plotting 36 plugin. 42 :param auto_plot: if True the datamanager sends data to plotting 43 plugin. 37 44 :param auto_set_data: if True the datamanager sends to the current 38 45 perspective … … 44 51 self.list_of_id = [] 45 52 self.time_stamp = time.time() 46 53 47 54 def __str__(self): 48 55 _str = "" … … 50 57 n_count = 0 51 58 for value in self.stored_data.values(): 52 n_count += 1 59 n_count += 1 53 60 _str += "State No %s \n" % str(n_count) 54 61 _str += str(value) + "\n" 55 62 return _str 56 63 57 64 def create_gui_data(self, data, path=None): 58 65 """ 59 66 Receive data from loader and create a data to use for guiframe 60 67 """ 61 68 62 69 if issubclass(Data2D, data.__class__): 63 new_plot = Data2D(image=None, err_image=None) 64 else: 70 new_plot = Data2D(image=None, err_image=None) 71 else: 65 72 new_plot = Data1D(x=[], y=[], dx=None, dy=None) 66 73 67 74 new_plot.copy_from_datainfo(data) 68 75 data.clone_without_data(clone=new_plot) … … 82 89 if title.strip() == "": 83 90 title = file_name 84 91 85 92 if new_plot.filename.strip() == "": 86 93 new_plot.filename = file_name 87 94 88 95 new_plot.name = name 89 96 new_plot.title = title … … 101 108 # plot data 102 109 return new_plot 103 110 104 111 def rename(self, name): 105 112 """ … … 108 115 ## name of the data allow to differentiate data when plotted 109 116 name = parse_name(name=name, expression="_") 110 117 111 118 max_char = name.find("[") 112 119 if max_char < 0: 113 120 max_char = len(name) 114 121 name = name[0:max_char] 115 122 116 123 if name not in self.data_name_dict: 117 124 self.data_name_dict[name] = 0 … … 120 127 name = name + " [" + str(self.data_name_dict[name]) + "]" 121 128 return name 122 123 129 130 124 131 def add_data(self, data_list): 125 132 """ 126 receive a list of 133 receive a list of 127 134 """ 128 135 for id, data in data_list.iteritems(): … … 138 145 data_state.path = data.path 139 146 self.stored_data[id] = data_state 140 147 141 148 def update_data(self, prev_data, new_data): 142 149 """ … … 144 151 if prev_data.id not in self.stored_data.keys(): 145 152 return None, {} 146 data_state = self.stored_data[prev_data.id] 153 data_state = self.stored_data[prev_data.id] 147 154 self.stored_data[new_data.id] = data_state.clone() 148 155 self.stored_data[new_data.id].data = new_data 149 156 if prev_data.id in self.stored_data.keys(): 150 del self.stored_data[prev_data.id] 157 del self.stored_data[prev_data.id] 151 158 return prev_data.id, {new_data.id: self.stored_data[new_data.id]} 152 159 153 160 def update_theory(self, theory, data_id=None, state=None): 154 161 """ … … 158 165 uid = theory.id 159 166 if uid in self.stored_data.keys(): 160 data_state = self.stored_data[uid] 167 data_state = self.stored_data[uid] 161 168 else: 162 169 data_state = DataState() … … 165 172 self.stored_data[uid] = data_state 166 173 return {uid: self.stored_data[uid]} 167 168 174 175 169 176 def get_message(self): 170 177 """ … … 172 179 """ 173 180 return self.message 174 181 175 182 def get_by_id(self, id_list=None): 176 183 """ … … 189 196 if search_id in theory_list.keys(): 190 197 _selected_theory_list[search_id] = theory_list[search_id] 191 198 192 199 return _selected_data, _selected_theory_list 193 194 200 201 195 202 def freeze(self, theory_id): 196 203 """ 197 204 """ 198 205 return self.freeze_theory(self.stored_data.keys(), theory_id) 199 206 200 207 def freeze_theory(self, data_id, theory_id): 201 208 """ … … 221 228 222 229 return selected_theory 223 224 230 231 225 232 def delete_data(self, data_id, theory_id=None, delete_all=False): 226 233 """ … … 232 239 del self.data_name_dict[data_state.data.name] 233 240 del self.stored_data[d_id] 234 241 235 242 self.delete_theory(data_id, theory_id) 236 243 if delete_all: 237 244 self.stored_data = {} 238 245 self.data_name_dict = {} 239 246 240 247 def delete_theory(self, data_id, theory_id): 241 248 """ … … 249 256 #del pure theory 250 257 self.delete_by_id(theory_id) 251 258 252 259 def delete_by_id(self, id_list=None): 253 260 """ … … 257 264 if id in self.stored_data: 258 265 del self.stored_data[id] 259 260 266 267 261 268 def get_by_name(self, name_list=None): 262 269 """ … … 269 276 _selected_data[id] = data_state.data 270 277 return _selected_data 271 278 272 279 def delete_by_name(self, name_list=None): 273 280 """ … … 288 295 _selected_data_state[id] = self.stored_data[id] 289 296 return _selected_data_state 290 297 291 298 def get_all_data(self): 292 299 """ … … 294 301 """ 295 302 return self.stored_data 296 297 298 303 304 def assign(self, other): 305 self.stored_data = other.stored_data 306 self.message = other.message 307 self.data_name_dict = other.data_name_dict 308 self.count = other.count 309 self.list_of_id = other.list_of_id 310 self.time_stamp = other.time_stamp 311 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 dict 320 321 def jdefault(o): 322 """ 323 objects that can't otherwise be serialized need to be converted 324 """ 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" types 331 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 # DataState 337 if isinstance(o, DataState): 338 # don't store parent 339 content = o.__dict__.copy() 340 content.pop('parent') 341 return add_type(content, type(o)) 342 343 # ndarray 344 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 supported 352 logging.info("data cannot be serialized to json: %s" % type(o)) 353 return None 354 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 pass 373 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 object 381 o = Empty() 382 o.__class__ = cls 383 384 return o 385 386 def construct(type, data, level): 387 try: 388 cls = lookup[type] 389 except KeyError: 390 logging.info('unknown type: %s' % type) 391 return None 392 393 # tuples and sets 394 if cls in (tuple, set): 395 # convert list to tuple/set 396 return cls(generate(data['data'], level)) 397 398 # "simple" types 399 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 # DataState 405 if cls == DataState: 406 o = simple_type(cls, data, level) 407 o.parent = None # TODO: set to ??? 408 return o 409 410 # ndarray 411 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 None 419 420 def generate(data, level): 421 if level > 16: # recursion limit (arbitrary number) 422 raise TooComplexException() 423 else: 424 level += 1 425 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 dictionary 431 o = {} 432 for key, value in data.iteritems(): 433 o[key] = generate(value, level) 434 return o 435 436 return construct(type, data, level) 437 438 if isinstance(data, list): 439 return [generate(item, level) for item in data] 440 441 return data 442 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.