"""
Functions are useful untilities for SITperturb experiments
 
Notes
-----
    Author : Zachary Labe
    Date   : 13 August 2017
    
Usage
-----
    [1] calcDecJan(varx,vary,lat,lon,level,levsq)
    [2] calcDecJanFeb(varx,vary,lat,lon,level,levsq)
    [3] calc_indttest(varx,vary)
    [4] calc_weightedAve(var,lats)
    [5] calc_spatialCorr(varx,vary,lats,lons,weight)
    [6] calc_RMSE(varx,vary,lats,lons,weight)
    [7] calc_spatialCorrHeight(varx,vary,lats,lons,weight)
    [8] calc_spatialCorrHeightLev(varx,vary,lats,lons,weight,levelq)
"""

def calcDecJan(varx,vary,lat,lon,level,levsq):
    """
    Function calculates average for December-January

    Parameters
    ----------
    varx : 4d array or 5d array
        [year,month,lat,lon] or [year,month,lev,lat,lon]
    vary : 4d array or 5d array
        [year,month,lat,lon] or [year,month,lev,lat,lon]
    lat : 1d numpy array
        latitudes
    lon : 1d numpy array
        longitudes
    level : string
        Height of variable (surface or profile)
    levsq : integer
        number of levels
        
    Returns
    -------
    varx_dj : 3d array or 4d array
        [year,lat,lon] or [year,lev,lat,lon]
    vary_dj : 3d array
        [year,lat,lon] or [year,lev,lat,lon]

    Usage
    -----
    varx_dj,vary_dj = calcDecJan(varx,vary,lat,lon,level,levsq)
    """
    print('\n>>> Using calcDecJan function!')
    
    ### Import modules
    import numpy as np
    
    ### Reshape for 3d variables
    if level == 'surface':    
        varxravel = np.reshape(varx.copy(),
                           (int(varx.shape[0]*12),
                            int(lat.shape[0]),int(lon.shape[0])))
        varyravel = np.reshape(vary.copy(),
                               (int(vary.shape[0]*12),
                                int(lat.shape[0]),int(lon.shape[0]))) 
                               
        varx_dj = np.empty((varx.shape[0]-1,lat.shape[0],lon.shape[0]))
        vary_dj = np.empty((vary.shape[0]-1,lat.shape[0],lon.shape[0]) )                 
        for i in range(0,varxravel.shape[0]-12,12):
            counter = 0
            if i >= 12:
                counter = i//12
            djappendh = np.append(varxravel[11+i,:,:],varxravel[12+i,:,:])
            djappendf = np.append(varyravel[11+i,:,:],varyravel[12+i,:,:])    
            varx_dj[counter,:,:] = np.nanmean(np.reshape(djappendh,
                                    (2,int(lat.shape[0]),int(lon.shape[0]))),
                                    axis=0)                   
            vary_dj[counter,:,:] = np.nanmean(np.reshape(djappendf,
                                    (2,int(lat.shape[0]),int(lon.shape[0]))),
                                    axis=0)
    ### Reshape for 4d variables
    elif level == 'profile':
        varxravel = np.reshape(varx.copy(),
                           (int(varx.shape[0]*12.),levsq,
                            int(lat.shape[0]),int(lon.shape[0])))
        varyravel = np.reshape(vary.copy(),
                               (int(vary.shape[0]*12.),levsq,
                                int(lat.shape[0]),int(lon.shape[0]))) 
                               
        varx_dj = np.empty((int(varx.shape[0]-1),levsq,
                            int(lat.shape[0]),int(lon.shape[0])))
        vary_dj = np.empty((int(vary.shape[0]-1),levsq,
                            int(lat.shape[0]),int(lon.shape[0])) )                 
        for i in range(0,varxravel.shape[0]-12,12):
            counter = 0
            if i >= 12:
                counter = i//12
            djappendh = np.append(varxravel[11+i,:,:,:],
                                  varxravel[12+i,:,:,:])
            djappendf = np.append(varyravel[11+i,:,:,:],
                                  varyravel[12+i,:,:,:])    
            varx_dj[counter,:,:] = np.nanmean(np.reshape(djappendh,
                                    (2,levsq,int(lat.shape[0]),
                                     int(lon.shape[0]))),axis=0)                   
            vary_dj[counter,:,:] = np.nanmean(np.reshape(djappendf,
                                    (2,levsq,int(lat.shape[0]),
                                     int(lon.shape[0]))),axis=0)                               
    else:
        print(ValueError('Selected wrong height - (surface or profile!)!'))    
                                
    print('Completed: Organized data by months (ON,DJ,FM)!')

    print('*Completed: Finished calcDecJan function!')
    return varx_dj,vary_dj

###############################################################################
###############################################################################
###############################################################################

