[GRASS-SVN] r58971 - grass/trunk/lib/python/temporal

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Feb 9 12:48:12 PST 2014


Author: huhabla
Date: 2014-02-09 12:48:12 -0800 (Sun, 09 Feb 2014)
New Revision: 58971

Added:
   grass/trunk/lib/python/temporal/temporal_raster3d_algebra.py
   grass/trunk/lib/python/temporal/temporal_raster_algebra.py
   grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py
   grass/trunk/lib/python/temporal/temporal_raster_operator.py
   grass/trunk/lib/python/temporal/unittests_temporal_raster3d_algebra.py
   grass/trunk/lib/python/temporal/unittests_temporal_raster_algebra.py
Modified:
   grass/trunk/lib/python/temporal/Makefile
   grass/trunk/lib/python/temporal/__init__.py
   grass/trunk/lib/python/temporal/open_stds.py
   grass/trunk/lib/python/temporal/temporal_algebra.py
   grass/trunk/lib/python/temporal/temporal_vector_algebra.py
Log:
Added temporal raster and 3D raster algebra classes and tests


Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile	2014-02-09 11:47:26 UTC (rev 58970)
+++ grass/trunk/lib/python/temporal/Makefile	2014-02-09 20:48:12 UTC (rev 58971)
@@ -8,7 +8,7 @@
 GDIR = $(PYDIR)/grass
 DSTDIR = $(GDIR)/temporal
 
-MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets open_stds factory gui_support list_stds register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity spatio_temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics temporal_topology_dataset_connector spatial_topology_dataset_connector c_libraries_interface temporal_algebra temporal_vector_algebra temporal_vector_operator
+MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets open_stds factory gui_support list_stds register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity spatio_temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics temporal_topology_dataset_connector spatial_topology_dataset_connector c_libraries_interface temporal_algebra temporal_vector_algebra temporal_vector_operator temporal_raster_operator temporal_raster_base_algebra temporal_raster_algebra temporal_raster3d_algebra
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)

Modified: grass/trunk/lib/python/temporal/__init__.py
===================================================================
--- grass/trunk/lib/python/temporal/__init__.py	2014-02-09 11:47:26 UTC (rev 58970)
+++ grass/trunk/lib/python/temporal/__init__.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -28,3 +28,7 @@
 from temporal_algebra import *
 from temporal_vector_algebra import *
 from temporal_vector_operator import *
+from temporal_raster_operator import *
+from temporal_raster_base_algebra import *
+from temporal_raster_algebra import *
+from temporal_raster3d_algebra import *

Modified: grass/trunk/lib/python/temporal/open_stds.py
===================================================================
--- grass/trunk/lib/python/temporal/open_stds.py	2014-02-09 11:47:26 UTC (rev 58970)
+++ grass/trunk/lib/python/temporal/open_stds.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -30,7 +30,7 @@
     """!This function opens an existing space time dataset and return the
        created and intialized object of the specified type.
 
-       This function will raise a ScriptError in case the type is wrong,
+       This function will call exit() or raise a grass.pygrass.messages.FatalError in case the type is wrong,
        or the space time dataset was not found.
 
        @param name The name of the space time dataset, if the name does not
@@ -112,7 +112,7 @@
     elif type == "stvds" or type == "vect" or type == "vector":
         sp = dataset_factory("stvds", id)
     else:
-        core.error(_("Unkown type: %s") % (type))
+        msgr.error(_("Unkown type: %s") % (type))
         return None
 
     dbif, connected = init_dbif(dbif)
@@ -142,12 +142,10 @@
        @param semantic Semantical information
        @param dbif The temporal database interface to be used
        @param overwrite Flag to allow overwriting
-       @param dry Do not create the space time dataset in the temporal database,
-                  make a dry run with including all checks
 
        @return The new created space time dataset
 
-       This function will raise a ScriptError in case of an error.
+       This function will raise a FatalError in case of an error.
     """
     dbif, connected = init_dbif(dbif)
     msgr = get_tgis_message_interface()
@@ -177,7 +175,7 @@
 
 ############################################################################
 
-def check_new_map_dataset(name, layer=None, type="raster", 
+def check_new_map_dataset(name, layer=None, type="raster",
                           overwrite=False, dbif=None):
     """!Check if a new map dataset of a specific type can be created in
         the temporal database

Modified: grass/trunk/lib/python/temporal/temporal_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_algebra.py	2014-02-09 11:47:26 UTC (rev 58970)
+++ grass/trunk/lib/python/temporal/temporal_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -390,10 +390,7 @@
 except:
     pass
 
-import re
-import sys
 import os
-import grass.pygrass.modules as pygrass
 import grass.script as grass
 from space_time_datasets import *
 from factory import *
@@ -608,6 +605,7 @@
              print tok
 
 ###############################################################################
+
 class GlobalTemporalVar(object):
     """ This class handles global temporal variable conditional expressions,
         like start_doy() == 3.
@@ -650,11 +648,23 @@
 
         return(valuelist)
 
+    def __str__(self):
+        return str(self.tfunc) + str(self.compop) + str(self.value)
+
 ###############################################################################
 
 class TemporalAlgebraParser(object):
     """The temporal algebra class"""
 
+    # Get the tokens from the lexer class
+    tokens = TemporalAlgebraLexer.tokens
+
+    # Setting equal precedence level for select and hash operations.
+    precedence = (
+        ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
+        ('left', 'AND', 'OR', 'T_COMP_OPERATOR'), #2
+        )
+
     def __init__(self, pid=None, run = True, debug = False, spatial = False, null = False):
         self.run = run
         self.debug = debug
@@ -674,11 +684,12 @@
         if self.dbif.connected:
             self.dbif.close()
 
-    def parse(self, expression, stdstype = 'strds', basename = None):
+    def parse(self, expression, stdstype = 'strds', basename = None, overwrite=False):
         self.lexer = TemporalAlgebraLexer()
         self.lexer.build()
         self.parser = yacc.yacc(module=self, debug=self.debug)
 
+        self.overwrite = overwrite
         self.count = 0
         self.stdstype = stdstype
         self.basename = basename
@@ -701,15 +712,88 @@
         self.names[name] = name
         return name
 
-    # Get the tokens from the lexer class
-    tokens = TemporalAlgebraLexer.tokens
+    def generate_new_map(self, base_map, bool_op = 'and', copy = True):
+        """!Generate a new map using the spatio-temporal extent of the base map
 
-    # Setting equal precedence level for select and hash operations.
-    precedence = (
-        ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
-        ('left', 'AND', 'OR', 'T_COMP_OPERATOR'), #2
-        )
+           @param base_map This map is used to create the new map
+        """
+        # Generate an intermediate name for the result map list.
+        name = self.generate_map_name()
+        # Check for mapset in given stds input.
+        mapname = name + "@" + self.mapset
+        # Create new map based on the related map list.
+        map_new = base_map.get_new_instance(mapname)
+        # Set initial map extend of new vector map.
+        self.overlay_map_extent(map_new, base_map, bool_op = bool_op, copy = copy)
 
+        return map_new
+
+    def overlay_map_extent(self, mapA, mapB, bool_op = None, temp_op = '=',
+                            copy = False):
+        """!Compute the spatio-temporal extent of two topological related maps
+
+           @param mapA The first map
+           @param mapB The second maps
+           @param bool_op The boolean operator specifying the spatial extent
+                  operation (intersection, union, disjoint union)
+           @param temp_op The temporal operator specifying the temporal
+                  extent operation (intersection, union, disjoint union)
+           @param copy Specifies if the temporal extent of mapB should be
+                  copied to mapA
+           @return 0 if there is no overlay
+        """
+        returncode = 1
+        if copy:
+            map_extent_temporal = mapB.get_temporal_extent()
+            map_extent_spatial = mapB.get_spatial_extent()
+            # Set initial map extend of new vector map.
+            mapA.set_spatial_extent(map_extent_spatial)
+            mapA.set_temporal_extent(map_extent_temporal)
+            if "cmd_list" in dir(mapB):
+                mapA.cmd_list = mapB.cmd_list
+        else:
+            # Calculate spatial extent for different overlay operations.
+            if bool_op == 'and':
+                overlay_ext = mapA.spatial_intersection(mapB)
+                if overlay_ext != None:
+                    mapA.set_spatial_extent(overlay_ext)
+                else:
+                    returncode = 0
+            elif bool_op in ['or', 'xor']:
+                overlay_ext = mapA.spatial_union(mapB)
+                if overlay_ext != None:
+                    mapA.set_spatial_extent(overlay_ext)
+                else:
+                    returncode = 0
+            elif bool_op == 'disor':
+                overlay_ext = mapA.spatial_disjoint_union(mapB)
+                if overlay_ext != None:
+                    mapA.set_spatial_extent(overlay_ext)
+                else:
+                    returncode = 0
+
+            # Calculate temporal extent for different temporal operators.
+            if temp_op == '&':
+                temp_ext = mapA.temporal_intersection(mapB)
+                if temp_ext != None:
+                    mapA.set_temporal_extent(temp_ext)
+                else:
+                    returncode = 0
+            elif temp_op == '|':
+                temp_ext = mapA.temporal_union(mapB)
+                if temp_ext != None:
+                    mapA.set_temporal_extent(temp_ext)
+                else:
+                    returncode = 0
+            elif temp_op == '+':
+                temp_ext = mapA.temporal_disjoint_union(mapB)
+                if temp_ext != None:
+                    mapA.set_temporal_extent(temp_ext)
+                else:
+                    returncode = 0
+
+        return(returncode)
+
     ######################### Temporal functions ##############################
 
     def check_stds(self, input, clear = False):
@@ -1671,6 +1755,7 @@
             return(inverselist)
         else:
             return(resultlist)
+
     ###########################################################################
 
     def p_statement_assign(self, t):
@@ -1682,8 +1767,8 @@
         if self.run:
             resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
                                                         self.temporaltype, "", "", \
-                                                        'mean', None, \
-                                                        overwrite = grass.overwrite())
+                                                        'mean', dbif=self.dbif, \
+                                                        overwrite = self.overwrite)
             if isinstance(t[3], list):
                 num = len(t[3])
                 count = 0
@@ -1702,9 +1787,11 @@
                         dbif.close()
             t[0] = t[3]
 
+        else:
+            t[0] = t[3]
+
         if self.debug:
             print t[1], "=", t[3]
-            t[0] = t[3]
 
     def p_stds_1(self, t):
         # Definition of a space time dataset
@@ -1780,11 +1867,12 @@
                     map_i.map_value = gvar
 
             t[0] = maplist
+        else:
+            t[0] = "td(" + str(t[3]) + ")"
 
         if self.debug:
-            print "td(" + t[3] + ")"
+            print "td(" + str(t[3]) + ")"
 
-            t[0] = "td(" + t[3] + ")"
 
     def p_t_time_var(self, t):
         # Temporal variables that return a double or integer value
@@ -1862,13 +1950,14 @@
                 gvar.compop = t[4]
                 gvar.value  = t[5]
                 t[0] = gvar
+        else:
+            t[0] = True
 
         if self.debug:
             if len(t) == 6:
                 print t[1], t[4], t[5]
             if len(t) == 4:
                 print t[1], t[2], t[3]
-            t[0] = True
 
     def p_t_var_expr_time1(self, t):
         # Examples:
@@ -1889,10 +1978,11 @@
             gvar.compop = t[4]
             gvar.value  = t[5]
             t[0] = gvar
+        else:
+            t[0] = True
 
         if self.debug:
             print t[1], t[4], t[5]
-            t[0] = True
 
     def p_t_var_expr_time2(self, t):
         """
@@ -1911,11 +2001,12 @@
             gvar.compop = reverseop[t[2]]
             gvar.value  = t[1]
             t[0] = gvar
+        else:
+            t[0] = True
 
         if self.debug:
             print(t[4])
             print t[1], t[4], t[5]
-            t[0] = True
 
     def p_t_var_expr_comp(self, t):
         """
@@ -1934,10 +2025,11 @@
             resultlist.append(tvarexprB)
 
             t[0] = resultlist
+        else:
+            t[0] = True
 
         if self.debug:
             print t[1], t[2] + t[3], t[4]
