Changeset 1205


Ignore:
Timestamp:
06/02/09 17:16:11 (3 years ago)
Author:
Stuart Campbell
Message:

Merged latest changes to python binding from trunk. refs #115. fixes #160

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/4.2/bindings/python/nxs/napi.py

    r1180 r1205  
    315315        self.isopen = True 
    316316 
    317     def _getpath(self):  
    318         return '/'+'/'.join(self._path) 
     317    def _getpath(self): 
     318        mypath = [level[0] for level in self._path] 
     319        return '/'+'/'.join(mypath) 
    319320    path = property(_getpath,doc="Unix-style path to node") 
     321 
     322    def _getlongpath(self): 
     323        mypath = [':'.join(level) for level in self._path] 
     324        return '/' + '/'.join(mypath) 
     325    longpath = property(_getlongpath, doc="Unix-style path including " \ 
     326                        + "nxclass to the node") 
    320327 
    321328    def __del__(self): 
     
    421428    def openpath(self, path): 
    422429        """ 
    423         Open a particular group '/path/to/group'.  Paths can 
    424         be absolute or relative to the currently open group. 
    425         If openpath fails, then currently open path may not 
    426         be different from the starting path. 
     430        Open a particular group '/path/to/group'.  Paths can be 
     431        absolute or relative to the currently open group.  If openpath 
     432        fails, then currently open path may not be different from the 
     433        starting path. For better performation the types can be 
     434        specified as well using '/path:type1/to:type2/group:type3' 
     435        which will prevent searching the file for the types associated 
     436        with the supplied names. 
    427437 
    428438        Raises ValueError. 
     
    437447        if path == '/': 
    438448            target = [] 
    439         elif path.startswith('/'): 
    440             target = path[1:].split('/') 
    441449        else: 
    442             target = self._path + path.split('/') 
     450            if path.endswith("/"): 
     451                path = path[:-1] 
     452            if path.startswith('/'): 
     453                target = path[1:].split('/') 
     454            else: 
     455                target = self._path + path.split('/') 
    443456 
    444457        # Remove relative path indicators from target 
     
    455468                L.append(t) 
    456469        target = L 
     470 
     471        # split out nxclass from each level if available 
     472        L = [] 
     473        for t in target: 
     474            try: 
     475                item = t.split(":") 
     476                if len(item) == 1: 
     477                    L.append((item[0], None)) 
     478                else: 
     479                    L.append(tuple(item)) 
     480            except AttributeError: 
     481                L.append(t) 
     482        target = L 
     483 
    457484        #print "current path",self._path 
    458485        #print "%s"%path,target 
     
    461488        up = [] 
    462489        down = [] 
    463         for i,name in enumerate(target): 
     490        for (i, (name, nxclass)) in enumerate(target): 
    464491            if i == len(self._path): 
    465492                #print "target longer than current" 
     
    476503            up = self._path[len(target):] 
    477504            down = [] 
    478         up.reverse() 
     505 
     506        # add more information to the down path 
     507        for i in xrange(len(down)): 
     508            try: 
     509                (name, nxclass) = down[i] 
     510            except ValueError: 
     511                down[i] = (down[i], None) 
    479512        #print "close,open",up,down 
    480513 
     
    488521        # Open groups on the way down 
    489522        for target in down: 
    490             # Find target name in current group.  We need to do this because 
    491             # we can't open the group without knowing the class.  We also 
    492             # need the class so that we can handle SDS specially. 
    493             n,_,_ = self.getgroupinfo() 
    494             self.initgroupdir() 
    495             for i in range(n): 
    496                 name,nxclass = self.getnextentry() 
    497                 if name != target: continue 
    498                 if nxclass != 'SDS': 
    499                     self.opengroup(name,nxclass) 
    500                 elif opendata:  
    501                     self.opendata(name) 
    502                 break 
     523            (name, nxclass) = target 
     524            if nxclass is None: 
     525                nxclass = self.__getnxclass(name) 
     526            if nxclass != "SDS": 
     527                self.opengroup(name, nxclass) 
     528            elif opendata: 
     529                self.opendata(name) 
    503530            else: 
    504531                raise ValueError("node %s not in %s"%(name,self.path)) 
     
    520547    nxlib.nxiopengroup_.restype = c_int 
    521548    nxlib.nxiopengroup_.argtypes = [c_void_p, c_char_p, c_char_p] 
    522     def opengroup(self, name, nxclass): 
    523         """ 
    524         Open the group nxclass:name. 
     549    def opengroup(self, name, nxclass=None): 
     550        """ 
     551        Open the group nxclass:name. If the nxclass is not specified 
     552        this will search for it. 
    525553 
    526554        Raises ValueError if the group could not be opened. 
     
    529557        """ 
    530558        #print "open group",nxclass,name 
     559        if nxclass is None: 
     560            nxclass = self.__getnxclass(name) 
    531561        status = nxlib.nxiopengroup_(self.handle, name, nxclass) 
    532562        if status == ERROR: 
    533563            raise ValueError,\ 
    534564                "Could not open %s:%s in %s"%(nxclass,name,self._loc()) 
    535         self._path.append(name) 
     565        self._path.append((name,nxclass)) 
    536566 
    537567    nxlib.nxiclosegroup_.restype = c_int 
     
    596626    def getnextentry(self): 
    597627        """ 
    598         Return the next entry in the group as name,nxclass tuple. 
    599  
    600         Raises NeXusError if this fails, or if there is no next entry. 
     628        Return the next entry in the group as name,nxclass tuple. If 
     629        end of data is reached this returns the tuple (None, None) 
     630 
     631        Raises NeXusError if this fails. 
    601632 
    602633        Corresponds to NXgetnextentry(handle,name,nxclass,&storage). 
     
    616647        storage = c_int(0) 
    617648        status = nxlib.nxigetnextentry_(self.handle,name,nxclass,_ref(storage)) 
    618         if status == ERROR or status == EOD: 
     649        if status == EOD: 
     650            return (None, None) 
     651        if status == ERROR: 
    619652            raise NeXusError, \ 
    620653                "Could not get next entry: %s"%(self._loc()) 
     
    624657        #print "group next",nxclass.value, name.value, storage.value 
    625658        return name.value,nxclass.value 
     659 
     660    def getentries(self): 
     661        """ 
     662        Return a dictionary of the groups[name]=type below the 
     663        existing open one. 
     664 
     665        Raises NeXusError if this fails. 
     666        """ 
     667        self.initgroupdir() 
     668        result = {} 
     669        (name, nxclass) = self.getnextentry() 
     670        if (name, nxclass) != (None, None): 
     671            result[name] = nxclass 
     672        while (name, nxclass) != (None, None): 
     673            result[name] = nxclass 
     674            (name, nxclass) = self.getnextentry() 
     675        return result 
     676 
     677    def __getnxclass(self, target): 
     678        """ 
     679        Return the nxclass of the supplied name. 
     680        """ 
     681        self.initgroupdir() 
     682        while True: 
     683            (nxname, nxclass) = self.getnextentry() 
     684            if nxname == target: 
     685                return nxclass 
     686            if nxname is None: 
     687                break 
     688        raise NeXusError("Failed to find entry with name \"%s\" " \ 
     689                         + "at %s" % (target, self.path)) 
    626690 
    627691    def entries(self): 
     
    711775        if status == ERROR: 
    712776            raise ValueError, "Could not open data %s: %s"%(name, self._loc()) 
    713         self._path.append(name) 
     777        self._path.append((name,"SDS")) 
    714778        self._indata = True 
    715779 
     
    9421006        storage = c_int(0) 
    9431007        status = nxlib.nxigetnextattr_(self.handle,name,_ref(length),_ref(storage)) 
     1008        if status == EOD: 
     1009            return (None, None, None) 
    9441010        if status == ERROR or status == EOD: 
    9451011            raise NeXusError, "Could not get next attr: %s"%(self._loc()) 
     
    10201086        if status == ERROR: 
    10211087            raise NeXusError, "Could not write attr %s: %s"%(name,self._loc()) 
     1088 
     1089    def getattrs(self): 
     1090        """ 
     1091        Returns a dicitonary of the attributes on the current node. 
     1092 
     1093        This is a second form of attrs(self). 
     1094        """ 
     1095        result = {} 
     1096        for (name, value) in self.attrs(): 
     1097            result[name] = value 
     1098        return result 
    10221099 
    10231100    def attrs(self): 
Note: See TracChangeset for help on using the changeset viewer.