<commit_before>#!/usr/bin/python2.7
# encoding: utf-8

#Libs import
from __future__ import division
import numpy as np
import sys
from utide import ut_solv, ut_reconstr
#TR comment: 2 alternatives
#import netCDF4 as nc
from scipy.io import netcdf
import mmap
import cPickle as pkl
#import pickle as pkl
#WB_Alternative: import scipy.io as sio

#Add local path to utilities
sys.path.append('../utilities/')

#Utility import
from shortest_element_path import shortest_element_path
from object_from_dict import ObjectFromDict

#Local import
from variablesFvcom import _load_var, _load_grid
from functionsFvcom import *
from functionsFvcomThreeD import *
from plotsFvcom import *

class FVCOM:
    '''
Description:
----------
  A class/structure for FVCOM data.
  Functionality structured as follows:
                _Data. = raw netcdf file data
               |_Variables. = fvcom variables and quantities
               |_Grid. = fvcom grid data
               |_QC = Quality Control metadata
    testFvcom._|_Utils2D. = set of useful functions
               |_Utils3D. = set of useful functions
               |_Plots. = plotting functions
               |_method_1
               | ...      = methods and analysis techniques intrinsic to fvcom runs
               |_method_n

Inputs:
------
  Takes a file name as input, ex: testFvcom=FVCOM('./path_to_FVOM_output_file/filename')

Options:
-------
    Can be defined for a region only, i.e. a bounding box, as such:
        ax = [minimun longitude, maximun longitude,
              minimun latitude, maximum latitude]
    Can be defined for a time period only, as such:
        tx = ['2012.11.07','2012.11.09'], string of year.month.date
Notes:
-----
    As of right now, only takes a filename as input. It will then load in the
    data (except for timeseries, since loading in the whole time series can be
    too large)
    '''

    def __init__(self, filename, ax=[], tx=[], debug=False):
        ''' Initialize FVCOM class.'''
        self._debug = debug
        if debug:
            print '-Debug mode on-'

        #Loading pickle file
        if filename.endswith('.p'):
            f = open(filename, "rb")
            data = pkl.load(f)
            self.History = data['History']
            self.Grid = ObjectFromDict(data['Grid'])
            self.Variables = ObjectFromDict(data['Variables'])
            try:
                #WB_Alternative: self.Data = sio.netcdf.netcdf_file(filename, 'r')
                #WB_comments: scipy has causes some errors, and even though can be
                #             faster, can be unreliable
                #self.Data = nc.Dataset(data['Origin'], 'r')
                self.Data = netcdf.netcdf_file(data['Origin'], 'r',mmap=True)
            except: #TR: need to precise the type of error here
                print "the original *.nc file has not been found"
                pass

        #Loading netcdf file         
        elif filename.endswith('.nc'):
            #WB_Alternative: self.Data = sio.netcdf.netcdf_file(filename, 'r')
            #WB_comments: scipy has causes some errors, and even though can be
            #             faster, can be unreliable
            #self.Data = nc.Dataset(filename, 'r')
            self.Data = netcdf.netcdf_file(filename, 'r',mmap=True)
            text = 'Created from ' + filename
            self._origin_file = filename
            #Metadata
            self.History = [text]
            # Calling sub-class
            print "Initialisation..."
            #print "This might take some time..."
            try:
                self.Grid = _load_grid(self.Data,
                                       ax,
                                       self.History,
                                       debug=self._debug)
                self.Variables = _load_var(self.Data,
                                           self.Grid,
                                           tx,
                                           self.History,
                                           debug=self._debug)
            except MemoryError:
                print '---Data too large for machine memory---'
                print 'Tip: use ax or tx during class initialisation'
                print '---  to use partial data'
                raise

        elif filename.endswith('.mat'):
            print "Cannot handle *.mat file yet"

        else:
            print "---Wrong file format---"
            sys.exit()

        self.Plots = PlotsFvcom(self.Variables,
                                self.Grid,
                                self._debug)
        self.Util2D = FunctionsFvcom(self.Variables,
                                     self.Grid,
                                     self.Plots,
                                     self.History,
                                     self._debug)

        if self.Variables._3D:
            self.Util3D = FunctionsFvcomThreeD(self.Variables,
                                               self.Grid,
                                               self.Plots,
                                               self.Util2D,
                                               self.History,
                                               self._debug)
            self.Plots.vertical_slice = self.Util3D._vertical_slice

    #Special methods
    def __add__(self, FvcomClass, debug=False):
        """
        This special method permit to stack variables
        of 2 FVCOM objects through a simple addition:
          fvcom3 = fvcom1 + fvcom2

        Notes:
        -----
          - fvcom1 and fvcom2 have to cover the exact
            same spatial domain
          - last time step of fvcom1 must be <= to the 
            first time step of fvcom2 
        """
        debug = debug or self._debug
        #series of test before stacking
        if not ((self._ax == FvcomClass._ax) and
                (self.Grid.nele == FvcomClass.Grid.nele) and
                (self.Grid.node == FvcomClass.Grid.node) and
                (self.Variables._3D == FvcomClass.Grid._3D)):
            print "---Data dimensions do not match---"
            sys.exit()
        else:
            if not (self.Variables.julianTime[-1]<=
                    FvcomClass.Variables.julianTime[0]):
                print "---Data not consecutive in time---"
                sys.exit()
            #Copy self to newself
            newself = self
            if debug:
                print 'Stacking variables...'
            newself.Grid.siglay = np.vstack((newself.Grid.siglay,
                                             FvcomClass.Grid.siglay))
            newself.Grid.siglev = np.vstack((newself.Grid.siglev,
                                             FvcomClass.Grid.siglev))
            newself.Variables.ua = np.vstack((newself.Variables.ua,
                                              FvcomClass.Variables.ua))
            newself.Variables.va = np.vstack((newself.Variables.va,
                                              FvcomClass.Variables.va))
            newself.Variables.elev = np.vstack((newself.Variables.elev,
                                                FvcomClass.Variables.elev))
            if newself.Variables._3D:
                newself.Variables.u = np.vstack((newself.Variables.u,
                                                 FvcomClass.Variables.u))
                newself.Variables.v = np.vstack((newself.Variables.v,
                                                 FvcomClass.Variables.v))
                newself.Variables.w = np.vstack((newself.Variables.w,
                                                 FvcomClass.Variables.w))
            #Append to new object history
            text = 'Data from ' + FvcomClass.History[0].split('/')[-1] \
                 + ' has been stacked'

            newself.History.append(text)

        return newself  
   
    #Methods<commit_msg>Tested __add__ and it still points toward fvcom1<commit_after>#!/usr/bin/python2.7