def calcDecJanFeb(varx,vary,lat,lon,level,levsq):
    """
    Function calculates average for December-January-February

    Parameters
    ----------
    varx : 4d array or 5d array
        [year,month,lat,lon] or [year,month,lev,lat,lon]
    vary : 4d array or 5d array
        [year,month,lat,lon] or [year,month,lev,lat,lon]
    lat : 1d numpy array
        latitudes
    lon : 1d numpy array
        longitudes
    level : string
        Height of variable (surface or profile)
    levsq : integer
        number of levels
        
    Returns
    -------
    varx_djf : 3d array or 4d array
        [year,lat,lon] or [year,lev,lat,lon]
    vary_djf : 3d array
        [year,lat,lon] or [year,lev,lat,lon]

    Usage
    -----
    varx_djf,vary_djf = calcDecJanFeb(varx,vary,lat,lon,level,levsq)
    """
    print('\n>>> Using calcDecJan function!')
    
    ### Import modules
    import numpy as np
    
    ### Reshape for 3d variables
    if level == 'surface':    
        varxravel = np.reshape(varx.copy(),
                           (int(varx.shape[0]*12),
                            int(lat.shape[0]),int(lon.shape[0])))
        varyravel = np.reshape(vary.copy(),
                               (int(vary.shape[0]*12),
                                int(lat.shape[0]),int(lon.shape[0]))) 
                               
        varx_djf = np.empty((varx.shape[0]-1,lat.shape[0],lon.shape[0]))
        vary_djf = np.empty((vary.shape[0]-1,lat.shape[0],lon.shape[0]) )                 
        for i in range(0,varxravel.shape[0]-12,12):
            counter = 0
            if i >= 12:
                counter = i//12
            djfappendh1 = np.append(varxravel[11+i,:,:],varxravel[12+i,:,:])
            djfappendf1 = np.append(varyravel[11+i,:,:],varyravel[12+i,:,:])  
            djfappendh = np.append(djfappendh1,varxravel[13+i,:,:])
            djfappendf = np.append(djfappendf1,varyravel[13+i,:,:]) 
            varx_djf[counter,:,:] = np.nanmean(np.reshape(djfappendh,
                                    (3,int(lat.shape[0]),int(lon.shape[0]))),
                                    axis=0)                   
            vary_djf[counter,:,:] = np.nanmean(np.reshape(djfappendf,
                                    (3,int(lat.shape[0]),int(lon.shape[0]))),
                                    axis=0)
    ### Reshape for 4d variables
    elif level == 'profile':
        varxravel = np.reshape(varx.copy(),
                           (int(varx.shape[0]*12.),levsq,
                            int(lat.shape[0]),int(lon.shape[0])))
        varyravel = np.reshape(vary.copy(),
                               (int(vary.shape[0]*12.),levsq,
                                int(lat.shape[0]),int(lon.shape[0]))) 
                               
        varx_djf = np.empty((int(varx.shape[0]-1),levsq,
                            int(lat.shape[0]),int(lon.shape[0])))
        vary_djf = np.empty((int(vary.shape[0]-1),levsq,
                            int(lat.shape[0]),int(lon.shape[0])) )                 
        for i in range(0,varxravel.shape[0]-12,12):
            counter = 0
            if i >= 12:
                counter = i//12
            djfappendh1 = np.append(varxravel[11+i,:,:,:],
                                  varxravel[12+i,:,:,:])
            djfappendf1 = np.append(varyravel[11+i,:,:,:],
                                  varyravel[12+i,:,:,:]) 
            djfappendh = np.append(djfappendh1,
                                  varxravel[13+i,:,:,:])
            djfappendf = np.append(djfappendf1,
                                  varyravel[13+i,:,:,:])  
            varx_djf[counter,:,:] = np.nanmean(np.reshape(djfappendh,
                                    (3,levsq,int(lat.shape[0]),
                                     int(lon.shape[0]))),axis=0)                   
            vary_djf[counter,:,:] = np.nanmean(np.reshape(djfappendf,
                                    (3,levsq,int(lat.shape[0]),
                                     int(lon.shape[0]))),axis=0)                               
    else:
        print(ValueError('Selected wrong height - (surface or profile!)!'))    
                                
    print('Completed: Organized data by months (DJF)!')

    print('*Completed: Finished calcDecJanFeb function!')
    return varx_djf,vary_djf

###############################################################################
###############################################################################
###############################################################################
    
def calc_indttest(varx,vary):
    """
    Function calculates statistical difference for 2 independent
    sample t-test

    Parameters
    ----------
    varx : 3d array
    vary : 3d array
    
    Returns
    -------
    stat = calculated t-statistic
    pvalue = two-tailed p-value

    Usage
    -----
    stat,pvalue = calc_ttest(varx,vary)
    """
    print('\n>>> Using calc_ttest function!')
    
    ### Import modules
    import numpy as np
    import scipy.stats as sts
    
    ### 2-independent sample t-test
    stat,pvalue = sts.ttest_ind(varx,vary,nan_policy='omit')
    
    ### Significant at 95% confidence level
    pvalue[np.where(pvalue >= 0.05)] = np.nan
    pvalue[np.where(pvalue < 0.05)] = 1.
    
    print('*Completed: Finished calc_ttest function!')
    return stat,pvalue

