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

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Oct 18 09:09:32 EDT 2011


Author: huhabla
Date: 2011-10-18 06:09:31 -0700 (Tue, 18 Oct 2011)
New Revision: 48845

Added:
   grass/trunk/lib/python/temporal/temporal_granularity.py
   grass/trunk/lib/python/temporal/unit_tests.py
Modified:
   grass/trunk/lib/python/temporal/Makefile
   grass/trunk/lib/python/temporal/__init__.py
   grass/trunk/lib/python/temporal/abstract_dataset.py
   grass/trunk/lib/python/temporal/abstract_map_dataset.py
   grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
   grass/trunk/lib/python/temporal/base.py
   grass/trunk/lib/python/temporal/core.py
   grass/trunk/lib/python/temporal/datetime_math.py
Log:
New functions to compute the temporal granularity from registered maps
for absolute and relative time.


Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/Makefile	2011-10-18 13:09:31 UTC (rev 48845)
@@ -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 space_time_datasets_tools metadata spatial_extent temporal_extent datetime_math
+MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets space_time_datasets_tools metadata spatial_extent temporal_extent datetime_math temporal_granularity unit_tests
 
 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	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/__init__.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -9,3 +9,5 @@
 from space_time_datasets import *
 from space_time_datasets_tools import *
 from datetime_math import *
+from temporal_granularity import *
+from unit_tests import *

Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -49,6 +49,23 @@
     def get_id(self):
         return self.base.get_id()
 
+    def get_valid_time(self):
+        """Returns a tuple of the start, the end valid time, this can be either datetime or double values
+           @return A tuple of (start_time, end_time)
+        """
+
+        start = None
+        end = None
+               
+	if self.is_time_absolute():
+            start = self.absolute_time.get_start_time()
+            end = self.absolute_time.get_end_time()
+        if self.is_time_relative():
+            start = self.relative_time.get_start_time()
+            end = self.relative_time.get_end_time()
+        
+        return (start, end)
+ 
     def get_absolute_time(self):
         """Returns a tuple of the start, the end valid time and the timezone of the map
            @return A tuple of (start_time, end_time, timezone)

Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -221,6 +221,8 @@
 	""" Remove the map entry in each space time dataset in which this map is registered
 
            @param dbif: The database interface to be used
+           @param update: Call for each unregister statement the update_from_registered_maps 
+                          of the space time dataset. This can slow down the unregistration process significantly.
         """
 
         core.verbose(_("Unregister %s dataset <%s> from space time datasets") % (self.get_type(), self.get_id()))
@@ -237,7 +239,11 @@
 
         # For each stds in which the map is registered
         if rows:
+            count = 0
+            num_sps = len(rows)
             for row in rows:
+                core.percent(count, num_sps, 1)
+                count += 1
                 # Create a space time dataset object to remove the map
                 # from its register
                 stds = self.get_new_stds_instance(row["id"])
@@ -248,6 +254,7 @@
                 if update == True:
                     stds.update_from_registered_maps(dbif)
 
+            core.percent(1, 1, 1)
         dbif.connection.commit()
 
         if connect == True:

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -20,6 +20,7 @@
 @author Soeren Gebbert
 """
 from abstract_dataset import *
+from temporal_granularity import *
 
 ###############################################################################
 
@@ -65,13 +66,10 @@
         """
         raise IOError("This method must be implemented in the subclasses")
 
-    def set_initial_values(self, granularity, temporal_type, semantic_type, \
+    def set_initial_values(self, temporal_type, semantic_type, \
                            title=None, description=None):
         """Set the initial values of the space time dataset
 
-           @param granularity: The temporal granularity of this dataset. This value
-                               should be computed by the space time dataset itself,
-                               based on the granularity of the registered maps
            @param temporal_type: The temporal type of this space time dataset (absolute or relative)
            @param semantic_type: The semantic type of this dataset
            @param title: The title
@@ -80,10 +78,8 @@
 
         if temporal_type == "absolute":
             self.set_time_to_absolute()
-            self.absolute_time.set_granularity(granularity)
         elif temporal_type == "relative":
             self.set_time_to_relative()
-            self.relative_time.set_granularity(granularity)
         else:
             core.fatal(_("Unknown temporal type \"%s\"") % (temporal_type))
 
@@ -92,21 +88,40 @@
         self.metadata.set_description(description)
 
     def get_initial_values(self):
-        """Return the initial values: granularity, temporal_type, semantic_type, title, description"""
+        """Return the initial values: temporal_type, semantic_type, title, description"""
         
         temporal_type = self.get_temporal_type()
+        semantic_type = self.base.get_semantic_type()
+        title = self.metadata.get_title()
+        description = self.metadata.get_description()
 
+        return temporal_type, semantic_type, title, description
+
+    def get_granularity(self):
+        """Return the granularity"""
+        
+        temporal_type = self.get_temporal_type()
+
         if temporal_type == "absolute":
             granularity   = self.absolute_time.get_granularity()
         elif temporal_type == "relative":
             granularity = self.relative_time.get_granularity()
 
-        semantic_type = self.base.get_semantic_type()
-        title = self.metadata.get_title()
-        description = self.metadata.get_description()
+        return granularity
 
-        return granularity, temporal_type, semantic_type, title, description
+    def set_granularity(self, granularity):
 
+        temporal_type = self.get_temporal_type()
+ 
+        if temporal_type == "absolute":
+            self.set_time_to_absolute()
+            self.absolute_time.set_granularity(granularity)
+        elif temporal_type == "relative":
+            self.set_time_to_relative()
+            self.relative_time.set_granularity(granularity)
+        else:
+            core.fatal(_("Unknown temporal type \"%s\"") % (temporal_type))
+
     def get_map_time(self):
         """Return the type of the map time, interval, point, maixed or invalid"""
         
@@ -443,10 +458,15 @@
             rows = self.get_registered_maps("id", None, None, dbif)
             # Unregister each registered map in the table
             if rows:
+                num_maps = len(rows)
+                count = 0
                 for row in rows:
+	            core.percent(count, num_maps, 1)
                     # Unregister map
                     map = self.get_new_map_instance(row["id"])
                     self.unregister_map(map, dbif)
+                    count += 1
+	        core.percent(1, 1, 1)
             try:
                 # Drop the map register table
                 sql = "DROP TABLE " + self.get_map_register()
@@ -836,7 +856,8 @@
 		dbif.cursor.execute(sql)
 
         # Count the temporal map types
-        tlist = self.count_temporal_types(self.get_registered_maps_as_objects(dbif=dbif))
+        maps = self.get_registered_maps_as_objects(dbif=dbif)
+        tlist = self.count_temporal_types(maps)
 
         if tlist["interval"] > 0 and tlist["point"] == 0 and tlist["invalid"] == 0:
             map_time = "interval"
@@ -847,25 +868,38 @@
         else:
             map_time = "invalid"
 
-        # Set the map time type
+        # Compute the granularity
+
+        if map_time != "invalid":
+            # Smallest supported temporal resolution
+            if self.is_time_absolute():
+                gran = compute_absolute_time_granularity(maps)
+            elif self.is_time_relative():
+                gran = compute_absolute_time_granularity(maps)
+        else:
+            gran = None
+
+        # Set the map time type and update the time objects
         if self.is_time_absolute():
             self.absolute_time.select(dbif)
             self.metadata.select(dbif)
             if self.metadata.get_number_of_maps() > 0:
                 self.absolute_time.set_map_time(map_time)
+                self.absolute_time.set_granularity(gran)
             else:
                 self.absolute_time.set_map_time(None)
+                self.absolute_time.set_granularity(None)
             self.absolute_time.update_all(dbif)
         else:
             self.relative_time.select(dbif)
             self.metadata.select(dbif)
             if self.metadata.get_number_of_maps() > 0:
                 self.relative_time.set_map_time(map_time)
+                self.relative_time.set_granularity(gran)
             else:
                 self.relative_time.set_map_time(None)
+                self.relative_time.set_granularity(None)
             self.relative_time.update_all(dbif)
 
-        # TODO: Compute the granularity of the dataset and update the database entry
-
         if connect == True:
             dbif.close()

Modified: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/base.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -219,6 +219,8 @@
 	    self.connection.row_factory = dbmi.Row
             self.connection.isolation_level = None
 	    self.cursor = self.connection.cursor()