-            t[0] = True
 
     def p_t_var_expr_comp_op(self, t):
         """
@@ -1958,10 +2050,11 @@
             resultlist.append(tvarexprB)
 
             t[0] = resultlist
+        else:
+            t[0] = True
 
         if self.debug:
             print t[1], t[2], t[3]
-            t[0] = True
 
     def p_expr_t_select(self, t):
         # Temporal equal selection
@@ -1984,10 +2077,11 @@
             selectlist = self.perform_temporal_selection(maplistA, maplistB)
             # Return map list.
             t[0] = selectlist
+        else:
+            t[0] = t[1] + "*"
 
         if self.debug:
             print t[1] + "* = ", t[1], t[2], t[3]
-            t[0] = t[1] + "*"
 
     def p_expr_t_not_select(self, t):
         # Temporal equal selection
@@ -2009,10 +2103,11 @@
                                                          inverse = True)
             # Return map list.
             t[0] = selectlist
+        else:
+            t[0] = t[1] + "*"
 
         if self.debug:
             print t[1] + "* = ", t[1], t[2], t[3]
-            t[0] = t[1] + "*"
 
 
     def p_expr_t_select_operator(self, t):
@@ -2050,10 +2145,11 @@
 
             # Return map list.
             t[0] = selectlist
+        else:
+            t[0] = t[1] + "*"
 
         if self.debug:
             print t[1] + "* = ", t[1], t[2], t[3]
-            t[0] = t[1] + "*"
 
 
     def p_expr_condition_if(self, t):
@@ -2074,10 +2170,11 @@
             resultlist   = self.check_stds(thenresult, clear = True)
             # Return resulting map list.
             t[0] = resultlist
+        else:
+            t[0] = t[5] + "*"
 
         if self.debug:
-            print t[5] + "* = ", "if condition", t[3], ' then ', t[5]
-            t[0] = t[5] + "*"
+            print str(t[5]) + "* = ", "if condition", str(t[3]), ' then ', str(t[5])
 
     def p_expr_condition_if_relation(self, t):
         # Examples
@@ -2098,10 +2195,11 @@
             resultlist   = self.check_stds(thenresult, clear = True)
             # Return resulting map list.
             t[0] = resultlist
+        else:
+            t[0] = t[7] + "*"
 
         if self.debug:
-            print t[5] + "* = ", "if condition", t[3], ' then ', t[5]
-            t[0] = t[5] + "*"
+            print "result* = ", "if ", str(t[3]),  "condition", str(t[5]), " then ", str(t[7])
 
     def p_expr_condition_elif(self, t):
         # Examples
@@ -2130,10 +2228,11 @@
             resultlist   = self.check_stds(resultlist, clear = True)
             # Return resulting map list.
             t[0] = resultlist
+        else:
+            t[0] = t[5] + "*"
 
         if self.debug:
-            print t[5] + "* = ", "if condition", t[3], " then ", t[5], ' else ', t[7]
-            t[0] = t[5] + "*"
+            print str(t[5]) + "* = ", "if condition", str(t[3]), " then ", str(t[5]), ' else ', str(t[7])
 
     def p_expr_condition_elif_relation(self, t):
         # Examples
@@ -2165,15 +2264,18 @@
             resultlist   = self.check_stds(resultlist, clear = True)
             # Return resulting map list.
             t[0] = resultlist
-
-        if self.debug:
+        else:
             if t[5]:
-                print t[7], "* = ", "if condition", t[5], " then ", t[7], ' else ', t[9]
                 t[0] = str(t[7])
             else:
-                print t[9], "* = ", "if condition", t[5], " then ", t[7], ' else ', t[9]
                 t[0] = str(t[9])
 
+        if self.debug:
+            if t[5]:
+                print str(t[7]), "* = ", "if condition", str(t[5]), " then ", str(t[7]), ' else ', str(t[9])
+            else:
+                print str(t[9]), "* = ", "if condition", str(t[5]), " then ", str(t[7]), ' else ', str(t[9])
+
     def p_expr_t_buff(self, t):
         # Examples
         # buff_t(A : B, "10 minutes")  # Select the part of A that is temporally
@@ -2196,13 +2298,14 @@
                 # Perform buffering.
                 map.temporal_buffer(increment)
             t[0] = bufflist
+        else:
+            t[0] = t[3] + "*"
 
         if self.debug:
             if len(t) == 10:
-                print t[3] + "* = buff_t(", t[3], "," , '"', t[6], t[7], '"', ")"
+                print str(t[3]) + "* = buff_t(", str(t[3]), "," , '"', str(t[6]), str(t[7]), '"', ")"
             elif len(t) == 7:
-                print t[3] + "* = buff_t(", t[3], ",", t[5], ")"
-            t[0] = t[3] + "*"
+                print str(t[3]) + "* = buff_t(", str(t[3]), ",", str(t[5]), ")"
 
     def p_expr_t_snap(self, t):
         # Examples
@@ -2217,10 +2320,11 @@
             # Perform snapping.
             snaplist = AbstractSpaceTimeDataset.snap_map_list(maplist)
             t[0] = snaplist
+        else:
+            t[0] = t[3] + "*"
 
         if self.debug:
-            print t[3] + "* = tsnap(", t[3], ")"
-            t[0] = t[3] + "*"
+            print str(t[3]) + "* = tsnap(", str(t[3]), ")"
 
     def p_expr_t_shift(self, t):
         # Examples
@@ -2243,13 +2347,14 @@
             # Perform shifting.
             shiftlist = AbstractSpaceTimeDataset.shift_map_list(maplist, increment)
             t[0] = shiftlist
+        else:
+            t[0] = t[3] + "*"
 
         if self.debug:
             if len(t) == 10:
-                print t[3] + "* = tshift(", t[3], "," , '"', t[6], t[7], '"', ")"
+                print str(t[3]) + "* = tshift(", str(t[3]), "," , '"', str(t[6]), str(t[7]), '"', ")"
             elif len(t) == 7:
-                print t[3] + "* = tshift(", t[3], ",", t[5], ")"
-            t[0] = t[3] + "*"
+                print str(t[3]) + "* = tshift(", str(t[3]), ",", str(t[5]), ")"
 
     # Handle errors.
     def p_error(self, t):
@@ -2261,5 +2366,3 @@
 if __name__ == "__main__":
     import doctest
     doctest.testmod()
-
-

Added: grass/trunk/lib/python/temporal/temporal_raster3d_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_raster3d_algebra.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_raster3d_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -0,0 +1,110 @@
+"""!@package grass.temporal
+
+Temporal raster algebra
+
+(C) 2013 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Thomas Leppelt and Soeren Gebbert
+
+"""
+
+from temporal_raster_base_algebra import *
+
+###############################################################################
+
+class TemporalRaster3DAlgebraParser(TemporalRasterBaseAlgebraParser):
+    """The temporal raster algebra class"""
+
+    def __init__(self, pid=None, run=False, debug=True, spatial = False):
+        TemporalRasterBaseAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+        self.m_mapcalc = pygrass.Module('r3.mapcalc')
+
+    def parse(self, expression, basename = None, overwrite=False):
+        self.lexer = TemporalRasterAlgebraLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self, debug=self.debug)
+
+        self.overwrite = overwrite
+        self.count = 0
+        self.stdstype = "str3ds"
+        self.basename = basename
+        self.expression = expression
+        self.parser.parse(expression)
+
+    ######################### Temporal functions ##############################
+
+    def p_statement_assign(self, t):
+        # The expression should always return a list of maps.
+        """
+        statement : stds EQUALS expr
+        """
+        TemporalRasterBaseAlgebraParser.p_statement_assign(self, t)
+
+    def p_ts_neighbor_operation(self, t):
+        # Examples:
+        # A[1,0,-1]
+        # B[-2]
+        # C[1,-2,1,3]
+        """
+        expr : stds L_SPAREN number COMMA number COMMA number R_SPAREN
+             | stds L_SPAREN number R_SPAREN
+             | stds L_SPAREN number COMMA number COMMA number COMMA number R_SPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+        t_neighbor = 0
+        row_neighbor = None
+        col_neighbor = None
+        depth_neighbor = None
+        if len(t) == 5:
+            t_neighbor = t[3]
+        elif len(t) == 9:
+            row_neighbor = t[3]
+            col_neighbor = t[5]
+            depth_neighbor = t[7]
+        elif len(t) == 11:
+            t_neighbor = t[9]
+            row_neighbor = t[3]
+            col_neighbor = t[5]
+            depth_neighbor = t[7]
+        if self.run:
+            resultlist = []
+            max_index = len(maplist)
+            for map_i in maplist:
+                # Get map index and temporal extent.
+                map_index = maplist.index(map_i)
+                new_index = map_index + t_neighbor
+                if new_index < max_index and new_index >= 0:
+                    map_i_t_extent = map_i.get_temporal_extent()
+                    # Get neighboring map and set temporal extent.
+                    map_n = maplist[new_index]
+                    # Generate an intermediate map for the result map list.
+                    map_new = self.generate_new_map(map_n, bool_op = 'and', copy = True)
+                    map_new.set_temporal_extent(map_i_t_extent)
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_new.cmd_list)
+                    elif "cmd_list" not in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_n.get_id())
+                    elif "cmd_list" in dir(map_new) and len(t) in (9,11):
+                        cmdstring = "%s[%s,%s,%s]" %(map_new.cmd_list, row_neighbor, col_neighbor, depth_neighbor)
+                    elif "cmd_list" not in dir(map_new) and len(t) in (9,11):
+                        cmdstring = "%s[%s,%s,%s]" %(map_n.get_id(), row_neighbor, col_neighbor, depth_neighbor)
+                    # Set new command list for map.
+                    map_new.cmd_list = cmdstring
+                    # Append map with updated command list to result list.
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+
+