###############################################################################
###############################################################################
###############################################################################

def calc_weightedAve(var,lats):
    """
    Area weights sit array 5d [ens,year,month,lat,lon] into [ens,year,month]
    
    Parameters
    ----------
    var : 5d,4d,3d array of a gridded variable
    lats : 2d array of latitudes
    
    Returns
    -------
    meanvar : weighted average for 3d,2d,1d array

    Usage
    -----
    meanvar = calc_weightedAve(var,lats)
    """
    print('\n>>> Using calc_weightedAve function!')
    
    ### Import modules
    import numpy as np
    
    ### Calculate weighted average for various dimensional arrays
    if var.ndim == 5:
        meanvar = np.empty((var.shape[0],var.shape[1],var.shape[2]))
        for ens in range(var.shape[0]):
            for i in range(var.shape[1]):
                for j in range(var.shape[2]):
                    varq = var[ens,i,j,:,:]
                    mask = np.isfinite(varq) & np.isfinite(lats)
                    varmask = varq[mask]
                    areamask = np.cos(np.deg2rad(lats[mask]))
                    meanvar[ens,i,j] = np.nansum(varmask*areamask) \
                                        /np.sum(areamask)  
    elif var.ndim == 4:
        meanvar = np.empty((var.shape[0],var.shape[1]))
        for i in range(var.shape[0]):
            for j in range(var.shape[1]):
                varq = var[i,j,:,:]
                mask = np.isfinite(varq) & np.isfinite(lats)
                varmask = varq[mask]
                areamask = np.cos(np.deg2rad(lats[mask]))
                meanvar[i,j] = np.nansum(varmask*areamask)/np.sum(areamask)
    elif var.ndim == 3:
        meanvar = np.empty((var.shape[0]))
        for i in range(var.shape[0]):
            varq = var[i,:,:]
            mask = np.isfinite(varq) & np.isfinite(lats)
            varmask = varq[mask]
            areamask = np.cos(np.deg2rad(lats[mask]))
            meanvar[i] = np.nansum(varmask*areamask)/np.sum(areamask)
    elif var.ndim == 2:
        meanvar = np.empty((var.shape[0]))
        varq = var[:,:]
        mask = np.isfinite(varq) & np.isfinite(lats)
        varmask = varq[mask]
        areamask = np.cos(np.deg2rad(lats[mask]))
        meanvar = np.nansum(varmask*areamask)/np.sum(areamask)
    else:
        print(ValueError('Variable has the wrong dimensions!'))
     
    print('Completed: Weighted variable average!')
    
    print('*Completed: Finished calc_weightedAve function!')
    return meanvar

###############################################################################
###############################################################################
###############################################################################
    
def calc_spatialCorr(varx,vary,lats,lons,weight):
    """
    Calculates spatial correlation from pearson correlation coefficient
    
    Parameters
    ----------
    varx : 2d array
    vary : 2d array
    lats : 1d array
    lons : 1d array of latitude
    weight : string (yes or no)
    
    Returns
    -------
    corrcoef : 1d array of correlation coefficient (pearson r)
    
    Usage
    -----
    corrcoef = calc_spatialCorr(varx,vary,lats,lons)
    """
    
    print('\n>>> Using calc_spatialCorr function!')
    ### Import modules
    import numpy as np
    
    if weight == 'yes': # Computed weighted correlation coefficient   
        ### mask 
        mask = 'yes'
        if mask == 'yes':
            latq = np.where(lats > 40)[0]
            lats = lats[latq]
            varx = varx[latq,:]
            vary = vary[latq,:]
            print('MASKING LATITUDES!')
        
        ### Create 2d meshgrid for weights 
        lon2,lat2 = np.meshgrid(lons,lats)
        
        ### Create 2d array of weights based on latitude
        gw = np.cos(np.deg2rad(lat2))
        
        def m(x, w):
            """Weighted Mean"""
    
            wave = np.sum(x * w) / np.sum(w)
            print('Completed: Computed weighted average!') 
            return wave
        
        def cov(x, y, w):
            """Weighted Covariance"""
            
            wcov = np.sum(w * (x - m(x, w)) * (y - m(y, w))) / np.sum(w)
            print('Completed: Computed weighted covariance!')
            return wcov
        
        def corr(x, y, w):
            """Weighted Correlation"""
            
            wcor = cov(x, y, w) / np.sqrt(cov(x, x, w) * cov(y, y, w))
            print('Completed: Computed weighted correlation!')
            return wcor
        
        corrcoef = corr(varx,vary,gw)
        
    elif weight == 'no':   
        ### Correlation coefficient from numpy function (not weighted)
        corrcoef= np.corrcoef(varx.ravel(),vary.ravel())[0][1]
        print('Completed: Computed NON-weighted correlation!')
        
    else:
        ValueError('Wrong weighted arguement in function!')
    
    print('*Completed: Finished calc_SpatialCorr function!')
    return corrcoef

