diff --git a/.gitignore b/.gitignore
index b931629..d887a0c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,6 @@ __pycache__
*.egg-info
*.whl
.idea
+debian/files
+.pybuild
+.junie
diff --git a/MANIFEST.in b/MANIFEST.in
index 4bd8102..75040a8 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,6 @@
-include src/gui/DAMARIS3.png
-include src/gui/DAMARIS3.ico
-include src/gui/damaris.glade
-include src/gui/damaris.gladep
+include src/damaris/gui/DAMARIS3.png
+include src/damaris/gui/DAMARIS3.ico
+include src/damaris/gui/damaris3.glade
+include src/damaris/gui/python.xml
#recursive-include doc/reference-html *.html *.gif *.png *.css
#recursive-include doc/tutorial-html *.html *.gif *.png *.css *.tar.gz *.sh
diff --git a/debian/files b/debian/files
deleted file mode 100644
index 153d838..0000000
--- a/debian/files
+++ /dev/null
@@ -1,2 +0,0 @@
-python3-damaris_0.20_all.deb science optional
-python3-damaris_0.20_amd64.buildinfo science optional
diff --git a/pyproject.toml b/pyproject.toml
index 6977ac8..479d2a6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -39,7 +39,7 @@ DAMARIS3 = "damaris.__main__:main"
where = ["src"]
[tool.setuptools.package-data]
-"damaris.gui" = ["DAMARIS3.png", "DAMARIS3.ico", "damaris.xml", "python.xml", "damaris3.glade"]
+"damaris.gui" = ["DAMARIS3.png", "DAMARIS3.ico", "python.xml", "damaris3.glade"]
[tool.setuptools.dynamic]
version = {attr = "damaris.__version__"}
diff --git a/src/damaris/data/Accumulation.py b/src/damaris/data/Accumulation.py
index 717e8c7..53ff562 100644
--- a/src/damaris/data/Accumulation.py
+++ b/src/damaris/data/Accumulation.py
@@ -1160,26 +1160,66 @@ def read_from_hdf(hdf_node):
earliest_time=None
if "earliest_time" in dir(hdf_node._v_attrs):
timestring=hdf_node._v_attrs.__getattr__("earliest_time")
- earliest_time=datetime.datetime(int(timestring[:4]), # year
- int(timestring[4:6]), # month
- int(timestring[6:8]), # day
- int(timestring[9:11]), # hour
- int(timestring[12:14]), # minute
- int(timestring[15:17]), # second
- int(timestring[18:21])*1000 # microsecond
- )
+ # Handle both formats: "20260705 19:13:59.162" and "2026-07-05 19:13:59.162"
+ if '-' in timestring:
+ # New format: "2026-07-05 19:13:59.162"
+ try:
+ earliest_time=datetime.datetime.strptime(str(timestring), '%Y-%m-%d %H:%M:%S.%f')
+ except ValueError:
+ # Fallback to manual parsing
+ parts = timestring.split()
+ if len(parts) >= 2:
+ date_parts = parts[0].split('-')
+ time_parts = parts[1].split(':')
+ if len(date_parts) == 3 and len(time_parts) >= 2:
+ year, month, day = int(date_parts[0]), int(date_parts[1]), int(date_parts[2])
+ hour, minute = int(time_parts[0]), int(time_parts[1])
+ second_parts = time_parts[2].split('.') if len(time_parts) > 2 else ['0']
+ second = int(second_parts[0])
+ microsecond = int(second_parts[1].ljust(6, '0')[:6]) if len(second_parts) > 1 else 0
+ earliest_time=datetime.datetime(year, month, day, hour, minute, second, microsecond)
+ else:
+ # Old format: "20260705 19:13:59.162"
+ earliest_time=datetime.datetime(int(timestring[:4]), # year
+ int(timestring[4:6]), # month
+ int(timestring[6:8]), # day
+ int(timestring[9:11]), # hour
+ int(timestring[12:14]), # minute
+ int(timestring[15:17]), # second
+ int(timestring[18:21])*1000 # microsecond
+ )
oldest_time=None
if "oldest_time" in dir(hdf_node._v_attrs):
timestring=hdf_node._v_attrs.__getattr__("oldest_time")
- oldest_time=datetime.datetime(int(timestring[:4]), # year
- int(timestring[4:6]), # month
- int(timestring[6:8]), # day
- int(timestring[9:11]), # hour
- int(timestring[12:14]), # minute
- int(timestring[15:17]), # second
- int(timestring[18:21])*1000 # microsecond
- )
+ # Handle both formats: "20260705 19:13:59.162" and "2026-07-05 19:13:59.162"
+ if '-' in timestring:
+ # New format: "2026-07-05 19:13:59.162"
+ try:
+ oldest_time=datetime.datetime.strptime(str(timestring), '%Y-%m-%d %H:%M:%S.%f')
+ except ValueError:
+ # Fallback to manual parsing
+ parts = timestring.split()
+ if len(parts) >= 2:
+ date_parts = parts[0].split('-')
+ time_parts = parts[1].split(':')
+ if len(date_parts) == 3 and len(time_parts) >= 2:
+ year, month, day = int(date_parts[0]), int(date_parts[1]), int(date_parts[2])
+ hour, minute = int(time_parts[0]), int(time_parts[1])
+ second_parts = time_parts[2].split('.') if len(time_parts) > 2 else ['0']
+ second = int(second_parts[0])
+ microsecond = int(second_parts[1].ljust(6, '0')[:6]) if len(second_parts) > 1 else 0
+ oldest_time=datetime.datetime(year, month, day, hour, minute, second, microsecond)
+ else:
+ # Old format: "20260705 19:13:59.162"
+ oldest_time=datetime.datetime(int(timestring[:4]), # year
+ int(timestring[4:6]), # month
+ int(timestring[6:8]), # day
+ int(timestring[9:11]), # hour
+ int(timestring[12:14]), # minute
+ int(timestring[15:17]), # second
+ int(timestring[18:21])*1000 # microsecond
+ )
if oldest_time is None or earliest_time is None:
accu.time_period=None
@@ -1212,7 +1252,7 @@ def read_from_hdf(hdf_node):
accu.y_square=[]
accu.use_error=False
- for ch in range(accu_data.shape[1]/2):
+ for ch in range(accu_data.shape[1] // 2):
accu.y.append(accu_data[:,ch*2]*accu.n)
if accu.n<2 or numpy.all(accu_data[:,ch*2+1]==0.0):
accu.y_square.append(numpy.zeros((accu_data.shape[0]) ,dtype="float32"))
diff --git a/src/damaris/data/DataPool.py b/src/damaris/data/DataPool.py
index e5e8c5a..9fd436f 100644
--- a/src/damaris/data/DataPool.py
+++ b/src/damaris/data/DataPool.py
@@ -7,6 +7,7 @@ import collections
import threading
import traceback
import io
+import numpy
class DataPool(collections.abc.MutableMapping):
"""
@@ -107,7 +108,7 @@ class DataPool(collections.abc.MutableMapping):
self.__registered_listeners=None
def write_hdf5(self,hdffile,where="/",name="data_pool", complib=None, complevel=None):
- if type(hdffile) is bytes:
+ if isinstance(hdffile, (bytes, str)):
dump_file=tables.open_file(hdffile, mode="a")
elif isinstance(hdffile,tables.File):
dump_file=hdffile
@@ -156,7 +157,7 @@ class DataPool(collections.abc.MutableMapping):
value=self.__mydict[key]
self.__dictlock.release()
# now write data, assuming, the object is constant during write operation
- if "write_to_hdf" in dir(value):
+ if hasattr(value, "write_to_hdf"):
try:
value.write_to_hdf(hdffile=dump_file,
where=dump_dir,
@@ -170,16 +171,255 @@ class DataPool(collections.abc.MutableMapping):
traceback.print_tb(sys.exc_info()[2], None, traceback_file)
print("detailed traceback: %s\n"%str(e)+traceback_file.getvalue())
traceback_file=None
+ elif isinstance(value, (numpy.ndarray, int, float, str, bytes)):
+ try:
+ obj_to_save = value
+ if isinstance(value, str):
+ obj_to_save = value.encode('utf-8')
+ dump_file.create_array(dump_dir,
+ name=group_keyname,
+ obj=obj_to_save,
+ title=key)
+ except Exception as e:
+ print("failed to write data_pool[\"%s\"]: %s"%(key,str(e)))
else:
- print("don't know how to store data_pool[\"%s\"]"%key)
+ print("don't know how to store data_pool[\"%s\"] (type: %s)"%(key, type(value)))
value=None
finally:
dump_group=None
- if type(hdffile) is bytes:
+ if isinstance(hdffile, (bytes, str)):
dump_file.close()
dump_file=None
+ def read_from_hdf(self, hdffile, where="/data_pool"):
+ """
+ Read data from HDF5 file and populate the DataPool.
+
+ Parameters:
+ - hdffile: HDF5 file object or filename (bytes/str)
+ - where: Location within HDF5 file to read from (default: "/data_pool")
+ """
+ # Handle both filename and file object
+ if type(hdffile) is bytes or isinstance(hdffile, str):
+ hdf_file = tables.open_file(hdffile, mode="r")
+ close_file = True
+ elif isinstance(hdffile, tables.File):
+ hdf_file = hdffile
+ close_file = False
+ else:
+ raise Exception("expecting hdffile or string")
+
+ try:
+ # Navigate to the data pool group
+ if where not in hdf_file:
+ raise Exception(f"HDF5 location '{where}' not found")
+
+ data_pool_group = hdf_file.get_node(where)
+
+ # Recursively process the group structure
+ self._read_hdf_group(data_pool_group, "")
+
+ finally:
+ if close_file:
+ hdf_file.close()
+
+ def _read_hdf_group(self, group, path_prefix):
+ """
+ Recursively read HDF5 group and populate DataPool.
+
+ Parameters:
+ - group: HDF5 group object
+ - path_prefix: Current path in DataPool hierarchy
+ """
+ # Process all nodes in this group
+ for node in group:
+ # Get the node name (last part of the path)
+ node_name = node._v_name
+
+ # Try to get the original name from title
+ title = node._v_title
+
+ if title:
+ # For DAMARIS objects, the title is usually the full path
+ # For intermediate groups, it's just the part name
+ if "/" in title:
+ full_path = title
+ else:
+ if path_prefix:
+ full_path = f"{path_prefix}/{title}"
+ else:
+ full_path = title
+ else:
+ # Strip dir_ and dict_ prefixes from node name
+ clean_name = self._clean_hdf_name(node_name)
+
+ # Build the full path in DataPool hierarchy
+ if path_prefix:
+ full_path = f"{path_prefix}/{clean_name}"
+ else:
+ full_path = clean_name
+
+ full_path = full_path.replace("//", "/")
+
+ if isinstance(node, (tables.Group, tables.Table)):
+ # Check if this is a known DAMARIS object type
+ if hasattr(node._v_attrs, 'damaris_type'):
+ damaris_type = node._v_attrs.damaris_type
+
+ # Handle different DAMARIS object types
+ if damaris_type == "Accumulation":
+ from damaris.data.Accumulation import read_from_hdf
+ obj = read_from_hdf(node)
+ if obj is not None:
+ self[full_path] = obj
+
+ elif damaris_type == "ADC_Result":
+ from damaris.data.ADC_Result import read_from_hdf
+ obj = read_from_hdf(node)
+ if obj is not None:
+ self[full_path] = obj
+
+ elif damaris_type == "MeasurementResult":
+ from damaris.data.MeasurementResult import read_from_hdf
+ obj = read_from_hdf(node)
+ if obj is not None:
+ self[full_path] = obj
+
+ # Skip further processing of this group since we handled it
+ continue
+
+ # Recursively process sub-groups
+ if isinstance(node, tables.Group):
+ self._read_hdf_group(node, full_path)
+
+ elif isinstance(node, (tables.Array, tables.CArray, tables.EArray, tables.Table)):
+ # Handle simple array data
+ try:
+ data = node.read()
+ # If it's a scalar array of bytes, decode it to string
+ if hasattr(data, 'decode'):
+ try:
+ data = data.decode('utf-8')
+ except:
+ pass
+ elif isinstance(data, numpy.ndarray) and data.dtype.kind in ('S', 'V'):
+ # For numpy byte arrays, try to decode if they are scalar or small
+ if data.size == 1:
+ try:
+ decoded = data.item().decode('utf-8')
+ data = decoded
+ except:
+ pass
+ self[full_path] = data
+ except Exception as e:
+ print(f"Warning: Could not read array {full_path}: {e}")
+
+ # Note: Other node types (Table, etc.) would be handled here as needed
+
+ def _clean_hdf_name(self, name):
+ """
+ Clean HDF5 node name by removing dir_ and dict_ prefixes.
+
+ Parameters:
+ - name: HDF5 node name (may have dir_ or dict_ prefix)
+
+ Returns:
+ - Cleaned name with prefixes removed
+ """
+ if name.startswith("dir_"):
+ return name[4:] # Remove "dir_" prefix
+ elif name.startswith("dict_"):
+ return name[5:] # Remove "dict_" prefix
+ else:
+ return name
+
+ @classmethod
+ def load_hdf5(cls, filename):
+ """
+ Load a DAMARIS HDF5 file and return DataPool and metadata.
+
+ Parameters:
+ - filename: Path to HDF5 file
+
+ Returns:
+ - tuple: (DataPool instance, metadata dict)
+
+ metadata dict contains:
+ - 'scripts': dict with experiment scripts and spool info
+ - 'log': log data if available
+ - 'timeline': timeline data if available
+ """
+ # Validate file
+ if not tables.is_pytables_file(filename):
+ raise Exception(f"File {filename} is not a valid PyTables HDF5 file")
+
+ # Create DataPool and load data
+ data_pool = cls()
+
+ try:
+ hdf_file = tables.open_file(filename, mode="r")
+
+ # Load main data pool
+ if "/data_pool" in hdf_file:
+ data_pool.read_from_hdf(hdf_file, where="/data_pool")
+
+ # Extract metadata
+ metadata = {}
+
+ # Load scripts
+ if "/scripts" in hdf_file:
+ scripts_group = hdf_file.get_node("/scripts")
+ scripts_data = {}
+ # Use _v_children to get node names safely
+ if hasattr(scripts_group, '_v_children'):
+ for node_name, node in scripts_group._v_children.items():
+ try:
+ if hasattr(node, 'read'):
+ data = node.read()
+ # Handle numpy string arrays and other types
+ if hasattr(data, 'decode'):
+ # bytes or numpy bytes
+ scripts_data[node_name] = data.decode('utf-8', errors='replace')
+ elif hasattr(data, 'tolist'):
+ # numpy array
+ scripts_data[node_name] = str(data.tolist())
+ elif isinstance(data, (str, bytes)):
+ # string or bytes
+ if isinstance(data, bytes):
+ scripts_data[node_name] = data.decode('utf-8', errors='replace')
+ else:
+ scripts_data[node_name] = data
+ else:
+ scripts_data[node_name] = str(data)
+ except Exception as e:
+ print(f"Warning: Could not read script {node_name}: {e}")
+ metadata['scripts'] = scripts_data
+
+ # Load log
+ if "/log" in hdf_file:
+ try:
+ log_node = hdf_file.get_node("/log")
+ metadata['log'] = log_node.read()
+ except Exception as e:
+ print(f"Warning: Could not read log: {e}")
+
+ # Load timeline
+ if "/timeline" in hdf_file:
+ try:
+ timeline_node = hdf_file.get_node("/timeline")
+ metadata['timeline'] = timeline_node.read()
+ except Exception as e:
+ print(f"Warning: Could not read timeline: {e}")
+
+ return data_pool, metadata
+
+ except Exception as e:
+ raise Exception(f"Failed to load HDF5 file {filename}: {e}")
+ finally:
+ if 'hdf_file' in locals():
+ hdf_file.close()
+
def register_listener(self, listening_function):
self.__registered_listeners.append(listening_function)
diff --git a/src/damaris/data/__init__.py b/src/damaris/data/__init__.py
index 86bb2ca..8028bb3 100644
--- a/src/damaris/data/__init__.py
+++ b/src/damaris/data/__init__.py
@@ -6,5 +6,5 @@ from damaris.data.Error_Result import Error_Result
from damaris.data.Config_Result import Config_Result
from damaris.data.Temperature import TemperatureResult
-__all__=["ADC_Result", "Accumulation", "MeasurementResult", "AccumulatedValue", "DataPool", "FFT", "Error_Result", "Config_Result", "TemperatureResult" ]
+__all__=["ADC_Result", "Accumulation", "MeasurementResult", "AccumulatedValue", "DataPool", "Error_Result", "Config_Result", "TemperatureResult" ]
diff --git a/src/damaris/experiments/Experiment.py b/src/damaris/experiments/Experiment.py
index 763db7d..9c0b954 100644
--- a/src/damaris/experiments/Experiment.py
+++ b/src/damaris/experiments/Experiment.py
@@ -96,12 +96,10 @@ class Experiment:
#for tracking the experiment length:
#because loops are possible we need to track the length for each loop level
- self.total_time=[]
- self.total_time.append(0.0)
+ self.total_time=[0.0]
#and we need to know the number of iterations of the loops to multiply the state.
- self.loop_iterations=[]
- self.loop_iterations.append(1)
+ self.loop_iterations=[1]
# Commands -------------------------------------------------------------------------------------
diff --git a/src/damaris/gui/DamarisGUI.py b/src/damaris/gui/DamarisGUI.py
index bb546ad..e5724b7 100644
--- a/src/damaris/gui/DamarisGUI.py
+++ b/src/damaris/gui/DamarisGUI.py
@@ -165,7 +165,7 @@ class DamarisGUI:
self.log = LogWindow( self.xml_gui , self)
- self.sw = ScriptWidgets( self.xml_gui )
+ self.sw = ScriptWidgets( self.xml_gui, self )
self.toolbar_init( )
@@ -214,6 +214,7 @@ class DamarisGUI:
"on_experiment_script_line_textfield_value_changed": self.sw.column_line_widgets_changed_event,
"on_experiment_script_column_textfield_value_changed": self.sw.column_line_widgets_changed_event,
"on_toolbar_open_file_button_clicked": self.sw.open_file,
+ "on_toolbar_open_hdf5_button_clicked": self.sw.open_hdf5,
"on_toolbar_new_button_clicked": self.sw.new_file,
"on_toolbar_save_as_button_clicked": self.sw.save_file_as,
"on_toolbar_save_file_button_clicked": self.sw.save_file,
@@ -293,6 +294,14 @@ class DamarisGUI:
self.config = None
self.xml_gui = None
+ def observe_data_pool( self, data_pool ):
+ """
+ Delegate to monitor widgets
+ """
+ self.data = data_pool
+ if hasattr(self, "monitor"):
+ self.monitor.observe_data_pool(data_pool)
+
# event handling: the real acitons in gui programming
# first global events
@@ -1099,11 +1108,12 @@ class LogWindow:
class ScriptWidgets:
- def __init__( self, xml_gui ):
+ def __init__( self, xml_gui, outer_space ):
"""
initialize text widgets with text
"""
self.xml_gui = xml_gui
+ self.outer_space = outer_space
# my states
# editing enabled/disabled
@@ -1568,7 +1578,7 @@ get_ylabel set_ylabel"""
elif response == gtk.ResponseType.CANCEL:
return 0
- def response( self, response_id, script_widget ):
+ def response( dialog, response_id, script_widget ):
if response_id == gtk.ResponseType.OK:
file_name = dialog.get_filename( )
if file_name is None:
@@ -1576,7 +1586,13 @@ get_ylabel set_ylabel"""
script_filename = os.path.abspath( file_name )
if not os.access( script_filename, os.R_OK ):
- self.outer_space.show_error_dialog( "File I/O Error", "Cannot read from file %s" % script_filename )
+ error_dialog = gtk.MessageDialog(parent=script_widget.xml_gui.get_object( "main_window"),
+ type=gtk.MessageType.ERROR,
+ flags=gtk.DialogFlags.MODAL,
+ buttons=("_OK", gtk.ResponseType.OK))
+ error_dialog.set_markup("Cannot read from file %s" % script_filename)
+ error_dialog.run()
+ error_dialog.destroy()
return True
script_string = script_widget.load_file_as_unicode( script_filename )
@@ -1609,6 +1625,94 @@ get_ylabel set_ylabel"""
return True
+ def open_hdf5( self, widget, Data=None ):
+ """
+ Open and load an HDF5 file written by DAMARIS.
+ """
+ # ignore
+ if not self.editing_state:
+ return 0
+
+ parent_window = self.xml_gui.get_object( "main_window" )
+ dialog = gtk.FileChooserDialog( title="Open HDF5 File...",
+ parent=parent_window,
+ action=gtk.FileChooserAction.OPEN,
+ buttons=("_Open", gtk.ResponseType.OK, "_Cancel", gtk.ResponseType.CANCEL)
+ )
+ dialog.set_default_response( gtk.ResponseType.OK )
+ dialog.set_select_multiple( False )
+
+ # Add filter for HDF5 files
+ filter_hdf5 = gtk.FileFilter()
+ filter_hdf5.set_name("HDF5 files")
+ filter_hdf5.add_pattern("*.h5")
+ filter_hdf5.add_pattern("*.hdf5")
+ filter_hdf5.add_pattern("*.HDF5")
+ filter_hdf5.add_pattern("*.H5")
+ dialog.add_filter(filter_hdf5)
+
+ # Also allow all files
+ filter_all = gtk.FileFilter()
+ filter_all.set_name("All files")
+ filter_all.add_pattern("*")
+ dialog.add_filter(filter_all)
+
+ def response( dialog, response_id, script_widget ):
+ if response_id == gtk.ResponseType.OK:
+ file_name = dialog.get_filename( )
+ if file_name is None:
+ return
+
+ file_name = os.path.abspath( file_name )
+ if not os.access( file_name, os.R_OK ):
+ error_dialog = gtk.MessageDialog(parent=script_widget.xml_gui.get_object( "main_window"),
+ type=gtk.MessageType.ERROR,
+ flags=gtk.DialogFlags.MODAL,
+ buttons=("_OK", gtk.ResponseType.OK))
+ error_dialog.set_markup("Cannot read from file %s" % file_name)
+ error_dialog.run()
+ error_dialog.destroy()
+ return True
+
+ try:
+ # Load DataPool and metadata from HDF5
+ data_pool, metadata = DataPool.load_hdf5(file_name)
+
+ # Set the loaded data pool in the outer space (main application)
+ if hasattr(script_widget.outer_space, 'observe_data_pool'):
+ script_widget.outer_space.observe_data_pool(data_pool)
+ elif hasattr(script_widget.outer_space, 'monitor'):
+ # Fallback if delegate not present
+ script_widget.outer_space.data = data_pool
+ script_widget.outer_space.monitor.observe_data_pool(data_pool)
+
+ # If there are scripts in metadata, load them
+ if 'scripts' in metadata:
+ scripts = metadata['scripts']
+ exp_script = scripts.get('experiment_script', None)
+ res_script = scripts.get('result_script', None)
+ if exp_script or res_script:
+ script_widget.set_scripts(exp_script, res_script)
+
+ except Exception as e:
+ error_dialog = gtk.MessageDialog(parent=script_widget.xml_gui.get_object( "main_window"),
+ type=gtk.MessageType.ERROR,
+ flags=gtk.DialogFlags.MODAL,
+ buttons=("_OK", gtk.ResponseType.OK))
+ error_dialog.set_markup("Failed to load HDF5 file: %s" % str(e))
+ error_dialog.run()
+ error_dialog.destroy()
+
+ return True
+
+ # Event-Handler for response-signal (when one of the button is pressed)
+ dialog.connect( "response", response, self )
+
+ dialog.run( )
+ dialog.destroy( )
+
+ return True
+
def save_file( self, widget=None, Data=None ):
"""
save file to associated filename
@@ -2409,7 +2513,7 @@ class MonitorWidgets:
def source_list_find_one( self, model, iter, what ):
"""find node in subcategory"""
while iter is not None:
- if model.get( iter, 0 )[ 0 ] == what:
+ if str( model.get( iter, 0 )[ 0 ] ) == what:
return iter
iter = model.iter_next( iter )
return iter
@@ -2480,31 +2584,50 @@ class MonitorWidgets:
register a listener and save reference to data
assume to be in gtk/gdk lock
"""
- if self.data_pool is not None:
- # maybe some extra cleanup needed
- print("ToDo: cleanup widgets")
- if self.displayed_data[ 1 ] is not None and hasattr( self.displayed_data[ 1 ], "unregister_listener" ):
- self.displayed_data[ 1 ].unregister_listener( self.datastructures_listener )
- self.displayed_data[ 1 ] = None
- self.displayed_data = [ None, None ]
- self.data_pool.unregister_listener( self.datapool_listener )
- self.data_pool = None
+ gdk.threads_enter( )
+ try:
+ if self.data_pool is not None:
+ # maybe some extra cleanup needed
+ print("ToDo: cleanup widgets")
+ if self.displayed_data[ 1 ] is not None and hasattr( self.displayed_data[ 1 ], "unregister_listener" ):
+ self.displayed_data[ 1 ].unregister_listener( self.datastructures_listener )
+ self.displayed_data[ 1 ] = None
+ self.displayed_data = [ None, None ]
+ self.data_pool.unregister_listener( self.datapool_listener )
+ self.data_pool = None
+ self.update_counter_lock.acquire( )
+ self.update_counter = 0
+ self.update_counter_lock.release( )
+
+ # display states
self.source_list_reset( )
- self.update_counter_lock.acquire( )
- self.update_counter = 0
- self.update_counter_lock.release( )
+ self.__rescale = True
+ self.displayed_data = [ None, None ]
+ self.display_source_path_label.set_label( "" )
+ self.clear_display( )
- # display states
- self.__rescale = True
- self.displayed_data = [ None, None ]
- self.display_source_path_label.set_label( "" )
- self.clear_display( )
-
- if data_pool is not None:
- # keep track of data
- self.data_pool = data_pool
- self.data_pool.register_listener( self.datapool_listener )
+ if data_pool is not None:
+ # keep track of data
+ self.data_pool = data_pool
+ self.data_pool.register_listener( self.datapool_listener )
+
+ # Populate source list with existing data since the listener
+ # was registered after the data was loaded
+ for key in sorted(data_pool.keys()):
+ if key != "__builtins__": # Skip internal keys
+ self.source_list_add(key)
+
+ # Select first data item if available
+ keys = [k for k in data_pool.keys() if not k.startswith("__")]
+ if keys:
+ keys.sort()
+ first_key = keys[0]
+ first_iter = self.source_list_find(first_key.split("/"))
+ if first_iter:
+ self.display_source_combobox.set_active_iter(first_iter)
+ finally:
+ gdk.threads_leave( )
#################### observing data structures and produce idle events
@@ -2641,7 +2764,7 @@ class MonitorWidgets:
gdk.threads_leave( )
elif event.what == DataPool.Event.destroy:
gdk.threads_enter( )
- self.source_list_reset( 'None' )
+ self.source_list_reset( )
self.displayed_data = [ None, None ]
self.clear_display( )
gdk.threads_leave( )
diff --git a/src/damaris/gui/damaris.glade b/src/damaris/gui/damaris.glade
deleted file mode 100644
index 568f65a..0000000
--- a/src/damaris/gui/damaris.glade
+++ /dev/null
@@ -1,2130 +0,0 @@
-
-
-
-
-
- True
- DAMARIS
- GTK_WIN_POS_CENTER
- 790
-
-
-
-
- True
- 3
-
-
- True
-
-
- True
- Creates an empty script
- New
- True
- gtk-new
-
-
-
- True
-
-
-
-
- True
- Opens a script
- Open
- True
- gtk-open
-
-
-
- True
-
-
-
-
- True
- Saves a script
- Save
- True
- gtk-save
-
-
-
- True
-
-
-
-
- True
- Saves a script in a new file
- Save AS
- True
- gtk-save-as
-
-
-
- True
-
-
-
-
- True
- Saves all scripts
- Save All
- True
- gtk-copy
-
-
-
- True
-
-
-
-
- True
- Checks script's syntax
- Check Syntax
- True
- gtk-apply
-
-
-
- True
-
-
-
-
- True
-
-
-
-
- True
- Undo
- gtk-undo
-
-
-
- True
-
-
-
-
- True
- Redo
- gtk-redo
-
-
-
- True
-
-
-
-
- True
- Search
- gtk-find
-
-
-
- True
-
-
-
-
- True
-
-
-
-
- True
- gtk-print
-
-
-
- True
-
-
-
-
- True
-
-
-
-
- True
- Executes the scripts
- True
- Execute
- True
- gtk-execute
-
-
-
- True
-
-
-
-
- True
-
-
- True
- False
- True
- False
- 0
-
-
-
- True
-
-
- True
- gtk-media-pause
- 3
-
-
-
-
- True
- Pause
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
-
-
- True
- False
- Stops running experiment
- True
- Stop
- True
- gtk-stop
-
-
-
- True
-
-
-
-
- True
-
-
-
-
- True
- This progam's documentation
- Help
- True
- gtk-info
- documentation_menu
-
-
-
-
-
-
-
-
-
-
- True
- True
-
-
-
- True
- 2
- 5
-
-
- True
- 0
- Column:
-
-
- 3
- 4
- 1
- 2
-
-
-
-
-
-
- True
- 0
- Line:
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- 0
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- GTK_SHADOW_IN
-
-
- True
- True
-
-
-
-
- 5
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 1 1 1 1 10 0
- 1
- True
-
-
-
- 2
- 3
- 1
- 2
-
-
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 1 1 1 1 10 0
- 1
- True
- True
-
-
-
- 4
- 5
- 1
- 2
-
-
-
-
-
-
-
-
- True
- Experiment Script
-
-
- tab
- False
-
-
-
-
- True
- 2
- 5
-
-
- True
- 0
- Column:
-
-
- 3
- 4
- 1
- 2
-
-
-
-
-
-
- True
- 0
- Line:
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- True
- GTK_SHADOW_IN
-
-
- True
- True
-
-
-
-
-
- 5
-
-
-
-
- True
- 0
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 1 1 1 1 10 0
- 1
- True
-
-
-
- 2
- 3
- 1
- 2
-
-
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- 1 1 1 1 10 0
- 1
- True
-
-
-
- 4
- 5
- 1
- 2
-
-
-
-
-
-
- 1
-
-
-
-
- True
- Result Script
-
-
- tab
- 1
- False
-
-
-
-
- True
- 3
- 6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- 1
- 0
-
-
- True
- 2
- 4
- 12
- 4
-
-
- True
- 2
- 4
-
-
- True
-
-
- True
- Source
-
-
- False
- False
-
-
-
-
- True
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
-
- True
- False
- lin
-log
-log10
-
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- 0
- y-Scaling
-
-
- 2
- 3
- 1
- 2
-
-
- 3
-
-
-
-
- True
- False
- lin
-log
-log10
-ppm
-
-
-
- 1
- 2
-
-
-
-
-
-
- True
- 0
- x-Scaling
-
-
- 2
- 3
-
-
- 3
-
-
-
-
- True
- 0
- in ...
-
-
- 1
- 2
-
-
-
-
-
- True
- 0
-
-
- 1
- 2
-
-
-
-
-
-
- True
- True
- Rescale graph if new ymax is larger than the old one or shrinked more than 20%
- Auto-Scaling
- True
- 0
- True
-
-
-
- 3
- 4
- 1
- 2
-
-
-
-
-
-
- True
- True
- Plot error-bars if result to plot uses statistic
- Show Statistics
- True
- 0
- True
-
-
-
- 3
- 4
-
-
-
-
-
-
-
-
-
-
- True
- Settings:
- True
-
-
- label_item
-
-
-
-
- 6
- 2
- 3
-
- 2
- 2
-
-
-
-
- True
- True
- Save display data as text to file
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-floppy
-
-
- False
- False
-
-
-
-
- True
- 10
- Save as text
- True
-
-
- False
- 1
-
-
-
-
-
-
-
-
- 5
- 6
- 1
- 2
-
- GTK_FILL
-
-
-
-
- True
- True
- Copy display data as text to clipboard
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-copy
-
-
- False
- False
-
-
-
-
- True
- 10
- Copy to Cipboard
- True
-
-
- False
- 1
-
-
-
-
-
-
-
-
- 4
- 5
- 1
- 2
-
- GTK_FILL
-
-
-
-
- 2
-
-
-
-
- True
- Display
-
-
- tab
- 2
- False
-
-
-
-
- True
- 2
-
-
- True
- 3
-
-
- True
- 0
-
-
- 2
- 3
-
- 4
-
-
-
-
- True
- 0
- Lines in Buffer: 0
- GTK_JUSTIFY_RIGHT
-
-
-
-
- 3
- 4
-
-
-
-
- True
- 0
- File: Unnamed
-
-
- 1
- 2
-
-
- 16
- 4
-
-
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- GTK_SHADOW_IN
-
-
- True
- True
- False
- GTK_WRAP_WORD
- False
- False
-
-
-
-
-
-
- 3
-
-
-
-
- True
- Log
- True
-
-
- tab
- 3
- False
-
-
-
-
- True
-
-
- True
-
-
- True
-
-
- True
- Backend's Settings
-
-
- False
- False
-
-
-
-
- True
- True
- start backend
- True
- 0
- True
- True
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
- True
- executable
-
-
- False
- False
-
-
-
-
- True
- True
- backend
-
-
- 1
-
-
-
-
- True
- True
- browse
- True
- 0
-
-
-
- False
- False
- 2
-
-
-
-
- 2
-
-
-
-
- True
-
-
- True
- spool directory
-
-
- False
- False
-
-
-
-
- True
- True
- spool
-
-
- 1
-
-
-
-
- 3
-
-
-
-
- True
- True
- delete job data after execution
- True
- 0
- True
- True
-
-
- False
- False
- 4
-
-
-
-
- True
-
-
- True
- log file name
-
-
- False
- False
-
-
-
-
- True
- True
- logdata
-
-
- 1
-
-
-
-
- 5
-
-
-
-
- True
-
-
- True
- maximum number of log files to keep
-
-
- False
- False
-
-
-
-
- True
- True
- False
- 4
- 3
- 10
-
-
- False
- 1
-
-
-
-
- 6
-
-
-
-
-
-
- True
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
- True
- Scripts' Settings
-
-
- False
- False
-
-
-
-
- True
- True
- start experiment script
- True
- 0
- True
- True
-
-
- False
- False
- 1
-
-
-
-
- True
- True
- start result script
- True
- 0
- True
- True
-
-
- False
- False
- 2
-
-
-
-
- True
- True
- delete result data after processing
- True
- 0
- True
- True
-
-
- False
- False
- 3
-
-
-
-
- 2
-
-
-
-
- False
- False
-
-
-
-
- True
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
- True
- HDF5 Data Pool's Settings
-
-
- False
- False
-
-
-
-
- True
-
-
- True
- data pool file name
-
-
- False
- False
-
-
-
-
- True
- True
- DAMARIS_data_pool.h5
-
-
- 1
-
-
-
-
- 1
-
-
-
-
- True
-
-
- True
- data pool write interval
-
-
- False
- False
-
-
-
-
- True
- True
- 10
- 10
- 60
-
-
- False
- 1
-
-
-
-
- True
- min, compression
-
-
- False
- False
- 2
-
-
-
-
- True
- None
-
-
-
- False
- False
- 3
-
-
-
-
- True
- , ratio
-
-
- False
- False
- 4
-
-
-
-
- True
- True
- 0 0 9 1 1 0
- 1
- True
-
-
- False
- False
- 5
-
-
-
-
-
-
-
- 2
-
-
-
-
- False
- 2
-
-
-
-
- True
-
-
- False
- 3
-
-
-
-
- True
-
-
- False
- False
- 4
-
-
-
-
- True
-
-
- True
- Frontend's Settings
-
-
- False
- False
-
-
-
-
- True
-
-
- True
- Script Windows Font
-
-
- False
- False
-
-
-
-
- True
- True
- 0
-
-
-
- False
- False
- 1
-
-
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
- True
- ToDo
-
-
- False
- False
- 3
-
-
-
-
- False
- 5
-
-
-
-
- True
-
-
- False
- False
- 6
-
-
-
-
- True
-
-
- True
- info, authors and disclaimer
-
-
- False
- False
-
-
-
-
- True
- True
- GTK_POLICY_NEVER
- GTK_SHADOW_IN
-
-
- True
- False
- GTK_WRAP_WORD_CHAR
- False
- DAMARIS python frontend version %(damarisversion)s, 2012
-%(moduleversions)s
-
-DArmstadt Magnetic Resonance Instrument Software, 2004-2012
-Homepage https://element.fkp.physik.tu-darmstadt.de/damaris_cms/
-
-Python frontend written by Christopher Schmitt, Achim Gädke, Markus Rosenstihl and Christian Tacke
-Backends written by Achim Gädke, Markus Rosenstihl, Christian Tacke, tested by Holger Stork
-The drivers included in the backend may use proprietary interfaces.
-The source code distribution may include commercial third party's code,
-which is specially marked and not covered by this license.
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
-
-
-
-
-
- 1
-
-
-
-
- 7
-
-
-
-
- True
-
-
- True
- True
- True
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-floppy
-
-
- False
- False
-
-
-
-
- True
- save configuration
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
-
-
-
-
- True
- True
- True
- 0
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-refresh
-
-
- False
- False
-
-
-
-
- True
- reload configuration
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
- 1
-
-
-
-
- False
- False
- 8
-
-
-
-
- 4
-
-
-
-
- True
- Configuration
-
-
- tab
- 4
- False
-
-
-
-
- 1
- 2
-
-
-
-
- True
- 8
-
-
- True
-
-
- 6
- 7
-
- 5
-
-
-
-
- True
-
-
-
- 3
-
-
-
-
- True
-
-
- 4
- 5
-
- 5
-
-
-
-
- True
-
-
- 2
- 3
-
- 5
-
-
-
-
- True
- Backend: Idle.
-
-
- 3
- 4
-
-
-
-
-
-
- 20
- True
- Experiment Script: Idle.
-
-
- 1
- 2
-
-
-
-
-
-
- True
- Result Script: Idle.
-
-
- 5
- 6
-
-
-
-
-
-
- True
- 0
-
-
-
- 7
- 8
-
-
-
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
-
-
-
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
-
-
- True
- This program's documentation
- Python DAMARIS
- True
-
-
-
-
-
- True
- DArmstadt MAgnetic Resonance Instrument Homepage
- DAMARIS Homepage
- True
-
-
-
-
-
- 2
- True
-
-
-
-
- True
- Python scripting Language
- Python
- True
-
-
-
-
-
- True
- Array and Numeric Processing Support
- numpy/scipy
- True
-
-
-
-
-
- True
- Hierachical Data Format Support
- pytables
- True
-
-
-
-
-
- 2
- True
-
-
-
-
- True
- (developer's stuff)
- DAMARIS Backends
- True
-
-
-
-
-
- True
- (developers' stuff)
- DAMARIS Repository
- True
-
-
-
-
-
diff --git a/src/damaris/gui/damaris.gladep b/src/damaris/gui/damaris.gladep
deleted file mode 100644
index 19cf0e7..0000000
--- a/src/damaris/gui/damaris.gladep
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- damaris-gui
- damaris
- FALSE
-
diff --git a/src/damaris/gui/damaris.xml b/src/damaris/gui/damaris.xml
deleted file mode 100644
index 26c7c83..0000000
--- a/src/damaris/gui/damaris.xml
+++ /dev/null
@@ -1,2177 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- DAMARIS
- GTK_WIN_POS_CENTER
- 790
-
-
-
-
- True
- 3
-
-
- True
-
-
- True
- Creates an empty script
- New
- True
- gtk-new
-
-
-
- True
-
-
-
-
- True
- Opens a script
- Open
- True
- gtk-open
-
-
-
- True
-
-
-
-
- True
- Saves a script
- Save
- True
- gtk-save
-
-
-
- True
-
-
-
-
- True
- Saves a script in a new file
- Save AS
- True
- gtk-save-as
-
-
-
- True
-
-
-
-
- True
- Saves all scripts
- Save All
- True
- gtk-copy
-
-
-
- True
-
-
-
-
- True
- Checks script's syntax
- Check Syntax
- True
- gtk-apply
-
-
-
- True
-
-
-
-
- True
-
-
-
-
- True
- Undo
- gtk-undo
-
-
-
- True
-
-
-
-
- True
- Redo
- gtk-redo
-
-
-
- True
-
-
-
-
- True
- Search
- gtk-find
-
-
-
- True
-
-
-
-
- True
-
-
-
-
-
-
-
- True
-
-
-
-
- True
- Executes the scripts
- True
- Execute
- True
- gtk-execute
-
-
-
- True
-
-
-
-
- True
-
-
- True
- False
- True
- False
-
-
-
- True
-
-
- True
- gtk-media-pause
- 3
-
-
-
-
- True
- Pause
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
-
-
- True
- False
- Stops running experiment
- True
- Stop
- True
- gtk-stop
-
-
-
- True
-
-
-
-
- True
-
-
-
-
- True
- This progam's documentation
- Help
- True
- gtk-info
- documentation_menu
-
-
-
-
-
-
-
-
-
-
- True
- True
-
-
-
- True
- 2
- 5
-
-
- True
- 0
- Column:
-
-
- 3
- 4
- 1
- 2
-
-
-
-
-
-
- True
- 0
- Line:
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- 0
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- GTK_SHADOW_IN
-
-
- True
- True
-
-
-
-
-
- 5
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- adjustment1
- 1
- True
-
-
-
- 2
- 3
- 1
- 2
-
-
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- adjustment2
- 1
- True
- True
-
-
-
- 4
- 5
- 1
- 2
-
-
-
-
-
-
-
-
- True
- Experiment Script
-
-
- False
-
-
-
-
- True
- 2
- 5
-
-
- True
- 0
- Column:
-
-
- 3
- 4
- 1
- 2
-
-
-
-
-
-
- True
- 0
- Line:
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- True
- GTK_SHADOW_IN
-
-
- True
- True
-
-
-
-
-
- 5
-
-
-
-
- True
- 0
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- adjustment3
- 1
- True
-
-
-
- 2
- 3
- 1
- 2
-
-
-
-
-
-
- True
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- adjustment4
- 1
- True
-
-
-
- 4
- 5
- 1
- 2
-
-
-
-
-
-
-
-
- True
- Result Script
-
-
- 1
- False
-
-
-
-
- True
- 3
- 6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- 1
- 0
-
-
- True
- 2
- 4
- 12
- 4
-
-
- True
- 2
- 4
-
-
- True
-
-
- True
- Source
-
-
- False
- False
-
-
-
-
- True
- False
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
-
- True
- False
-
- model1
-
-
- 1
- 2
- 1
- 2
-
-
-
-
-
-
- True
- 0
- y-Scaling
-
-
- 2
- 3
- 1
- 2
-
-
- 3
-
-
-
-
- True
- False
-
- model2
-
-
- 1
- 2
-
-
-
-
-
-
- True
- 0
- x-Scaling
-
-
- 2
- 3
-
-
- 3
-
-
-
-
- True
- 0
- in ...
-
-
- 1
- 2
-
-
-
-
-
- True
- 0
-
-
- 1
- 2
-
-
-
-
-
-
- True
- True
- Rescale graph if new ymax is larger than the old one or shrinked more than 20%
- Auto-Scaling
- True
- True
-
-
-
- 3
- 4
- 1
- 2
-
-
-
-
-
-
- True
- True
- Plot error-bars if result to plot uses statistic
- Show Statistics
- True
- True
-
-
-
- 3
- 4
-
-
-
-
-
-
-
-
-
-
- True
- Settings:
- True
-
-
-
-
- 6
- 2
- 3
-
- 2
- 2
-
-
-
-
- True
- True
- Save display data as text to file
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-floppy
-
-
- False
- False
-
-
-
-
- True
- 10
- Save as text
- True
-
-
- False
- 1
-
-
-
-
-
-
-
-
- 5
- 6
- 1
- 2
-
- GTK_FILL
-
-
-
-
- True
- True
- Copy display data as text to clipboard
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-copy
-
-
- False
- False
-
-
-
-
- True
- 10
- Copy to Cipboard
- True
-
-
- False
- 1
-
-
-
-
-
-
-
-
- 4
- 5
- 1
- 2
-
- GTK_FILL
-
-
-
-
-
-
- True
- Display
-
-
- 2
- False
-
-
-
-
- True
- 2
-
-
- True
- 3
-
-
- True
- 0
-
-
- 2
- 3
-
- 4
-
-
-
-
- True
- 0
- Lines in Buffer: 0
- GTK_JUSTIFY_RIGHT
-
-
-
-
- 3
- 4
-
-
-
-
- True
- 0
- File: Unnamed
-
-
- 1
- 2
-
-
- 16
- 4
-
-
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- GTK_SHADOW_IN
-
-
- True
- True
- False
- GTK_WRAP_WORD
- False
- False
-
-
-
-
-
-
-
-
- True
- Log
- True
-
-
- 3
- False
-
-
-
-
- True
-
-
- True
-
-
- True
-
-
- True
- Backend's Settings
-
-
- False
- False
-
-
-
-
- True
- True
- start backend
- True
- True
- True
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
- True
- executable
-
-
- False
- False
-
-
-
-
- True
- True
- backend
-
-
- 1
-
-
-
-
- True
- True
- browse
- True
-
-
-
- False
- False
- 2
-
-
-
-
- 2
-
-
-
-
- True
-
-
- True
- spool directory
-
-
- False
- False
-
-
-
-
- True
- True
- spool
-
-
- 1
-
-
-
-
- 3
-
-
-
-
- True
- True
- delete job data after execution
- True
- True
- True
-
-
- False
- False
- 4
-
-
-
-
- True
-
-
- True
- log file name
-
-
- False
- False
-
-
-
-
- True
- True
- logdata
-
-
- 1
-
-
-
-
- 5
-
-
-
-
- True
-
-
- True
- maximum number of log files to keep
-
-
- False
- False
-
-
-
-
- True
- True
- False
- 4
- 3
- 10
-
-
- False
- 1
-
-
-
-
- 6
-
-
-
-
-
-
- True
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
- True
- Scripts' Settings
-
-
- False
- False
-
-
-
-
- True
- True
- start experiment script
- True
- True
- True
-
-
- False
- False
- 1
-
-
-
-
- True
- True
- start result script
- True
- True
- True
-
-
- False
- False
- 2
-
-
-
-
- True
- True
- delete result data after processing
- True
- True
- True
-
-
- False
- False
- 3
-
-
-
-
- 2
-
-
-
-
- False
- False
-
-
-
-
- True
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
- True
- HDF5 Data Pool's Settings
-
-
- False
- False
-
-
-
-
- True
-
-
- True
- data pool file name
-
-
- False
- False
-
-
-
-
- True
- True
- DAMARIS_data_pool.h5
-
-
- 1
-
-
-
-
- 1
-
-
-
-
- True
-
-
- True
- data pool write interval
-
-
- False
- False
-
-
-
-
- True
- True
- 10
- 10
- 60
-
-
- False
- 1
-
-
-
-
- True
- min, compression
-
-
- False
- False
- 2
-
-
-
-
- True
- model3
-
-
- False
- False
- 3
-
-
-
-
- True
- , ratio
-
-
- False
- False
- 4
-
-
-
-
- True
- True
- adjustment5
- 1
- True
-
-
- False
- False
- 5
-
-
-
-
-
-
-
- 2
-
-
-
-
- False
- 2
-
-
-
-
- True
-
-
- False
- 3
-
-
-
-
- True
-
-
- False
- False
- 4
-
-
-
-
- True
-
-
- True
- Frontend's Settings
-
-
- False
- False
-
-
-
-
- True
-
-
- True
- Script Windows Font
-
-
- False
- False
-
-
-
-
- True
- True
-
-
-
- False
- False
- 1
-
-
-
-
- False
- False
- 1
-
-
-
-
- True
-
-
-
-
-
- 2
-
-
-
-
- True
- ToDo
-
-
- False
- False
- 3
-
-
-
-
- False
- 5
-
-
-
-
- True
-
-
- False
- False
- 6
-
-
-
-
- True
-
-
- True
- info, authors and disclaimer
-
-
- False
- False
-
-
-
-
- True
- True
- GTK_POLICY_NEVER
- GTK_SHADOW_IN
-
-
- True
- False
- GTK_WRAP_WORD_CHAR
- False
- textbuffer1
-
-
-
-
- 1
-
-
-
-
- 7
-
-
-
-
- True
-
-
- True
- True
- True
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-floppy
-
-
- False
- False
-
-
-
-
- True
- save configuration
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
-
-
-
-
- True
- True
- True
-
-
-
- True
- 0
- 0
-
-
- True
- 2
-
-
- True
- gtk-refresh
-
-
- False
- False
-
-
-
-
- True
- reload configuration
- True
-
-
- False
- False
- 1
-
-
-
-
-
-
-
-
- False
- False
- 1
-
-
-
-
- False
- False
- 8
-
-
-
-
-
-
- True
- Configuration
-
-
- 4
- False
-
-
-
-
- 1
- 2
-
-
-
-
- True
- 8
-
-
- True
-
-
- 6
- 7
-
- 5
-
-
-
-
- True
-
-
-
- 3
-
-
-
-
- True
-
-
- 4
- 5
-
- 5
-
-
-
-
- True
-
-
- 2
- 3
-
- 5
-
-
-
-
- True
- Backend: Idle.
-
-
- 3
- 4
-
-
-
-
-
-
- 20
- True
- Experiment Script: Idle.
-
-
- 1
- 2
-
-
-
-
-
-
- True
- Result Script: Idle.
-
-
- 5
- 6
-
-
-
-
-
-
- True
- 0
-
-
-
- 7
- 8
-
-
-
-
-
- 2
- 3
- GTK_FILL
-
-
-
-
-
-
-
- True
- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
-
-
diff --git a/src/damaris/gui/damaris3.glade b/src/damaris/gui/damaris3.glade
index 42bbde0..a91e401 100644
--- a/src/damaris/gui/damaris3.glade
+++ b/src/damaris/gui/damaris3.glade
@@ -491,6 +491,21 @@ Public License instead of this License.
True
+
+
+ True
+ False
+ Open DAMARIS HDF5 file
+ Open HDF5
+ True
+ document-open
+
+
+
+ False
+ True
+
+ True