<commit_before>"""
Copyright (c) 2017 <NAME>. All rights reserved.
Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
@author: eshook (<NAME>, <EMAIL>)
@contributors: <Contribute and add your name here!>
"""

from .Primitive import *
from ..bobs.Bobs import *

import math

# RFunct is an extended primitive where you can apply a function
# to the left and right raster layers or just a single raster layer.
class RFunct(Primitive):
    def __init__(self, name, function, buffersize = None):
        # Call Primitive.__init__ as the super class
        super(RFunct,self).__init__(name)
        
        # Reset the name
        self.name = "RFunct "+name
    
        # Set the function to be applied to left and right raster layers
        self.function = function

    # Define the __call__ function which will be called for all RFunct methods.
    def __call__(self, left = None, right = None):

        # Duplicate our left raster for the output # FIXME: Is this right?
        out = Raster(left.y,left.x,left.h,left.w)

        # If left and right are set, apply function to left and right
        if left != None and right != None:
            out.data = self.function(left.data,right.data)
        # If only left is set, then apply function to only left 
        elif left != None and right == None: 
            out.data = self.function(left.data)
        else: # This is a problem
            raise
        
        return out


# RMap is an extended primitive where you can apply a function
# to each element of the raster cell
# FIXME: This may need to additional work to make it truly generic
class RMap(Primitive):
    def __init__(self, name, function, buffersize = 0, pass_cellsize = False):
        # Call Primitive.__init__ as the super class
        super(RMap,self).__init__(name)
        
        # Reset the name
        self.name = "RMap "+name
    
        # Set the function to be applied to left and right raster layers
        self.function = function

        # Set the buffersize
        self.buffersize = buffersize
        
        # Determine if cellsize should be passed to the function
        self.pass_cellsize = pass_cellsize
        
    # Define the __call__ function which will be called for all RMap methods.
    # FIXME: I don't think that there is a need for a 'right' here.
    def __call__(self, left = None):

        buffersize = self.buffersize # Local variable for readability
        
        # Duplicate our left raster for the output # FIXME: Is this right?
        out = Raster(left.y,left.x,left.h,left.w,nrows = left.nrows, ncols = left.ncols, cellsize = left.cellsize)

        print("left = ",left)
        print("buffersize = ",buffersize)
        print("function = ",self.function)
        
        if self.pass_cellsize == True:
            for r in range(buffersize,len(out.data)-buffersize):
                for c in range(buffersize,len(out.data[0])-buffersize):
                    # Apply the function to the data in that cell
                    out.data[r][c]=self.function(
                                    left.data[r-buffersize:r + buffersize + 1, 
                                              c-buffersize:c + buffersize + 1], cellsize = left.cellsize)
        else: # Do not pass in cellsize
            # Loop over all the cells in the Raster Bob
            # Make sure to skip the buffered areas
            # Instead of a nested for loop, could we generate the pair of r,c
            # or use itertools.map or something to loop over the data efficiently.
            # nditer multi-indexing is promising: https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.nditer.html
            for r in range(buffersize,len(out.data)-buffersize):
                for c in range(buffersize,len(out.data[0])-buffersize):
                    # Apply the function to the data in that cell
                    out.data[r][c]=self.function(
                                    left.data[r-buffersize:r + buffersize + 1, 
                                              c-buffersize:c + buffersize + 1])
            
        return out


# Create a number of local primitives for raster data using Raster Function
# using numpy libraries
        
LocalSum =       RFunct("LocalSum",np.add)
LocalSub =       RFunct("LocalSubtract",np.subtract)
LocalMultiply =  RFunct("LocalMultiply",np.multiply)
LocalDivide =    RFunct("LocalDivide",np.divide)
LocalPower =     RFunct("LocalPower",np.power)
LocalMod =       RFunct("LocalModulus",np.mod)
LocalRemainder = RFunct("LocalRemainder",np.remainder)
LocalFloorDivide = RFunct("LocalFloorDivide",np.floor_divide)
LocalMaximum =   RFunct("LocalMaximum",np.maximum)
LocalMinimum =   RFunct("LocalMinimum",np.minimum)



# Create a number of focal operations for raster data using Raster Map
FocalMean =    RMap("FocalMean",np.mean,buffersize=1)
FocalMaximum = RMap("FocalMaximum",np.amax,buffersize=1)
FocalMinimum = RMap("FocalMinimum",np.amin,buffersize=1)



<commit_msg>Added Map Algebra override operators for Raster<commit_after>"""
Copyright (c) 2017 <NAME>. All rights reserved.
Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
@author: eshook (<NAME>, <EMAIL>)
@contributors: <Contribute and add your name here!>
"""

from .Primitive import *
from ..bobs.Bobs import *

import math