###############################################################################
###############################################################################
###############################################################################

def calc_RMSE(varx,vary,lats,lons,weight):
        """
        Calculates root mean square weighted average
        
        Parameters
        ----------
        varx : 2d array
        vary : 2d array
        lons : 1d array of latitude
        weight : string (yes or no)
        
        Returns
        -------
        rmse : 1d array
        
        Usage
        -----
        rmse = calc_RMSE(varx,vary,lats,lons)
        """
        
        print('\n>>> Using calc_RMSE function!')
        ### Import modules
        import numpy as np
        from sklearn.metrics import mean_squared_error
        
        if weight == 'yes': # Computed weighted correlation coefficient   
            ### mask
            mask = 'yes'
            if mask == 'yes':
                latq = np.where(lats > 40)[0]
                lats = lats[latq]
                varx = varx[latq,:]
                vary = vary[latq,:]
                print('MASKING LATITUDES!')
            
            ### Create 2d meshgrid for weights 
            lon2,lat2 = np.meshgrid(lons,lats)
            
            ### Create 2d array of weights based on latitude
            gw = np.cos(np.deg2rad(lat2))
            
            ### Calculate rmse 
            sq_err = (varx - vary)**2
            rmse = np.sqrt((np.sum(sq_err*gw))/np.sum(gw))
     
        elif weight == 'no':   
            ### Root mean square error from sklearn (not weighted)
            rmse = np.sqrt(mean_squared_error(varx.ravel(),vary.ravel()))
            print('Completed: Computed NON-weighted correlation!')
            
        else:
            ValueError('Wrong weighted arguement in function!')
        
        print('*Completed: Finished calc_RMSE function!')
        return rmse
    
###############################################################################
###############################################################################
###############################################################################
    
def calc_spatialCorrHeight(varx,vary,levs,lons,weight):
    """
    Calculates spatial correlation from pearson correlation coefficient for
    grids over vertical height (17 pressure coordinate levels)
    
    Parameters
    ----------
    varx : 2d array
    vary : 2d array
    levs : 1d array of levels
    lons : 1d array of latitude
    weight : string (yes or no)
    
    Returns
    -------
    corrcoef : 1d array of correlation coefficient (pearson r)
    
    Usage
    -----
    corrcoef = calc_spatialCorrHeight(varx,vary,lats,lons)
    """
    
    print('\n>>> Using calc_spatialCorrHeight function!')
    ### Import modules
    import numpy as np
    
    if weight == 'yes': # Computed weighted correlation coefficient   
        
        ### Create 2d meshgrid for weights 
        lon2,lev2 = np.meshgrid(lons,levs)
        
        ### Create 2d array of weights based on latitude
        gwq = np.array([0.25,0.25,0.25,0.25,0.25,0.25,0.4,0.5,0.5,0.5,
              0.5,0.5,0.5,0.7,0.7,0.7,1.])
        gw,gw2 = np.meshgrid(lons,gwq)
        
        def m(x, w):
            """Weighted Mean"""
    
            wave = np.sum(x * w) / np.sum(w)
            print('Completed: Computed weighted average (17 P Levels)!') 
            return wave
        
        def cov(x, y, w):
            """Weighted Covariance"""
            
            wcov = np.sum(w * (x - m(x, w)) * (y - m(y, w))) / np.sum(w)
            print('Completed: Computed weighted covariance (17 P Levels)!')
            return wcov
        
        def corr(x, y, w):
            """Weighted Correlation"""
            
            wcor = cov(x, y, w) / np.sqrt(cov(x, x, w) * cov(y, y, w))
            print('Completed: Computed weighted correlation (17 P Levels)!')
            return wcor
        
        corrcoef = corr(varx,vary,gw)
        
    elif weight == 'no':   
        ### Correlation coefficient from numpy function (not weighted)
        corrcoef= np.corrcoef(varx.ravel(),vary.ravel())[0][1]
        print('Completed: Computed NON-weighted correlation!')
        
    else:
        ValueError('Wrong weighted argument in function!')
    
    print('*Completed: Finished calc_SpatialCorrHeight function!')
    return corrcoef

###############################################################################
###############################################################################
###############################################################################
    
