• Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • ← Previous Changeset
  • Next Changeset →

Changeset 93

Show
Ignore:
Timestamp:
09/19/07 13:52:48 (11 months ago)
Author:
andrew
Message:

Applied Version 2 - September 2007 changes to schema and improved Tiff chacks in validator

Location:
Xml
Files:
2 added
9 modified

  • Validator/Backend/OmeValidator.py (modified) (3 diffs)
  • Validator/Backend/RunAndCheck.py (modified) (2 diffs)
  • Validator/Backend/ValidatorBackend.tmproj (modified) (5 diffs)
  • Validator/Backend/mateTiff.py (added)
  • Validator/Backend/ome-fc-tiff.xsd (modified) (1 diff)
  • Validator/WebApp/validator/OmeValidator.py (modified) (12 diffs)
  • Working (modified) (1 prop)
  • Working/AnalysisModule.xsd (modified) (1 diff)
  • Working/SPW.xsd (modified) (6 diffs)
  • Working/completesample-local.xml (added)
  • Working/ome.xsd (modified) (8 diffs)

Legend:

Unmodified
Added
Removed
  • Xml/Validator/Backend/OmeValidator.py

    r92 r93  
    238238                # create an IO string for the xml string provided 
    239239                stringXml = StringIO(self.theDom.toxml()) 
     240                 
     241                # 
     242                print self.theDom.toprettyxml() 
     243                 
    240244                # building the document tree from the input xml 
    241245                try: 
    … …  
    440444                    pass 
    441445                 
     446                self.isOmeTiffConsistent = True 
     447                 
    442448                # compare with values from xml and tiff 
    443449                if self.tiffFileFrames > self.ome5dPlaneCount: 
    … …  
    454460                if self.tiffFileFrames < totalTiffDataFrames: 
    455461                        self.errorList.append(ParseMessage(None, None, None, "TIFF", ("Frames %s out of %s" % (self.tiffFileFrames,totalTiffDataFrames)) , "Not all required frames are present in this Tiff file")) 
    456  
     462                        self.isOmeTiffConsistent = False 
     463                 
    457464# Used by sax parser to handle errors when processing Elements 
    458465class ParseErrorHandler(sax.ErrorHandler): 
  • Xml/Validator/Backend/RunAndCheck.py

    r86 r93  
    1515 
    1616def main(): 
     17        print OmeValidator.XmlReport.validateTiff("samples/claire-multi-channel-4D-series.ome.tif") 
     18        """ 
    1719        for aFilename in ["samples/completesamplenopre.xml","samples/completesample.xml", 
    1820                "samples/sdub.ome", "samples/sdub-fix.ome", "samples/sdub-fix-pre.ome",  
    … …  
    2628                print "============ XML file %s ============ " % aFilename 
    2729                print OmeValidator.XmlReport.validateTiff(aFilename) 
    28  
     30        """ 
    2931        print "============" 
    3032 
  • Xml/Validator/Backend/ValidatorBackend.tmproj

    r92 r93  
    44<dict> 
    55        <key>currentDocument</key> 
    6         <string>OmeValidator.py</string> 
     6        <string>RunAndCheck.py</string> 
    77        <key>documents</key> 
    88        <array> 
    99                <dict> 
    1010                        <key>filename</key> 
     11                        <string>mateTiff.py</string> 
     12                        <key>lastUsed</key> 
     13                        <date>2007-09-17T09:26:23Z</date> 
     14                </dict> 
     15                <dict> 
     16                        <key>filename</key> 
    1117                        <string>RunAndCheck.py</string> 
    1218                        <key>lastUsed</key> 
    13                         <date>2007-09-06T11:24:18Z</date> 
     19                        <date>2007-09-18T09:26:59Z</date> 
     20                        <key>selected</key> 
     21                        <true/> 
    1422                </dict> 
    1523                <dict> 
    … …  
    1725                        <string>OmeValidator.py</string> 
    1826                        <key>lastUsed</key> 
    19                         <date>2007-09-13T09:19:26Z</date> 
    20                         <key>selected</key> 
    21                         <true/> 
     27                        <date>2007-09-18T09:26:59Z</date> 
    2228                </dict> 
    2329                <dict> 
    … …  
    5359                        <dict> 
    5460                                <key>column</key> 
    55                                 <integer>21</integer> 
     61                                <integer>8</integer> 
    5662                                <key>line</key> 
    57                                 <integer>35</integer> 
     63                                <integer>241</integer> 
     64                        </dict> 
     65                        <key>firstVisibleColumn</key> 
     66                        <integer>0</integer> 
     67                        <key>firstVisibleLine</key> 
     68                        <integer>206</integer> 
     69                </dict> 
     70                <key>RunAndCheck.py</key> 
     71                <dict> 
     72                        <key>caret</key> 
     73                        <dict> 
     74                                <key>column</key> 
     75                                <integer>1</integer> 
     76                                <key>line</key> 
     77                                <integer>29</integer> 
    5878                        </dict> 
    5979                        <key>firstVisibleColumn</key> 
    … …  
    6181                        <key>firstVisibleLine</key> 
    6282                        <integer>0</integer> 
     83                </dict> 
     84                <key>mateTiff.py</key> 
     85                <dict> 
     86                        <key>caret</key> 
     87                        <dict> 
     88                                <key>column</key> 
     89                                <integer>0</integer> 
     90                                <key>line</key> 
     91                                <integer>24</integer> 
     92                        </dict> 
     93                        <key>firstVisibleColumn</key> 
     94                        <integer>0</integer> 
     95                        <key>firstVisibleLine</key> 
     96                        <integer>19</integer> 
    6397                </dict> 
    6498                <key>samples/completesamplenoenc.xml</key> 
    … …  
    137171        <key>openDocuments</key> 
    138172        <array> 
     173                <string>mateTiff.py</string> 
    139174                <string>OmeValidator.py</string> 
     175                <string>RunAndCheck.py</string> 
    140176        </array> 
    141177        <key>showFileHierarchyDrawer</key> 
    142178        <true/> 
    143179        <key>windowFrame</key> 
    144         <string>{{162, 48}, {1189, 830}}</string> 
     180        <string>{{580, 61}, {788, 840}}</string> 
    145181</dict> 
    146182</plist> 
  • Xml/Validator/Backend/ome-fc-tiff.xsd

    r75 r93  
    88         xmlns:Bin = "http://www.openmicroscopy.org/XMLschemas/BinaryFile/RC1/BinaryFile.xsd" 
    99         xmlns:CA = "http://www.openmicroscopy.org/XMLschemas/CA/RC1/CA.xsd" 
    10          version = "FC" 
     10         version = "FC+TIFF" 
    1111         elementFormDefault = "qualified"> 
    1212        <xs:import namespace = "http://www.openmicroscopy.org/XMLschemas/AnalysisModule/RC1/AnalysisModule.xsd" schemaLocation = "http://www.openmicroscopy.org/XMLschemas/AnalysisModule/RC1/AnalysisModule.xsd"/> 
  • Xml/Validator/WebApp/validator/OmeValidator.py

    r88 r93  
    1818 
    1919# Standard Imports 
    20 import logging, cherrypy 
     20import logging 
    2121from xml.dom.minidom import getDOMImplementation 
    2222from StringIO import StringIO 
    … …  
    2525from stat import * 
    2626 
    27 # LocalDir for shames 
     27 
     28# Load schemas from configured directory  
     29import cherrypy 
     30# LocalDir for schemas 
    2831SCHEMA_DIR = cherrypy.config.get("validator.schema", os.path.join(os.getcwd(),"schema")) 
    29  
     32def schemaFilePath(inFilename): 
     33        return os.path.join(os.getcwd(), SCHEMA_DIR, inFilename) 
     34""" 
     35# Load schemas from current directory  
     36def schemaFilePath(inFilename): 
     37        return inFilename 
     38""" 
    3039# Try to load Image for XML Schema Vlaidation Support 
    3140haveTiffSupport = True 
    … …  
    135144        warningList = None 
    136145        unresolvedList = None 
     146         
     147        """ 
     148        Create variables used to check internal consistency 
     149        """ 
     150        # count of TiffData elements founf in the XML 
     151        omeTiffDataCount = None 
     152        # count of image frames found in Tiff file 
     153        tiffFileFrames = None 
     154         
     155        # count of pixels 
     156        omePixelsCount = None 
     157        # count of planes 
     158        omePlanesCount = None 
     159        # count of Z * C * T 
     160        ome5dPlaneCount = None 
     161        # count of number of times a tiff data block has asked for "all available frames" - value of more then 1 indicates an error 
     162        theAllFrameCount = None 
    137163         
    138164        def __init__(self): 
    … …  
    212238                # create an IO string for the xml string provided 
    213239                stringXml = StringIO(self.theDom.toxml()) 
     240                 
     241                # 
     242                # print self.theDom.toprettyxml() 
     243                 
    214244                # building the document tree from the input xml 
    215245                try: 
    … …  
    232262                # choose the schema source 
    233263                # assume the new schema 
    234                 theSchemaFile = os.path.join(os.getcwd(), SCHEMA_DIR, "ome-2007-07.xsd") 
     264                theSchemaFile = "ome-2007-07.xsd" 
    235265                # if old schema 
    236266                if self.theNamespace == "http://www.openmicroscopy.org/XMLschemas/OME/FC/ome.xsd": 
    … …  
    238268                        if self.isOmeTiff: 
    239269                                # use special tiff version of old schema 
    240                                 theSchemaFile = os.path.join(os.getcwd(), SCHEMA_DIR, "ome-fc-tiff.xsd") 
     270                                theSchemaFile = "ome-fc-tiff.xsd" 
    241271                        else: 
    242272                                # use normal version of old schema 
    243                                 theSchemaFile = os.path.join(os.getcwd(), SCHEMA_DIR, "ome-fc.xsd") 
     273                                theSchemaFile = "ome-fc.xsd" 
    244274                 
    245275                # loading the OME schema to validate against 
    246276                try: 
    247                         schema = etree.XMLSchema(etree.parse(theSchemaFile)) 
     277                        schema = etree.XMLSchema(etree.parse(schemaFilePath(theSchemaFile))) 
    248278                except: 
    249279                        #chosen scema failed to laod 
    … …  
    275305                        if reference not in handlerContent.ids: 
    276306                                self.unresolvedList.append(ParseMessage(None, None, None, "UnresolvedID",None, reference)) 
     307                 
     308                # store the internal counters 
     309                self.omeTiffDataCount = handlerContent.omeTiffDataCount 
     310                self.omePixelsCount = handlerContent.omePixelsCount 
     311                self.omePlanesCount = handlerContent.omePlanesCount 
     312                self.ome5dPlaneCount = handlerContent.ome5dPlaneCount 
     313                self.omeTiffDataPlaneCount = handlerContent.omeTiffDataPlaneCount 
     314                self.theAllFrameCount = handlerContent.theAllFrameCount 
    277315                 
    278316                # store the namespace 
    … …  
    358396                                        # parse the new string/file object into the report and validate it  
    359397                                        theTiffReport.parse(theFileString) 
     398                                        theTiffReport.validateTiffImageData(image) 
     399                                        """ 
     400                                        # print theXml 
     401                                        print "Tiff Frames    : %s" % theTiffReport.tiffFileFrames       
     402                                        print "Ome Frames     : %s" % theTiffReport.omeTiffDataCount     
     403                                        print "Ome Pixels     : %s" % theTiffReport.omePixelsCount       
     404                                        print "Ome Planes     : %s" % theTiffReport.omePlanesCount       
     405                                        print "Ome 5dPlane    : %s" % theTiffReport.ome5dPlaneCount      
     406                                        print "Ome TiffPlane  : %s" % theTiffReport.omeTiffDataPlaneCount        
     407                                        print "Ome AllFrame   : %s" % theTiffReport.theAllFrameCount     
     408                                        """ 
     409                                         
    360410                return theTiffReport 
    361411        validateTiff = classmethod(validateTiff) 
    362412         
     413        def validateTiffImageData(self, inImage, ): 
     414                """ 
     415                Examines the tiff image data to compare with  
     416                """ 
     417                 
     418                """ code to look at the list of tiff image dimensions 
     419                theTiffWidth = None 
     420                theTiffHeight = None 
     421                try: 
     422                        #theTiffWidth = int(inImage.tag[256]) 
     423                        print inImage.tag[256] 
     424                except KeyError: 
     425                        pass 
     426                except ValueError: 
     427                        pass 
     428                try: 
     429                        theTiffHeight = int(inImage.tag[257]) 
     430                except KeyError: 
     431                        pass 
     432                except ValueError: 
     433                        pass 
     434                """ 
     435                 
     436                #look for frames 
     437                self.tiffFileFrames = 0 
     438                try: 
     439                    while True: 
     440                        inImage.seek( self.tiffFileFrames ) 
     441                        self.tiffFileFrames = self.tiffFileFrames + 1 
     442                except EOFError: 
     443                    inImage.seek( 0 ) 
     444                    pass 
     445                 
     446                self.isOmeTiffConsistent = True 
     447                 
     448                # compare with values from xml and tiff 
     449                if self.tiffFileFrames > self.ome5dPlaneCount: 
     450                        self.warningList.append(ParseMessage(None, None, None, "TIFF", ("Frames %s needing %s" % (self.tiffFileFrames,self.ome5dPlaneCount)) , "Extra frames are present in this Tiff file")) 
     451 
     452                if self.tiffFileFrames < self.ome5dPlaneCount: 
     453                        self.warningList.append(ParseMessage(None, None, None, "TIFF", ("Frames %s out of %s" % (self.tiffFileFrames,self.ome5dPlaneCount)) , "Not all possible frames are present in this Tiff file")) 
     454 
     455                # compare with values from xml TiffData and tiff 
     456                totalTiffDataFrames = self.omeTiffDataPlaneCount + (self.tiffFileFrames * self.theAllFrameCount) 
     457                if self.tiffFileFrames > totalTiffDataFrames: 
     458                        self.warningList.append(ParseMessage(None, None, None, "TIFF", ("Frames %s referenced %s" % (self.tiffFileFrames,totalTiffDataFrames)) , "Unreferenced frames are present in this Tiff file")) 
     459 
     460                if self.tiffFileFrames < totalTiffDataFrames: 
     461                        self.errorList.append(ParseMessage(None, None, None, "TIFF", ("Frames %s out of %s" % (self.tiffFileFrames,totalTiffDataFrames)) , "Not all required frames are present in this Tiff file")) 
     462                        self.isOmeTiffConsistent = False 
    363463 
    364464# Used by sax parser to handle errors when processing Elements 
    … …  
    399499                self.inBinDataContent = False 
    400500                self.shortFormXml = "" 
     501                # internal check counters 
    401502                self.skipCount = 0 
     503                self.omeTiffDataCount = 0 
     504                self.omePixelsCount = 0 
     505                self.omePlanesCount = 0 
     506                self.ome5dPlaneCount = 0 
     507                self.omeTiffDataPlaneCount = 0 
     508                self.theAllFrameCount = 0 
    402509                self.hasCustomAttributes = False 
    403510                 
    … …  
    486593                if name[-7:] == "BinData": 
    487594                        self.inBinData = True 
     595                 
     596                if name[-8:] == "TiffData": 
     597                        self.omeTiffDataCount = self.omeTiffDataCount + 1 
     598                        # record the number of planes used by the TiffData block 
     599                        if "NumPlanes" in attribs: 
     600                                # use the number of planes specified 
     601                                self.omeTiffDataPlaneCount = self.omeTiffDataPlaneCount + int(attribs.getValue("NumPlanes")) 
     602                                if self.theAllFrameCount > 0: 
     603                                        self.errorList.append(ParseMessage(None, None, None, "OME","", "Inconsistent use of TiffData element [Type 1]")) 
     604                                 
     605                        else: 
     606                                if "IFD" in attribs: 
     607                                        # use one frame 
     608                                        self.omeTiffDataPlaneCount = self.omeTiffDataPlaneCount + 1 
     609                                        if self.theAllFrameCount > 0: 
     610                                                self.errorList.append(ParseMessage(None, None, None, "OME","", "Inconsistent use of TiffData element [Type 2]")) 
     611                                else: 
     612                                        # use all the frames in the tiff 
     613                                        self.theAllFrameCount = self.theAllFrameCount + 1 
     614                                        if (self.theAllFrameCount > 1) or (self.omeTiffDataPlaneCount > 0): 
     615                                                self.errorList.append(ParseMessage(None, None, None, "OME","", "Inconsistent use of TiffData element [Type 3]")) 
     616                         
     617                if name[-6:] == "Pixels": 
     618                        self.omePixelsCount = self.omePixelsCount + 1 
     619                        try: 
     620                                # total up planes needed from Z, C and T 
     621                                theZ = int(attribs.getValue("SizeZ")) 
     622                                theC = int(attribs.getValue("SizeC")) 
     623                                theT = int(attribs.getValue("SizeT")) 
     624                                # print "Z: %s, C: %s, T: %s" % (theZ, theC, theT) 
     625                                self.ome5dPlaneCount = self.ome5dPlaneCount + (theZ * theC * theT) 
     626                        except KeyError: 
     627                                pass 
     628                        except ValueError: 
     629                                pass 
     630                 
     631                if name[-5:] == "Plane": 
     632                        self.omePlanesCount = self.omePlanesCount + 1 
     633                 
    488634                self.domify(name, attribs) 
    489635                         
    … …  
    556702 
    557703if __name__ == '__main__': 
    558         for aFilename in ["samples/sdub.ome", "samples/tiny.ome", "samples/broke.ome"]: 
    559                 print "============ XML file %s ============ " % aFilename 
    560                 print XmlReport.validateFile(aFilename) 
     704        for aFilename in ["samples/completesamplenopre.xml","samples/completesample.xml","samples/completesamplenoenc.xml", 
     705                        "samples/sdub.ome", "samples/sdub-fix.ome", "samples/sdub-fix-pre.ome",  
     706                        "samples/tiny.ome", "samples/broke.ome"]: 
     707                        print "============ XML file %s ============ " % aFilename 
     708                        print XmlReport.validateFile(aFilename) 
     709         
    561710         
    562711        for aFilename in ["samples/4d2wOME.tif", "samples/4d2wOME-fixed.tif", 
    … …  
    567716         
    568717        print "============" 
    569  
    570  
  • Xml/Working

    • Property svn:ignore
      •  

        old new  
        11.DS_Store 
        22Working Project.tmproj 
         3ClareQuestions.xml 
  • Xml/Working/AnalysisModule.xsd

    r71 r93  
    415415        <simpleType name = "ModuleID"> 
    416416                <restriction base = "OME:LSID"> 
    417                         <pattern value = "(urn:lsid:([\w-\.]+\.[\w-\.]+)+:Module:\S+)|(Module:\S+)"/> 
     417                        <pattern value = "(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:Module:\S+)|(Module:\S+)"/> 
    418418                </restriction> 
    419419        </simpleType> 
  • Xml/Working/SPW.xsd

    r68 r93  
    9898    <xsd:simpleType name="PlateID"> 
    9999        <xsd:restriction base="OME:LSID"> 
    100             <xsd:pattern value="(urn:lsid:([\w-\.]+\.[\w-\.]+)+:Plate:\S+)|(Plate:\S+)"/> 
     100            <xsd:pattern value="(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:Plate:\S+)|(Plate:\S+)"/> 
    101101        </xsd:restriction> 
    102102    </xsd:simpleType> 
    … …  
    147147    <xsd:simpleType name="ReagentID"> 
    148148        <xsd:restriction base="OME:LSID"> 
    149             <xsd:pattern value="(urn:lsid:([\w-\.]+\.[\w-\.]+)+:Reagent:\S+)|(Reagent:\S+)"/> 
     149            <xsd:pattern value="(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:Reagent:\S+)|(Reagent:\S+)"/> 
    150150        </xsd:restriction> 
    151151    </xsd:simpleType> 
    … …  
    215215    <xsd:simpleType name="ScreenID"> 
    216216        <xsd:restriction base="OME:LSID"> 
    217             <xsd:pattern value="(urn:lsid:([\w-\.]+\.[\w-\.]+)+:Screen:\S+)|(Screen:\S+)"/> 
     217            <xsd:pattern value="(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:Screen:\S+)|(Screen:\S+)"/> 
    218218        </xsd:restriction> 
    219219    </xsd:simpleType> 
    … …  
    269269    <xsd:simpleType name="ScreenAcquisitionID"> 
    270270        <xsd:restriction base="OME:LSID"> 
    271             <xsd:pattern value="(urn:lsid:([\w-\.]+\.[\w-\.]+)+:ScreenAcquisition:\S+)|(ScreenAcquisition:\S+)"/> 
     271            <xsd:pattern value="(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:ScreenAcquisition:\S+)|(ScreenAcquisition:\S+)"/> 
    272272        </xsd:restriction> 
    273273    </xsd:simpleType> 
    … …  
    333333    <xsd:simpleType name="WellID"> 
    334334        <xsd:restriction base="OME:LSID"> 
    335             <xsd:pattern value="(urn:lsid:([\w-\.]+\.[\w-\.]+)+:Well:\S+)|(Well:\S+)"/> 
     335            <xsd:pattern value="(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:Well:\S+)|(Well:\S+)"/> 
    336336        </xsd:restriction> 
    337337    </xsd:simpleType> 
    … …  
    381381    <xsd:simpleType name="WellSampleID"> 
    382382        <xsd:restriction base="OME:LSID"> 
    383             <xsd:pattern value="(urn:lsid:([\w-\.]+\.[\w-\.]+)+:WellSample:\S+)|(WellSample:\S+)"/> 
     383            <xsd:pattern value="(urn:lsid:([\w\-\.]+\.[\w\-\.]+)+:WellSample:\S+)|(WellSample:\S+)"/> 
    384384        </xsd:restriction> 
    385385    </xsd:simpleType> 
  • Xml/Working/ome.xsd

    r73 r93  
    2424        xmlns:CA="http://www.openmicroscopy.org/Schemas/CA/2007-06"  
    2525        xmlns:SPW="http://www.openmicroscopy.org/Schemas/SPW/2007-06"  
    26         version="1"  
     26        version="2"  
    2727        elementFormDefault="qualified"> 
    2828        <xsd:import namespace="http://www.openmicroscopy.org/Schemas/AnalysisModule/2007-06" schemaLocation="http://www.openmicroscopy.org/Schemas/AnalysisModule/2007-06/AnalysisModule.xsd"/> 
    … …  
    3434                <xsd:documentation> 
    3535                        Open Microscopy Environment 
    36                         OME XML Schema 2.0-RC1 
     36                        OME XML Schema June 2007 - Update Version 2 September 2007 
    3737                        Author:  Ilya G. Goldberg, Andrew J Patterson 
    3838                        Copyright 2002 - 2007 OME. All rights reserved. 
    … …  
    685685                        <xsd:sequence> 
    686686                                <xsd:element ref="Microscope"/> 
    687                                 <xsd:element ref="LightSource" maxOccurs="unbounded"/> 
    688                                 <xsd:element ref="Detector" maxOccurs="unbounded"/> 
    689                                 <xsd:element ref="Objective" maxOccurs="unbounded"/> 
     687                                <xsd:element ref="LightSource" minOccurs="0" maxOccurs="unbounded"/> 
     688                                <xsd:element ref="Detector" minOccurs="0" maxOccurs="unbounded"/> 
     689                                <xsd:element ref="Objective" minOccurs="0" maxOccurs="unbounded"/> 
    690690                                <xsd:element ref="FilterSet" minOccurs="0" maxOccurs="unbounded"/> 
    691691                                <xsd:element ref="Filter" minOccurs="0" maxOccurs="unbounded"/> 
    692692                                <xsd:element ref="Dichroic" minOccurs="0" maxOccurs="unbounded"/> 
    693                                 <xsd:element ref="OTF" maxOccurs="unbounded"/> 
     693                                <xsd:element ref="OTF" minOccurs="0" maxOccurs="unbounded"/> 
    694694                        </xsd:sequence> 
    695695                        <xsd:attribute name="ID" use="required" type="InstrumentID"/> 
    … …  
    709709                </xsd:complexType> 
    710710        </xsd:element> 
    711         <xsd:element name="Experimenter" type="ExperimenterType"> 
     711        <xsd:element name="Experimenter"> 
    712712                <xsd:annotation> 
    713713                        <xsd:documentation> 
    … …  
    715715                                This person may also be a user of the OME system, in which case the OMEName element contains their login name. 
    716716                                Experimenters may belong to one or more groups which are specified using one or more GroupRef elements. 
    717                         </xsd:documentation> 
    718                 </xsd:annotation> 
     717                                Note while FirstName, LastName, Email and OMEName are all optional to be valid an Experimenter must have AT LEAST ONE present 
     718                        </xsd:documentation> 
     719                </xsd:annotation> 
     720                <xsd:complexType> 
     721                        <xsd:sequence> 
     722                                <xsd:choice> 
     723                            &nbs