#NEWLINE# def difference( self , other , minuend = 'self' , mask_zero_diff = True ) : #NEWLINE# #INDENT# 'make a new NetCDF instance that is the difference with another\n        netcdf file\n\n        Parameters\n        ----------\n        other : either an str filename of a netcdf file or\n            a netCDF4 instance\n\n        minuend : (optional) the order of the difference operation.\n            Default is self (e.g. self - other).  Can be "self" or "other"\n\n        mask_zero_diff : bool flag to mask differences that are zero.  If\n            True, positions in the difference array that are zero will be set\n            to self.fillvalue\n\n        Returns\n        -------\n        net NetCDF instance\n\n        Notes\n        -----\n        assumes the current NetCDF instance has been populated.  The\n        variable names and dimensions between the two files must match\n        exactly. The name of the new .nc file is\n        <self.output_filename>.diff.nc.  The masks from both self and\n        other are carried through to the new instance\n\n        ' #NEWLINE# assert ( self . nc is not None ) , ( "can't call difference() if nc " + "hasn't been populated" ) #NEWLINE# try : #NEWLINE# #INDENT# import netCDF4 #NEWLINE# #UNINDENT# except Exception as e : #NEWLINE# #INDENT# mess = 'error import netCDF4: {0}' . format ( str ( e ) ) #NEWLINE# self . logger . warn ( mess ) #NEWLINE# raise Exception ( mess ) #NEWLINE# #UNINDENT# if isinstance ( other , str ) : #NEWLINE# #INDENT# assert os . path . exists ( other ) , ( "filename 'other' not found:" + '{0}' . format ( other ) ) #NEWLINE# other = netCDF4 . Dataset ( other , 'r' ) #NEWLINE# #UNINDENT# assert isinstance ( other , netCDF4 . Dataset ) #NEWLINE# self_vars = set ( self . nc . variables . keys ( ) ) #NEWLINE# other_vars = set ( other . variables ) #NEWLINE# diff = self_vars . symmetric_difference ( other_vars ) #NEWLINE# if ( len ( diff ) > 0 ) : #NEWLINE# #INDENT# self . logger . warn ( ( ( 'variables are not the same between the two ' + 'nc files: ' ) + ',' . join ( diff ) ) ) #NEWLINE# return #NEWLINE# #UNINDENT# self_dimens = self . nc . dimensions #NEWLINE# other_dimens = other . dimensions #NEWLINE# for d in self_dimens . keys ( ) : #NEWLINE# #INDENT# if ( d not in other_dimens ) : #NEWLINE# #INDENT# self . logger . warn ( 'missing dimension in other:{0}' . format ( d ) ) #NEWLINE# return #NEWLINE# #UNINDENT# if ( len ( self_dimens [ d ] ) != len ( other_dimens [ d ] ) ) : #NEWLINE# #INDENT# self . logger . warn ( ( 'dimension not consistent: ' + '{0}:{1}' . format ( self_dimens [ d ] , other_dimens [ d ] ) ) ) #NEWLINE# return #NEWLINE# #UNINDENT# #UNINDENT# time_values = self . nc . variables . get ( 'time' ) [ : ] #NEWLINE# new_net = NetCdf ( self . output_filename . replace ( '.nc' , '.diff.nc' ) , self . model , time_values = time_values ) #NEWLINE# for vname in self_vars : #NEWLINE# #INDENT# if ( ( vname not in self . var_attr_dict ) or ( new_net . nc . variables . get ( vname ) is not None ) ) : #NEWLINE# #INDENT# self . logger . warn ( 'skipping variable: {0}' . format ( vname ) ) #NEWLINE# continue #NEWLINE# #UNINDENT# self . log ( 'processing variable {0}' . format ( vname ) ) #NEWLINE# s_var = self . nc . variables [ vname ] #NEWLINE# o_var = other . variables [ vname ] #NEWLINE# s_data = s_var [ : ] #NEWLINE# o_data = o_var [ : ] #NEWLINE# ( o_mask , s_mask ) = ( None , None ) #NEWLINE# if isinstance ( s_data , np . ma . MaskedArray ) : #NEWLINE# #INDENT# self . logger . warn ( 'masked array for {0}' . format ( vname ) ) #NEWLINE# s_mask = s_data . mask #NEWLINE# o_mask = o_data . mask #NEWLINE# s_data = np . array ( s_data ) #NEWLINE# o_data = np . array ( o_data ) #NEWLINE# #UNINDENT# if ( minuend . lower ( ) == 'self' ) : #NEWLINE# #INDENT# d_data = ( s_data - o_data ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( minuend . lower ( ) == 'other' ) : #NEWLINE# #INDENT# d_data = ( o_data - s_data ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# mess = 'unrecognized minuend {0}' . format ( minuend ) #NEWLINE# self . logger . warn ( mess ) #NEWLINE# raise Exception ( mess ) #NEWLINE# #UNINDENT# #UNINDENT# if ( s_mask is not None ) : #NEWLINE# #INDENT# self . log ( 'applying self mask' ) #NEWLINE# d_data [ s_mask ] = FILLVALUE #NEWLINE# self . log ( 'applying self mask' ) #NEWLINE# #UNINDENT# if ( o_mask is not None ) : #NEWLINE# #INDENT# self . log ( 'applying other mask' ) #NEWLINE# d_data [ o_mask ] = FILLVALUE #NEWLINE# self . log ( 'applying other mask' ) #NEWLINE# #UNINDENT# var = new_net . create_variable ( vname , self . var_attr_dict [ vname ] , s_var . dtype , dimensions = s_var . dimensions ) #NEWLINE# d_data [ np . isnan ( d_data ) ] = FILLVALUE #NEWLINE# if mask_zero_diff : #NEWLINE# #INDENT# d_data [ np . where ( ( d_data == 0.0 ) ) ] = FILLVALUE #NEWLINE# #UNINDENT# var [ : ] = d_data #NEWLINE# self . log ( 'processing variable {0}' . format ( vname ) )