mailr27022 - in /branches/nmrglue: data_store/ pipe_control/


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by edward on December 08, 2014 - 17:40:
Author: bugman
Date: Mon Dec  8 17:40:35 2014
New Revision: 27022

URL: http://svn.gna.org/viewcvs/relax?rev=27022&view=rev
Log:
Full support for saving and loading nmrglue data in the relax data store.

This is for XML formatted relax state and results files.  The implementation 
was complicated as a
special data_store.data_classes.RelaxDictType object with to_xml() and 
from_xml() method has been
introduced to handle custom dictionary-type objects.

The cdp.nmrglue object is the data_store.nmrglue.Nmrglue_dict object which 
inherits from the
RelaxDictType object.  This has elements set to data_store.nmrglue.Nmrglue 
instances.  This Nmrglue
object inherits from data_store.data_classes.Element, however the to_xml() 
and from_xml() methods
have been copied and modified for this special object.  This Nmrglue 
container has three main
attributes, the nmrglue dic, udic, and data objects.

The Nmrglue to_xml() and from_xml() methods handle the 'data' object by 
encoding and decoding it in
the Base64 string format.  All the other objects are handled by the 
fill_object_contents() or
xml_to_object() functions of lib.xml.


Modified:
    branches/nmrglue/data_store/data_classes.py
    branches/nmrglue/data_store/nmrglue.py
    branches/nmrglue/data_store/pipe_container.py
    branches/nmrglue/pipe_control/nmrglue.py

Modified: branches/nmrglue/data_store/data_classes.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/nmrglue/data_store/data_classes.py?rev=27022&r1=27021&r2=27022&view=diff
==============================================================================
--- branches/nmrglue/data_store/data_classes.py (original)
+++ branches/nmrglue/data_store/data_classes.py Mon Dec  8 17:40:35 2014
@@ -162,6 +162,110 @@
         # Execute the object to_xml() methods.
         for obj in to_xml_list:
             obj.to_xml(doc, cont_element)
+
+
+
+class RelaxDictType(dict):
+    """An empty dict type container."""
+
+    def __init__(self):
+        """Initialise some class variables."""
+
+        # Execute the base class __init__() method.
+        super(RelaxDictType, self).__init__()
+
+        # Some generic initial names.
+        self.dict_name = 'relax_dict'
+        self.dict_desc = 'relax dict container'
+        self.element_name = 'relax_dict_element'
+        self.element_desc = 'relax container'
+
+        # Blacklisted objects.
+        self.blacklist = []
+
+
+    def from_xml(self, super_node, file_version=1):
+        """Recreate the data structure from the XML node.
+
+        @param super_node:      The XML nodes.
+        @type super_node:       xml.dom.minicompat.Element instance
+        @keyword file_version:  The relax XML version of the XML file.
+        @type file_version:     int
+        """
+
+        # Recreate all the data structures.
+        xml_to_object(super_node, self, file_version=file_version, 
blacklist=self.blacklist)
+
+        # Get the individual elements.
+        nodes = super_node.getElementsByTagName(self.element_name)
+
+        # Loop over the child nodes (each element).
+        for node in nodes:
+            # Get the key.
+            key = str(node.getAttribute('key'))
+            key = key.strip("'")
+
+            # Add the data container.
+            self.add_item(key=key, node=node, file_version=file_version)
+
+
+    def to_xml(self, doc, element):
+        """Create an XML element for the dict data structure.
+
+        @param doc:     The XML document object.
+        @type doc:      xml.dom.minidom.Document instance
+        @param element: The element to add the dict data structure XML 
element to.
+        @type element:  XML element object
+        """
+
+        # Create the element and add it to the higher level element.
+        dict_element = doc.createElement(self.dict_name)
+        element.appendChild(dict_element)
+
+        # Set the dict attributes.
+        dict_element.setAttribute('desc', self.dict_desc)
+
+        # Blacklisted objects.
+        blacklist = ['dict_name', 'dict_desc', 'element_name', 
'element_desc', 'blacklist'] + list(self.__dict__.keys()) + 
list(RelaxListType.__dict__.keys()) + list(self.__class__.__dict__.keys()) + 
list(dict.__dict__.keys()) + list(dict.__dict__.keys())
+
+        # Add all simple python objects within the list to the list element.
+        fill_object_contents(doc, dict_element, object=self, 
blacklist=blacklist)
+
+        # Loop over the keys.
+        for key in self:
+            # Create an XML element for each container.
+            dict_item_element = doc.createElement(self.element_name)
+            dict_element.appendChild(dict_item_element)
+            dict_item_element.setAttribute('key', repr(key))
+            dict_item_element.setAttribute('desc', self.element_desc)
+
+            # The element has its own to_xml() method.
+            if hasattr(self[key], 'to_xml'):
+                self[key].to_xml(doc, dict_item_element)
+
+            # Normal element.
+            else:
+                # Blacklisted objects.
+                blacklist = list(self[key].__class__.__dict__.keys())
+
+                # Add objects which have to_xml() methods.
+                for name in dir(self[key]):
+                    # Skip blacklisted objects.
+                    if name in blacklist:
+                        continue
+
+                    # Skip special objects.
+                    if search('^_', name):
+                        continue
+
+                    # Execute any to_xml() methods, and add that object to 
the blacklist.
+                    obj = getattr(self[key], name)
+                    if hasattr(obj, 'to_xml'):
+                        obj.to_xml(doc, list_item_element)
+                        blacklist = blacklist + [name]
+
+                # Add all simple python objects within the container to the 
XML element.
+                fill_object_contents(doc, dict_item_element, 
object=self[key], blacklist=blacklist)
 
 
 