def calc_spatialCorrHeightLev(varx,vary,levs,lons,weight,levelq):
    """
    Calculates spatial correlation from pearson correlation coefficient for
    grids over vertical height (17 pressure coordinate levels). Change the 
    weighting for different level correlations
    
    Parameters
    ----------
    varx : 2d array
    vary : 2d array
    levs : 1d array of levels
    lons : 1d array of latitude
    weight : string (yes or no)
    levelq : string (all, tropo, strato)
    
    Returns
    -------
    corrcoef : 1d array of correlation coefficient (pearson r)
    
    Usage
    -----
    corrcoef = calc_spatialCorrHeight(varx,vary,lats,lons,levels)
    """
    
    print('\n>>> Using calc_spatialCorrHeightLev function!')
    ### Import modules
    import numpy as np
    
    if weight == 'yes': # Computed weighted correlation coefficient   
        
        ### Create 2d meshgrid for weights 
        lon2,lev2 = np.meshgrid(lons,levs)
        
        if levelq == 'all':
            ### Create 2d array of weights based on latitude
            gwq = np.array([0.25,0.25,0.25,0.25,0.25,0.25,0.4,0.5,0.5,0.5,
                  0.5,0.5,0.5,0.7,0.7,0.7,1.])
            gw,gw2 = np.meshgrid(lons,gwq)
        elif levelq == 'tropo':
           gwq = np.array([1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.2,0.2,0.,0.,0.,
                           0.,0.,0.,0.,0.])
           gw,gw2 = np.meshgrid(lons,gwq)
        elif levelq == 'strato':
           gwq = np.array([0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.5,1.,1.,1.,1.
                           ,1.,1.])
           gw,gw2 = np.meshgrid(lons,gwq)
        
        def m(x, w):
            """Weighted Mean"""
    
            wave = np.sum(x * w) / np.sum(w)
            print('Completed: Computed weighted average (17 P Levels)!') 
            return wave
        
        def cov(x, y, w):
            """Weighted Covariance"""
            
            wcov = np.sum(w * (x - m(x, w)) * (y - m(y, w))) / np.sum(w)
            print('Completed: Computed weighted covariance (17 P Levels)!')
            return wcov
        
        def corr(x, y, w):
            """Weighted Correlation"""
            
            wcor = cov(x, y, w) / np.sqrt(cov(x, x, w) * cov(y, y, w))
            print('Completed: Computed weighted correlation (17 P Levels)!')
            return wcor
        
        corrcoef = corr(varx,vary,gw)
        
    elif weight == 'no':   
        ### Correlation coefficient from numpy function (not weighted)
        corrcoef= np.corrcoef(varx.ravel(),vary.ravel())[0][1]
        print('Completed: Computed NON-weighted correlation!')
        
    else:
        ValueError('Wrong weighted argument in function!')
    
    print('*Completed: Finished calc_SpatialCorrHeightLev function!')
    return corrcoef