# encoding: utf-8

#Libs import
from __future__ import division
import numpy as np
import sys
from utide import ut_solv, ut_reconstr
#TR comment: 2 alternatives
#import netCDF4 as nc
from scipy.io import netcdf
import mmap
import cPickle as pkl
#import pickle as pkl
#WB_Alternative: import scipy.io as sio
import copy

#Add local path to utilities
sys.path.append('../utilities/')

#Utility import
from shortest_element_path import shortest_element_path
from object_from_dict import ObjectFromDict

#Local import
from variablesFvcom import _load_var, _load_grid
from functionsFvcom import *
from functionsFvcomThreeD import *
from plotsFvcom import *

class FVCOM:
    '''
Description:
----------
  A class/structure for FVCOM data.
  Functionality structured as follows:
                _Data. = raw netcdf file data
               |_Variables. = fvcom variables and quantities
               |_Grid. = fvcom grid data
               |_QC = Quality Control metadata
    testFvcom._|_Utils2D. = set of useful functions
               |_Utils3D. = set of useful functions
               |_Plots. = plotting functions
               |_method_1
               | ...      = methods and analysis techniques intrinsic to fvcom runs
               |_method_n

Inputs:
------
  Takes a file name as input, ex: testFvcom=FVCOM('./path_to_FVOM_output_file/filename')

Options:
-------
    Can be defined for a region only, i.e. a bounding box, as such:
        ax = [minimun longitude, maximun longitude,
              minimun latitude, maximum latitude]
    Can be defined for a time period only, as such:
        tx = ['2012.11.07','2012.11.09'], string of year.month.date
Notes:
-----
    As of right now, only takes a filename as input. It will then load in the
    data (except for timeseries, since loading in the whole time series can be
    too large)
    '''

    def __init__(self, filename, ax=[], tx=[], debug=False):
        ''' Initialize FVCOM class.'''
        self._debug = debug
        if debug:
            print '-Debug mode on-'

        #Loading pickle file
        if filename.endswith('.p'):
            f = open(filename, "rb")
            data = pkl.load(f)
            self.History = data['History']
            self.Grid = ObjectFromDict(data['Grid'])
            self.Variables = ObjectFromDict(data['Variables'])
            try:
                #WB_Alternative: self.Data = sio.netcdf.netcdf_file(filename, 'r')
                #WB_comments: scipy has causes some errors, and even though can be
                #             faster, can be unreliable
                #self.Data = nc.Dataset(data['Origin'], 'r')
                self.Data = netcdf.netcdf_file(data['Origin'], 'r',mmap=True)
            except: #TR: need to precise the type of error here
                print "the original *.nc file has not been found"
                pass

        #Loading netcdf file         
        elif filename.endswith('.nc'):
            #WB_Alternative: self.Data = sio.netcdf.netcdf_file(filename, 'r')
            #WB_comments: scipy has causes some errors, and even though can be
            #             faster, can be unreliable
            #self.Data = nc.Dataset(filename, 'r')
            self.Data = netcdf.netcdf_file(filename, 'r',mmap=True)
            text = 'Created from ' + filename
            self._origin_file = filename
            #Metadata
            self.History = [text]
            # Calling sub-class
            print "Initialisation..."
            #print "This might take some time..."
            try:
                self.Grid = _load_grid(self.Data,
                                       ax,
                                       self.History,
                                       debug=self._debug)
                self.Variables = _load_var(self.Data,
                                           self.Grid,
                                           tx,
                                           self.History,
                                           debug=self._debug)
            except MemoryError:
                print '---Data too large for machine memory---'
                print 'Tip: use ax or tx during class initialisation'
                print '---  to use partial data'
                raise

        elif filename.endswith('.mat'):
            print "Cannot handle *.mat file yet"

        else:
            print "---Wrong file format---"
            sys.exit()

        self.Plots = PlotsFvcom(self.Variables,
                                self.Grid,
                                self._debug)
        self.Util2D = FunctionsFvcom(self.Variables,
                                     self.Grid,
                                     self.Plots,
                                     self.History,
                                     self._debug)

        if self.Variables._3D:
            self.Util3D = FunctionsFvcomThreeD(self.Variables,
                                               self.Grid,
                                               self.Plots,
                                               self.Util2D,
                                               self.History,
                                               self._debug)
            self.Plots.vertical_slice = self.Util3D._vertical_slice

    #Special methods
    def __add__(self, FvcomClass, debug=False):
        """
        This special method permit to stack variables
        of 2 FVCOM objects through a simple addition:
          fvcom3 = fvcom1 + fvcom2

        Notes:
        -----
          - fvcom1 and fvcom2 have to cover the exact
            same spatial domain
          - last time step of fvcom1 must be <= to the 
            first time step of fvcom2 
        """
        debug = debug or self._debug
        #series of test before stacking
        if not ((self.Grid._ax == FvcomClass.Grid._ax) and
                (self.Grid.nele == FvcomClass.Grid.nele) and
                (self.Grid.node == FvcomClass.Grid.node) and
                (self.Variables._3D == FvcomClass.Variables._3D)):
            print "---Data dimensions do not match---"
            sys.exit()
        else:
            if not (self.Variables.julianTime[-1]<=
                    FvcomClass.Variables.julianTime[0]):
                print "---Data not consecutive in time---"
                sys.exit()
            #Copy self to newself
            newself = copy.copy(self)
            #TR comment: it still points toward self and mofiies it
            if debug:
                print 'Stacking variables...'
            newself.Grid.siglay = np.vstack((newself.Grid.siglay,
                                             FvcomClass.Grid.siglay))
            newself.Grid.siglev = np.vstack((newself.Grid.siglev,
                                             FvcomClass.Grid.siglev))
            newself.Variables.ua = np.vstack((newself.Variables.ua,
                                              FvcomClass.Variables.ua))
            newself.Variables.va = np.vstack((newself.Variables.va,
                                              FvcomClass.Variables.va))
            newself.Variables.el = np.vstack((newself.Variables.el,
                                                FvcomClass.Variables.el))
            if newself.Variables._3D:
                newself.Variables.u = np.vstack((newself.Variables.u,
                                                 FvcomClass.Variables.u))
                newself.Variables.v = np.vstack((newself.Variables.v,
                                                 FvcomClass.Variables.v))
                newself.Variables.w = np.vstack((newself.Variables.w,
                                                 FvcomClass.Variables.w))
            newself.Grid.ntime = newself.Grid.ntime + FvcomClass.Grid.ntime
            #Append to new object history
            text = 'Data from ' + FvcomClass.History[0].split('/')[-1] \
                 + ' has been stacked'
            newself.History.append(text)

        return newself  
   
    #Methods
{'fraction_non_alphanumeric': 0.08670411985018726, 'fraction_numerical': 0.005555555555555556, 'mean_word_length': 1.3222206116828525, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 82, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6403769', 'n_tokens_mistral': 4192, 'n_tokens_neox': 3988, 'n_words': 1131}