Modified: branches/nmrglue/data_store/nmrglue.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/nmrglue/data_store/nmrglue.py?rev=27022&r1=27021&r2=27022&view=diff
==============================================================================
--- branches/nmrglue/data_store/nmrglue.py      (original)
+++ branches/nmrglue/data_store/nmrglue.py      Mon Dec  8 17:40:35 2014
@@ -25,14 +25,43 @@
 # Python module imports.
 from base64 import b64encode, decodestring
 from numpy import float32, frombuffer
+from re import search
 
 # relax module imports.
-from data_store.data_classes import Element
-from lib.xml import object_to_xml, xml_to_object
+from data_store.data_classes import Element, RelaxDictType
+from lib.xml import fill_object_contents, xml_to_object
 
 
 class Nmrglue(Element):
     """Container for the global GUI data structures."""
+
+    def __repr__(self):
+        # Header.
+        text = "%-25s%-100s\n\n" % ("Data structure", "Value")
+
+        # Data structures.
+        for name in dir(self):
+            # Skip Nmrglue and derived class methods.
+            if name in Nmrglue.__dict__ or name in self.__class__.__dict__:
+                continue
+
+            # Skip special objects.
+            if search("^_", name):
+                continue
+
+            # Get the object.
+            obj = getattr(self, name)
+
+            # The data.
+            if name == 'data':
+                obj = obj.shape
+
+            # Generate the text.
+            text = text + "%-25s %-100s\n" % (name, repr(obj))
+
+        # Return the lot.
+        return text
+
 
     def __init__(self, dic=None, udic=None, data=None):
         """Initialise the container info.
@@ -52,6 +81,7 @@
         self.dic = dic
         self.udic = udic
         self.data = data
+        self.element_name = 'nmrglue_container'
 
 
     def from_xml(self, nmrglue_node, file_version=1):
@@ -67,21 +97,25 @@
         data_nodes = nmrglue_node.getElementsByTagName('data')
 
         # Loop over the info nodes of the Python object.
-        for sub_node in node.childNodes:
-            # Get the value.
-            if sub_node.localName == 'value':
+        for sub_node in nmrglue_node.childNodes:
+            # Get the numpy data.
+            if sub_node.localName == 'data':
+                # Get the value node.
+                value_node = sub_node.getElementsByTagName('value')[0]
+
                 # Convert from Base64 to numpy.float32.
-                buffer = decodestring(sub_node.childNodes[0])
-                self.data = frombuffer(buffer, dtype=np.float32)
+                value = value_node.childNodes[0].nodeValue.strip()
+                buffer = decodestring(value)
+                self.data = frombuffer(buffer, dtype=float32)
 
                 # The shape attribute.
-                shape = eval(node.getAttribute('shape'))
+                shape = eval(sub_node.getAttribute('shape'))
 
                 # Reshape the data.
-                self.data.reshape(shape)
+                self.data = self.data.reshape(shape)
 
         # Recreate all the other data structures.
-        xml_to_object(gui_node, self, file_version=file_version, 
blacklist=['data'])
+        xml_to_object(nmrglue_node, self, file_version=file_version, 
blacklist=['data'])
 
 
     def to_xml(self, doc, element):
@@ -93,18 +127,69 @@
         @type element:  XML element object
         """
 