Added: grass/trunk/lib/python/temporal/temporal_raster_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_raster_algebra.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_raster_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -0,0 +1,149 @@
+"""!@package grass.temporal
+
+Temporal raster algebra
+
+(C) 2013 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Thomas Leppelt and Soeren Gebbert
+
+ at code
+
+    >>> p = TemporalRasterAlgebraLexer()
+    >>> p.build()
+    >>> p.debug = True
+    >>> expression =  'R = A[0,1,0] / B[0,0,1] * 20 + C[0,1,1] - 2.45'
+    >>> p.test(expression)
+    R = A[0,1,0] / B[0,0,1] * 20 + C[0,1,1] - 2.45
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(L_SPAREN,'[',1,5)
+    LexToken(INT,0,1,6)
+    LexToken(COMMA,',',1,7)
+    LexToken(INT,1,1,8)
+    LexToken(COMMA,',',1,9)
+    LexToken(INT,0,1,10)
+    LexToken(R_SPAREN,']',1,11)
+    LexToken(DIV,'/',1,13)
+    LexToken(NAME,'B',1,15)
+    LexToken(L_SPAREN,'[',1,16)
+    LexToken(INT,0,1,17)
+    LexToken(COMMA,',',1,18)
+    LexToken(INT,0,1,19)
+    LexToken(COMMA,',',1,20)
+    LexToken(INT,1,1,21)
+    LexToken(R_SPAREN,']',1,22)
+    LexToken(MULT,'*',1,24)
+    LexToken(INT,20,1,26)
+    LexToken(ADD,'+',1,29)
+    LexToken(NAME,'C',1,31)
+    LexToken(L_SPAREN,'[',1,32)
+    LexToken(INT,0,1,33)
+    LexToken(COMMA,',',1,34)
+    LexToken(INT,1,1,35)
+    LexToken(COMMA,',',1,36)
+    LexToken(INT,1,1,37)
+    LexToken(R_SPAREN,']',1,38)
+    LexToken(SUB,'-',1,40)
+    LexToken(FLOAT,2.45,1,42)
+
+ at endcode
+"""
+
+from temporal_raster_base_algebra import *
+
+###############################################################################
+
+class TemporalRasterAlgebraParser(TemporalRasterBaseAlgebraParser):
+    """The temporal raster algebra class"""
+
+    def __init__(self, pid=None, run=False, debug=True, spatial = False):
+        TemporalRasterBaseAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+        self.m_mapcalc = pygrass.Module('r.mapcalc')
+
+    def parse(self, expression, basename = None, overwrite=False):
+        self.lexer = TemporalRasterAlgebraLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self, debug=self.debug)
+
+        self.overwrite = overwrite
+        self.count = 0
+        self.stdstype = "strds"
+        self.basename = basename
+        self.expression = expression
+        self.parser.parse(expression)
+
+    ######################### Temporal functions ##############################
+
+    def p_statement_assign(self, t):
+        # The expression should always return a list of maps.
+        """
+        statement : stds EQUALS expr
+        """
+        TemporalRasterBaseAlgebraParser.p_statement_assign(self, t)
+
+    def p_ts_neighbour_operation(self, t):
+        # Examples:
+        # A[1,0]
+        # B[-2]
+        # C[-2,1,3]
+        """
+        expr : stds L_SPAREN number COMMA number R_SPAREN
+             | stds L_SPAREN number R_SPAREN
+             | stds L_SPAREN number COMMA number COMMA number R_SPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+        row_neigbour = None
+        col_neigbour = None
+        if len(t) == 5:
+            t_neighbour = t[3]
+        elif len(t) == 7:
+            t_neighbour = 0
+            row_neigbour = t[3]
+            col_neigbour = t[5]
+        elif len(t) == 9:
+            t_neighbour = t[7]
+            row_neigbour = t[3]
+            col_neigbour = t[5]
+        if self.run:
+            resultlist = []
+            max_index = len(maplist)
+            for map_i in maplist:
+                # Get map index and temporal extent.
+                map_index = maplist.index(map_i)
+                new_index = map_index + t_neighbour
+                if new_index < max_index and new_index >= 0:
+                    map_i_t_extent = map_i.get_temporal_extent()
+                    # Get neighbouring map and set temporal extent.
+                    map_n = maplist[new_index]
+                    # Generate an intermediate map for the result map list.
+                    map_new = self.generate_new_map(map_n, bool_op = 'and', copy = True)
+                    map_new.set_temporal_extent(map_i_t_extent)
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_new.cmd_list)
+                    elif "cmd_list" not in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_n.get_id())
+                    elif "cmd_list" in dir(map_new) and len(t) in (7, 9):
+                        cmdstring = "%s[%s,%s]" %(map_new.cmd_list, row_neigbour, col_neigbour)
+                    elif "cmd_list" not in dir(map_new) and len(t) in (7, 9):
+                        cmdstring = "%s[%s,%s]" %(map_n.get_id(), row_neigbour, col_neigbour)
+                    # Set new command list for map.
+                    map_new.cmd_list = cmdstring
+                    # Append map with updated command list to result list.
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+
+

Added: grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -0,0 +1,2590 @@
+"""!@package grass.temporal
+
+Temporal raster algebra
+
+(C) 2013 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Thomas Leppelt and Soeren Gebbert
+
+ at code
+
+    >>> p = TemporalRasterAlgebraLexer()
+    >>> p.build()
+    >>> p.debug = True
+    >>> expression =  'R = A / B * 20 + C - 2.45'
+    >>> p.test(expression)
+    R = A / B * 20 + C - 2.45
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(DIV,'/',1,6)
+    LexToken(NAME,'B',1,8)
+    LexToken(MULT,'*',1,10)
+    LexToken(INT,20,1,12)
+    LexToken(ADD,'+',1,15)
+    LexToken(NAME,'C',1,17)
+    LexToken(SUB,'-',1,19)
+    LexToken(FLOAT,2.45,1,21)
+    >>> expression =  'R = A {equal,|/} B'
+    >>> p.test(expression)
+    R = A {equal,|/} B
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_ARITH1_OPERATOR,'{equal,|/}',1,6)
+    LexToken(NAME,'B',1,17)
+    >>> expression =  'R = A {equal,||} B'
+    >>> p.test(expression)
+    R = A {equal,||} B
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_COMP_OPERATOR,'{equal,||}',1,6)
+    LexToken(NAME,'B',1,17)
+    >>> expression =  'R = A {equal,&&} B'
+    >>> p.test(expression)
+    R = A {equal,&&} B
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_COMP_OPERATOR,'{equal,&&}',1,6)
+    LexToken(NAME,'B',1,17)
+    >>> expression =  'R = A {equal | during,+*} B'
+    >>> p.test(expression)
+    R = A {equal | during,+*} B
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_ARITH1_OPERATOR,'{equal | during,+*}',1,6)
+    LexToken(NAME,'B',1,26)
+    >>> expression =  'R = A {equal | during,+:} B'
+    >>> p.test(expression)
+    R = A {equal | during,+:} B
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_SELECT_OPERATOR,'{equal | during,+:}',1,6)
+    LexToken(NAME,'B',1,26)
+    >>> expression =  'R = abs(A) {equal,+:} exp(B) / sqrt(C) - log(D)'
+    >>> p.test(expression)
+    R = abs(A) {equal,+:} exp(B) / sqrt(C) - log(D)
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(ABS,'abs',1,4)
+    LexToken(LPAREN,'(',1,7)
+    LexToken(NAME,'A',1,8)
+    LexToken(RPAREN,')',1,9)
+    LexToken(T_SELECT_OPERATOR,'{equal,+:}',1,11)
+    LexToken(EXP,'exp',1,22)
+    LexToken(LPAREN,'(',1,25)
+    LexToken(NAME,'B',1,26)
+    LexToken(RPAREN,')',1,27)
+    LexToken(DIV,'/',1,29)
+    LexToken(SQRT,'sqrt',1,31)
+    LexToken(LPAREN,'(',1,35)
+    LexToken(NAME,'C',1,36)
+    LexToken(RPAREN,')',1,37)
+    LexToken(SUB,'-',1,39)
+    LexToken(LOG,'log',1,41)
+    LexToken(LPAREN,'(',1,44)
+    LexToken(NAME,'D',1,45)
+    LexToken(RPAREN,')',1,46)
+
+ at endcode
+"""
+
+import grass.pygrass.modules as pygrass
+from temporal_raster_operator import *
+from temporal_algebra import *
+
+##############################################################################
+
+class TemporalRasterAlgebraLexer(TemporalAlgebraLexer):
+    """!Lexical analyzer for the GRASS GIS temporal algebra"""
+
+    def __init__(self):
+        TemporalAlgebraLexer.__init__(self)
+
+    # Supported r.mapcalc functions.
+    mapcalc_functions = {
+        'exp'     : 'EXP',
+        'log'     : 'LOG',
+        'sqrt'    : 'SQRT',
+        'abs'     : 'ABS',
+        'cos'     : 'COS',
+        'acos'    : 'ACOS',
+        'sin'     : 'SIN',
+        'asin'    : 'ASIN',
+        'tan'     : 'TAN',
+        'double'  : 'DOUBLE',
+        'float'   : 'FLOATEXP',
+        'int'     : 'INTEXP',
+        'isnull'  : 'ISNULL',
+        'null'    : 'NULL',
+        'exist'   : 'EXIST',
+    }
+
+    # This is the list of token names.
+    raster_tokens = (
+        'MOD',
+        'DIV',
+        'MULT',
+        'ADD',
+        'SUB',
+        'T_ARITH1_OPERATOR',
+        'T_ARITH2_OPERATOR',
+        'L_SPAREN',
+        'R_SPAREN',
+    )
+
+    # Build the token list
+    tokens = TemporalAlgebraLexer.tokens \
+                    + raster_tokens \
+                    + tuple(mapcalc_functions.values())
+
+    # Regular expression rules for simple tokens
+    t_MOD                 = r'[\%]'
+    t_DIV                 = r'[\/]'
+    t_MULT                = r'[\*]'
+    t_ADD                 = r'[\+]'
+    t_SUB                 = r'[-]'
+    t_T_ARITH1_OPERATOR   = r'\{([a-zA-Z\| ]+[,])?([\|&+=]?[\%\*\/])\}'
+    t_T_ARITH2_OPERATOR   = r'\{([a-zA-Z\| ]+[,])?([\|&+=]?[+-])\}'
+    t_L_SPAREN            = r'\['
+    t_R_SPAREN            = r'\]'
+
+    # Parse symbols
+    def temporal_symbol(self, t):
+        # Check for reserved words
+        if t.value in TemporalRasterAlgebraLexer.time_functions.keys():
+            t.type = TemporalRasterAlgebraLexer.time_functions.get(t.value)
+        elif t.value in TemporalRasterAlgebraLexer.datetime_functions.keys():
+            t.type = TemporalRasterAlgebraLexer.datetime_functions.get(t.value)
+        elif t.value in TemporalRasterAlgebraLexer.conditional_functions.keys():
+            t.type = TemporalRasterAlgebraLexer.conditional_functions.get(t.value)
+        elif t.value in TemporalRasterAlgebraLexer.mapcalc_functions.keys():
+            t.type = TemporalRasterAlgebraLexer.mapcalc_functions.get(t.value)
+        else:
+            t.type = 'NAME'
+        return t
+
+##############################################################################
+
+class TemporalRasterBaseAlgebraParser(TemporalAlgebraParser):
+    """The temporal algebra class"""
+
+    # Get the tokens from the lexer class
+    tokens = TemporalRasterAlgebraLexer.tokens
+
+    # Setting equal precedence level for select and hash operations.
+    precedence = (
+        ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
+        ('left', 'ADD', 'SUB', 'T_ARITH2_OPERATOR'), #2
+        ('left', 'AND', 'OR', 'T_COMP_OPERATOR', 'MOD', 'DIV', 'MULT',
+         'T_ARITH1_OPERATOR'))
+
+    def __init__(self, pid=None, run = True, debug = False, spatial = False, \
+                  null = False):
+        TemporalAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+    ######################### Temporal functions ##############################
+
+    def eval_toperator(self, operator, comparison = False):
+        """!This function evaluates a string containing temporal operations.
+
+         @param operator String of temporal operations, e.g. {equal|during,=!:}.
+
+         @return List of temporal relations (equal, during), the given function
+          (!:) and the interval/instances (=).
+        @code
+         >>> init(True)
+         >>> p = TemporalRasterBaseAlgebraParser()
+         >>> operator = "{equal,:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL'], '=', ':')
+         >>> operator = "{equal|during,:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL', 'DURING'], '=', ':')
+         >>> operator = "{equal,!:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL'], '=', '!:')
+         >>> operator = "{equal|during,!:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL', 'DURING'], '=', '!:')
+         >>> operator = "{equal|during,=!:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL', 'DURING'], '=', '!:')
+         >>> operator = "{equal|during|starts,#}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL', 'DURING', 'STARTS'], '=', '#')
+         >>> operator = "{!:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL'], '=', '!:')
+         >>> operator = "{=:}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL'], '=', ':')
+         >>> operator = "{#}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL'], '=', '#')
+         >>> operator = "{equal|during}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL', 'DURING'], None, None)
+         >>> operator = "{equal}"
+         >>> p.eval_toperator(operator)
+         (['EQUAL'], None, None)
+         >>> operator = "{equal,||}"
+         >>> p.eval_toperator(operator, True)
+         (['EQUAL'], '=', '||')
+         >>> operator = "{equal|during,&&}"
+         >>> p.eval_toperator(operator, True)
+         (['EQUAL', 'DURING'], '=', '&&')
+
+        @endcode
+
+        """
+        p = TemporalRasterOperatorParser()
+        p.parse(operator, comparison)
+        p.relations = [rel.upper() for rel in p.relations]
+
+        return(p.relations, p.temporal, p.function)
+
+    ###########################################################################
+
+    def p_statement_assign(self, t):
+        # The expression should always return a list of maps.
+        """
+        statement : stds EQUALS expr
+
+        """
+        if self.run:
+            if isinstance(t[3], list):
+                num = len(t[3])
+                count = 0
+                returncode = 0
+                register_list = []
+                for i in range(num):
+                    # Check if resultmap names exist in GRASS database.
+                    rastername = self.basename + "_" + str(i) + "@" + self.mapset
+                    rastermap = RasterDataset(rastername)
+                    if rastermap.map_exists() and self.overwrite == False:
+                        self.msgr.fatal("Error raster maps with basename %s exist. Use --o flag to overwrite existing file" \
+                                            %(rastername))
+                for map_i in t[3]:
+                    newident = self.basename + "_" + str(count)
+                    if "cmd_list" in dir(map_i):
+                        returncode = 0
+                        print(newident + ' = ' + map_i.cmd_list)
+                        # Build r.mapcalc module and execute expression.
+                        # Change map name to given basename.
+                        # Create deepcopy of r.mapcalc module.
+                        m = copy.deepcopy(self.m_mapcalc)
+                        m_expression = newident + "=" + map_i.cmd_list
+                        m.inputs["expression"].value = m_expression
+                        m.flags["overwrite"].value = self.overwrite
+                        m.run()
+                        if m.popen.returncode != 0:
+                            self.msgr.fatal("Error starting %s : \n%s" \
+                                                %(m.get_bash(), \
+                                                m.popen.stderr))
+                        map_test = map_i.get_new_instance(newident + "@" + self.mapset)
+                        if not map_test.map_exists():
+                            returncode = 1
+                            break
+                        if returncode == 0:
+                            map_i.set_id(newident + "@" + self.mapset)
+                            count += 1
+                            register_list.append(map_i)
+                    else:
+                        register_list.append(map_i)
+                # Open connection to temporal database.
+                dbif, connect = init_dbif(self.dbif)
+                # Create result space time dataset.
+                resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
+                                                         'absolute', t[1], t[1], \
+                                                         'mean', self.dbif, \
+                                                         overwrite = self.overwrite)
+                for map_i in register_list:
+                    # Check if modules should be executed from command list.
+                    if "cmd_list" in dir(map_i):
+                        # Get meta data from grass database.
+                        map_i.load()
+                        if map_i.is_in_db(dbif) and self.overwrite:
+                            # Update map in temporal database.
+                            map_i.update_all(dbif)
+                        elif map_i.is_in_db(dbif) and self.overwrite == False:
+                            # Raise error if map exists and no overwrite flag is given.
+                            self.msgr.fatal("Error vector map %s exist in temporal database. Use overwrite flag.  : \n%s" \
+                                                %(map_i.get_map_id(), cmd.popen.stderr))
+                        else:
+                            # Insert map into temporal database.
+                            map_i.insert(dbif)
+                    # Register map in result space time dataset.
+                    success = resultstds.register_map(map_i, dbif)
+                resultstds.update_from_registered_maps(dbif)
+                dbif.close()
+                t[0] = register_list
+
+    def p_arith1_operation(self, t):
+        """
+        expr : stds MOD stds
+             | expr MOD stds
+             | stds MOD expr
+             | expr MOD expr
+             | stds DIV stds
+             | expr DIV stds
+             | stds DIV expr
+             | expr DIV expr
+             | stds MULT stds
+             | expr MULT stds
+             | stds MULT expr
+             | expr MULT expr
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[3])
+        topolist = self.get_temporal_topo_list(maplistA, maplistB)
+
+        if self.run:
+            resultlist = []
+            for map_i in topolist:
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for map_j in (tbrelations['EQUAL']):
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                            temp_op = '=')
+                    # Stop the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        break
+                    if count == 0:
+                        # Set map name.
+                        name = map_new.get_id()
+                    else:
+                        # Generate an intermediate map
+                        name = self.generate_map_name()
+
+                    # Set first input for overlay module.
+                    mapbinput = map_j.get_id()
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "(%s %s %s)" %(map_new.cmd_list, t[2], mapbinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "(%s %s %s)" %(mapainput, t[2], map_j.cmd_list)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "(%s %s %s)" %(map_new.cmd_list, t[2], map_j.cmd_list)
+                    else:
+                        cmdstring = "(%s %s %s)" %(mapainput, t[2], mapbinput)
+                    # Conditional append of module command.
+                    map_new.cmd_list = cmdstring
+                    # Set new map name to temporary map name.
+                    mapainput = name
+                    count += 1
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_arith1_operation_numeric1(self, t):
+        """
+        expr : stds MOD number
+             | expr MOD number
+             | stds DIV number
+             | expr DIV number
+             | stds MULT number
+             | expr MULT number
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                mapinput = map_i.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "(%s %s %s)" %(map_i.cmd_list, t[2], t[3])
+                else:
+                    cmdstring = "(%s %s %s)" %(mapinput, t[2], t[3])
+                # Conditional append of module command.
+                map_i.cmd_list = cmdstring
+                # Append map to result map list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_arith1_operation_numeric2(self, t):
+        """
+        expr : number MOD stds
+             | number MOD expr
+             | number DIV stds
+             | number DIV expr
+             | number MULT stds
+             | number MULT expr
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[3])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                mapinput = map_i.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "(%s %s %s)" %(t[1], t[2], map_i.cmd_list)
+                else:
+                    cmdstring = "(%s %s %s)" %(t[1], t[2], mapinput)
+                # Conditional append of module command.
+                map_i.cmd_list = cmdstring
+                # Append map to result map list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_arith2_operation(self, t):
+        """
+        expr : stds ADD stds
+             | expr ADD stds
+             | stds ADD expr
+             | expr ADD expr
+             | stds SUB stds
+             | expr SUB stds
+             | stds SUB expr
+             | expr SUB expr
+
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[3])
+        topolist = self.get_temporal_topo_list(maplistA, maplistB)
+
+        if self.run:
+            resultlist = []
+            for map_i in topolist:
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for map_j in (tbrelations['EQUAL']):
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                            temp_op = '=')
+                    # Stop the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        break
+                    if count == 0:
+                        # Set map name.
+                        name = map_new.get_id()
+                    else:
+                        # Generate an intermediate map
+                        name = self.generate_map_name()
+
+                    # Set first input for overlay module.
+                    mapbinput = map_j.get_id()
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "(%s %s %s)" %(map_new.cmd_list, t[2], mapbinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "(%s %s %s)" %(mapainput, t[2], map_j.cmd_list)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "(%s %s %s)" %(map_new.cmd_list, t[2], map_j.cmd_list)
+                    else:
+                        cmdstring = "(%s %s %s)" %(mapainput, t[2], mapbinput)
+                    # Conditional append of module command.
+                    map_new.cmd_list = cmdstring
+                    # Set new map name to temporary map name.
+                    mapainput = name
+                    count += 1
+
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_arith2_operation_numeric1(self, t):
+        """
+        expr : stds ADD number
+             | expr ADD number
+             | stds SUB number
+             | expr SUB number
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                mapinput = map_i.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "(%s %s %s)" %(map_i.cmd_list, t[2], t[3])
+                else:
+                    cmdstring = "(%s %s %s)" %(mapinput, t[2], t[3])
+                # Conditional append of module command.
+                map_i.cmd_list = cmdstring
+                # Append map to result map list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_arith2_operation_numeric2(self, t):
+        """
+        expr : number ADD stds
+             | number ADD expr
+             | number SUB stds
+             | number SUB expr
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[3])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                mapinput = map_i.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "(%s %s %s)" %(t[1], t[2], map_i.cmd_list)
+                else:
+                    cmdstring = "(%s %s %s)" %(t[1], t[2], mapinput)
+                # Conditional append of module command.
+                map_i.cmd_list = cmdstring
+                # Append map to result map list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_arith1_operation_relation(self, t):
+        """
+        expr : stds T_ARITH1_OPERATOR stds
+             | expr T_ARITH1_OPERATOR stds
+             | stds T_ARITH1_OPERATOR expr
+             | expr T_ARITH1_OPERATOR expr
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[3])
+        relations, temporal, function= self.eval_toperator(t[2])
+        topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist = relations)
+
+        if self.run:
+            resultlist = []
+            for map_i in topolist:
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for topo in relations:
+                    if topo in tbrelations.keys():
+                        for map_j in (tbrelations[topo]):
+                            # Create overlayed map extent.
+                            returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                                    temp_op = temporal)
+                            print(returncode)
+                            # Stop the loop if no temporal or spatial relationship exist.
+                            if returncode == 0:
+                                break
+                            if count == 0:
+                                # Set map name.
+                                name = map_new.get_id()
+                            else:
+                                # Generate an intermediate map
+                                name = self.generate_map_name()
+                                map_new.set_id(name + "@" + mapset)
+                            # Set second input for overlay module.
+                            mapbinput = map_j.get_id()
+                            # Create r.mapcalc expression string for the operation.
+                            if "cmd_list" in dir(map_new):
+                                cmdstring = "(%s %s %s)" %(map_new.cmd_list, function, mapbinput)
+                                print('with cmd in a: ' + map_j.get_id())
+                            elif "cmd_list" in dir(map_j):
+                                cmdstring = "(%s %s %s)" %(mapainput, function, map_j.cmd_list)
+                                print('with cmd in b')
+                            elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                                cmdstring = "(%s %s %s)" %(map_new.cmd_list, function, map_j.cmd_list)
+                                print('with cmd in b')
+                            else:
+                                cmdstring = "(%s %s %s)" %(mapainput, function, mapbinput)
+                            print(cmdstring)
+                            # Conditional append of module command.
+                            map_new.cmd_list = cmdstring
+                            # Set new map name to temporary map name.
+                            mapainput = name
+                            count += 1
+                        if returncode == 0:
+                            break
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_arith2_operation_relation(self, t):
+        """
+        expr : stds T_ARITH2_OPERATOR stds
+             | expr T_ARITH2_OPERATOR stds
+             | stds T_ARITH2_OPERATOR expr
+             | expr T_ARITH2_OPERATOR expr
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[3])
+        relations, temporal, function= self.eval_toperator(t[2])
+        topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist = relations)
+
+        if self.run:
+            resultlist = []
+            for map_i in topolist:
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for topo in relations:
+                    if topo in tbrelations.keys():
+                        for map_j in (tbrelations[topo]):
+                            # Create overlayed map extent.
+                            returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                                    temp_op = temporal)
+                            # Stop the loop if no temporal or spatial relationship exist.
+                            if returncode == 0:
+                                break
+                            if count == 0:
+                                # Set map name.
+                                name = map_new.get_id()
+                            else:
+                                # Generate an intermediate map
+                                name = self.generate_map_name()
+                                map_new.set_id(name + "@" + self.mapset)
+                            # Set second input for overlay module.
+                            mapbinput = map_j.get_id()
+                            # Create r.mapcalc expression string for the operation.
+                            if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                                cmdstring = "(%s %s %s)" %(map_new.cmd_list, function, mapbinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                                cmdstring = "(%s %s %s)" %(mapainput, function, map_j.cmd_list)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                                cmdstring = "(%s %s %s)" %(map_new.cmd_list, function, map_j.cmd_list)
+                            else:
+                                cmdstring = "(%s %s %s)" %(mapainput, function, mapbinput)
+                            # Conditional append of module command.
+                            map_new.cmd_list = cmdstring
+                            # Set new map name to temporary map name.
+                            mapainput = name
+                            count += 1
+                        if returncode == 0:
+                            break
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_mapcalc_function(self, t):
+        # Supported mapcalc functions.
+        """
+        mapcalc_arith : ABS
+                      | LOG
+                      | SQRT
+                      | EXP
+                      | COS
+                      | ACOS
+                      | SIN
+                      | ASIN
+                      | TAN
+                      | DOUBLE
+                      | FLOATEXP
+                      | INTEXP
+        """
+        t[0] = t[1]
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_mapcalc_operation(self, t):
+        # Examples:
+        # sin(A)
+        # log(B)
+        """
+        expr : mapcalc_arith LPAREN stds RPAREN
+             | mapcalc_arith LPAREN expr RPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[3])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "%s(%s)" %(t[1].lower(), map_i.cmd_list)
+                else:
+                    cmdstring = "%s(%s)" %(t[1].lower(), map_i.get_id())
+                # Set new command list for map.
+                map_i.cmd_list = cmdstring
+                # Append map with updated command list to result list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_var_expr(self, t):
+        # Examples:
+        #   isnull(A)
+        """
+        s_var_expr : ISNULL LPAREN stds RPAREN
+                   | ISNULL LPAREN expr RPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[3])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "%s(%s)" %(t[1].lower(), map_i.cmd_list)
+                else:
+                    cmdstring = "%s(%s)" %(t[1].lower(), map_i.get_id())
+                # Set new command list for map.
+                map_i.cmd_list = cmdstring
+                # Append map with updated command list to result list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_var_expr2(self, t):
+        # Examples:
+        #   A <= 2
+        """
+        s_var_expr : stds comp_op number
+                   | expr comp_op number
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "%s %s %s" %(map_i.cmd_list, t[2], t[3])
+                else:
+                    cmdstring = "%s %s %s" %(map_i.get_id(), t[2], t[3])
+                # Set new command list for map.
+                map_i.cmd_list = cmdstring
+                # Append map with updated command list to result list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_var_expr3(self, t):
+        # Examples:
+        #   A <= 2 || B == 10
+        #   A < 3 && A > 1
+        """
+        s_var_expr : s_var_expr AND AND s_var_expr
+                   | s_var_expr OR OR s_var_expr
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[4])
+        topolist = self.get_temporal_topo_list(maplistA, maplistB)
+
+        if self.run:
+            resultlist = []
+            for map_i in topolist:
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for map_j in (tbrelations['EQUAL']):
+                    # Generate an intermediate map for the result map list.
+                    map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                    # Set first input for overlay module.
+                    mapainput = map_i.get_id()
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                            temp_op = '=')
+                    # Stop the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        break
+                    if count == 0:
+                        # Set map name.
+                        name = map_new.get_id()
+                    else:
+                        # Generate an intermediate map
+                        name = self.generate_map_name()
+
+                    # Set first input for overlay module.
+                    mapbinput = map_j.get_id()
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "%s %s %s" %(map_new.cmd_list, t[2] + t[3], mapbinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "%s %s %s" %(mapainput, t[2] + t[3], map_j.cmd_list)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "%s %s %s" %(map_new.cmd_list, t[2] + t[3], map_j.cmd_list)
+                    else:
+                        cmdstring = "%s %s %s" %(mapainput, t[2] + t[3], mapbinput)
+                    # Conditional append of module command.
+                    map_new.cmd_list = cmdstring
+                    # Set new map name to temporary map name.
+                    #mapainput = name
+                    count += 1
+                    # Append map to result map list.
+                    if returncode == 1:
+                        resultlist.append(map_new)
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_var_expr4(self, t):
+        # Examples:
+        #   exist(B)
+        """
+        s_var_expr : EXIST LPAREN stds RPAREN
+                   | EXIST LPAREN expr RPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[3])
+
+        if self.run:
+            resultlist = []
+            for map_i in maplist:
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_i):
+                    cmdstring = "%s" %(map_i.cmd_list)
+                else:
+                    cmdstring = "%s" %(map_i.get_id())
+                # Set new command list for map.
+                map_i.cmd_list = cmdstring
+                # Append map with updated command list to result list.
+                resultlist.append(map_i)
+
+            t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_expr_condition_if(self, t):
+        # Examples:
+        #   if(s_var_expr, B)
+        #   if(A == 1, B)
+        """
+        expr : IF LPAREN s_var_expr COMMA stds RPAREN
+             | IF LPAREN s_var_expr COMMA expr RPAREN
+        """
+
+        ifmaplist = self.check_stds(t[3])
+        thenmaplist = self.check_stds(t[5])
+        topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist)
+        resultlist = []
+        for map_i in topolist:
+            #print(map_i.get_id())
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for map_j in (tbrelations['EQUAL']):
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Create overlayed map extent.
+                returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                        temp_op = '=')
+                # Stop the loop if no temporal or spatial relationship exist.
+                if returncode == 0:
+                    break
+                if count == 0:
+                    # Set map name.
+                    name = map_new.get_id()
+                else:
+                    # Generate an intermediate map
+                    name = self.generate_map_name()
+
+                # Set first input for overlay module.
+                mapbinput = map_j.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                    cmdstring = "if(%s,%s)" %(map_new.cmd_list, mapbinput)
+                elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                    cmdstring = "if(%s,%s)" %(mapainput, map_j.cmd_list)
+                elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                    cmdstring = "if(%s,%s)" %(map_new.cmd_list, map_j.cmd_list)
+                else:
+                    cmdstring = "if(%s,%s)" %(mapainput, mapbinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Set new map name to temporary map name.
+                #mapainput = name
+                count += 1
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_numeric_condition_if(self, t):
+        # Examples:
+        #   if(s_var_expr, 1)
+        #   if(A == 5, 10)
+        """
+        expr : IF LPAREN s_var_expr COMMA number RPAREN
+             | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN RPAREN
+        """
+        ifmaplist = self.check_stds(t[3])
+        resultlist = []
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 7:
+            numinput = t[5]
+        elif len(t) == 9:
+            numinput = t[5] + t[6] + t[7]
+        # Iterate over condition map list.
+        for map_i in ifmaplist:
+            mapinput = map_i.get_id()
+            # Create r.mapcalc expression string for the operation.
+            if "cmd_list" in dir(map_i):
+                cmdstring = "if(%s,%s)" %(map_i.cmd_list, numinput)
+            else:
+                cmdstring = "if(%s,%s)" %(mapinput, numinput)
+            # Conditional append of module command.
+            map_i.cmd_list = cmdstring
+            # Append map to result map list.
+            resultlist.append(map_i)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_expr_condition_if_relation(self, t):
+        # Examples:
+        #   if({equal||during}, s_var_expr, A)
+        """
+        expr : IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr RPAREN
+        """
+        relations, temporal, function= self.eval_toperator(t[3])
+        ifmaplist = self.check_stds(t[5])
+        thenmaplist = self.check_stds(t[7])
+        topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist,
+                    topolist = relations)
+        resultlist = []
+        for map_i in topolist:
+            #print(map_i.get_id())
+            # Loop over temporal related maps.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for topo in relations:
+                if topo in tbrelations.keys():
+                    for map_j in (tbrelations[topo]):
+                        # Generate an intermediate map for the result map list.
+                        map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                        # Set first input for overlay module.
+                        mapainput = map_i.get_id()
+                        # Create overlayed map extent.
+                        returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                                temp_op = '=')
+                        # Stop the loop if no temporal or spatial relationship exist.
+                        if returncode == 0:
+                            break
+                        if count == 0:
+                            # Set map name.
+                            name = map_new.get_id()
+                        else:
+                            # Generate an intermediate map
+                            name = self.generate_map_name()
+
+                        # Set first input for overlay module.
+                        mapbinput = map_j.get_id()
+                        #print(mapbinput)
+                        #mapbinput = mapbinput.split('@')[0]
+                        # Create r.mapcalc expression string for the operation.
+                        if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                            cmdstring = "if(%s,%s)" %(map_new.cmd_list, mapbinput)
+                        elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                            cmdstring = "if(%s,%s)" %(mapainput, map_j.cmd_list)
+                        elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                            cmdstring = "if(%s,%s)" %(map_new.cmd_list, map_j.cmd_list)
+                        else:
+                            cmdstring = "if(%s,%s)" %(mapainput, mapbinput)
+                        # Conditional append of module command.
+                        map_new.cmd_list = cmdstring
+                        # Set new map name to temporary map name.
+                        #mapainput = name
+                        count += 1
+                        # Append map to result map list.
+                        if returncode == 1:
+                            resultlist.append(map_new)
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_expr_condition_elif(self, t):
+        # Examples:
+        #   if(s_var_expr, A, B)
+        """
+        expr : IF LPAREN s_var_expr COMMA stds COMMA stds RPAREN
+             | IF LPAREN s_var_expr COMMA stds COMMA expr RPAREN
+             | IF LPAREN s_var_expr COMMA expr COMMA stds RPAREN
+             | IF LPAREN s_var_expr COMMA expr COMMA expr RPAREN
+        """
+        ifmaplist = self.check_stds(t[3])
+        thenmaplist = self.check_stds(t[5])
+        elsemaplist = self.check_stds(t[7])
+        resultlist = []
+        thendict = {}
+        elsedict = {}
+        # Get topologies for the appropriate conclusion term.
+        thentopolist = self.get_temporal_topo_list(ifmaplist, thenmaplist)
+        # Fill dictionaries with related maps for both conclusion terms.
+        for map_i in thentopolist:
+            thenrelations = map_i.get_temporal_relations()
+            relationmaps = thenrelations['EQUAL']
+            thendict[map_i.get_id()] = relationmaps
+        # Get topologies for the alternative conclusion term.
+        elsetopolist = self.get_temporal_topo_list(ifmaplist, elsemaplist)
+        for map_i in elsetopolist:
+            elserelations = map_i.get_temporal_relations()
+            relationmaps = elserelations['EQUAL']
+            elsedict[map_i.get_id()] = relationmaps
+        # Loop through conditional map list.
+        for map_i in ifmaplist:
+            if map_i.get_id() in thendict.keys():
+                thenlist = thendict[map_i.get_id()]
+            else:
+                thenlist = []
+            if map_i.get_id() in elsedict.keys():
+                elselist = elsedict[map_i.get_id()]
+            else:
+                elselist = []
+            # Set iteration amount to maximal or minimum number of related
+            # conclusion maps, depending on null map creation flag.
+            if self.null:
+                iternum = max(len(thenlist), len(elselist))
+            else:
+                iternum = min(len(thenlist), len(elselist))
+            # Calculate difference in conclusion lengths.
+            iterthen = iternum - len(thenlist)
+            iterelse = iternum - len(elselist)
+            # Extend null maps to the list to get conclusions with same length.
+            if iterthen != 0:
+                for i in range(iterthen):
+                    thenlist.extend(['null()'])
+            if iterelse != 0:
+                for i in range(iterelse):
+                    elselist.extend(['null()'])
+
+            # Combine the conclusions in a paired list.
+            conclusionlist = zip(thenlist, elselist)
+            for i in range(iternum):
+                conclusionmaps = conclusionlist[i]
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapifinput = map_i.get_id()
+                # Get conclusion maps.
+                map_then = conclusionmaps[0]
+                map_else = conclusionmaps[1]
+
+                # Check if conclusions are map objects.
+                if map_then != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_then, 'and', \
+                                                            temp_op = '=')
+                    maptheninput = map_then.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    maptheninput = 'null()'
+                # Check if conclusions are map objects.
+                if map_else != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_else, 'and', \
+                                                            temp_op = '=')
+                    mapelseinput = map_else.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    mapelseinput = 'null()'
+
+                #if map_then != 'null()' and map_else != 'null()':
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    map_else.cmd_list)
+                else:
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    mapelseinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_numeric_condition_elif(self, t):
+        # Examples:
+        #   if(s_var_expr, 1, 2)
+        #   if(A == 5, 10, 0)
+        """
+        expr : IF LPAREN s_var_expr COMMA number COMMA number RPAREN
+             | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA number RPAREN
+             | IF LPAREN s_var_expr COMMA number COMMA NULL LPAREN RPAREN RPAREN
+             | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA NULL LPAREN RPAREN RPAREN
+        """
+        ifmaplist = self.check_stds(t[3])
+        resultlist = []
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 9:
+            numthen = t[5]
+            numelse = t[7]
+        elif len(t) == 11 and t[6] == '(':
+            numthen = t[5] + t[6] + t[7]
+            numelse = t[9]
+        elif len(t) == 11 and t[6] == ',':
+            numthen = t[5]
+            numelse = t[7] + t[8] + t[9]
+        elif len(t) == 13:
+            numthen = t[5] + t[6] + t[7]
+            numelse = t[9] + t[10] + t[11]
+        # Iterate over condition map list.
+        for map_i in ifmaplist:
+            mapinput = map_i.get_id()
+            # Create r.mapcalc expression string for the operation.
+            if "cmd_list" in dir(map_i):
+                cmdstring = "if(%s, %s, %s)" %(map_i.cmd_list, numthen, numelse)
+            else:
+                cmdstring = "if(%s, %s, %s)" %(mapinput, numthen, numelse)
+            # Conditional append of module command.
+            map_i.cmd_list = cmdstring
+            # Append map to result map list.
+            resultlist.append(map_i)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_numeric_expr_condition_elif(self, t):
+        # Examples:
+        #   if(s_var_expr, 1, A)
+        #   if(A == 5 && C > 5, A, null())
+        """
+        expr : IF LPAREN s_var_expr COMMA number COMMA stds RPAREN
+             | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
+             | IF LPAREN s_var_expr COMMA number COMMA expr RPAREN
+             | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
+             | IF LPAREN s_var_expr COMMA stds COMMA number RPAREN
+             | IF LPAREN s_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
+             | IF LPAREN s_var_expr COMMA expr COMMA number RPAREN
+             | IF LPAREN s_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
+        """
+        ifmaplist = self.check_stds(t[3])
+        resultlist = []
+        thenmaplist = []
+        numthen = ''
+        elsemaplist = []
+        numelse = ''
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 9:
+            try:
+                thenmaplist = self.check_stds(t[5])
+            except:
+                numthen = t[5]
+            try:
+                elsemaplist = self.check_stds(t[7])
+            except:
+                numelse = t[7]
+        elif len(t) == 11:
+            try:
+                thenmaplist = self.check_stds(t[5])
+            except:
+                numthen = t[5] + t[6] + t[7]
+            try:
+                elsemaplist = self.check_stds(t[9])
+            except:
+                numelse = t[7] + t[8] + t[9]
+        if thenmaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist)
+        elif elsemaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, elsemaplist)
+        if numthen !=  '':
+            numinput = numthen
+        elif numelse !=  '':
+            numinput = numelse
+
+        # Iterate over condition map lists with temporal relations.
+        for map_i in topolist:
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for map_j in (tbrelations['EQUAL']):
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Create overlayed map extent.
+                returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                        temp_op = '=')
+                # Stop the loop if no temporal or spatial relationship exist.
+                if returncode == 0:
+                    break
+                if count == 0:
+                    # Set map name.
+                    name = map_new.get_id()
+                else:
+                    # Generate an intermediate map
+                    name = self.generate_map_name()
+
+                # Set first input for overlay module.
+                mapbinput = map_j.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if thenmaplist != []:
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, mapbinput, \
+                                                      numinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, map_j.cmd_list, \
+                                                      numinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, map_j.cmd_list, \
+                                                      numinput)
+                    else:
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, mapbinput, numinput)
+                if elsemaplist != []:
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                      mapbinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, \
+                                                      map_j.cmd_list)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                      map_j.cmd_list)
+                    else:
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, mapbinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Set new map name to temporary map name.
+                #mapainput = name
+                count += 1
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_s_numeric_expr_condition_elif_relation(self, t):
+        # Examples:
+        #   if({during},s_var_expr, 1, A)
+        #   if({during}, A == 5, A, null())
+        """
+        expr : IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA number COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA number COMMA expr RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA number RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA number RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
+        """
+        relations, temporal, function= self.eval_toperator(t[3])
+        ifmaplist = self.check_stds(t[5])
+        resultlist = []
+        thenmaplist = []
+        numthen = ''
+        elsemaplist = []
+        numelse = ''
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 11:
+            try:
+                thenmaplist = self.check_stds(t[7])
+            except:
+                numthen = t[7]
+            try:
+                elsemaplist = self.check_stds(t[9])
+            except:
+                numelse = t[9]
+        elif len(t) == 13:
+            try:
+                thenmaplist = self.check_stds(t[7])
+            except:
+                numthen = t[9] + t[10] + t[11]
+            try:
+                elsemaplist = self.check_stds(t[11])
+            except:
+                numelse = t[9] + t[10] + t[11]
+        if thenmaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist, \
+                                                    topolist = relations)
+        elif elsemaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, elsemaplist, \
+                                                    topolist = relations)
+        if numthen !=  '':
+            numinput = numthen
+        elif numelse !=  '':
+            numinput = numelse
+
+        # Iterate over condition map lists with temporal relations.
+        for map_i in topolist:
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for topo in relations:
+                if topo in tbrelations.keys():
+                    for map_j in (tbrelations[topo]):
+                        # Generate an intermediate map for the result map list.
+                        map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                        # Set first input for overlay module.
+                        mapainput = map_i.get_id()
+                        # Create overlayed map extent.
+                        returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                                temp_op = '=')
+                        # Stop the loop if no temporal or spatial relationship exist.
+                        if returncode == 0:
+                            break
+                        if count == 0:
+                            # Set map name.
+                            name = map_new.get_id()
+                        else:
+                            # Generate an intermediate map
+                            name = self.generate_map_name()
+
+                        # Set first input for overlay module.
+                        mapbinput = map_j.get_id()
+                        # Create r.mapcalc expression string for the operation.
+                        if thenmaplist != []:
+                            if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, mapbinput, \
+                                                              numinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, map_j.cmd_list, \
+                                                              numinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, map_j.cmd_list, \
+                                                              numinput)
+                            else:
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, mapbinput, numinput)
+                        if elsemaplist != []:
+                            if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                              mapbinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, \
+                                                              map_j.cmd_list)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                              map_j.cmd_list)
+                            else:
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, mapbinput)
+                        # Conditional append of module command.
+                        map_new.cmd_list = cmdstring
+                        # Set new map name to temporary map name.
+                        #mapainput = name
+                        count += 1
+                        # Append map to result map list.
+                        if returncode == 1:
+                            resultlist.append(map_new)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_s_expr_condition_elif_relation(self, t):
+        # Examples:
+        #   if({equal||during}, s_var_expr, A, B)
+        """
+        expr : IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA expr RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA expr RPAREN
+        """
+        relations, temporal, function= self.eval_toperator(t[3])
+        ifmaplist = self.check_stds(t[5])
+        thenmaplist = self.check_stds(t[7])
+        elsemaplist = self.check_stds(t[9])
+        resultlist = []
+        thendict = {}
+        elsedict = {}
+        # Get topologies for the appropriate conclusion term.
+        thentopolist = self.get_temporal_topo_list(ifmaplist, thenmaplist, \
+                                                    topolist = relations)
+        # Fill dictionaries with related maps for both conclusion terms.
+        for map_i in thentopolist:
+            thenrelations = map_i.get_temporal_relations()
+            relationmaps = []
+            for topo in relations:
+                if topo in thenrelations.keys():
+                    relationmaps = relationmaps + thenrelations[topo]
+            thendict[map_i.get_id()] = relationmaps
+        # Get topologies for the alternative conclusion term.
+        elsetopolist = self.get_temporal_topo_list(ifmaplist, elsemaplist, \
+                                                    topolist = relations)
+        for map_i in elsetopolist:
+            elserelations = map_i.get_temporal_relations()
+            relationmaps = []
+            for topo in relations:
+                if topo in elserelations.keys():
+                    relationmaps = relationmaps + elserelations[topo]
+            elsedict[map_i.get_id()] = relationmaps
+        # Loop trough conditional map list.
+        for map_i in ifmaplist:
+            if map_i.get_id() in thendict.keys():
+                thenlist = thendict[map_i.get_id()]
+            else:
+                thenlist = []
+            if map_i.get_id() in elsedict.keys():
+                elselist = elsedict[map_i.get_id()]
+            else:
+                elselist = []
+            # Set iteration amount to maximal or minimum number of related
+            # conclusion maps, depending on null map creation flag.
+            if self.null:
+                iternum = max(len(thenlist), len(elselist))
+            else:
+                iternum = min(len(thenlist), len(elselist))
+            # Calculate difference in conclusion lengths.
+            iterthen = iternum - len(thenlist)
+            iterelse = iternum - len(elselist)
+            # Extend null maps to the list to get conclusions with same length.
+            if iterthen != 0:
+                for i in range(iterthen):
+                    thenlist.extend(['null()'])
+            if iterelse != 0:
+                for i in range(iterelse):
+                    elselist.extend(['null()'])
+
+            # Combine the conclusions in a paired list.
+            conclusionlist = zip(thenlist, elselist)
+            for i in range(iternum):
+                conclusionmaps = conclusionlist[i]
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapifinput = map_i.get_id()
+                # Get conclusion maps.
+                map_then = conclusionmaps[0]
+                map_else = conclusionmaps[1]
+
+                # Check if conclusions are map objects.
+                if map_then != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_then, 'and', \
+                                                            temp_op = '=')
+                    maptheninput = map_then.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    maptheninput = 'null()'
+                # Check if conclusions are map objects.
+                if map_else != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_else, 'and', \
+                                                            temp_op = '=')
+                    mapelseinput = map_else.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    mapelseinput = 'null()'
+
+                #if map_then != 'null()' and map_else != 'null()':
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    map_else.cmd_list)
+                else:
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    mapelseinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+    def p_ts_var_expr1(self, t):
+        # Combination of spatial and temporal conditional expressions.
+        # Examples:
+        #   A <= 2 || start_date <= 2013-01-01
+        #   end_date > 2013-01-15 && A > 10
+        #  IMPORTANT: Only the intersection of map lists in conditionals are
+        #  exported.
+        """
+        ts_var_expr : s_var_expr AND AND t_var_expr
+                    | t_var_expr AND AND s_var_expr
+                    | t_var_expr OR OR s_var_expr
+                    | s_var_expr OR OR t_var_expr
+                    | ts_var_expr AND AND s_var_expr
+                    | ts_var_expr AND AND t_var_expr
+                    | ts_var_expr OR OR s_var_expr
+                    | ts_var_expr OR OR t_var_expr
+                    | s_var_expr AND AND ts_var_expr
+                    | t_var_expr AND AND ts_var_expr
+                    | s_var_expr OR OR ts_var_expr
+                    | t_var_expr OR OR ts_var_expr
+        """
+        # Check whether inputs are map lists or global temporal variables and
+        # store each in separate lists.
+        ts_var_dict = {"temporal" : [], "spatial" : []}
+        temporal_list = []
+        spatial_list = []
+        operator = t[2] + t[3]
+        temporalop = GlobalTemporalVar()
+        temporalop.relationop = operator
+        temporalop.topology.append("EQUAL")
+
+        if isinstance(t[1], dict) and "spatial" in t[1]:
+            temporal_list = temporal_list + t[1]["temporal"]
+            spatial_list.append(t[1]["spatial"])
+        elif isinstance(t[1], list):
+            if all([isinstance(i, ta.GlobalTemporalVar) for i in t[1]]):
+                temporal_list = temporal_list + t[1]
+            else:
+                tsexprA = self.check_stds(t[1])
+                spatial_list.append(tsexprA)
+        elif isinstance(t[1], ta.GlobalTemporalVar):
+            temporal_list.append(t[1])
+        if temporal_list != [] and \
+            isinstance(t[4], ta.GlobalTemporalVar):
+            temporal_list.append(temporalop)
+        if temporal_list != [] and \
+            isinstance(t[4], list) and \
+            all([isinstance(i, ta.GlobalTemporalVar) for i in t[4]]):
+            temporal_list.append(temporalop)
+        if isinstance(t[4], dict) and "spatial" in t[4]:
+            temporal_list = temporal_list + t[4]["temporal"]
+            spatial_list.append(t[4]["spatial"])
+        elif isinstance(t[4], list):
+            if all([isinstance(i, ta.GlobalTemporalVar) for i in t[4]]):
+                temporal_list = temporal_list + t[4]
+            else:
+                tsexprB = self.check_stds(t[4])
+                spatial_list.append(tsexprB)
+        elif isinstance(t[4], ta.GlobalTemporalVar):
+            temporal_list.append(t[4])
+
+        ts_var_dict["temporal"] = temporal_list
+        # Condition for two map lists in spatio temporal expression.
+        if len(spatial_list) == 2:
+            # Build topology for both map lists in spatio temporal expression.
+            topolist = self.get_temporal_topo_list(spatial_list[0], spatial_list[1])
+            resultlist = []
+            for map_i in topolist:
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for map_j in (tbrelations['EQUAL']):
+                    # Generate an intermediate map for the result map list.
+                    map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                    # Set first input for overlay module.
+                    mapainput = map_i.get_id()
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                            temp_op = '=')
+                    # Stop the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        break
+                    if count == 0:
+                        # Set map name.
+                        name = map_new.get_id()
+                    else:
+                        # Generate an intermediate map
+                        name = self.generate_map_name()
+
+                    # Set first input for overlay module.
+                    mapbinput = map_j.get_id()
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "%s %s %s" %(map_new.cmd_list, operator, mapbinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "%s %s %s" %(mapainput, operator, map_j.cmd_list)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "%s %s %s" %(map_new.cmd_list, operator, map_j.cmd_list)
+                    else:
+                        cmdstring = "%s %s %s" %(mapainput, operator, mapbinput)
+                    # Conditional append of module command.
+                    map_new.cmd_list = cmdstring
+                    # Set new map name to temporary map name.
+                    #mapainput = name
+                    count += 1
+                    # Append map to result map list.
+                    if returncode == 1:
+                      resultlist.append(map_new)
+                    # Return dictionary with spatial map list of temporal
+                    # intersected maps and temporal expression in list form.
+                    ts_var_dict["spatial"] = resultlist
+        # Condition for only one map list in spatio temporal expression.
+        elif len(spatial_list) == 1:
+            ts_var_dict["spatial"] = spatial_list[0]
+
+        t[0] = ts_var_dict
+
+    def p_ts_expr_condition_if(self, t):
+        # Examples:
+        #   if(ts_var_expr, A)
+        #   if(start_year == 2013 || B != 5, A)
+        """
+        expr : IF LPAREN ts_var_expr COMMA stds RPAREN
+             | IF LPAREN ts_var_expr COMMA expr RPAREN
+        """
+        ts_var_dict = t[3]
+        spatialcond = ts_var_dict["spatial"]
+        # Extract spatial map list from condition.
+        ifmaplist = self.check_stds(spatialcond)
+        thenmaplist = self.check_stds(t[5])
+        topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist)
+        resultlist = []
+        resultspatial = []
+        for map_i in topolist:
+            #print(map_i.get_id())
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for map_j in (tbrelations['EQUAL']):
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Create overlayed map extent.
+                returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                        temp_op = '=')
+                # Stop the loop if no temporal or spatial relationship exist.
+                if returncode == 0:
+                    break
+                if count == 0:
+                    # Set map name.
+                    name = map_new.get_id()
+                else:
+                    # Generate an intermediate map
+                    name = self.generate_map_name()
+
+                # Set first input for overlay module.
+                mapbinput = map_j.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                    cmdstring = "if(%s,%s)" %(map_new.cmd_list, mapbinput)
+                elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                    cmdstring = "if(%s,%s)" %(mapainput, map_j.cmd_list)
+                elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                    cmdstring = "if(%s,%s)" %(map_new.cmd_list, map_j.cmd_list)
+                else:
+                    cmdstring = "if(%s,%s)" %(mapainput, mapbinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Set new map name to temporary map name.
+                #mapainput = name
+                count += 1
+                # Append map to result map list.
+                if returncode == 1:
+                    resultspatial.append(map_new)
+        # Evaluate temporal statements in spatio temporal condition.
+
+        #if len(ts_var_dict["temporal"]) == 1:
+            #temporalcond = ts_var_dict["temporal"][0]
+        #else:
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial)
+        thenresult = self.eval_condition_list(thencond)
+        # Clear the map list.
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_ts_expr_condition_if_relation(self, t):
+        # Examples:
+        #   if({equal||during}, ts_var_expr, A)
+        #   if({starts||during}, B > 2 || end_month() == 4, A)
+        """
+        expr : IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr RPAREN
+        """
+        relations, temporal, function= self.eval_toperator(t[3])
+        ts_var_dict = t[5]
+        spatialcond = ts_var_dict["spatial"]
+        # Extract spatial map list from condition.
+        ifmaplist = self.check_stds(spatialcond)
+        thenmaplist = self.check_stds(t[7])
+        topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist,
+                                                topolist = relations)
+        resultspatial = []
+        for map_i in topolist:
+            #print(map_i.get_id())
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for topo in relations:
+                if topo in tbrelations.keys():
+                    for map_j in (tbrelations[topo]):
+                        # Generate an intermediate map for the result map list.
+                        map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                        # Set first input for overlay module.
+                        mapainput = map_i.get_id()
+                        # Create overlayed map extent.
+                        returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                                temp_op = '=')
+                        # Stop the loop if no temporal or spatial relationship exist.
+                        if returncode == 0:
+                            break
+                        if count == 0:
+                            # Set map name.
+                            name = map_new.get_id()
+                        else:
+                            # Generate an intermediate map
+                            name = self.generate_map_name()
+
+                        # Set first input for overlay module.
+                        mapbinput = map_j.get_id()
+                        # Create r.mapcalc expression string for the operation.
+                        if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                            cmdstring = "if(%s,%s)" %(map_new.cmd_list, mapbinput)
+                        elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                            cmdstring = "if(%s,%s)" %(mapainput, map_j.cmd_list)
+                        elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                            cmdstring = "if(%s,%s)" %(map_new.cmd_list, map_j.cmd_list)
+                        else:
+                            cmdstring = "if(%s,%s)" %(mapainput, mapbinput)
+                        # Conditional append of module command.
+                        map_new.cmd_list = cmdstring
+                        # Set new map name to temporary map name.
+                        #mapainput = name
+                        count += 1
+                        # Append map to result map list.
+                        if returncode == 1:
+                            resultspatial.append(map_new)
+        # Evaluate temporal statements in spatio temporal condition.
+
+        #if len(ts_var_dict["temporal"]) == 1:
+            #temporalcond = ts_var_dict["temporal"][0]
+        #else:
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial, relations)
+        thenresult = self.eval_condition_list(thencond)
+        # Clear the map list.
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_ts_numeric_condition_if(self, t):
+        # Examples:
+        #   if(ts_var_expr, 1)
+        #   if(A == 5 && start_day() > 5, 10)
+        """
+        expr : IF LPAREN ts_var_expr COMMA number RPAREN
+             | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN RPAREN
+        """
+        ts_var_dict = t[3]
+        spatialcond = ts_var_dict["spatial"]
+        ifmaplist = self.check_stds(spatialcond)
+        resultspatial = []
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 7:
+            numinput = t[5]
+        elif len(t) == 9:
+            numinput = t[5] + t[6] + t[7]
+        # Iterate over condition map list.
+        for map_i in ifmaplist:
+            mapinput = map_i.get_id()
+            # Create r.mapcalc expression string for the operation.
+            if "cmd_list" in dir(map_i):
+                cmdstring = "if(%s,%s)" %(map_i.cmd_list, numinput)
+            else:
+                cmdstring = "if(%s,%s)" %(mapinput, numinput)
+            # Conditional append of module command.
+            map_i.cmd_list = cmdstring
+            # Append map to result map list.
+            resultspatial.append(map_i)
+
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial)
+        thenresult = self.eval_condition_list(thencond)
+        # Clear the map list.
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_ts_expr_condition_elif(self, t):
+        # Examples:
+        #   if(s_var_expr, A, B)
+        #   if(start_day() < 20 && B > 2, A, B)
+        """
+        expr : IF LPAREN ts_var_expr COMMA stds COMMA stds RPAREN
+             | IF LPAREN ts_var_expr COMMA stds COMMA expr RPAREN
+             | IF LPAREN ts_var_expr COMMA expr COMMA stds RPAREN
+             | IF LPAREN ts_var_expr COMMA expr COMMA expr RPAREN
+        """
+        ts_var_dict = t[3]
+        spatialcond = ts_var_dict["spatial"]
+        ifmaplist = self.check_stds(spatialcond)
+        thenmaplist = self.check_stds(t[5])
+        elsemaplist = self.check_stds(t[7])
+        resultspatial = []
+        thendict = {}
+        elsedict = {}
+        # Get topologies for the appropriate conclusion term.
+        thentopolist = self.get_temporal_topo_list(ifmaplist, thenmaplist)
+        # Fill dictionaries with related maps for both conclusion terms.
+        for map_i in thentopolist:
+            thenrelations = map_i.get_temporal_relations()
+            relationmaps = thenrelations['EQUAL']
+            thendict[map_i.get_id()] = relationmaps
+        # Get topologies for the alternative conclusion term.
+        elsetopolist = self.get_temporal_topo_list(ifmaplist, elsemaplist)
+        for map_i in elsetopolist:
+            elserelations = map_i.get_temporal_relations()
+            relationmaps = elserelations['EQUAL']
+            elsedict[map_i.get_id()] = relationmaps
+        # Loop through conditional map list.
+        for map_i in ifmaplist:
+            if map_i.get_id() in thendict.keys():
+                thenlist = thendict[map_i.get_id()]
+            else:
+                thenlist = []
+            if map_i.get_id() in elsedict.keys():
+                elselist = elsedict[map_i.get_id()]
+            else:
+                elselist = []
+            # Set iteration amount to maximal or minimum number of related
+            # conclusion maps, depending on null map creation flag.
+            if self.null:
+                iternum = max(len(thenlist), len(elselist))
+            else:
+                iternum = min(len(thenlist), len(elselist))
+            # Calculate difference in conclusion lengths.
+            iterthen = iternum - len(thenlist)
+            iterelse = iternum - len(elselist)
+            # Extend null maps to the list to get conclusions with same length.
+            if iterthen != 0:
+                for i in range(iterthen):
+                    thenlist.extend(['null()'])
+            if iterelse != 0:
+                for i in range(iterelse):
+                    elselist.extend(['null()'])
+            # Combine the conclusions in a paired list.
+            conclusionlist = zip(thenlist, elselist)
+            for i in range(iternum):
+                conclusionmaps = conclusionlist[i]
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapifinput = map_i.get_id()
+                # Get conclusion maps.
+                map_then = conclusionmaps[0]
+                map_else = conclusionmaps[1]
+
+                # Check if conclusions are map objects.
+                if map_then != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_then, 'and', \
+                                                            temp_op = '=')
+                    maptheninput = map_then.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    maptheninput = 'null()'
+                # Check if conclusions are map objects.
+                if map_else != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_else, 'and', \
+                                                            temp_op = '=')
+                    mapelseinput = map_else.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    mapelseinput = 'null()'
+
+                #if map_then != 'null()' and map_else != 'null()':
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    map_else.cmd_list)
+                else:
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    mapelseinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Append map to result map list.
+                if returncode == 1:
+                    resultspatial.append(map_new)
+
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial)
+        thenresult = self.eval_condition_list(thencond)
+        #elseresult = self.eval_condition_list(thencond, inverse = True)
+        # Combine and sort else and then statement to result map list.
+        #combilist = thenresult + elseresult
+        #resultlist = sorted(combilist, key = AbstractDatasetComparisonKeyStartTime)
+        # Clear the map list.
+        #resultlist = self.check_stds(resultlist, clear = True)
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_ts_expr_condition_elif_relation(self, t):
+        # Examples:
+        #   if({equal||during}, s_var_expr, A, B)
+        #   if({contains}, start_day() == 3 || C != 2, A, B)
+        """
+        expr : IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA expr RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA expr RPAREN
+        """
+        relations, temporal, function= self.eval_toperator(t[3])
+        ts_var_dict = t[5]
+        spatialcond = ts_var_dict["spatial"]
+        # Extract spatial map list from condition.
+        ifmaplist = self.check_stds(spatialcond)
+        thenmaplist = self.check_stds(t[7])
+        elsemaplist = self.check_stds(t[9])
+        resultspatial = []
+        thendict = {}
+        elsedict = {}
+        # Get topologies for the appropriate conclusion term.
+        thentopolist = self.get_temporal_topo_list(ifmaplist, thenmaplist, \
+                                                    topolist = relations)
+        # Fill dictionaries with related maps for both conclusion terms.
+        for map_i in thentopolist:
+            thenrelations = map_i.get_temporal_relations()
+            relationmaps = []
+            for topo in relations:
+                if topo in thenrelations.keys():
+                    relationmaps = relationmaps + thenrelations[topo]
+            thendict[map_i.get_id()] = relationmaps
+        # Get topologies for the alternative conclusion term.
+        elsetopolist = self.get_temporal_topo_list(ifmaplist, elsemaplist, \
+                                                    topolist = relations)
+        for map_i in elsetopolist:
+            elserelations = map_i.get_temporal_relations()
+            relationmaps = []
+            for topo in relations:
+                if topo in elserelations.keys():
+                    relationmaps = relationmaps + elserelations[topo]
+            elsedict[map_i.get_id()] = relationmaps
+        # Loop trough conditional map list.
+        for map_i in ifmaplist:
+            if map_i.get_id() in thendict.keys():
+                thenlist = thendict[map_i.get_id()]
+            else:
+                thenlist = []
+            if map_i.get_id() in elsedict.keys():
+                elselist = elsedict[map_i.get_id()]
+            else:
+                elselist = []
+            # Set iteration amount to maximal or minimum number of related
+            # conclusion maps, depending on null map creation flag.
+            if self.null:
+                iternum = max(len(thenlist), len(elselist))
+            else:
+                iternum = min(len(thenlist), len(elselist))
+            # Calculate difference in conclusion lengths.
+            iterthen = iternum - len(thenlist)
+            iterelse = iternum - len(elselist)
+            # Extend null maps to the list to get conclusions with same length.
+            if iterthen != 0:
+                for i in range(iterthen):
+                    thenlist.extend(['null()'])
+            if iterelse != 0:
+                for i in range(iterelse):
+                    elselist.extend(['null()'])
+
+            # Combine the conclusions in a paired list.
+            conclusionlist = zip(thenlist, elselist)
+            for i in range(iternum):
+                conclusionmaps = conclusionlist[i]
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapifinput = map_i.get_id()
+                # Get conclusion maps.
+                map_then = conclusionmaps[0]
+                map_else = conclusionmaps[1]
+
+                # Check if conclusions are map objects.
+                if map_then != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_then, 'and', \
+                                                            temp_op = '=')
+                    maptheninput = map_then.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    maptheninput = 'null()'
+                # Check if conclusions are map objects.
+                if map_else != 'null()':
+                    # Create overlayed map extent.
+                    returncode = self.overlay_map_extent(map_new, map_else, 'and', \
+                                                            temp_op = '=')
+                    mapelseinput = map_else.get_id()
+                    # Continue the loop if no temporal or spatial relationship exist.
+                    if returncode == 0:
+                        continue
+                else:
+                    mapelseinput = 'null()'
+
+                #if map_then != 'null()' and map_else != 'null()':
+                # Create r.mapcalc expression string for the operation.
+                if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(map_new.cmd_list, map_then.cmd_list,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" not in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    mapelseinput)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" not in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    map_else.cmd_list)
+                elif "cmd_list" not in dir(map_new) and "cmd_list" in dir(map_then) \
+                    and "cmd_list" in dir(map_else):
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, map_then.cmd_list,
+                    map_else.cmd_list)
+                else:
+                    cmdstring = "if(%s, %s, %s)" %(mapifinput, maptheninput,
+                    mapelseinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Append map to result map list.
+                if returncode == 1:
+                    resultspatial.append(map_new)
+
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial, relations)
+        thenresult = self.eval_condition_list(thencond)
+        #elseresult = self.eval_condition_list(thencond, inverse = True)
+        # Combine and sort else and then statement to result map list.
+        #combilist = thenresult + elseresult
+        #resultlist = sorted(combilist, key = AbstractDatasetComparisonKeyStartTime)
+        # Clear the map list.
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_ts_numeric_condition_elif(self, t):
+        # Examples:
+        #   if(ts_var_expr, 1, 2)
+        #   if(A == 1 || end_year == 2013, 10, null())
+        """
+        expr : IF LPAREN ts_var_expr COMMA number COMMA number RPAREN
+             | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA number RPAREN
+             | IF LPAREN ts_var_expr COMMA number COMMA NULL LPAREN RPAREN RPAREN
+             | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA NULL LPAREN RPAREN RPAREN
+        """
+        ts_var_dict = t[3]
+        spatialcond = ts_var_dict["spatial"]
+        # Extract spatial map list from condition.
+        ifmaplist = self.check_stds(spatialcond)
+        resultspatial = []
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 9:
+            numthen = t[5]
+            numelse = t[7]
+        elif len(t) == 11 and t[6] == '(':
+            numthen = t[5] + t[6] + t[7]
+            numelse = t[9]
+        elif len(t) == 11 and t[6] == ',':
+            numthen = t[5]
+            numelse = t[7] + t[8] + t[9]
+        elif len(t) == 13:
+            numthen = t[5] + t[6] + t[7]
+            numelse = t[9] + t[10] + t[11]
+        # Iterate over condition map list.
+        for map_i in ifmaplist:
+            mapinput = map_i.get_id()
+            # Create r.mapcalc expression string for the operation.
+            if "cmd_list" in dir(map_i):
+                cmdstring = "if(%s, %s, %s)" %(map_i.cmd_list, numthen, numelse)
+            else:
+                cmdstring = "if(%s, %s, %s)" %(mapinput, numthen, numelse)
+            # Conditional append of module command.
+            map_i.cmd_list = cmdstring
+            # Append map to result map list.
+            resultspatial.append(map_i)
+
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial)
+        thenresult = self.eval_condition_list(thencond)
+        #elseresult = self.eval_condition_list(thencond, inverse = True)
+        # Combine and sort else and then statement to result map list.
+        #combilist = thenresult + elseresult
+        #resultlist = sorted(combilist, key = AbstractDatasetComparisonKeyStartTime)
+        # Clear the map list.
+        #resultlist = self.check_stds(resultlist, clear = True)
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+    def p_ts_numeric_expr_condition_elif(self, t):
+        # Examples:
+        #   if(ts_var_expr, 1, A)
+        #   if(A == 5 && start_day() > 5, A, null())
+        """
+        expr : IF LPAREN ts_var_expr COMMA number COMMA stds RPAREN
+             | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
+             | IF LPAREN ts_var_expr COMMA number COMMA expr RPAREN
+             | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
+             | IF LPAREN ts_var_expr COMMA stds COMMA number RPAREN
+             | IF LPAREN ts_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
+             | IF LPAREN ts_var_expr COMMA expr COMMA number RPAREN
+             | IF LPAREN ts_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
+        """
+        ts_var_dict = t[3]
+        spatialcond = ts_var_dict["spatial"]
+        ifmaplist = self.check_stds(spatialcond)
+        resultspatial = []
+        thenmaplist = []
+        numthen = ''
+        elsemaplist = []
+        numelse = ''
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 9:
+            try:
+                thenmaplist = self.check_stds(t[5])
+            except:
+                numthen = t[5]
+            try:
+                elsemaplist = self.check_stds(t[7])
+            except:
+                numelse = t[7]
+        elif len(t) == 11:
+            try:
+                thenmaplist = self.check_stds(t[5])
+            except:
+                numthen = t[5] + t[6] + t[7]
+            try:
+                elsemaplist = self.check_stds(t[9])
+            except:
+                numelse = t[7] + t[8] + t[9]
+        if thenmaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist)
+        elif elsemaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, elsemaplist)
+        if numthen !=  '':
+            numinput = numthen
+        elif numelse !=  '':
+            numinput = numelse
+
+        # Iterate over condition map lists with temporal relations.
+        for map_i in topolist:
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for map_j in (tbrelations['EQUAL']):
+                # Generate an intermediate map for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Create overlayed map extent.
+                returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                        temp_op = '=')
+                # Stop the loop if no temporal or spatial relationship exist.
+                if returncode == 0:
+                    break
+                if count == 0:
+                    # Set map name.
+                    name = map_new.get_id()
+                else:
+                    # Generate an intermediate map
+                    name = self.generate_map_name()
+
+                # Set first input for overlay module.
+                mapbinput = map_j.get_id()
+                # Create r.mapcalc expression string for the operation.
+                if thenmaplist != []:
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, mapbinput, \
+                                                      numinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, map_j.cmd_list, \
+                                                      numinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, map_j.cmd_list, \
+                                                      numinput)
+                    else:
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, mapbinput, numinput)
+                if elsemaplist != []:
+                    if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                      mapbinput)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, \
+                                                      map_j.cmd_list)
+                    elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                        cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                      map_j.cmd_list)
+                    else:
+                        cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, mapbinput)
+                # Conditional append of module command.
+                map_new.cmd_list = cmdstring
+                # Set new map name to temporary map name.
+                #mapainput = name
+                count += 1
+                # Append map to result map list.
+                if returncode == 1:
+                    resultspatial.append(map_new)
+
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial)
+        thenresult = self.eval_condition_list(thencond)
+        # Clear the map list.
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+    def p_ts_numeric_expr_condition_elif_relation(self, t):
+        # Examples:
+        #   if({during},ts_var_expr, 1, A)
+        #   if({during}, A == 5 && start_day() > 5, A, null())
+        """
+        expr : IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA number COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA number COMMA expr RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA number RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA number RPAREN
+             | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
+        """
+        relations, temporal, function= self.eval_toperator(t[3])
+        ts_var_dict = t[5]
+        spatialcond = ts_var_dict["spatial"]
+        ifmaplist = self.check_stds(spatialcond)
+        resultspatial = []
+        thenmaplist = []
+        numthen = ''
+        elsemaplist = []
+        numelse = ''
+        # Select input for r.mapcalc expression based on length of PLY object.
+        if len(t) == 11:
+            try:
+                thenmaplist = self.check_stds(t[7])
+            except:
+                numthen = t[7]
+            try:
+                elsemaplist = self.check_stds(t[9])
+            except:
+                numelse = t[9]
+        elif len(t) == 13:
+            try:
+                thenmaplist = self.check_stds(t[7])
+            except:
+                numthen = t[9] + t[10] + t[11]
+            try:
+                elsemaplist = self.check_stds(t[11])
+            except:
+                numelse = t[9] + t[10] + t[11]
+        if thenmaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, thenmaplist, \
+                                                    topolist = relations)
+        elif elsemaplist != []:
+            topolist = self.get_temporal_topo_list(ifmaplist, elsemaplist, \
+                                                    topolist = relations)
+        if numthen !=  '':
+            numinput = numthen
+        elif numelse !=  '':
+            numinput = numelse
+
+        # Iterate over condition map lists with temporal relations.
+        for map_i in topolist:
+            # Loop over temporal related maps and create overlay modules.
+            tbrelations = map_i.get_temporal_relations()
+            count = 0
+            for topo in relations:
+                if topo in tbrelations.keys():
+                    for map_j in (tbrelations[topo]):
+                        # Generate an intermediate map for the result map list.
+                        map_new = self.generate_new_map(base_map=map_i, bool_op = 'and', copy = True)
+                        # Set first input for overlay module.
+                        mapainput = map_i.get_id()
+                        # Create overlayed map extent.
+                        returncode = self.overlay_map_extent(map_new, map_j, 'and', \
+                                                                temp_op = '=')
+                        # Stop the loop if no temporal or spatial relationship exist.
+                        if returncode == 0:
+                            break
+                        if count == 0:
+                            # Set map name.
+                            name = map_new.get_id()
+                        else:
+                            # Generate an intermediate map
+                            name = self.generate_map_name()
+
+                        # Set first input for overlay module.
+                        mapbinput = map_j.get_id()
+                        # Create r.mapcalc expression string for the operation.
+                        if thenmaplist != []:
+                            if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, mapbinput, \
+                                                              numinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, map_j.cmd_list, \
+                                                              numinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, map_j.cmd_list, \
+                                                              numinput)
+                            else:
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, mapbinput, numinput)
+                        if elsemaplist != []:
+                            if "cmd_list" in dir(map_new) and "cmd_list" not in dir(map_j):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                              mapbinput)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" not in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, \
+                                                              map_j.cmd_list)
+                            elif "cmd_list" in dir(map_j) and "cmd_list" in dir(map_new):
+                                cmdstring = "if(%s,%s,%s)" %(map_new.cmd_list, numinput, \
+                                                              map_j.cmd_list)
+                            else:
+                                cmdstring = "if(%s,%s,%s)" %(mapainput, numinput, mapbinput)
+                        # Conditional append of module command.
+                        map_new.cmd_list = cmdstring
+                        # Set new map name to temporary map name.
+                        #mapainput = name
+                        count += 1
+                        # Append map to result map list.
+                        if returncode == 1:
+                            resultspatial.append(map_new)
+
+        temporalcond = ts_var_dict["temporal"]
+        resultspatial = self.check_stds(resultspatial)
+        thencond = self.build_condition_list(temporalcond, resultspatial)
+        thenresult = self.eval_condition_list(thencond)
+        # Clear the map list.
+        resultlist = self.check_stds(thenresult, clear = True)
+
+        t[0] = resultlist
+
+        if self.debug:
+            for map in resultlist:
+                print map.cmd_list
+
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()