+            self.cursor.execute("PRAGMA synchronous = OFF")
+            self.cursor.execute("PRAGMA journal_mode = MEMORY")
         elif dbmi.__name__ == "psycopg2":
 	    self.connection = dbmi.connect(self.database)
 	    self.connection.set_isolation_level(dbmi.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/core.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -27,11 +27,13 @@
 
 ###############################################################################
 
-def get_temporal_dbmi_default_path(grassenv):
+def get_temporal_sqlite3_default_path(grassenv):
     dbpath = os.path.join(grassenv["GISDBASE"], grassenv["LOCATION_NAME"])
     dbpath = os.path.join(dbpath, "PERMANENT")
-    return os.path.join(dbpath, "grass.db")
+    return dbpath
 
+def get_temporal_sqlite3_default_dbname(grassenv):
+    return "tgis.db"
 
 # The chosen DBMI backend can be defined on runtime
 # Check the grass environment before import
@@ -48,8 +50,9 @@
 else:
     # Use the default sqlite variable
     import sqlite3 as dbmi
-    core.run_command("g.gisenv", set="TDBMI=sqlite3")
-    core.run_command("g.gisenv", set="TDBMI_INIT=%s" % get_temporal_dbmi_default_path(grassenv))
+    # We do not set the path due to issues with the grass build system
+    #core.run_command("g.gisenv", set="TDBMI=sqlite3")
+    #core.run_command("g.gisenv", set="TDBMI_INIT=%s" % get_temporal_sqlite3_default_dbname(grassenv))
 
 ###############################################################################
 
@@ -57,9 +60,16 @@
     grassenv = core.gisenv()
     if dbmi.__name__ == "sqlite3":
         if grassenv.has_key("TDBMI_INIT"):
+
+            string =  grassenv["TDBMI_INIT"]
+
+            # In case no path is present in the sqlite3 database string, we attach the default path
+            if string.find("/") < 0 or string.find("\\") < 0:
+                return os.path.join(get_temporal_sqlite3_default_path(grassenv), string)
+            
             return grassenv["TDBMI_INIT"]
         else:
-            return get_temporal_dbmi_default_path(grassenv)
+            return os.path.join(get_temporal_sqlite3_default_path(grassenv), get_temporal_sqlite3_default_dbname(grassenv))
     elif dbmi.__name__ == "psycopg2":
         if grassenv.has_key("TDBMI_INIT"):
             return grassenv["TDBMI_INIT"]

Modified: grass/trunk/lib/python/temporal/datetime_math.py
===================================================================
--- grass/trunk/lib/python/temporal/datetime_math.py	2011-10-17 19:59:40 UTC (rev 48844)
+++ grass/trunk/lib/python/temporal/datetime_math.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -24,15 +24,28 @@
 import grass.script.core as core
 import copy
 
+
 ###############################################################################
 
-def datetime_delta_to_double(dt1, dt2):
-    """Compute the the dfference dt2 - dt1 and convert the time delta into a 
-       double value, representing days.
+def relative_time_to_time_delta(value):
+    """Convert the double value representing days
+       into a timedelta object.
     """
 
-    delta = dt2 - dt1
 
+    days = int(value)
+    seconds = value % 1
+    seconds = round(seconds * 86400)
+
+    return timedelta(days, seconds)
+
+###############################################################################
+
+def time_delta_to_relative_time(delta):
+    """Convert the time delta into a 
+       double value, representing days.
+    """
+
     return float(delta.days) + float(delta.seconds/86400.0)
 
 ###############################################################################
@@ -90,74 +103,6 @@
 
 ###############################################################################
 
-def test_increment_datetime_by_string():
-
-    # First test
-    print "# Test 1"
-    dt = datetime(2001, 9, 1, 0, 0, 0)
-    string = "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
-
-    dt1 = datetime(2003,2,18,12,5,0)
-    dt2 = increment_datetime_by_string(dt, string)
-
-    print dt
-    print dt2
-
-    delta = dt1 -dt2
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("increment computation is wrong %s" % (delta))
-
-    # Second test
-    print "# Test 2"
-    dt = datetime(2001, 11, 1, 0, 0, 0)
-    string = "1 months"
-
-    dt1 = datetime(2001,12,1)
-    dt2 = increment_datetime_by_string(dt, string)
-
-    print dt
-    print dt2
-
-    delta = dt1 -dt2
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("increment computation is wrong %s" % (delta))
-
-    # Third test
-    print "# Test 3"
-    dt = datetime(2001, 11, 1, 0, 0, 0)
-    string = "13 months"
-
-    dt1 = datetime(2002,12,1)
-    dt2 = increment_datetime_by_string(dt, string)
-
-    print dt
-    print dt2
-
-    delta = dt1 -dt2
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("increment computation is wrong %s" % (delta))
-
-    # 4. test
-    print "# Test 4"
-    dt = datetime(2001, 1, 1, 0, 0, 0)
-    string = "72 months"
-
-    dt1 = datetime(2007,1,1)
-    dt2 = increment_datetime_by_string(dt, string)
-
-    print dt
-    print dt2
-
-    delta = dt1 -dt2
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("increment computation is wrong %s" % (delta))
-
-###############################################################################
-
 def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0):
     """Return a new datetime object incremented with the provided relative dates and times"""
 
@@ -199,7 +144,6 @@
     return mydate + tdelta_seconds + tdelta_minutes + tdelta_hours + \
                     tdelta_days + tdelta_weeks + tdelta_months + tdelta_years
 
-
 ###############################################################################
 
 def adjust_datetime_to_granularity(mydate, granularity):
@@ -282,126 +226,91 @@
 
         return result
 
+###############################################################################
 
-def test_adjust_datetime_to_granularity():
+def compute_datetime_delta(start, end):
+    """Return a dictionary with the accumulated delta in year, month, day, hour, minute and second
+    
+       @return A dictionary with year, month, day, hour, minute and second as keys()
+    """
+    comp = {}
 
-    # First test
-    print "Test 1"
-    dt = datetime(2001, 8, 8, 12,30,30)
-    result = adjust_datetime_to_granularity(dt, "5 seconds")
-    correct =  datetime(2001, 8, 8, 12,30,30)
+    day_diff = (end - start).days
 
-    delta = correct - result 
+    comp["max_days"] = day_diff
 
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
+    # Date
+    # Count full years
+    d = end.year - start.year
+    comp["year"] = d
 
-    # Second test
-    print "Test 2"
-    result = adjust_datetime_to_granularity(dt, "20 minutes")
-    correct =  datetime(2001, 8, 8, 12,30,00)
+    # Count full months
+    if start.month == 1 and end.month == 1:
+        comp["month"] = 0
+    elif   start.day == 1 and end.day == 1:
+        d = end.month - start.month
+        if d < 0:
+            d = d + 12 * comp["year"]
+        elif d == 0:
+            d = 12 * comp["year"]
+        comp["month"] = d
 
-    delta = correct - result 
+    # Count full days
+    if  start.day == 1 and end.day == 1:
+        comp["day"] = 0
+    else:
+        comp["day"] = day_diff
 
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
+    # Time
+    # Hours
+    if start.hour == 0 and end.hour == 0:
+        comp["hour"] = 0
+    else:
+        d = end.hour - start.hour
+        if d < 0:
+            d = d + 24  + 24 * day_diff
+        else:
+            d = d + 24 * day_diff
+        comp["hour"] = d
+    
+    # Minutes
+    if start.minute == 0 and end.minute == 0:
+        comp["minute"] = 0
+    else:
+        d = end.minute - start.minute
+        if d != 0:
+            if comp["hour"]:
+                d = d + 60 * comp["hour"]
+            else:
+                d = d + 24 * 60 * day_diff
+        elif d == 0:
+            if comp["hour"]:
+                d = 60* comp["hour"]
+            else:
+                d = 24 * 60 * day_diff
 
-    # Third test
-    print "Test 2"
-    result = adjust_datetime_to_granularity(dt, "20 minutes")
-    correct =  datetime(2001, 8, 8, 12,30,00)
+        comp["minute"] = d
 
-    delta = correct - result 
+    # Seconds
+    if start.second == 0 and end.second == 0:
+        comp["second"] = 0
+    else:
+        d = end.second - start.second
+        if d != 0:
+            if comp["minute"]:
+                d = d + 60* comp["minute"]
+            elif comp["hour"]:
+                d = d + 3600* comp["hour"]
+            else:
+                d = d + 24 * 60 * 60 * day_diff
+        elif d == 0:
+            if comp["minute"]:
+                d = 60* comp["minute"]
+            elif comp["hour"]:
+                d = 3600 * comp["hour"]
+            else:
+                d = 24 * 60 * 60 * day_diff
+        comp["second"] = d
 
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
+    return comp
 
-    # 4. test
-    print "Test 4"
-    result = adjust_datetime_to_granularity(dt, "3 hours")
-    correct =  datetime(2001, 8, 8, 12,00,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 5. test
-    print "Test 5"
-    result = adjust_datetime_to_granularity(dt, "5 days")
-    correct =  datetime(2001, 8, 8, 00,00,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 6. test
-    print "Test 6"
-    result = adjust_datetime_to_granularity(dt, "2 weeks")
-    correct =  datetime(2001, 8, 6, 00,00,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 7. test
-    print "Test 7"
-    result = adjust_datetime_to_granularity(dt, "6 months")
-    correct =  datetime(2001, 8, 1, 00,00,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 8. test
-    print "Test 8"
-    result = adjust_datetime_to_granularity(dt, "2 years")
-    correct =  datetime(2001, 1, 1, 00,00,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 9. test
-    print "Test 9"
-    result = adjust_datetime_to_granularity(dt, "2 years, 3 months, 5 days, 3 hours, 3 minutes, 2 seconds")
-    correct =  datetime(2001, 8, 8, 12,30,30)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 10. test
-    print "Test 10"
-    result = adjust_datetime_to_granularity(dt, "3 months, 5 days, 3 minutes")
-    correct =  datetime(2001, 8, 8, 12,30,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-    # 11. test
-    print "Test 11"
-    result = adjust_datetime_to_granularity(dt, "3 weeks, 5 days")
-    correct =  datetime(2001, 8, 8, 00,00,00)
-
-    delta = correct - result 
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.error("Granularity adjustment computation is wrong %s" % (delta))
-
-
-
-
-
-
-
-
-
-

Added: grass/trunk/lib/python/temporal/temporal_granularity.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_granularity.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_granularity.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -0,0 +1,229 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.compute_relative_time_granularity(maps)
+...
+ at endcode
+
+(C) 2008-2011 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
+"""
+from abstract_dataset import *
+from datetime_math import *
+
+###############################################################################
+
+def compute_relative_time_granularity(maps):            
+    granularity = None
+
+    delta = []
+    # First we compute the timedelta of the intervals
+    for map in maps:
+        start, end = map.get_valid_time()
+        if start and end:
+            t =  relative_time_to_time_delta(abs(end - start))
+            full_seconds = t.days * 86400 + t.seconds
+            delta.append(full_seconds)
+
+    # Compute the timedelta of the gaps
+    for i in range(len(maps)):
+        if i < len(maps) - 1:
+            relation = maps[i + 1].temporal_relation(maps[i])
+            if relation == "after":
+                start1, end1 = maps[i].get_valid_time()
+                start2, end2 = maps[i + 1].get_valid_time()
+                # Gaps are between intervals, intervals and points, points and points
+                if end1 and start2:
+                    t =  relative_time_to_time_delta(abs(end1 - start2))
+                    full_seconds = t.days * 86400 + t.seconds
+                    delta.append(full_seconds)
+                if  not end1 and start2:
+                    t =  relative_time_to_time_delta(abs(start1 - start2))
+                    full_seconds = t.days * 86400 + t.seconds
+                    delta.append(full_seconds)
+
+    delta.sort()
+    ulist = list(set(delta))
+    if len(ulist) > 1:
+        # Find greatest common divisor
+        granularity = gcd_list(ulist)
+    else:
+        granularity = ulist[0]
+
+    return float(granularity / 86400.0)
+
+###############################################################################
+
+def compute_absolute_time_granularity(maps):            
+
+    has_seconds = False
+    has_minutes = False
+    has_hours = False
+    has_days = False
+    has_months = False
+    has_years = False
+
+    use_seconds = False
+    use_minutes = False
+    use_hours = False
+    use_days = False
+    use_months = False
+    use_years = False
+
+    delta = []
+    datetime_delta = []
+    # First we compute the timedelta of the intervals
+    for map in maps:
+        start, end = map.get_valid_time()
+        if start and end:
+            delta.append(end - start)
+            datetime_delta.append(compute_datetime_delta(start, end))
+
+    # Compute the timedelta of the gaps
+    for i in range(len(maps)):
+        if i < len(maps) - 1:
+            relation = maps[i + 1].temporal_relation(maps[i])
+            if relation == "after":
+                start1, end1 = maps[i].get_valid_time()
+                start2, end2 = maps[i + 1].get_valid_time()
+                # Gaps are between intervals, intervals and points, points and points
+                if end1 and start2:
+                    delta.append(end1 - start2)
+                    datetime_delta.append(compute_datetime_delta(end1, start2))
+                if  not end1 and start2:
+                    delta.append(start2 - start1)
+                    datetime_delta.append(compute_datetime_delta(start1, start2))
+
+    # Check what changed
+    dlist = []
+    for d in datetime_delta:
+        if d.has_key("second") and d["second"] > 0:
+            has_seconds = True
+        if d.has_key("minute") and d["minute"] > 0:
+            has_minutes = True
+        if d.has_key("hour") and d["hour"] > 0:
+            has_hours = True
+        if d.has_key("day") and d["day"] > 0:
+            has_days = True
+        if d.has_key("month") and d["month"] > 0:
+            has_months = True
+        if d.has_key("year") and d["year"] > 0:
+            has_years = True
+
+    # Create a list with a single time unit only
+    if has_seconds:
+        for d in datetime_delta:
+            if d.has_key("second"):
+                dlist.append(d["second"])   
+            elif d.has_key("minute"):
+                dlist.append(d["minute"] * 60)   
+            elif d.has_key("hour"):
+                dlist.append(d["hour"] * 3600)   
+            elif d.has_key("day"):
+                dlist.append(d["day"] * 24 * 3600)   
+            else:
+                dlist.append(d["max_days"] * 24 * 3600)   
+        use_seconds = True        
+    elif has_minutes:
+        for d in datetime_delta:
+            if d.has_key("minute"):
+                dlist.append(d["minute"])   
+            elif d.has_key("hour"):
+                dlist.append(d["hour"] * 60)   
+            elif d.has_key("day"):
+                dlist.append(d["day"] * 24 * 60)   
+            else:
+                dlist.append(d["max_days"] * 24 * 60)   
+        use_minutes = True        
+    elif has_hours:
+        for d in datetime_delta:
+            if d.has_key("hour"):
+                dlist.append(d["hour"])   
+            elif d.has_key("day"):
+                dlist.append(d["day"] * 24)   
+            else:
+                dlist.append(d["max_days"] * 24)   
+        use_hours = True        
+    elif has_days:
+        for d in datetime_delta:
+            if d.has_key("day"):
+                dlist.append(d["day"])   
+            else:
+                dlist.append(d["max_days"])   
+        use_days = True        
+    elif has_months:
+        for d in datetime_delta:
+            if d.has_key("month"):
+                dlist.append(d["month"])   
+            elif d.has_key("year"):
+                dlist.append(d["year"] * 12)   
+        use_months = True        
+    elif has_years:
+        for d in datetime_delta:
+            if d.has_key("year"):
+                dlist.append(d["year"])   
+        use_years = True        
+
+    dlist.sort()
+    ulist = list(set(dlist))
+
+    if len(ulist) == 0:
+        return None
+
+    if len(ulist) > 1:
+        # Find greatest common divisor
+        granularity = gcd_list(ulist)
+    else:
+        granularity = ulist[0]
+
+    if use_seconds:
+        return "%i seconds" % granularity
+    elif use_minutes:
+        return "%i minutes" % granularity
+    elif use_hours:
+        return "%i hours" % granularity
+    elif use_days:
+        return "%i days" % granularity
+    elif use_months:
+        return "%i months" % granularity
+    elif use_years:
+        return "%i years" % granularity
+
+    return None
+
+###############################################################################
+# http://akiscode.com/articles/gcd_of_a_list.shtml
+# Copyright (c) 2010 Stephen Akiki
+# MIT License (Means you can do whatever you want with this)
+#  See http://www.opensource.org/licenses/mit-license.php
+# Error Codes:
+#   None
+def gcd(a,b):
+	""" The Euclidean Algorithm """
+	a = abs(a)
+	b = abs(b)
+        while a:
+                a, b = b%a, a
+        return b
+        
+###############################################################################
+
+def gcd_list(list):
+	""" Finds the GCD of numbers in a list.
+	Input: List of numbers you want to find the GCD of
+		E.g. [8, 24, 12]
+	Returns: GCD of all numbers
+	"""
+	return reduce(gcd, list)

Added: grass/trunk/lib/python/temporal/unit_tests.py
===================================================================
--- grass/trunk/lib/python/temporal/unit_tests.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/unit_tests.py	2011-10-18 13:09:31 UTC (rev 48845)
@@ -0,0 +1,974 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS unit tests
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.test_increment_datetime_by_string()
+...
+ at endcode
+
+(C) 2008-2011 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
+"""
+from datetime import datetime, date, time, timedelta
+import grass.script.core as core
+from temporal_granularity import *
+from datetime_math import *
+from space_time_datasets import *
+
+###############################################################################
+
+def test_increment_datetime_by_string():
+
+    # First test
+    print "# Test 1"
+    dt = datetime(2001, 9, 1, 0, 0, 0)
+    string = "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+
+    dt1 = datetime(2003,2,18,12,5,0)
+    dt2 = increment_datetime_by_string(dt, string)
+
+    print dt
+    print dt2
+
+    delta = dt1 -dt2
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("increment computation is wrong %s" % (delta))
+
+    # Second test
+    print "# Test 2"
+    dt = datetime(2001, 11, 1, 0, 0, 0)
+    string = "1 months"
+
+    dt1 = datetime(2001,12,1)
+    dt2 = increment_datetime_by_string(dt, string)
+
+    print dt
+    print dt2
+
+    delta = dt1 -dt2
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("increment computation is wrong %s" % (delta))
+
+    # Third test
+    print "# Test 3"
+    dt = datetime(2001, 11, 1, 0, 0, 0)
+    string = "13 months"
+
+    dt1 = datetime(2002,12,1)
+    dt2 = increment_datetime_by_string(dt, string)
+
+    print dt
+    print dt2
+
+    delta = dt1 -dt2
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("increment computation is wrong %s" % (delta))
+
+    # 4. test
+    print "# Test 4"
+    dt = datetime(2001, 1, 1, 0, 0, 0)
+    string = "72 months"
+
+    dt1 = datetime(2007,1,1)
+    dt2 = increment_datetime_by_string(dt, string)
+
+    print dt
+    print dt2
+
+    delta = dt1 -dt2
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("increment computation is wrong %s" % (delta))
+
+###############################################################################
+
+def test_adjust_datetime_to_granularity():
+
+    # First test
+    print "Test 1"
+    dt = datetime(2001, 8, 8, 12,30,30)
+    result = adjust_datetime_to_granularity(dt, "5 seconds")
+    correct =  datetime(2001, 8, 8, 12,30,30)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # Second test
+    print "Test 2"
+    result = adjust_datetime_to_granularity(dt, "20 minutes")
+    correct =  datetime(2001, 8, 8, 12,30,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # Third test
+    print "Test 2"
+    result = adjust_datetime_to_granularity(dt, "20 minutes")
+    correct =  datetime(2001, 8, 8, 12,30,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 4. test
+    print "Test 4"
+    result = adjust_datetime_to_granularity(dt, "3 hours")
+    correct =  datetime(2001, 8, 8, 12,00,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 5. test
+    print "Test 5"
+    result = adjust_datetime_to_granularity(dt, "5 days")
+    correct =  datetime(2001, 8, 8, 00,00,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 6. test
+    print "Test 6"
+    result = adjust_datetime_to_granularity(dt, "2 weeks")
+    correct =  datetime(2001, 8, 6, 00,00,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 7. test
+    print "Test 7"
+    result = adjust_datetime_to_granularity(dt, "6 months")
+    correct =  datetime(2001, 8, 1, 00,00,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 8. test
+    print "Test 8"
+    result = adjust_datetime_to_granularity(dt, "2 years")
+    correct =  datetime(2001, 1, 1, 00,00,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 9. test
+    print "Test 9"
+    result = adjust_datetime_to_granularity(dt, "2 years, 3 months, 5 days, 3 hours, 3 minutes, 2 seconds")
+    correct =  datetime(2001, 8, 8, 12,30,30)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 10. test
+    print "Test 10"
+    result = adjust_datetime_to_granularity(dt, "3 months, 5 days, 3 minutes")
+    correct =  datetime(2001, 8, 8, 12,30,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+    # 11. test
+    print "Test 11"
+    result = adjust_datetime_to_granularity(dt, "3 weeks, 5 days")
+    correct =  datetime(2001, 8, 8, 00,00,00)
+
+    delta = correct - result 
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.error("Granularity adjustment computation is wrong %s" % (delta))
+
+###############################################################################
+
+def test_compute_datetime_delta():
+
+    print "Test 1"
+    start = datetime(2001, 1, 1, 00,00,00)
+    end = datetime(2001, 1, 1, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["second"]
+    correct = 0
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 2"
+    start = datetime(2001, 1, 1, 00,00,14)
+    end = datetime(2001, 1, 1, 00,00,44)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["second"]
+    correct = 30
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 3"
+    start = datetime(2001, 1, 1, 00,00,44)
+    end = datetime(2001, 1, 1, 00,01,14)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["second"]
+    correct = 30
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 4"
+    start = datetime(2001, 1, 1, 00,00,30)
+    end = datetime(2001, 1, 1, 00,05,30)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["second"]
+    correct = 300
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 5"
+    start = datetime(2001, 1, 1, 00,00,00)
+    end = datetime(2001, 1, 1, 00,01,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["minute"]
+    correct = 1
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 6"
+    start = datetime(2011,10,31, 00,45,00)
+    end = datetime(2011,10,31, 01,45,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["minute"]
+    correct = 60
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 7"
+    start = datetime(2011,10,31, 00,45,00)
+    end = datetime(2011,10,31, 01,15,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["minute"]
+    correct = 30
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 8"
+    start = datetime(2011,10,31, 00,45,00)
+    end = datetime(2011,10,31, 12,15,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["minute"]
+    correct = 690
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 9"
+    start = datetime(2011,10,31, 00,00,00)
+    end = datetime(2011,10,31, 01,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["hour"]
+    correct = 1
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 10"
+    start = datetime(2011,10,31, 00,00,00)
+    end = datetime(2011,11,01, 01,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["hour"]
+    correct = 25
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 11"
+    start = datetime(2011,10,31, 12,00,00)
+    end = datetime(2011,11,01, 06,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["hour"]
+    correct = 18
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 12"
+    start = datetime(2011,11,01, 00,00,00)
+    end = datetime(2011,12,01, 01,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["hour"]
+    correct = 30 * 24 + 1
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+
+    print "Test 13"
+    start = datetime(2011,11,01, 00,00,00)
+    end = datetime(2011,11,05, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["day"]
+    correct = 4
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 14"
+    start = datetime(2011,10,06, 00,00,00)
+    end = datetime(2011,11,05, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["day"]
+    correct = 30
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 15"
+    start = datetime(2011,12,02, 00,00,00)
+    end = datetime(2012,01,01, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["day"]
+    correct = 30
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 16"
+    start = datetime(2011,01,01, 00,00,00)
+    end = datetime(2011,02,01, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["month"]
+    correct = 1
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 17"
+    start = datetime(2011,12,01, 00,00,00)
+    end = datetime(2012,01,01, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["month"]
+    correct = 1
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 18"
+    start = datetime(2011,12,01, 00,00,00)
+    end = datetime(2012,06,01, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["month"]
+    correct = 6
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 19"
+    start = datetime(2011,06,01, 00,00,00)
+    end = datetime(2021,06,01, 00,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["year"]
+    correct = 10
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 20"
+    start = datetime(2011,06,01, 00,00,00)
+    end = datetime(2012,06,01, 12,00,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["hour"]
+    d = end - start
+    correct = 12 + d.days * 24
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 21"
+    start = datetime(2011,06,01, 00,00,00)
+    end = datetime(2012,06,01, 12,30,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["minute"]
+    d = end - start
+    correct = d.days * 24 * 60 + 12 * 60 + 30
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 22"
+    start = datetime(2011,06,01, 00,00,00)
+    end = datetime(2012,06,01, 12,00,05)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["second"]
+    d = end - start
+    correct = 5 + 60 * 60 * 12 + d.days * 24 * 60 * 60
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 23"
+    start = datetime(2011,06,01, 00,00,00)
+    end = datetime(2012,06,01, 00,30,00)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["minute"]
+    d = end - start
+    correct = 30 + d.days * 24 * 60
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+    print "Test 24"
+    start = datetime(2011,06,01, 00,00,00)
+    end = datetime(2012,06,01, 00,00,05)
+
+    comp = compute_datetime_delta(start, end)
+
+    result = comp["second"]
+    d = end - start
+    correct = 5 + d.days * 24 * 60 * 60
+
+    delta = correct - result 
+
+    if delta != 0:
+        core.error("Compute datetime delta is wrong %s" % (delta))
+
+###############################################################################
+
+def test_compute_relative_time_granularity():            
+    
+
+    # First we test intervals
+
+    print "Test 1"
+    maps = []
+    fact = 5
+    start = 1
+    end = start * fact
+    for i in range(6):
+        end = start * fact
+        map = raster_dataset(None)
+        map.set_relative_time(start, end)
+        maps.append(map)
+        start = end
+
+    fact = fact - 1
+    gran = round(compute_relative_time_granularity(maps))
+    if fact - gran != 0:
+        core.error("Wrong granularity reference %i != gran %i" % (fact, gran))
+ 
+    print "Test 2"
+    maps = []
+    fact = 3
+    start = 1.0/86400
+    end = start * fact
+    for i in range(10):
+        end = start * fact
+        map = raster_dataset(None)
+        map.set_relative_time(start, end)
+        maps.append(map)
+        start = end
+
+    fact = fact - 1
+    gran = round(compute_relative_time_granularity(maps) * 86400)
+    if fact - gran != 0:
+        core.error("Wrong granularity reference %i != gran %i" % (fact, gran))
+
+    print "Test 3 with gaps"
+    maps = []
+    fact = 3
+    start = 1
+    end = start + fact
+    for i in range(10):
+        shift = i*2*fact
+        start = shift
+        end = start + fact
+
+        map = raster_dataset(None)
+        map.set_relative_time(start, end)
+        maps.append(map)
+
+    gran = round(compute_relative_time_granularity(maps))
+    if fact - gran != 0:
+        core.error("Wrong granularity reference %i != gran %i" % (fact, gran))
+
+    # Second we test intervals and points mixed
+
+    print "Test 4 intervals and points"
+    maps = []
+    fact = 5
+    start = 1
+    end = start * fact
+    count = 0
+    for i in range(6):
+        end = start * fact
+        map = raster_dataset(None)
+        if count % 2 == 0:
+            map.set_relative_time(start, end)
+        else:
+            map.set_relative_time(start, None)
+        maps.append(map)
+        start = end
+        count += 1
+
+    fact = fact - 1
+    gran = round(compute_relative_time_granularity(maps))
+    if fact - gran != 0:
+        core.error("Wrong granularity reference %i != gran %i" % (fact, gran))
+ 
+    # Second we test points only
+ 
+    print "Test 5 points only"
+    maps = []
+    fact = 3
+    start = 1.0/86400
+    for i in range(10):
+        point = (i + 1)*fact*start
+        map = raster_dataset(None)
+        map.set_relative_time(point, None)
+        maps.append(map)
+
+    gran = round(compute_relative_time_granularity(maps) * 86400)
+    if fact - gran != 0:
+        core.error("Wrong granularity reference %i != gran %i" % (fact, gran))
+
+###############################################################################
+
+def test_compute_absolute_time_granularity():
+ 
+
+    # First we test intervals
+
+    print "Test 1"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "1 years"
+    for i in range(10):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 2"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "3 years"
+    for i in range(10):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 3"
+    maps = []
+    a = datetime(2001, 5, 1)
+    increment = "1 months"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 4"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "3 months"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 3"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "1 days"
+    for i in range(6):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 4"
+    maps = []
+    a = datetime(2001, 1, 14)
+    increment = "14 days"
+    for i in range(6):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 5"
+    maps = []
+    a = datetime(2001, 3, 1)
+    increment = "1 months, 4 days"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    increment = "1 days"
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 6"
+    maps = []
+    a = datetime(2001, 2, 11)
+    increment = "1 days, 1 hours"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    increment = "25 hours"
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 7"
+    maps = []
+    a = datetime(2001, 6, 12)
+    increment = "6 hours"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 8"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "20 minutes"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 9"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "5 hours, 25 minutes"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    increment = "325 minutes"
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 10"
+    maps = []
+    a = datetime(2001, 1, 1)
+    increment = "5 minutes, 30 seconds"
+    for i in range(20):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    increment = "330 seconds"
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 11"
+    maps = []
+    a = datetime(2001,12,31)
+    increment = "60 minutes, 30 seconds"
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    increment = "3630 seconds"
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 12"
+    maps = []
+    a = datetime(2001,12,31, 12, 30, 30)
+    increment = "3600 seconds"
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    # Test absolute time points    
+
+    print "Test 13"
+    maps = []
+    a = datetime(2001,12,31, 12, 30, 30)
+    increment = "3600 seconds"
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = None
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 14"
+    maps = []
+    a = datetime(2001,12,31, 00, 00, 00)
+    increment = "20 days"
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = None
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 15"
+    maps = []
+    a = datetime(2001,12,01, 00, 00, 00)
+    increment = "5 months"
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = None
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    # Test absolute time interval and points    
+
+    print "Test 16"
+    maps = []
+    a = datetime(2001,12,31, 12, 30, 30)
+    increment = "3600 seconds"
+
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    a = datetime(2002,02,01, 12, 30, 30)
+    for i in range(24):
+        start = increment_datetime_by_string(a, increment, i)
+        end = None
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))
+
+    print "Test 17"
+    maps = []
+    a = datetime(2001,1,1)
+    increment = "2 days"
+
+    for i in range(8):
+        start = increment_datetime_by_string(a, increment, i)
+        end = increment_datetime_by_string(a, increment, i + 1)
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    a = datetime(2001,02,02)
+    for i in range(8):
+        start = increment_datetime_by_string(a, increment, i)
+        end = None
+        map = raster_dataset(None)
+        map.set_absolute_time(start, end)
+        maps.append(map)
+
+    gran = compute_absolute_time_granularity(maps)
+    if increment != gran:
+        core.error("Wrong granularity reference %s != gran %s" % (increment, gran))



More information about the grass-commit mailing list