-        # Call the parent class method for all but the data variable.
-        self.blacklist.append('data')
-        super(Nmrglue, self).to_xml(doc, element)
+        # Create an XML element for the numpy data.
+        data_elem = doc.createElement('data')
+        element.appendChild(data_elem)
 
         # Convert the data into a Base64 string.
         string = b64encode(self.data)
 
         # Store the value as the string.
         val_elem = doc.createElement('value')
-        element.appendChild(val_elem)
+        data_elem.appendChild(val_elem)
         val_elem.appendChild(doc.createTextNode(string))
 
         # Set the type and shape as attributes.
-        element.setAttribute('type', 'base64, numpy.float32')
-        element.setAttribute('shape', repr(self.data.shape))
+        data_elem.setAttribute('type', 'base64, numpy.float32')
+        data_elem.setAttribute('shape', repr(self.data.shape))
+
+        # Add all simple Python objects within the container to the XML 
element.
+        fill_object_contents(doc, element, object=self, blacklist=['name', 
'desc', 'blacklist', 'data', 'is_empty', 'element_name'] + 
list(Nmrglue.__dict__.keys()) + list(self.__class__.__dict__.keys()))
+
+
+
+class Nmrglue_dict(RelaxDictType):
+    """The main storage structure for all nmrglue data."""
+
+    def __init__(self):
+        """Initialise the class."""
+
+        # Call the base class method.
+        super(Nmrglue_dict, self).__init__()
+
+        # The metadata.
+        self.dict_name = 'nmrglue'
+        self.dict_desc = 'main storage for nmrglue data'
+        self.element_name = 'nmrglue_container'
+        self.element_desc = 'nmrglue container'
+
+        # Blacklist.
+        self.blacklist.append('nmrglue_container')
+
+
+    def from_xml(self, super_node, file_version=1):
+        """Recreate the data structure from the XML node.
+
+        @param super_node:      The XML nodes.
+        @type super_node:       xml.dom.minicompat.Element instance
+        @keyword file_version:  The relax XML version of the XML file.
+        @type file_version:     int
+        """
+
+        # Recreate all the data structures.
+        xml_to_object(super_node, self, file_version=file_version, 
blacklist=self.blacklist)
+
+        # Get the individual elements.
+        nodes = super_node.getElementsByTagName(self.element_name)
+
+        # Loop over the child nodes (each element).
+        for node in nodes:
+            # Get the key.
+            key = str(node.getAttribute('key'))
+            key = key.strip("'")
+
+            # Create a new element.
+            self[key] = Nmrglue()
+
+            # Recreate from the XML.
+            self[key].from_xml(node, file_version=file_version)

Modified: branches/nmrglue/data_store/pipe_container.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/nmrglue/data_store/pipe_container.py?rev=27022&r1=27021&r2=27022&view=diff
==============================================================================
--- branches/nmrglue/data_store/pipe_container.py       (original)
+++ branches/nmrglue/data_store/pipe_container.py       Mon Dec  8 17:40:35 
2014
@@ -31,6 +31,7 @@
 from data_store.exp_info import ExpInfo
 from data_store.interatomic import InteratomList
 from data_store.mol_res_spin import MoleculeList
+from data_store.nmrglue import Nmrglue, Nmrglue_dict
 from data_store.prototype import Prototype
 from lib.errors import RelaxFromXMLNotEmptyError
 from lib.structure.internal.object import Internal
@@ -224,6 +225,15 @@
             # Fill its contents.
             self.align_tensors.from_xml(align_tensor_nodes[0], 
file_version=file_version)
 
+        # Get the nmrglue data nodes and, if they exist, fill the contents.
+        nmrglue_nodes = pipe_node.getElementsByTagName('nmrglue')
+        if nmrglue_nodes:
+            # Create the data container.
+            self.nmrglue = Nmrglue_dict()
+
+            # Fill its contents.
+            self.nmrglue.from_xml(nmrglue_nodes[0], 
file_version=file_version)
+
         # Recreate the interatomic data structure (this needs to be before 
the 'mol' structure as the backward compatibility hooks can create 
interatomic data containers!).
         interatom_nodes = pipe_node.getElementsByTagName('interatomic')
         self.interatomic.from_xml(interatom_nodes, file_version=file_version)