[((247, 18, 247, 60), 'scipy.stats.ttest_ind', 'sts.ttest_ind', (), '', True, 'import scipy.stats as sts\n'), ((65, 18, 65, 71), 'numpy.empty', 'np.empty', ({(65, 27, 65, 70): '(varx.shape[0] - 1, lat.shape[0], lon.shape[0])'}, {}), '((varx.shape[0] - 1, lat.shape[0], lon.shape[0]))', True, 'import numpy as np\n'), ((66, 18, 66, 72), 'numpy.empty', 'np.empty', ({(66, 27, 66, 70): '(vary.shape[0] - 1, lat.shape[0], lon.shape[0])'}, {}), '((vary.shape[0] - 1, lat.shape[0], lon.shape[0]))', True, 'import numpy as np\n'), ((162, 19, 162, 72), 'numpy.empty', 'np.empty', ({(162, 28, 162, 71): '(varx.shape[0] - 1, lat.shape[0], lon.shape[0])'}, {}), '((varx.shape[0] - 1, lat.shape[0], lon.shape[0]))', True, 'import numpy as np\n'), ((163, 19, 163, 73), 'numpy.empty', 'np.empty', ({(163, 28, 163, 71): '(vary.shape[0] - 1, lat.shape[0], lon.shape[0])'}, {}), '((vary.shape[0] - 1, lat.shape[0], lon.shape[0]))', True, 'import numpy as np\n'), ((284, 18, 284, 68), 'numpy.empty', 'np.empty', ({(284, 27, 284, 67): '(var.shape[0], var.shape[1], var.shape[2])'}, {}), '((var.shape[0], var.shape[1], var.shape[2]))', True, 'import numpy as np\n'), ((366, 20, 366, 42), 'numpy.meshgrid', 'np.meshgrid', ({(366, 32, 366, 36): 'lons', (366, 37, 366, 41): 'lats'}, {}), '(lons, lats)', True, 'import numpy as np\n'), ((445, 24, 445, 46), 'numpy.meshgrid', 'np.meshgrid', ({(445, 36, 445, 40): 'lons', (445, 41, 445, 45): 'lats'}, {}), '(lons, lats)', True, 'import numpy as np\n'), ((498, 20, 498, 42), 'numpy.meshgrid', 'np.meshgrid', ({(498, 32, 498, 36): 'lons', (498, 37, 498, 41): 'levs'}, {}), '(lons, levs)', True, 'import numpy as np\n'), ((501, 14, 502, 42), 'numpy.array', 'np.array', ({(501, 23, 502, 41): '[0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.7,\n    0.7, 0.7, 1.0]'}, {}), '([0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5,\n    0.5, 0.7, 0.7, 0.7, 1.0])', True, 'import numpy as np\n'), ((503, 17, 503, 38), 'numpy.meshgrid', 'np.meshgrid', ({(503, 29, 503, 33): 'lons', (503, 34, 503, 37): 'gwq'}, {}), '(lons, gwq)', True, 'import numpy as np\n'), ((574, 20, 574, 42), 'numpy.meshgrid', 'np.meshgrid', ({(574, 32, 574, 36): 'lons', (574, 37, 574, 41): 'levs'}, {}), '(lons, levs)', True, 'import numpy as np\n'), ((71, 24, 71, 74), 'numpy.append', 'np.append', ({(71, 34, 71, 53): 'varxravel[(11 + i), :, :]', (71, 54, 71, 73): 'varxravel[(12 + i), :, :]'}, {}), '(varxravel[(11 + i), :, :], varxravel[(12 + i), :, :])', True, 'import numpy as np\n'), ((72, 24, 72, 74), 'numpy.append', 'np.append', ({(72, 34, 72, 53): 'varyravel[(11 + i), :, :]', (72, 54, 72, 73): 'varyravel[(12 + i), :, :]'}, {}), '(varyravel[(11 + i), :, :], varyravel[(12 + i), :, :])', True, 'import numpy as np\n'), ((168, 26, 168, 76), 'numpy.append', 'np.append', ({(168, 36, 168, 55): 'varxravel[(11 + i), :, :]', (168, 56, 168, 75): 'varxravel[(12 + i), :, :]'}, {}), '(varxravel[(11 + i), :, :], varxravel[(12 + i), :, :])', True, 'import numpy as np\n'), ((169, 26, 169, 76), 'numpy.append', 'np.append', ({(169, 36, 169, 55): 'varyravel[(11 + i), :, :]', (169, 56, 169, 75): 'varyravel[(12 + i), :, :]'}, {}), '(varyravel[(11 + i), :, :], varyravel[(12 + i), :, :])', True, 'import numpy as np\n'), ((170, 25, 170, 67), 'numpy.append', 'np.append', ({(170, 35, 170, 46): 'djfappendh1', (170, 47, 170, 66): 'varxravel[(13 + i), :, :]'}, {}), '(djfappendh1, varxravel[(13 + i), :, :])', True, 'import numpy as np\n'), ((171, 25, 171, 67), 'numpy.append', 'np.append', ({(171, 35, 171, 46): 'djfappendf1', (171, 47, 171, 66): 'varyravel[(13 + i), :, :]'}, {}), '(djfappendf1, varyravel[(13 + i), :, :])', True, 'import numpy as np\n'), ((250, 11, 250, 35), 'numpy.where', 'np.where', ({(250, 20, 250, 34): '(pvalue >= 0.05)'}, {}), '(pvalue >= 0.05)', True, 'import numpy as np\n'), ((251, 11, 251, 34), 'numpy.where', 'np.where', ({(251, 20, 251, 33): '(pvalue < 0.05)'}, {}), '(pvalue < 0.05)', True, 'import numpy as np\n'), ((295, 18, 295, 55), 'numpy.empty', 'np.empty', ({(295, 27, 295, 54): '(var.shape[0], var.shape[1])'}, {}), '((var.shape[0], var.shape[1]))', True, 'import numpy as np\n'), ((369, 20, 369, 36), 'numpy.deg2rad', 'np.deg2rad', ({(369, 31, 369, 35): 'lat2'}, {}), '(lat2)', True, 'import numpy as np\n'), ((448, 24, 448, 40), 'numpy.deg2rad', 'np.deg2rad', ({(448, 35, 448, 39): 'lat2'}, {}), '(lat2)', True, 'import numpy as np\n'), ((578, 18, 579, 46), 'numpy.array', 'np.array', ({(578, 27, 579, 45): '[0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.7,\n    0.7, 0.7, 1.0]'}, {}), '([0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5,\n    0.5, 0.7, 0.7, 0.7, 1.0])', True, 'import numpy as np\n'), ((580, 21, 580, 42), 'numpy.meshgrid', 'np.meshgrid', ({(580, 33, 580, 37): 'lons', (580, 38, 580, 41): 'gwq'}, {}), '(lons, gwq)', True, 'import numpy as np\n'), ((96, 24, 97, 56), 'numpy.append', 'np.append', ({(96, 34, 96, 55): 'varxravel[(11 + i), :, :, :]', (97, 34, 97, 55): 'varxravel[(12 + i), :, :, :]'}, {}), '(varxravel[(11 + i), :, :, :], varxravel[(12 + i), :, :, :])', True, 'import numpy as np\n'), ((98, 24, 99, 56), 'numpy.append', 'np.append', ({(98, 34, 98, 55): 'varyravel[(11 + i), :, :, :]', (99, 34, 99, 55): 'varyravel[(12 + i), :, :, :]'}, {}), '(varyravel[(11 + i), :, :, :], varyravel[(12 + i), :, :, :])', True, 'import numpy as np\n'), ((195, 26, 196, 56), 'numpy.append', 'np.append', ({(195, 36, 195, 57): 'varxravel[(11 + i), :, :, :]', (196, 34, 196, 55): 'varxravel[(12 + i), :, :, :]'}, {}), '(varxravel[(11 + i), :, :, :], varxravel[(12 + i), :, :, :])', True, 'import numpy as np\n'), ((197, 26, 198, 56), 'numpy.append', 'np.append', ({(197, 36, 197, 57): 'varyravel[(11 + i), :, :, :]', (198, 34, 198, 55): 'varyravel[(12 + i), :, :, :]'}, {}), '(varyravel[(11 + i), :, :, :], varyravel[(12 + i), :, :, :])', True, 'import numpy as np\n'), ((199, 25, 200, 56), 'numpy.append', 'np.append', ({(199, 35, 199, 46): 'djfappendh1', (200, 34, 200, 55): 'varxravel[(13 + i), :, :, :]'}, {}), '(djfappendh1, varxravel[(13 + i), :, :, :])', True, 'import numpy as np\n'), ((201, 25, 202, 56), 'numpy.append', 'np.append', ({(201, 35, 201, 46): 'djfappendf1', (202, 34, 202, 55): 'varyravel[(13 + i), :, :, :]'}, {}), '(djfappendf1, varyravel[(13 + i), :, :, :])', True, 'import numpy as np\n'), ((304, 18, 304, 42), 'numpy.empty', 'np.empty', ({(304, 28, 304, 40): 'var.shape[0]'}, {}), '(var.shape[0])', True, 'import numpy as np\n'), ((359, 19, 359, 38), 'numpy.where', 'np.where', ({(359, 28, 359, 37): '(lats > 40)'}, {}), '(lats > 40)', True, 'import numpy as np\n'), ((374, 19, 374, 32), 'numpy.sum', 'np.sum', ({(374, 26, 374, 31): '(x * w)'}, {}), '(x * w)', True, 'import numpy as np\n'), ((374, 35, 374, 44), 'numpy.sum', 'np.sum', ({(374, 42, 374, 43): 'w'}, {}), '(w)', True, 'import numpy as np\n'), ((381, 63, 381, 72), 'numpy.sum', 'np.sum', ({(381, 70, 381, 71): 'w'}, {}), '(w)', True, 'import numpy as np\n'), ((438, 23, 438, 42), 'numpy.where', 'np.where', ({(438, 32, 438, 41): '(lats > 40)'}, {}), '(lats > 40)', True, 'import numpy as np\n'), ((452, 28, 452, 45), 'numpy.sum', 'np.sum', ({(452, 35, 452, 44): 'sq_err * gw'}, {}), '(sq_err * gw)', True, 'import numpy as np\n'), ((452, 47, 452, 57), 'numpy.sum', 'np.sum', ({(452, 54, 452, 56): 'gw'}, {}), '(gw)', True, 'import numpy as np\n'), ((508, 19, 508, 32), 'numpy.sum', 'np.sum', ({(508, 26, 508, 31): '(x * w)'}, {}), '(x * w)', True, 'import numpy as np\n'), ((508, 35, 508, 44), 'numpy.sum', 'np.sum', ({(508, 42, 508, 43): 'w'}, {}), '(w)', True, 'import numpy as np\n'), ((515, 63, 515, 72), 'numpy.sum', 'np.sum', ({(515, 70, 515, 71): 'w'}, {}), '(w)', True, 'import numpy as np\n'), ((582, 17, 583, 43), 'numpy.array', 'np.array', ({(582, 26, 583, 42): '[1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.2, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n    0.0, 0.0]'}, {}), '([1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.2, 0.2, 0.0, 0.0, 0.0, 0.0, \n    0.0, 0.0, 0.0, 0.0])', True, 'import numpy as np\n'), ((584, 20, 584, 41), 'numpy.meshgrid', 'np.meshgrid', ({(584, 32, 584, 36): 'lons', (584, 37, 584, 40): 'gwq'}, {}), '(lons, gwq)', True, 'import numpy as np\n'), ((593, 19, 593, 32), 'numpy.sum', 'np.sum', ({(593, 26, 593, 31): '(x * w)'}, {}), '(x * w)', True, 'import numpy as np\n'), ((593, 35, 593, 44), 'numpy.sum', 'np.sum', ({(593, 42, 593, 43): 'w'}, {}), '(w)', True, 'import numpy as np\n'), ((600, 63, 600, 72), 'numpy.sum', 'np.sum', ({(600, 70, 600, 71): 'w'}, {}), '(w)', True, 'import numpy as np\n'), ((312, 18, 312, 42), 'numpy.empty', 'np.empty', ({(312, 28, 312, 40): 'var.shape[0]'}, {}), '(var.shape[0])', True, 'import numpy as np\n'), ((586, 17, 587, 35), 'numpy.array', 'np.array', ({(586, 26, 587, 34): '[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0,\n    1.0, 1.0]'}, {}), '([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, \n    1.0, 1.0, 1.0, 1.0])', True, 'import numpy as np\n'), ((588, 20, 588, 41), 'numpy.meshgrid', 'np.meshgrid', ({(588, 32, 588, 36): 'lons', (588, 37, 588, 40): 'gwq'}, {}), '(lons, gwq)', True, 'import numpy as np\n'), ((289, 27, 289, 44), 'numpy.isfinite', 'np.isfinite', ({(289, 39, 289, 43): 'varq'}, {}), '(varq)', True, 'import numpy as np\n'), ((289, 47, 289, 64), 'numpy.isfinite', 'np.isfinite', ({(289, 59, 289, 63): 'lats'}, {}), '(lats)', True, 'import numpy as np\n'), ((291, 38, 291, 60), 'numpy.deg2rad', 'np.deg2rad', ({(291, 49, 291, 59): 'lats[mask]'}, {}), '(lats[mask])', True, 'import numpy as np\n'), ((292, 39, 292, 66), 'numpy.nansum', 'np.nansum', ({(292, 49, 292, 65): '(varmask * areamask)'}, {}), '(varmask * areamask)', True, 'import numpy as np\n'), ((293, 41, 293, 57), 'numpy.sum', 'np.sum', ({(293, 48, 293, 56): 'areamask'}, {}), '(areamask)', True, 'import numpy as np\n'), ((299, 23, 299, 40), 'numpy.isfinite', 'np.isfinite', ({(299, 35, 299, 39): 'varq'}, {}), '(varq)', True, 'import numpy as np\n'), ((299, 43, 299, 60), 'numpy.isfinite', 'np.isfinite', ({(299, 55, 299, 59): 'lats'}, {}), '(lats)', True, 'import numpy as np\n'), ((301, 34, 301, 56), 'numpy.deg2rad', 'np.deg2rad', ({(301, 45, 301, 55): 'lats[mask]'}, {}), '(lats[mask])', True, 'import numpy as np\n'), ((302, 31, 302, 58), 'numpy.nansum', 'np.nansum', ({(302, 41, 302, 57): '(varmask * areamask)'}, {}), '(varmask * areamask)', True, 'import numpy as np\n'), ((302, 59, 302, 75), 'numpy.sum', 'np.sum', ({(302, 66, 302, 74): 'areamask'}, {}), '(areamask)', True, 'import numpy as np\n'), ((307, 19, 307, 36), 'numpy.isfinite', 'np.isfinite', ({(307, 31, 307, 35): 'varq'}, {}), '(varq)', True, 'import numpy as np\n'), ((307, 39, 307, 56), 'numpy.isfinite', 'np.isfinite', ({(307, 51, 307, 55): 'lats'}, {}), '(lats)', True, 'import numpy as np\n'), ((309, 30, 309, 52), 'numpy.deg2rad', 'np.deg2rad', ({(309, 41, 309, 51): 'lats[mask]'}, {}), '(lats[mask])', True, 'import numpy as np\n'), ((310, 25, 310, 52), 'numpy.nansum', 'np.nansum', ({(310, 35, 310, 51): '(varmask * areamask)'}, {}), '(varmask * areamask)', True, 'import numpy as np\n'), ((310, 53, 310, 69), 'numpy.sum', 'np.sum', ({(310, 60, 310, 68): 'areamask'}, {}), '(areamask)', True, 'import numpy as np\n'), ((314, 15, 314, 32), 'numpy.isfinite', 'np.isfinite', ({(314, 27, 314, 31): 'varq'}, {}), '(varq)', True, 'import numpy as np\n'), ((314, 35, 314, 52), 'numpy.isfinite', 'np.isfinite', ({(314, 47, 314, 51): 'lats'}, {}), '(lats)', True, 'import numpy as np\n'), ((316, 26, 316, 48), 'numpy.deg2rad', 'np.deg2rad', ({(316, 37, 316, 47): 'lats[mask]'}, {}), '(lats[mask])', True, 'import numpy as np\n'), ((317, 18, 317, 45), 'numpy.nansum', 'np.nansum', ({(317, 28, 317, 44): '(varmask * areamask)'}, {}), '(varmask * areamask)', True, 'import numpy as np\n'), ((317, 46, 317, 62), 'numpy.sum', 'np.sum', ({(317, 53, 317, 61): 'areamask'}, {}), '(areamask)', True, 'import numpy as np\n')]