Changeset 364


Ignore:
Timestamp:
11/06/05 14:18:10 (14 years ago)
Author:
astephen
Message:

Latest changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • nappy/trunk/cdms2na.py

    r353 r364  
    3535    pass 
    3636else: 
    37     import cdms, cdtime 
     37    import cdms, cdtime, Numeric 
    3838    # Define cdms variables 
    3939    cdms.setAutoBounds("off") 
     
    4747from naError import * 
    4848 
     49 
     50# Set up functions 
    4951def compareAxes(ax1, ax2): 
    50     """Takes 2 cmds axis objects returning 1 if they are essentially 
    51     the same and 0 if not.""" 
     52    """ 
     53    Takes 2 cmds axis objects returning 1 if they are essentially 
     54    the same and 0 if not. 
     55    """ 
    5256    for axtype in ("time", "level", "latitude", "longitude"): 
    5357        if cdms.axisMatches(ax1, axtype) and not cdms.axisMatches(ax2, axtype): 
     
    6569    return 1 
    6670 
     71 
    6772def compareVariables(var1, var2): 
    68     """Compares two cdms variables to see if they are defined on identical 
    69     axes. Returns 1 if true, 0 if not.""" 
     73    """ 
     74    Compares two cdms variables to see if they are defined on identical 
     75    axes. Returns 1 if true, 0 if not. 
     76    """ 
    7077    try: 
    7178        for i in range(len(var1.getAxisList())): 
     
    7885    return 1 
    7986 
     87 
    8088def isAuxAndVar(avar, var): 
    81     """Compares two cdms variables and returns true if the first dimension of the 
    82     main variable is the only dimension the auxiliary variable is defined against.""" 
     89    """ 
     90    Compares two cdms variables and returns true if the first dimension of the 
     91    main variable is the only dimension the auxiliary variable is defined against. 
     92    """ 
    8393    if len(avar.shape)>1: 
    8494        return 0 
     
    8797    return compareAxes(auxax, varax) 
    8898 
     99 
    89100def arrayToList(array, inlist): 
    90  
    91     """ Takes an n-dimensional Numeric array and converts it to an  
     101    """  
     102    Takes an n-dimensional Numeric array and converts it to an  
    92103    n-dimensional list object. 
    93104    """ 
     
    101112    return inlist 
    102113 
     114 
    103115def listOfListsCreator(inlist, dimlist): 
    104116    """ 
     
    111123    return inlist 
    112124 
     125 
    113126def getBestName(var):   
    114127    """ 
    115128    Returns the most appropriate variable name for a NASA Ames header 
    116129    """ 
     130    name=None 
    117131    if hasattr(var, "id"): name=var.id 
     132    if hasattr(var, "shortname"): name=var.short_name 
    118133    if hasattr(var, "name"): name=var.name 
     134    if hasattr(var, "title"): name=var.title 
    119135    if hasattr(var, "long_name"): name=var.long_name 
    120136    if hasattr(var, "standard_name"): name=var.standard_name 
     137     
     138    if hasattr(var, "has_key"): 
     139        if var.has_key("id"): name=var["id"] 
     140        if var.has_key("short_name"): name=var["short_name"]     
     141        if var.has_key("name"): name=var["name"] 
     142        if var.has_key("title"): name=var["title"]       
     143        if var.has_key("long_name"): name=var["long_name"] 
     144        if var.has_key("standard_name"): name=var["standard_name"]    
     145     
    121146    if hasattr(var, "units") and not re.match("^\s+$", var.units):  
    122147        name="%s (%s)" % (name, var.units)     
     
    129154        if name.count("(%s)" % var.units)>1: 
    130155            name=name.replace("(%s)" % var.units, "") 
     156            name="%s (%s)" % (name, var.units) 
    131157         
    132158    if name[-2:]=="()": name=name[:-2] 
    133159    return name 
    134160 
     161 
    135162def getMissingValue(var): 
    136     if hasattr(var, "missing_value"): return var.missing_value 
    137     if hasattr(var, "fill_value"): return var.fill_value 
    138     if hasattr(var, "_FillValue"): return var._FillValue 
    139     return 1.E20 
     163    """ 
     164    Returns the missing value or defaults to 1.E20. 
     165    """ 
     166    miss=None 
     167    if hasattr(var, "missing_value"): miss=var.missing_value 
     168    # if hasattr(var, "fill_value"): miss=var.fill_value  # returns an array???? 
     169    if hasattr(var, "_FillValue"): miss=var._FillValue 
     170    if miss==None: 
     171        return 1.E20 
     172    else: 
     173        return miss 
    140174 
    141175 
    142176def fixHeaderLength(file): 
     177    """ 
     178    Fixes length of header. 
     179    """ 
    143180    lines=open(file).readlines()[:200] 
    144181    count=0 
     
    159196 
    160197 
    161 def cdms2na(infilename, outfilename, variable=None, ffi="automatic", rules=None): 
     198def cdms2na(infilename, outfilename, naVars={}, variables=None, ffi="automatic", rules=None): 
     199    """ 
     200    Main conversion function that calls the appropriate classes and functions 
     201    to write a NASA Ames file. 
     202    """ 
     203    allowedOverwriteMetadata="DATE RDATE".split() 
     204     
    162205    print "Reading data from: %s" % infilename 
    163206    cdmsfile=cdms.open(infilename) 
    164207    globals=cdmsfile.attributes 
    165     if not variable: 
    166         vars=[] 
    167         for var in cdmsfile.variables: 
    168             vars.append(cdmsfile(var))     
    169     else: 
    170         vars=[cdmsfile(variable)] 
    171  
     208     
     209    vars=[] 
     210    if not variables: 
     211        variables=cdmsfile.listvariables() 
     212        #for var in cdmsfile.listvariables(): 
     213            #vars.append(cdmsfile(var))     
     214             
     215    for variable in variables: 
     216        varObj=cdmsfile(variable) 
     217        # Deal with singleton variables 
     218        if not hasattr(varObj, "rank"): 
     219                varMetadata=cdmsfile[variable].attributes 
     220                varValue=varObj 
     221                #print varMetadata, varValue, varMetadata.keys(), varMetadata._obj_.id 
     222                varObj=cdms.createVariable(Numeric.array(varObj), id=getBestName(varMetadata).replace(" ", "_"), attributes=varMetadata) 
     223                #varObj.rank=0 
     224                 
     225        #print varObj, varObj.attributes                          
     226        vars.append(varObj) 
     227         
    172228    # Re-order variables if they have the attribute 'nasa_ames_var_number' 
    173229    orderedVars=[None]*1000 
     
    190246    builder=CdmsToNABuilder(vars, globals) 
    191247    #print builder.naDict["X"] 
    192      
    193     print "\nWriting output NASA Ames file: %s" % outfilename 
    194     general.openNAFile(outfilename, 'w', builder.naDict) 
    195     nlhead=fixHeaderLength(outfilename)    
    196     print "\nNASA Ames file written successfully: %s" % outfilename 
     248    builtNADicts=[[builder.naDict, builder.varIDs]] 
     249    while len(builder.varBin)>0: 
     250        builder=CdmsToNABuilder(builder.varBin, globals) 
     251        builtNADicts.append([builder.naDict, builder.varIDs]) 
     252         
     253    print "%s files to write" % len(builtNADicts) 
     254 
     255    count=1 
     256    for i in builtNADicts: 
     257        if len(builtNADicts)==1: 
     258            suffix="" 
     259        else: 
     260            suffix="_%s" % count 
     261        nameparts=outfilename.split(".")     
     262        newname=(".".join(nameparts[:-1]))+suffix+"."+nameparts[-1] 
     263        print "\nWriting output NASA Ames file: %s" % newname 
     264        builtNADict=i[0] 
     265        for key in naVars.keys(): 
     266            if key in allowedOverwriteMetadata: 
     267                if type(builtNADict[key])==list: 
     268                    builtNADict[key]=naVars[key].split() 
     269                else: 
     270                    builtNADict[key]=naVars[key] 
     271                print "Key replace in: ", key, builtNADict[key] 
     272        general.openNAFile(newname, 'w', builtNADict) 
     273        nlhead=fixHeaderLength(newname)   
     274        print "\nWrote the following variables to this file:" 
     275        print "\n\t"+("\n\t".join(i[1][0])) 
     276        if len(i[1][1])>0: 
     277            print "\nWrote the following auxiliary variables to this file:" 
     278            print "\n\t"+("\n\t".join(i[1][1]))  
     279            print "\nNASA Ames file written successfully: %s" % newname 
     280        count=count+1 
     281               
     282    print "\n%s files written." % (count-1) 
    197283 
    198284 
     
    212298        self.globals=global_attributes 
    213299        (self.orderedVars, auxVars)=self.analyseVariables() 
    214         self.naDict["NLHEAD"]="-999" 
    215         self.defineNAVars(self.orderedVars) 
    216         self.defineNAAuxVars(auxVars) 
    217         self.defineNAGlobals() 
    218         self.defineNAComments() 
    219         self.defineGeneralHeader() 
    220         # Quick fudge 
    221         if self.naDict["FFI"]==1001: self.naDict["X"]=self.naDict["X"][0] 
     300        if self.orderedVars==None: 
     301            print "All variables located." 
     302            self.varBin=[] 
     303        else: 
     304            #print "NAMELISTS:", [var.id for var in self.orderedVars],[var.id for var in auxVars] 
     305            self.varIDs=[[var.id for var in self.orderedVars],[var.id for var in auxVars]] 
     306         
     307            self.naDict["NLHEAD"]="-999" 
     308         
     309            #print [var.id for var in self.orderedVars] 
     310            #print [var.rank() for var in self.orderedVars]      
     311            self.defineNAVars(self.orderedVars) 
     312            self.defineNAAuxVars(auxVars) 
     313            self.defineNAGlobals() 
     314            self.defineNAComments() 
     315            self.defineGeneralHeader() 
     316            # Quick fudge 
     317            if self.naDict["FFI"]==1001: self.naDict["X"]=self.naDict["X"][0] 
     318 
    222319 
    223320    def analyseVariables(self): 
     
    226323        a tuple of two lists containing variables and auxiliary variables 
    227324        for the NASA Ames file object. 
     325        Variables not compatible with the first file are binned to be used next. 
    228326        """ 
     327        # Need to group the variables together in bins 
     328        self.varBin=[] 
     329        self.rankZeroVars=[] 
     330        self.rankZeroVarIDs=[] 
    229331        # Get largest ranked variable as the one we use as standard 
    230         rank=0 
     332        highrank=-1 
    231333        count=0 
    232334        for var in self.vars: 
     335            print "Analysing:", var.id 
    233336            count=count+1 
    234             if var.rank()>rank: 
    235                 rank=var.rank() 
     337            #print count 
     338            # Deal with singleton dimensions 
     339            #if callable(var.rank): 
     340            #    rank=var.rank() 
     341            #else: 
     342            #    rank=var.rank 
     343            #print var.id, var.rank() 
     344            rank=var.rank() 
     345            if rank==0:  
     346                self.rankZeroVars.append(var) 
     347                self.rankZeroVarIDs.append(var.id) 
     348                continue 
     349             
     350            if rank>highrank: 
     351                highrank=rank 
    236352                bestVar=var 
    237353                bestVarIndex=count 
    238             elif var.rank()==rank: 
     354            elif rank==highrank: 
    239355                if len(var.flat)>len(bestVar.flat): 
    240356                    bestVar=var 
    241357                    bestVarIndex=count 
    242                  
     358         
     359        if len(self.rankZeroVars)==len(self.vars):  return (None, None) 
     360         
    243361        vars4NA=[bestVar] 
    244362        auxVars4NA=[] 
     
    261379         
    262380        # Get other variable info 
     381        #print [v.id for v in self.vars], bestVarIndex 
     382        #print [v.id for v in self.vars[:bestVarIndex-1]+self.vars[bestVarIndex:]] 
    263383        for var in self.vars[:bestVarIndex-1]+self.vars[bestVarIndex:]: 
     384            #print self.rankZeroVars 
     385            #for rzv in self.rankZeroVars:   
     386            #    if var.id==rzv.id and var[0]==rzv[0]: continue 
     387            #print [v.id for v in self.rankZeroVars] 
     388            if var.id in self.rankZeroVarIDs: continue 
     389            #print var.id, ndims, shape, len(var.shape), var.shape 
    264390            if len(var.shape)!=ndims or var.shape!=shape:  
    265391                # Could it be an auxiliary variable  
    266                 if len(var.shape)!=1:  continue 
     392                if len(var.shape)!=1:  
     393                    self.varBin.append(var) 
     394                    continue 
    267395                caxis=var.getAxis(0) 
    268                 if compareAxes(axes[0], caxis)==0:  continue 
     396                if compareAxes(axes[0], caxis)==0:  
     397                    self.varBin.append(var) 
     398                    continue 
    269399                # I think it is an auxiliary variable 
    270400                auxVars4NA.append(var)  
     401                # Also put it in var bin because auxiliary vars might be useful 
     402                self.varBin.append(var) 
    271403            else: 
    272404                caxes=var.getAxisList() 
     405                #print var.id, "here" 
    273406                for i in range(ndims):             
    274407                    if compareAxes(axes[i], caxes[i])==0: 
     408                        self.varBin.append(var) 
    275409                        continue 
    276410                # OK, I think they are compatible 
     
    309443        return (vars4NA, auxVars4NA) 
    310444 
     445 
    311446    def defineNAVars(self, vars): 
    312447        """ 
     
    323458            self.naDict["VNAME"].append(name) 
    324459            miss=getMissingValue(var) 
    325             if type(miss)!=float:  miss=miss[0] 
     460            if type(miss) not in (float, int, long):  miss=miss[0] 
    326461            self.naDict["VMISS"].append(miss) 
    327462            #print self.naDict["VMISS"] 
     
    339474                self.naDict["NX"]=[] 
    340475                # Create independent variable information 
     476                #print var.id, var.getAxis(0) 
    341477                self.ax0=var.getAxis(0) 
    342478                self.naDict["X"]=[list(self.ax0._data_)] 
     
    355491                for axis in var.getAxisList()[1:]: 
    356492                    self.getAxisDefinition(axis) 
     493 
    357494 
    358495    def defineNAAuxVars(self, auxVars): 
     
    380517            #listOfListsCreator(inlist, var.shape) 
    381518            #arrayToList(var, inlist)      
     519 
    382520 
    383521    def getAxisDefinition(self, axis): 
     
    409547        return 
    410548 
     549 
    411550    def defineNAGlobals(self): 
    412551        """ 
     
    439578                        self.naDict["ONAME"]=self.globals[key] 
    440579                        self.naDict["ORG"]=self.globals[key]                 
     580                     
     581                    # NOte: should probably do the following search and replace on all string lines 
     582                    self.naDict["ONAME"]=self.naDict["ONAME"].replace("\n", "  ") 
     583                    self.naDict["ORG"]=self.naDict["ORG"].replace("\n", "  ") 
    441584                                     
    442585                elif key=="comment": 
     
    526669        varCommentsFlag=None 
    527670 
     671        # Create a string for the Special comments to hold rank-zero vars 
     672        rankZeroVarsString=[] 
     673        for var in self.rankZeroVars: 
     674            rankZeroVarsString.append("\tVariable (%s): %s" % (var.id, getBestName(var))) 
     675            for att in var.attributes.keys(): 
     676                value=var.attributes[att] 
     677                if type(value) in (str, float, int): 
     678                    rankZeroVarsString.append("\t\t%s = %s" % (att, var.attributes[att])) 
     679            #print "VALUES", dir(var), var._data ; rankZeroVarsString.append("\t\tvalue = %s" % var._data) 
     680         
     681        if len(rankZeroVarsString)>0: 
     682            rankZeroVarsString.insert(0, "###Singleton Variables defined in the source file follow###") 
     683            rankZeroVarsString.append("###Singleton Variables defined in the source file end###") 
     684 
    528685        for var in self.orderedVars: 
    529686            varflag="unused" 
     
    535692                            varCommentsFlag=1 
    536693                            if specCommentsFlag==None: 
    537                                 SCOM=["###NASA Ames Special Comments follow###"] 
     694                                SCOM=["###NASA Ames Special Comments follow###"]+rankZeroVarsString 
    538695                            SCOM.append("Additional Variable Attributes defined in the source file and not translated elsewhere:") 
    539696                            SCOM.append("###Variable attributes from source (NetCDF) file follow###") 
     
    565722        self.naDict["NSCOML"]=len(self.naDict["SCOM"]) 
    566723        return 
     724 
    567725 
    568726    def defineGeneralHeader(self, header_items={}): 
     
    597755                 
    598756 
    599  
    600 if __name__=="__main__": 
     757usenc2nainstead="""if __name__=="__main__": 
    601758 
    602759    args=sys.argv[1:] 
     
    612769            outfile=args[args.index(arg)+1] 
    613770 
    614     cdms2na(infile, outfile)  
     771    cdms2na(infile, outfile) """ 
Note: See TracChangeset for help on using the changeset viewer.