@@ -303,7 +313,7 @@
         global_element = doc.createElement('global')
         element.appendChild(global_element)
         global_element.setAttribute('desc', 'Global data located in the top 
level of the data pipe')
-        fill_object_contents(doc, global_element, object=self, 
blacklist=['align_tensors', 'diff_tensor', 'exp_info', 'interatomic', 
'hybrid_pipes', 'mol', 'pipe_type', 'structure'] + 
list(self.__class__.__dict__.keys()))
+        fill_object_contents(doc, global_element, object=self, 
blacklist=['align_tensors', 'diff_tensor', 'exp_info', 'interatomic', 
'hybrid_pipes', 'mol', 'pipe_type', 'structure', 'nmrglue'] + 
list(self.__class__.__dict__.keys()))
 
         # Hybrid info.
         self.xml_create_hybrid_element(doc, element)
@@ -319,6 +329,10 @@
         # Add the alignment tensor data.
         if hasattr(self, 'align_tensors'):
             self.align_tensors.to_xml(doc, element)
+
+        # Add the experimental information.
+        if hasattr(self, 'nmrglue'):
+            self.nmrglue.to_xml(doc, element)
 
         # Add the molecule-residue-spin data.
         self.mol.to_xml(doc, element, pipe_type=pipe_type)

Modified: branches/nmrglue/pipe_control/nmrglue.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/nmrglue/pipe_control/nmrglue.py?rev=27022&r1=27021&r2=27022&view=diff
==============================================================================
--- branches/nmrglue/pipe_control/nmrglue.py    (original)
+++ branches/nmrglue/pipe_control/nmrglue.py    Mon Dec  8 17:40:35 2014
@@ -23,30 +23,32 @@
 """Module for the using of nmrglue."""
 
 # relax module imports.
+from data_store.nmrglue import Nmrglue, Nmrglue_dict
 from lib.errors import RelaxError
 from lib.software.nmrglue import contour_plot, hist_plot, read_spectrum
 from pipe_control.pipes import check_pipe
 from pipe_control.spectrum import check_spectrum_id, delete
 
 
-def add_nmrglue_data(object_name=None, nmrglue_id=None, nmrglue_data=None):
+def add_nmrglue_data(nmrglue_id=None, dic=None, udic=None, data=None):
     """Add the nmrglue data to the data store under the the given 
object_name within a dictionary with nmrglue_id key.
 
-    @keyword object_name:       The object name for where to store the data. 
 As cdp.object_name.
-    @type object_name:          str
-    @keyword nmrglue_id:        The dictionary key, to access the data.  As 
As cdp.object_name['nmrglue_id']
-    @type nmrglue_id:           str
-    @keyword nmrglue_data:      The type of data depending on called 
function.
-    @type nmrglue_data:         depend on function
+    @keyword nmrglue_id:    The dictionary key, to access the data as 
cdp.nmrglue['nmrglue_id'].
+    @type nmrglue_id:       str
+    @keyword dic:           The dic structure from nmrglue.
+    @type dic:              dict
+    @keyword udic:          The dic structure from nmrglue.
+    @type udic:             dict
+    @keyword data:          The type of data depending on called function.
+    @type data:             depend on function
     """
 
     # Initialise the structure, if needed.
-    if not hasattr(cdp, object_name):
-        setattr(cdp, object_name, {})
+    if not hasattr(cdp, 'nmrglue'):
+        cdp.nmrglue = Nmrglue_dict()
 
     # Add the data under the dictionary key.
-    obj_dict = getattr(cdp, object_name)
-    obj_dict[nmrglue_id] = nmrglue_data
+    cdp.nmrglue[nmrglue_id] = Nmrglue(dic=dic, udic=udic, data=data)
 
 
 def add_nmrglue_id(nmrglue_id=None):
@@ -130,9 +132,7 @@
         dic, udic, data = read_spectrum(file=file_i, dir=dir)
 
         # Store the data.
-        add_nmrglue_data(object_name='nmrglue_dic', nmrglue_id=nmrglue_id_i, 
nmrglue_data=dic)
-        add_nmrglue_data(object_name='nmrglue_udic', 
nmrglue_id=nmrglue_id_i, nmrglue_data=udic)
-        add_nmrglue_data(object_name='nmrglue_data', 
nmrglue_id=nmrglue_id_i, nmrglue_data=data)
+        add_nmrglue_data(nmrglue_id=nmrglue_id_i, dic=dic, udic=udic, 
data=data)
 
 
 def plot_contour(nmrglue_id=None, contour_start=30000., contour_num=20, 
contour_factor=1.20, ppm=True, show=False):




Related Messages


Powered by MHonArc, Updated Mon Dec 08 18:00:02 2014