# RFunct is an extended primitive where you can apply a function
# to the left and right raster layers or just a single raster layer.
class RFunct(Primitive):
    def __init__(self, name, function, buffersize = None):
        # Call Primitive.__init__ as the super class
        super(RFunct,self).__init__(name)
        
        # Reset the name
        self.name = "RFunct "+name
    
        # Set the function to be applied to left and right raster layers
        self.function = function

    # Define the __call__ function which will be called for all RFunct methods.
    def __call__(self, left = None, right = None):

        # Duplicate our left raster for the output # FIXME: Is this right?
        out = Raster(left.y,left.x,left.h,left.w)

        # If left and right are set, apply function to left and right
        if left != None and right != None:
            out.data = self.function(left.data,right.data)
        # If only left is set, then apply function to only left 
        elif left != None and right == None: 
            out.data = self.function(left.data)
        else: # This is a problem
            raise
        
        return out


# RMap is an extended primitive where you can apply a function
# to each element of the raster cell
# FIXME: This may need to additional work to make it truly generic
class RMap(Primitive):
    def __init__(self, name, function, buffersize = 0, pass_cellsize = False):
        # Call Primitive.__init__ as the super class
        super(RMap,self).__init__(name)
        
        # Reset the name
        self.name = "RMap "+name
    
        # Set the function to be applied to left and right raster layers
        self.function = function

        # Set the buffersize
        self.buffersize = buffersize
        
        # Determine if cellsize should be passed to the function
        self.pass_cellsize = pass_cellsize
        
    # Define the __call__ function which will be called for all RMap methods.
    # FIXME: I don't think that there is a need for a 'right' here.
    def __call__(self, left = None):

        buffersize = self.buffersize # Local variable for readability
        
        # Duplicate our left raster for the output # FIXME: Is this right?
        out = Raster(left.y,left.x,left.h,left.w,nrows = left.nrows, ncols = left.ncols, cellsize = left.cellsize)

        print("left = ",left)
        print("buffersize = ",buffersize)
        print("function = ",self.function)
        
        if self.pass_cellsize == True:
            for r in range(buffersize,len(out.data)-buffersize):
                for c in range(buffersize,len(out.data[0])-buffersize):
                    # Apply the function to the data in that cell
                    out.data[r][c]=self.function(
                                    left.data[r-buffersize:r + buffersize + 1, 
                                              c-buffersize:c + buffersize + 1], cellsize = left.cellsize)
        else: # Do not pass in cellsize
            # Loop over all the cells in the Raster Bob
            # Make sure to skip the buffered areas
            # Instead of a nested for loop, could we generate the pair of r,c
            # or use itertools.map or something to loop over the data efficiently.
            # nditer multi-indexing is promising: https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.nditer.html
            for r in range(buffersize,len(out.data)-buffersize):
                for c in range(buffersize,len(out.data[0])-buffersize):
                    # Apply the function to the data in that cell
                    out.data[r][c]=self.function(
                                    left.data[r-buffersize:r + buffersize + 1, 
                                              c-buffersize:c + buffersize + 1])
            
        return out


# Create a number of local primitives for raster data using Raster Function
# using numpy libraries
        
LocalSum =       RFunct("LocalSum",np.add)
LocalSub =       RFunct("LocalSubtract",np.subtract)
LocalMultiply =  RFunct("LocalMultiply",np.multiply)
LocalDivide =    RFunct("LocalDivide",np.divide)
LocalPower =     RFunct("LocalPower",np.power)
LocalMod =       RFunct("LocalModulus",np.mod)
LocalRemainder = RFunct("LocalRemainder",np.remainder)
LocalFloorDivide = RFunct("LocalFloorDivide",np.floor_divide)
LocalMaximum =   RFunct("LocalMaximum",np.maximum)
LocalMinimum =   RFunct("LocalMinimum",np.minimum)



# Create a number of focal operations for raster data using Raster Map
FocalMean =    RMap("FocalMean",np.mean,buffersize=1)
FocalMaximum = RMap("FocalMaximum",np.amax,buffersize=1)
FocalMinimum = RMap("FocalMinimum",np.amin,buffersize=1)



def _Raster_add(self,right):
    return LocalSum(self,right)

def _Raster_sub(self,right):
    return LocalSub(self,right)

def _Raster_div(self,right):
    return LocalDivide(self,right)

def _Raster_mul(self,right):
    return LocalMultiply(self,right)
    
# Overload Raster with new operators
Raster.__add__ = _Raster_add
Raster.__sub__ = _Raster_sub
Raster.__mul__ = _Raster_mul
Raster.__truediv__ = _Raster_div
    

{'fraction_non_alphanumeric': 0.08555386372287781, 'fraction_numerical': 0.0034259611724400457, 'mean_word_length': 2.414230019493177, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '233390', 'n_tokens_mistral': 3102, 'n_tokens_neox': 2960, 'n_words': 1003}