Added: grass/trunk/lib/python/temporal/temporal_raster_operator.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_raster_operator.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_raster_operator.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -0,0 +1,390 @@
+"""!@package grass.temporal
+
+Temporal operator evaluation with PLY
+
+(C) 2013 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Thomas Leppelt and Soeren Gebbert
+
+ at code
+    >>> p = TemporalRasterOperatorParser()
+    >>> expression =  "{equal| during | follows,+!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'follows'], '+', '!:')
+    >>> expression =  "{equal| during,!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during'], '=', '!:')
+    >>> expression =  "{!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '=', '!:')
+    >>> expression =  "{|#}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '|', '#')
+    >>> expression =  "{equal|during,=!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during'], '=', '!:')
+    >>> expression =  "{equal|during|starts}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'starts'], None, None)
+    >>> expression =  "{equal,++}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '+', '+')
+    >>> expression =  "{equal | during,|%}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during'], '|', '%')
+    >>> expression =  "{||}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '=', '||')
+    >>> expression =  "{equal,||}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '=', '||')
+    >>> expression =  "{equal | during | contains,&&}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'contains'], '=', '&&')
+    >>> expression =  "{equal | during | contains,/}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'contains'], '=', '/')
+    >>> expression =  "{equal | during | contains,|*}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'contains'], '|', '*')
+
+ at endcode
+"""
+
+try:
+    import ply.lex as lex
+    import ply.yacc as yacc
+except:
+    pass
+
+class TemporalRasterOperatorLexer(object):
+    """!Lexical analyzer for the GRASS GIS temporal operator"""
+
+    # Functions that defines topological relations.
+    relations = {
+        'equal'      : "EQUAL",
+        'follows'    : "FOLLOWS",
+        'precedes'   : "PRECEDES",
+        'overlaps'   : "OVERLAPS",
+        'overlapped' : "OVERLAPPED",
+        'during'     : "DURING",
+        'starts'     : "STARTS",
+        'finishes'   : "FINISHES",
+        'contains'   : "CONTAINS",
+        'started'    : "STARTED",
+        'finished'   : "FINISHED",
+        'over'       : "OVER"
+        }
+
+    # This is the list of token names.
+    tokens = (
+        'COMMA',
+        'LEFTREF',
+        'HASH',
+        'OR',
+        'AND',
+        'MOD',
+        'DIV',
+        'MULT',
+        'ADD',
+        'SUB',
+        'T_SELECT',
+        'T_NOT_SELECT',
+        'CLPAREN',
+        'CRPAREN',
+    )
+
+    # Build the token list
+    tokens = tokens + tuple(relations.values())
+
+    # Regular expression rules for simple tokens
+    t_T_SELECT           = r':'
+    t_T_NOT_SELECT       = r'!:'
+    t_COMMA              = r','
+    t_LEFTREF             = r'='
+    t_HASH               = r'\#'
+    t_OR                 = r'[\|]'
+    t_AND                = r'[&]'
+    t_MOD                = r'[\%]'
+    t_DIV                = r'[\/]'
+    t_MULT               = r'[\*]'
+    t_ADD                = r'[\+]'
+    t_SUB                = r'[-]'
+    t_CLPAREN             = r'\{'
+    t_CRPAREN             = r'\}'
+
+    # These are the things that should be ignored.
+    t_ignore = ' \t'
+
+    # Track line numbers.
+    def t_newline(self, t):
+        r'\n+'
+        t.lineno += len(t.value)
+
+    def t_NAME(self, t):
+        r'[a-zA-Z_][a-zA-Z_0-9]*'
+        self.temporal_symbol(t)
+        return t
+
+    # Parse symbols
+    def temporal_symbol(self, t):
+        # Check for reserved words
+        if t.value in TemporalRasterOperatorLexer.relations.keys():
+            t.type = TemporalRasterOperatorLexer.relations.get(t.value)
+        #else:
+        #    t.type = 'NAME'
+        return(t)
+
+    # Handle errors.
+    def t_error(self, t):
+        raise SyntaxError("syntax error on line %d near '%s'" %
+            (t.lineno, t.value))
+
+    # Build the lexer
+    def build(self,**kwargs):
+        self.lexer = lex.lex(module=self, **kwargs)
+
+    # Just for testing
+    def test(self,data):
+        self.name_list = {}
+        print(data)
+        self.lexer.input(data)
+        while True:
+             tok = self.lexer.token()
+             if not tok: break
+             print tok
+
+###############################################################################
+
+class TemporalRasterOperatorParser(object):
+    """The temporal algebra class"""
+
+    def __init__(self):
+        self.lexer = TemporalRasterOperatorLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self)
+
+    def parse(self, expression, comparison = False):
+        self.comparison = comparison
+        self.parser.parse(expression)
+
+    # Error rule for syntax errors.
+    def p_error(self, t):
+        raise SyntaxError("invalid syntax")
+
+    # Get the tokens from the lexer class
+    tokens = TemporalRasterOperatorLexer.tokens
+
+    def p_relation_only(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation CRPAREN
+                 | CLPAREN relationlist CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal  = None
+        self.function  = None
+
+        t[0] = t[2]
+
+
+    def p_operator(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN select CRPAREN
+                 | CLPAREN HASH CRPAREN
+                 | CLPAREN arithmetic CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        self.temporal  = "="
+        self.function  = t[2]
+
+        t[0] = t[2]
+
+    def p_comparison(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN temporal AND CRPAREN
+                 | CLPAREN temporal OR CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        self.temporal  = "="
+        if t[2] == t[3]:
+            self.function  = t[2] + t[3]
+        else:
+            raise SyntaxError("syntax error on line %d near '%s'" %
+                                (t.lineno, t.value))
+
+        t[0] = t[2]
+
+    def p_operator_temporal(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN temporal select CRPAREN
+                 | CLPAREN temporal HASH CRPAREN
+                 | CLPAREN temporal arithmetic CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        self.temporal = t[2]
+        self.function = t[3]
+
+        t[0] = t[3]
+
+    def p_operator_relation(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation COMMA select CRPAREN
+                 | CLPAREN relationlist COMMA select CRPAREN
+                 | CLPAREN relation COMMA HASH CRPAREN
+                 | CLPAREN relationlist COMMA HASH CRPAREN
+                 | CLPAREN relation COMMA arithmetic CRPAREN
+                 | CLPAREN relationlist COMMA arithmetic CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal  = "="
+        self.function  = t[4]
+
+        t[0] = t[4]
+
+    def p_comparison_relation(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation COMMA temporal AND CRPAREN
+                 | CLPAREN relation COMMA temporal OR CRPAREN
+                 | CLPAREN relationlist COMMA temporal AND CRPAREN
+                 | CLPAREN relationlist COMMA temporal OR CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal  = "="
+        if t[4] == t[5]:
+            self.function  = t[4] + t[5]
+        else:
+            raise SyntaxError("syntax error on line %d near '%s'" %
+                                (t.lineno, t.value))
+
+        t[0] = t[4]
+
+    def p_operator_relation_temporal(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation COMMA temporal select CRPAREN
+                 | CLPAREN relationlist COMMA temporal select CRPAREN
+                 | CLPAREN relation COMMA temporal HASH CRPAREN
+                 | CLPAREN relationlist COMMA temporal HASH CRPAREN
+                 | CLPAREN relation COMMA temporal arithmetic CRPAREN
+                 | CLPAREN relationlist COMMA temporal arithmetic CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal = t[4]
+        self.function = t[5]
+        t[0] = t[5]
+
+    def p_relation(self, t):
+        # The list of relations.
+        """
+        relation : EQUAL
+                 | FOLLOWS
+                 | PRECEDES
+                 | OVERLAPS
+                 | OVERLAPPED
+                 | DURING
+                 | STARTS
+                 | FINISHES
+                 | CONTAINS
+                 | STARTED
+                 | FINISHED
+        """
+        t[0] = t[1]
+
+    def p_over(self, t):
+        # The list of relations.
+        """
+        relation : OVER
+        """
+        over_list = ["overlaps", "overlapped"]
+        t[0] = over_list
+
+    def p_relationlist(self, t):
+        # The list of relations.
+        """
+        relationlist : relation OR relation
+                     | relation OR relationlist
+        """
+        rel_list = []
+        rel_list.append(t[1])
+        if isinstance(t[3], list):
+            rel_list = rel_list + t[3]
+        else:
+            rel_list.append(t[3])
+        t[0] =  rel_list
+
+    def p_temporal_operator(self, t):
+        # The list of relations.
+        """
+        temporal : LEFTREF
+                 | OR
+                 | AND
+                 | ADD
+        """
+        t[0] = t[1]
+
+    def p_select_operator(self, t):
+        # The list of relations.
+        """
+        select : T_SELECT
+               | T_NOT_SELECT
+        """
+        t[0] = t[1]
+
+    def p_arithmetic_operator(self, t):
+        # The list of relations.
+        """
+        arithmetic : MOD
+                   | DIV
+                   | MULT
+                   | ADD
+                   | SUB
+        """
+        t[0] = t[1]
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+

Modified: grass/trunk/lib/python/temporal/temporal_vector_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_vector_algebra.py	2014-02-09 11:47:26 UTC (rev 58970)
+++ grass/trunk/lib/python/temporal/temporal_vector_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -419,17 +419,7 @@
 @endcode
 """
 
-try:
-    import ply.yacc as yacc
-except:
-    pass
-
 import grass.pygrass.modules as pygrass
-import grass.script as grass
-from space_time_datasets import *
-from factory import *
-from open_stds import *
-import copy
 from temporal_vector_operator import *
 from temporal_algebra import *
 
@@ -482,6 +472,8 @@
             t.type = 'NAME'
         return t
 
+##############################################################################
+
 class TemporalVectorAlgebraParser(TemporalAlgebraParser):
     """The temporal algebra class"""
 
@@ -504,13 +496,14 @@
         self.m_mremove = pygrass.Module('g.mremove', quiet=True, run_=False)
         self.m_buffer = pygrass.Module('v.buffer', quiet=True, run_=False)
 
-    def parse(self, expression, stdstype = 'strds', basename = None):
+    def parse(self, expression, basename = None, overwrite = False):
         self.lexer = TemporalVectorAlgebraLexer()
         self.lexer.build()
         self.parser = yacc.yacc(module=self, debug=self.debug)
 
+        self.overwrite = overwrite
         self.count = 0
-        self.stdstype = stdstype
+        self.stdstype = "stvds"
         self.basename = basename
         self.expression = expression
         self.parser.parse(expression)
@@ -613,59 +606,15 @@
            @param copy Specifies if the temporal extent of mapB should be
                   copied to mapA
         """
-        returncode = 1
-        if copy:
-            map_extent_temporal = mapB.get_temporal_extent()
-            map_extent_spatial = mapB.get_spatial_extent()
-            # Set initial map extend of new vector map.
-            mapA.set_spatial_extent(map_extent_spatial)
-            mapA.set_temporal_extent(map_extent_temporal)
-            if "cmd_list" in dir(mapB):
-                mapA.cmd_list = mapB.cmd_list
-        else:
-            # Calculate spatial extent for different overlay operations.
-            if bool_op == 'and':
-                overlay_ext = mapA.spatial_intersection(mapB)
-                if overlay_ext != None:
-                    mapA.set_spatial_extent(overlay_ext)
-                else:
-                    returncode = 0
-            elif bool_op in ['or', 'xor']:
-                overlay_ext = mapA.spatial_union(mapB)
-                if overlay_ext != None:
-                    mapA.set_spatial_extent(overlay_ext)
-                else:
-                    returncode = 0
-            elif bool_op == 'disor':
-                overlay_ext = mapA.spatial_disjoint_union(mapB)
-                if overlay_ext != None:
-                    mapA.set_spatial_extent(overlay_ext)
-                else:
-                    returncode = 0
+        returncode = TemporalAlgebraParser.overlay_map_extent(self, mapA, mapB,
+                                                              bool_op, temp_op,
+                                                              copy)
+        if not copy and returncode == 1:
             # Conditional append of command list.
             if "cmd_list" in dir(mapA) and "cmd_list" in dir(mapB):
                 mapA.cmd_list = mapA.cmd_list + mapB.cmd_list
             elif "cmd_list" not in dir(mapA) and "cmd_list" in dir(mapB):
                 mapA.cmd_list = mapB.cmd_list
-            # Calculate temporal extent for different temporal operators.
-            if temp_op == '&':
-                temp_ext = mapA.temporal_intersection(mapB)
-                if temp_ext != None:
-                    mapA.set_temporal_extent(temp_ext)
-                else:
-                    returncode = 0
-            elif temp_op == '|':
-                temp_ext = mapA.temporal_union(mapB)
-                if temp_ext != None:
-                    mapA.set_temporal_extent(temp_ext)
-                else:
-                    returncode = 0
-            elif temp_op == '+':
-                temp_ext = mapA.temporal_disjoint_union(mapB)
-                if temp_ext != None:
-                    mapA.set_temporal_extent(temp_ext)
-                else:
-                    returncode = 0
 
         return(returncode)
 
@@ -688,7 +637,7 @@
                     # Check if resultmap names exist in GRASS database.
                     vectorname = self.basename + "_" + str(i)
                     vectormap = VectorDataset(vectorname + "@" + get_current_mapset())
-                    if vectormap.map_exists() and grass.overwrite() == False:
+                    if vectormap.map_exists() and self.overwrite == False:
                         self.msgr.fatal(_("Error vector maps with basename %s exist. "
                                       "Use --o flag to overwrite existing file") \
                                       %(vectorname))
@@ -741,10 +690,10 @@
                             newident = self.basename + "_" + str(count)
                             m = copy.deepcopy(self.m_rename)
                             m.inputs["vect"].value = (map_i.get_name(),newident)
-                            m.flags["overwrite"].value = grass.overwrite()
+                            m.flags["overwrite"].value = self.overwrite
                             m.run()
                             #m(vect = (map_i.get_name(),newident), \
-                            #    overwrite = grass.overwrite)
+                            #    overwrite = self.overwrite)
                             map_i.set_id(newident + "@" + mapset)
                             count += 1
                             register_list.append(map_i)
@@ -758,16 +707,16 @@
                     resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
                                                                 'absolute', t[1], t[1], \
                                                                 "temporal vector algebra", dbif=dbif,
-                                                                overwrite = grass.overwrite())
+                                                                overwrite = self.overwrite)
                     for map_i in register_list:
                         # Check if modules should be executed from command list.
                         if "cmd_list" in dir(map_i):
                             # Get meta data from grass database.
                             map_i.load()
-                            if map_i.is_in_db(dbif=dbif) and grass.overwrite():
+                            if map_i.is_in_db(dbif=dbif) and self.overwrite:
                                 # Update map in temporal database.
                                 map_i.update_all(dbif=dbif)
-                            elif map_i.is_in_db(dbif=dbif) and grass.overwrite() == False:
+                            elif map_i.is_in_db(dbif=dbif) and self.overwrite == False:
                                 # Raise error if map exists and no overwrite flag is given.
                                 self.msgr.fatal(_("Error vector map %s exist in temporal database. "
                                                   "Use overwrite flag.  : \n%s") \
@@ -789,14 +738,6 @@
                 self.remove_intermediate_vector_maps()
             t[0] = register_list
 
-        if self.debug:
-            if isinstance(t[3], list):
-                for map_i in t[3]:
-                    print(map_i.get_id())
-            else:
-                print(t[1] + " = " + str(t[3]))
-            t[0] = t[3]
-
     def p_overlay_operation(self, t):
         """
         expr : stds AND stds
@@ -826,7 +767,7 @@
 
         if self.run:
             t[0] = self.create_overlay_operations(maplistA, maplistB, ("EQUAL",), "=", t[2])
-        if self.debug:
+        else:
             t[0] = t[1]
 
     def p_overlay_operation_relation(self, t):
@@ -843,7 +784,7 @@
 
         if self.run:
             t[0] = self.create_overlay_operations(maplistA, maplistB, relations, temporal, function)
-        if self.debug:
+        else:
             t[0] = t[1]
 
     def create_overlay_operations(self, maplistA, maplistB, relations, temporal, function):
@@ -875,15 +816,8 @@
             resultlist = []
             for map_i in topolist:
                 # Generate an intermediate name for the result map list.
-                name = self.generate_map_name()
-                # Get mapset input.
-                mapset = get_current_mapset()
-                # Check for mapset in given stds input.
-                mapname = name + "@" + mapset
-                # Create new map based on the related map list.
-                map_new = map_i.get_new_instance(mapname)
-                # Set initial map extend of new vector map.
-                self.overlay_map_extent(map_new, map_i, bool_op = opname, copy = True)
+                map_new = self.generate_new_map(base_map=map_i, bool_op=opname,
+                                                copy=True)
                 # Set first input for overlay module.
                 mapainput = map_i.get_id()
                 # Loop over temporal related maps and create overlay modules.
@@ -915,14 +849,14 @@
                                 m.inputs["ainput"].value = str(mapainput)
                                 m.inputs["binput"].value = str(mapbinput)
                                 m.outputs["output"].value = name
-                                m.flags["overwrite"].value = grass.overwrite()
+                                m.flags["overwrite"].value = self.overwrite
                             else:
                                 patchinput = str(mapainput) + ',' + str(mapbinput)
                                 m = copy.deepcopy(self.m_patch)
                                 m.run_ = False
                                 m.inputs["input"].value = patchinput
                                 m.outputs["output"].value = name
-                                m.flags["overwrite"].value = grass.overwrite()
+                                m.flags["overwrite"].value = self.overwrite
                             # Conditional append of module command.
                             if "cmd_list" in dir(map_new):
                                 map_new.cmd_list.append(m)
@@ -952,16 +886,9 @@
             resultlist = []
 
             for map_i in bufflist:
-                # Generate an intermediate name
-                name = self.generate_map_name()
-                # Get mapset input.
-                mapset = get_current_mapset()
-                # Check for mapset in given stds input.
-                mapname = name + "@" + mapset
-                # Create new map based on the related map list.
-                map_new = map_i.get_new_instance(mapname)
-                # Set initial map extend of new vector map.
-                self.overlay_map_extent(map_new, map_i, copy = True)
+                # Generate an intermediate name for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op=None,
+                                                copy=True)
                 # Change spatial extent based on buffer size.
                 map_new.spatial_buffer(float(t[5]))
                 # Check buff type.
@@ -976,8 +903,8 @@
                 m.inputs["type"].value = buff_type
                 m.inputs["input"].value = str(map_i.get_id())
                 m.inputs["distance"].value = float(t[5])
-                m.outputs["output"].value = name
-                m.flags["overwrite"].value = grass.overwrite()
+                m.outputs["output"].value = map_new.get_name()
+                m.flags["overwrite"].value = self.overwrite
 
                 # Conditional append of module command.
                 if "cmd_list" in dir(map_new):
@@ -988,9 +915,6 @@
 
             t[0] = resultlist
 
-        if self.debug:
-            pass
-
     def p_buff_function(self, t):
         """buff_function    : BUFF_POINT
                             | BUFF_LINE
@@ -1008,5 +932,3 @@
 if __name__ == "__main__":
     import doctest
     doctest.testmod()
-
-

Added: grass/trunk/lib/python/temporal/unittests_temporal_raster3d_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/unittests_temporal_raster3d_algebra.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/unittests_temporal_raster3d_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -0,0 +1,84 @@
+"""!Unit test to register raster maps with absolute and relative
+   time using tgis.register_maps_in_space_time_dataset()
+
+(C) 2013 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+
+import grass.script
+import grass.temporal as tgis
+import unittest
+import datetime
+import os
+
+class TestRegisterFunctions(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        """!Initiate the temporal GIS and set the region
+        """
+        tgis.init(True) # Raise on error instead of exit(1)
+        grass.script.use_temp_region()
+        ret = grass.script.run_command("g.region", n=80.0, s=0.0, e=120.0,
+                                       w=0.0, t=100.0, b=0.0, res=10.0)
+
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a1 = 1")
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a2 = 2")
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a3 = 3")
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a4 = 4")
+
+
+        tgis.open_new_space_time_dataset(name="A", type="str3ds", temporaltype="absolute",
+                                         title="A", descr="A", semantic="field", overwrite=True)
+
+        tgis.register_maps_in_space_time_dataset(type="rast3d", name="A", maps="a1,a2,a3,a4",
+                                                 start="2001-01-01", increment="1 day", interval=True)
+
+    def test_temporal_neighbors_1(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRaster3DAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[-1] + A[1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="str3ds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_neighbors_2(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRaster3DAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[0,0,0,-1] + A[0,0,0,1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="str3ds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def tearDown(self):
+        ret = grass.script.run_command("t.remove", type="str3ds", flags="rf", input="D", quiet=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        """!Remove the temporary region
+        """
+        ret = grass.script.run_command("t.remove", type="str3ds", flags="rf", input="A", quiet=True)
+        grass.script.del_temp_region()
+
+if __name__ == '__main__':
+    unittest.main()
+
+

Added: grass/trunk/lib/python/temporal/unittests_temporal_raster_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/unittests_temporal_raster_algebra.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/unittests_temporal_raster_algebra.py	2014-02-09 20:48:12 UTC (rev 58971)
@@ -0,0 +1,282 @@
+"""!Unit test to register raster maps with absolute and relative
+   time using tgis.register_maps_in_space_time_dataset()
+
+(C) 2013 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+
+import grass.script
+import grass.temporal as tgis
+import unittest
+import datetime
+import os
+
+class TestRegisterFunctions(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        """!Initiate the temporal GIS and set the region
+        """
+        tgis.init(True) # Raise on error instead of exit(1)
+        grass.script.use_temp_region()
+        ret = grass.script.run_command("g.region", n=80.0, s=0.0, e=120.0,
+                                       w=0.0, t=1.0, b=0.0, res=10.0)
+
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a1 = 1")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a2 = 2")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a3 = 3")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a4 = 4")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="b1 = 5")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="b2 = 6")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="c1 = 7")
+
+
+        tgis.open_new_space_time_dataset(name="A", type="strds", temporaltype="absolute",
+                                         title="A", descr="A", semantic="field", overwrite=True)
+        tgis.open_new_space_time_dataset(name="B", type="strds", temporaltype="absolute",
+                                         title="B", descr="B", semantic="field", overwrite=True)
+        tgis.open_new_space_time_dataset(name="C", type="strds", temporaltype="absolute",
+                                         title="B", descr="C", semantic="field", overwrite=True)
+
+        tgis.register_maps_in_space_time_dataset(type="rast", name="A", maps="a1,a2,a3,a4",
+                                                 start="2001-01-01", increment="1 day", interval=True)
+        tgis.register_maps_in_space_time_dataset(type="rast", name="B", maps="b1,b2",
+                                                 start="2001-01-01", increment="2 day", interval=True)
+
+        tgis.register_maps_in_space_time_dataset(type="rast", name="C", maps="c1",
+                                                 start="2001-01-02", increment="2 day", interval=True)
+
+    def test_simple_arith_if_1(self):
+        """Simple arithmetic test with if condition"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = if({equal}, start_date() >= "2001-01-02", A + A)', basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 3)
+        self.assertEqual(D.metadata.get_min_min(), 4)
+        self.assertEqual(D.metadata.get_max_max(), 8)
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_simple_arith_if_2(self):
+        """Simple arithmetic test with if condition"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = if({equal}, A#A == 1, A - A)', basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 0)
+        self.assertEqual(D.metadata.get_max_max(), 0)
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_complex_arith_if_1(self):
+        """Complex arithmetic test with if condition"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = if(start_date() < "2001-01-03" && A#A == 1, A{starts,=+}C, A{finishes,=+}C)', \
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 9)  # 2 + 7 a2 + c1
+        self.assertEqual(D.metadata.get_max_max(), 10) # 3 + 7 a3 + c1
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_simple_arith_1(self):
+        """Simple arithmetic test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {equal,*} A {equal,+} A", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 2)  # 1*1 + 1
+        self.assertEqual(D.metadata.get_max_max(), 20) # 4*4 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_simple_arith_2(self):
+        """Simple arithmetic test that creates an empty strds"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {during,*} A {during,+} A", basename="d", overwrite=True)
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 0)
+
+    def test_simple_arith_3(self):
+        """Simple arithmetic test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A / A + A*A/A", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 2) # 1/1 + 1*1/1
+        self.assertEqual(D.metadata.get_max_max(), 5) # 4/4 + 4*4/4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_1(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {equal,&+} B", basename="d", overwrite=True)
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 0)
+
+    def test_temporal_intersection_2(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {during,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 6) # 1 + 5
+        self.assertEqual(D.metadata.get_max_max(), 10) # 4 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_3(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {starts,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 6) # 1 + 5
+        self.assertEqual(D.metadata.get_max_max(), 9) # 3 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_intersection_4(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {finishes,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 7)  # 2 + 5
+        self.assertEqual(D.metadata.get_max_max(), 10) # 4 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_5(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {starts|finishes,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 6)  # 1 + 5
+        self.assertEqual(D.metadata.get_max_max(), 10) # 4 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_6(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = B {overlaps,|+} C", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 1)
+        self.assertEqual(D.metadata.get_min_min(), 12) # 5 + 7
+        self.assertEqual(D.metadata.get_max_max(), 12) # 5 + 7
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_intersection_7(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = B {overlapped,|+} C", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 1)
+        self.assertEqual(D.metadata.get_min_min(), 13) # 6 + 7
+        self.assertEqual(D.metadata.get_max_max(), 13) # 6 + 7
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_8(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A {during,=+} buff_t(C, "1 day") ',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 8)  # 1 + 7  a1 + c1
+        self.assertEqual(D.metadata.get_max_max(), 11) # 4 + 7  a4 + c1
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_neighbors_1(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[-1] + A[1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_neighbors_2(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[0,0,-1] + A[0,0,1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def tearDown(self):
+        ret = grass.script.run_command("t.remove", flags="rf", input="D", quiet=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        """!Remove the temporary region
+        """
+        ret = grass.script.run_command("t.remove", flags="rf", input="A,B,C", quiet=True)
+        grass.script.del_temp_region()
+
+if __name__ == '__main__':
+    unittest.main()
+
+



More information about the grass-commit mailing list