Repository: ioos/compliance-checker

Issue:
Valid_coordinates not functioning properly
When a non Lat,Lon,Time,Elevation dimension is given as a coordinate, and it is not a coordinate varaible, an error was being raised.  That case should pass this check as only lat,lon,time,elev dimensions are checked here.   



Discussion:
Is this done and/or related to #20 ?

This block of code:

```
                for dim in var.dimensions:
                    if dim not in _possibleaxis:
                        break
                    elif dim not in ds.dataset.variables:
```

is checking to see if the dimension name is what we expect.  In actuality it should be the units (For lat/lon especially).  There may be more needed here.

The fix from #29 causes a regression bug to occur for me. a16b3b2 falsely assumes that if the dimension name is not in `_possibleaxis`, then the object is not a string but a netCDF4.Variable object.

``` bash
Running Compliance Checker on the dataset from: /Users/ochang/Downloads/sss20140107.v2.0cap.nc
Traceback (most recent call last):
  File "cchecker.py", line 24, in <module>
    main()
  File "cchecker.py", line 21, in main
    args.criteria)
  File "/Users/ochang/podaac/compliance-checker/compliance_checker/runner.py", line 39, in run_checker
    score_groups = cs.run(ds, *checker_names)
  File "/Users/ochang/podaac/compliance-checker/compliance_checker/suite.py", line 87, in run
    vals = list(itertools.chain.from_iterable(map(lambda c: self._run_check(c, dsp), checks)))
  File "/Users/ochang/podaac/compliance-checker/compliance_checker/suite.py", line 87, in <lambda>
    vals = list(itertools.chain.from_iterable(map(lambda c: self._run_check(c, dsp), checks)))
  File "/Users/ochang/podaac/compliance-checker/compliance_checker/suite.py", line 31, in _run_check
    val = check_method(ds)
  File "/Users/ochang/podaac/compliance-checker/compliance_checker/cf/cf.py", line 1421, in check_independent_axis_dimensions
    if dim not in _possibleaxis or dim.units not in _possibleaxisunits or dim.units.split(" ")[0] not in _possibleaxisunits or hasattr(dim,'positive'):
AttributeError: 'unicode' object has no attribute 'units'
```

from the dataset `ftp://podaac-ftp.jpl.nasa.gov/allData/aquarius/L3/mapped/CAPv2/7day/SCI/2014/007/sss20140107.v2.0cap.nc` with 

``` bash
netcdf sss20140107.v2.0cap {
dimensions:
    Longitude = 360 ;
    Latitude = 180 ;
... }
```

Thanks @oychang, we'll revisit.


Resolving patch:
diff --git a/compliance_checker/cf/cf.py b/compliance_checker/cf/cf.py
--- a/compliance_checker/cf/cf.py
+++ b/compliance_checker/cf/cf.py
@@ -1410,34 +1410,45 @@ def check_independent_axis_dimensions(self, ds):
 
         """
         ret_val = []
-        for name,var in ds.dataset.variables.iteritems():
-            if is_variable(name, var):
-                # If each dimension that's an axis is a proper coordinate variable
-                # then this is a valid compliance
-                reasoning = []
-                valid_coordinate = True
-                for dim in var.dimensions:
-                    #Looks to see if the dimension name or unit is not in the alloweable lists.  
-                    if dim not in _possibleaxis or dim.units not in _possibleaxisunits or dim.units.split(" ")[0] not in _possibleaxisunits or hasattr(dim,'positive'):
-                        break
-                    elif dim not in ds.dataset.variables:
-                        valid_coordinate = False
-                        reasoning.append('%s is not a coordinate variable' % dim)
 
+        space_time_coord_var = []
+        #Check to find all space-time coordinate variables (Lat/Lon/Time/Height)
+        for each in  self._find_coord_vars(ds):
+            if str(each._name)  in _possibleaxis or each.units in _possibleaxisunits or each.units.split(" ")[0]  in _possibleaxisunits or hasattr(each,'positive'):
+                space_time_coord_var.append(each._name)
 
-                    
-                if valid_coordinate:
-                    r = Result(BaseCheck.MEDIUM, \
-                               valid_coordinate, \
-                               ('var', name, 'valid_coordinates'))
-                else:
-                    r = Result(BaseCheck.MEDIUM,                   \
-                               valid_coordinate,                   \
-                               ('var', name, 'valid_coordinates'), \
-                               reasoning)
-                ret_val.append(r)
+        #Find all all space-time variables that are not coordinate variables
+        space_time_non_coord_var=[]
+        space_time_non_coord_var_dim = []
+        for name,var in ds.dataset.variables.iteritems():
+            if hasattr(var,'units'):
+                if (var  in _possibleaxis or var.units in _possibleaxisunits or var.units.split(" ")[0]  in _possibleaxisunits or hasattr(var,'positive')) and name not in space_time_coord_var:
+                    space_time_non_coord_var.append(name)
+                    for every in var.dimensions:
+                        space_time_non_coord_var_dim.append(every)
+
+        #Looks to ensure that every dimension of each variable that is a space-time dimension has associated coordinate variables
+        for name,var in ds.dataset.variables.iteritems():
+            valid = ''
+            for each in var.dimensions:
+                if each in space_time_non_coord_var_dim:
+                    valid = False
+                    dim_name = each
+                    break
+                elif each in space_time_coord_var:
+                    valid = True
+
+            if valid == False :
+                ret_val.append(Result(BaseCheck.MEDIUM, \
+                               valid, \
+                               ('var', name, 'check_independent_axis_dimensions'),['The %s dimension for the variable %s does not have an associated coordinate variable, but is a Lat/Lon/Time/Height dimension.'%(dim_name,name)]))
+
+            if valid == True and name not in space_time_coord_var:
+                ret_val.append(Result(BaseCheck.MEDIUM, \
+                               valid, \
+                               ('var', name, 'check_independent_axis_dimensions')))
         return ret_val
-                        
+
 
     def check_two_dimensional(self, ds):
         """


Test patch: