← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 1125: Work in progress on outlier analysis GUI.

 

------------------------------------------------------------
revno: 1125
committer: Lars Helge Oeverland larshelge@xxxxxxxxx
branch nick: trunk
timestamp: Wed 2009-11-25 16:56:24 +0100
message:
  Work in progress on outlier analysis GUI.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/outlieranalysis/OutlierValue.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/AbstractOutlierAnalysisService.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisService.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisService.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/JdbcOutlierAnalysisStore.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/OutlierAnalysisStore.java
  dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisServiceTest.java
  dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisServiceTest.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ConversionUtils.java
  dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/outlieranalysis/GetOutliersAction.java
  dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties
  dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierForm.vm
  dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierSearchResult.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription.
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/outlieranalysis/OutlierValue.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/outlieranalysis/OutlierValue.java	2009-11-24 17:34:15 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/outlieranalysis/OutlierValue.java	2009-11-25 15:56:24 +0000
@@ -27,7 +27,11 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import org.hisp.dhis.datavalue.DeflatedDataValue;
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.datavalue.DataValue;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.Period;
 
 /**
  * The OutlierValue class wraps an outlier DataValue. The value is outside of
@@ -39,105 +43,154 @@
  */
 public class OutlierValue
 {
-    /**
-     * Outlier datavalue.
-     */
-    private DeflatedDataValue outlier;
+    private DataElement dataElement;
+    
+    private Period period;
+    
+    private OrganisationUnit organisationUnit;
+    
+    private DataElementCategoryOptionCombo categoryOptionCombo;
+    
+    private double value;
 
-    /**
-     * Lower bound. This is the lower cut-off point for 
-     * whether a value is considered an outlier or not.
-     */
     private double lowerBound;
 
-    /**
-     * Upper boundary.
-     */
     private double upperBound;
 
     // -------------------------------------------------------------------------
     // Constructor
     // -------------------------------------------------------------------------
     
-    public OutlierValue( DeflatedDataValue outlier, double lowerBound, double upperBound )
-    {
-        this.outlier = outlier;
-        this.lowerBound = lowerBound;
-        this.upperBound = upperBound;
-    }
-
+    public OutlierValue( DataElement dataElement, Period period, OrganisationUnit organisationUnit,
+        DataElementCategoryOptionCombo categoryOptionCombo, double value, double lowerBound, double upperBound )
+    {
+        this.dataElement = dataElement;
+        this.period = period;
+        this.organisationUnit = organisationUnit;
+        this.categoryOptionCombo = categoryOptionCombo;
+        this.value = value;
+        this.lowerBound = lowerBound;
+        this.upperBound = upperBound;
+    }
+    
+    public OutlierValue( DataValue dataValue, double lowerBound, double upperBound )
+    {
+        this.dataElement = dataValue.getDataElement();
+        this.period = dataValue.getPeriod();
+        this.organisationUnit = (OrganisationUnit) dataValue.getSource();
+        this.categoryOptionCombo = dataValue.getOptionCombo();
+        this.value = Double.valueOf( dataValue.getValue() );
+        this.lowerBound = lowerBound;
+        this.upperBound = upperBound;
+    }
+
+    // -------------------------------------------------------------------------
+    // Logic
+    // -------------------------------------------------------------------------
+
+    public String getLowerBoundFormatted() 
+    {
+        return String.format("%.2f", lowerBound);
+    }
+    
+
+    public String getUpperBoundFormatted() 
+    {
+        return String.format("%.2f", upperBound);
+    }
+    
     // -------------------------------------------------------------------------
     // Setters and getters
     // -------------------------------------------------------------------------
 
-    /**
-     * Returns the lower bound. The value is either smaller than the lower
-     * bound, or bigger than the upper bound.
-     * 
-     * @return The lower bound for non-outlier values.
-     */
+    public DataElement getDataElement()
+    {
+        return dataElement;
+    }
+
+    public void setDataElement( DataElement dataElement )
+    {
+        this.dataElement = dataElement;
+    }
+
+    public Period getPeriod()
+    {
+        return period;
+    }
+
+    public void setPeriod( Period period )
+    {
+        this.period = period;
+    }
+
+    public OrganisationUnit getOrganisationUnit()
+    {
+        return organisationUnit;
+    }
+
+    public void setOrganisationUnit( OrganisationUnit organisationUnit )
+    {
+        this.organisationUnit = organisationUnit;
+    }
+
+    public DataElementCategoryOptionCombo getCategoryOptionCombo()
+    {
+        return categoryOptionCombo;
+    }
+
+    public void setCategoryOptionCombo( DataElementCategoryOptionCombo categoryOptionCombo )
+    {
+        this.categoryOptionCombo = categoryOptionCombo;
+    }
+
+    public double getValue()
+    {
+        return value;
+    }
+
+    public void setValue( double value )
+    {
+        this.value = value;
+    }
+
     public double getLowerBound()
     {
         return lowerBound;
     }
 
-    /**
-     * Returns the upper bound.
-     * 
-     * @see OutlierCollection#getLowerBound()
-     * @return The upper bound for non-outlier values.
-     */
+    public void setLowerBound( double lowerBound )
+    {
+        this.lowerBound = lowerBound;
+    }
+
     public double getUpperBound()
     {
         return upperBound;
     }
 
-    
-    public String getLowerBoundFormatted() {
-        return String.format("%.2f", lowerBound);
-    }
-    
-
-    public String getUpperBoundFormatted() {
-        return String.format("%.2f", upperBound);
-    }
-    
-    /**
-     * Returns the outlier.
-     * 
-     * @return The outlier DataValue.
-     */
-    public DeflatedDataValue getOutlier()
-    {
-        return outlier;
-    }
-
-    /**
-     * Sets the outlier DataValue.
-     * 
-     * @param outlier An outlier DataValue.
-     */
-    public void setOutlier( DeflatedDataValue outlier )
-    {
-        this.outlier = outlier;
-    }
-
-    /**
-     * @param lowerBound the lowerBound to set
-     */
-    public void setLowerBound( double lowerBound )
-    {
-        this.lowerBound = lowerBound;
-    }
-
-    /**
-     * @param upperBound the upperBound to set
-     */
     public void setUpperBound( double upperBound )
     {
         this.upperBound = upperBound;
     }
 
+    // -------------------------------------------------------------------------
+    // hashCode and equals
+    // -------------------------------------------------------------------------
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+
+        result = prime * result + ( ( categoryOptionCombo == null ) ? 0 : categoryOptionCombo.hashCode() );
+        result = prime * result + ( ( dataElement == null ) ? 0 : dataElement.hashCode() );
+        result = prime * result + ( ( organisationUnit == null ) ? 0 : organisationUnit.hashCode() );
+        result = prime * result + ( ( period == null ) ? 0 : period.hashCode() );
+
+        return result;
+    }
+
     @Override
     public boolean equals( Object o )
     {
@@ -158,12 +211,7 @@
 
         final OutlierValue other = (OutlierValue) o;
 
-        return outlier.equals( other.outlier ) && lowerBound == other.lowerBound && upperBound == other.upperBound;
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return outlier.hashCode();
+        return dataElement.equals( other.dataElement ) && period.equals( other.period ) &&
+            organisationUnit.equals( other.organisationUnit ) && categoryOptionCombo.equals( other.categoryOptionCombo );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/AbstractOutlierAnalysisService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/AbstractOutlierAnalysisService.java	2009-11-24 17:34:15 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/AbstractOutlierAnalysisService.java	2009-11-25 15:56:24 +0000
@@ -29,12 +29,14 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Map;
 
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.system.util.ConversionUtils;
 
 /**
  * @author Dag Haavi Finstad
@@ -63,7 +65,11 @@
     {
         Collection<OrganisationUnit> units = organisationUnitService.getOrganisationUnitWithChildren( organisationUnit.getId() );
         
-        final Collection<OutlierValue> outlierCollection = new ArrayList<OutlierValue>();
+        Map<Integer, DataElement> dataElementMap = ConversionUtils.getIdentifierMap( dataElements );
+        Map<Integer, Period> periodMap = ConversionUtils.getIdentifierMap( periods );
+        Map<Integer, OrganisationUnit> organisationUnitMap = ConversionUtils.getIdentifierMap( units );
+        
+        Collection<OutlierValue> outlierCollection = new ArrayList<OutlierValue>();
         
         for ( OrganisationUnit unit : units )
         {
@@ -73,9 +79,12 @@
                 {                    
                     Collection<DataElementCategoryOptionCombo> categoryOptionCombos = dataElement.getCategoryCombo().getOptionCombos();
                     
+                    Map<Integer, DataElementCategoryOptionCombo> categoryOptionComboMap = ConversionUtils.getIdentifierMap( categoryOptionCombos );
+                    
                     for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryOptionCombos )
                     {
-                        outlierCollection.addAll( findOutliers( unit, dataElement, categoryOptionCombo, periods, stdDevFactor ) );
+                        outlierCollection.addAll( findOutliers( unit, dataElement, categoryOptionCombo, periods, stdDevFactor,
+                            dataElementMap, periodMap, organisationUnitMap, categoryOptionComboMap ) );
                     }
                 }
             }
@@ -89,5 +98,7 @@
     // -------------------------------------------------------------------------
 
     protected abstract Collection<OutlierValue> findOutliers( OrganisationUnit organisationUnit, 
-        DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor );
+        DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor,
+        Map<Integer, DataElement> dataElementMap, Map<Integer, Period> periodMap, Map<Integer, OrganisationUnit> organisationUnitMap,
+        Map<Integer, DataElementCategoryOptionCombo> categoryOptionComboMap );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisService.java	2009-11-24 17:53:40 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisService.java	2009-11-25 15:56:24 +0000
@@ -30,6 +30,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Map;
 
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -70,8 +71,10 @@
     // MinMaxOutlierAnalysisService implementation
     // -------------------------------------------------------------------------
 
-    public Collection<OutlierValue> findOutliers( OrganisationUnit organisationUnit, DataElement dataElement,
-        DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor )
+    public Collection<OutlierValue> findOutliers( OrganisationUnit organisationUnit, 
+        DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor,
+        Map<Integer, DataElement> dataElementMap, Map<Integer, Period> periodMap, Map<Integer, OrganisationUnit> organisationUnitMap,
+        Map<Integer, DataElementCategoryOptionCombo> categoryOptionComboMap )
     {
         final Collection<OutlierValue> outlierValues = new ArrayList<OutlierValue>();
 
@@ -83,11 +86,13 @@
             double upperBound = minMaxDataElement.getMax();
 
             Collection<DeflatedDataValue> outliers = outlierAnalysisStore.
-                getDeflatedDataValues( dataElement, categoryOptionCombo, organisationUnit, lowerBound, upperBound );
+                getDeflatedDataValues( dataElement, categoryOptionCombo, periods, organisationUnit, lowerBound, upperBound );
 
             for ( DeflatedDataValue outlier : outliers )
             {
-                outlierValues.add( new OutlierValue( outlier, lowerBound, upperBound ) );
+                outlierValues.add( new OutlierValue( dataElementMap.get( outlier.getDataElementId() ), periodMap.get( outlier.getPeriodId() ),
+                    organisationUnitMap.get( outlier.getSourceId() ), categoryOptionComboMap.get( outlier.getCategoryOptionComboId() ),
+                    Double.valueOf( outlier.getValue() ), lowerBound, upperBound ) );
             }
         }
         

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisService.java	2009-11-24 17:34:15 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisService.java	2009-11-25 15:56:24 +0000
@@ -29,6 +29,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Map;
 
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -64,13 +65,15 @@
     // -------------------------------------------------------------------------
 
     public Collection<OutlierValue> findOutliers( OrganisationUnit organisationUnit, DataElement dataElement, 
-        DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor )
+        DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor,
+        Map<Integer, DataElement> dataElementMap, Map<Integer, Period> periodMap, Map<Integer, OrganisationUnit> organisationUnitMap,
+        Map<Integer, DataElementCategoryOptionCombo> categoryOptionComboMap)
     {
         final Collection<OutlierValue> outlierValues = new ArrayList<OutlierValue>();
 
         Double stdDev = outlierAnalysisStore.getStandardDeviation( dataElement, categoryOptionCombo, organisationUnit );
                 
-        if ( !isEqual( stdDev, 0.0 ) ) // If 0.0 no values found or no outliers exist
+        if ( !isEqual( stdDev, 0.0 ) ) // No values found or no outliers exist when 0.0
         {
             Double avg = outlierAnalysisStore.getAverage( dataElement, categoryOptionCombo, organisationUnit );
             
@@ -79,11 +82,13 @@
             double upperBound = avg + deviation;
             
             Collection<DeflatedDataValue> outliers = outlierAnalysisStore.
-                getDeflatedDataValues( dataElement, categoryOptionCombo, organisationUnit, lowerBound, upperBound );
+                getDeflatedDataValues( dataElement, categoryOptionCombo, periods, organisationUnit, lowerBound, upperBound );
             
             for ( DeflatedDataValue outlier : outliers )
             {
-                outlierValues.add( new OutlierValue( outlier, lowerBound, upperBound ) );
+                outlierValues.add( new OutlierValue( dataElementMap.get( outlier.getDataElementId() ), periodMap.get( outlier.getPeriodId() ),
+                    organisationUnitMap.get( outlier.getSourceId() ), categoryOptionComboMap.get( outlier.getCategoryOptionComboId() ),
+                    Double.valueOf( outlier.getValue() ), lowerBound, upperBound ) );
             }
         }
         

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/JdbcOutlierAnalysisStore.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/JdbcOutlierAnalysisStore.java	2009-11-24 17:34:15 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/JdbcOutlierAnalysisStore.java	2009-11-25 15:56:24 +0000
@@ -38,8 +38,11 @@
 import org.hisp.dhis.datavalue.DeflatedDataValue;
 import org.hisp.dhis.jdbc.StatementBuilder;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.Period;
 import org.hisp.dhis.system.objectmapper.DeflatedDataValueRowMapper;
 import org.hisp.dhis.system.objectmapper.ObjectMapper;
+import org.hisp.dhis.system.util.ConversionUtils;
+import org.hisp.dhis.system.util.TextUtils;
 
 /**
  * @author Lars Helge Overland
@@ -84,18 +87,21 @@
     }
     
     public Collection<DeflatedDataValue> getDeflatedDataValues( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo,
-        OrganisationUnit organisationUnit, double lowerBound, double upperBound )
+        Collection<Period> periods, OrganisationUnit organisationUnit, double lowerBound, double upperBound )
     {
         final StatementHolder holder = statementManager.getHolder();
         
         final ObjectMapper<DeflatedDataValue> mapper = new ObjectMapper<DeflatedDataValue>();
         
+        final String periodIds = TextUtils.getCommaDelimitedString( ConversionUtils.getIdentifiers( Period.class, periods ) );
+        
         try
         {
             final String sql =
                 "SELECT * FROM datavalue " +
                 "WHERE dataelementid='" + dataElement.getId() + "' " +
                 "AND categoryoptioncomboid='" + categoryOptionCombo.getId() + "' " +
+                "AND periodid IN (" + periodIds + ") " +
                 "AND sourceid='" + organisationUnit.getId() + "' " +
                 "AND ( CAST( value AS " + statementBuilder.getDoubleColumnType() + " ) < '" + lowerBound + "' " +
                 "OR CAST( value AS " + statementBuilder.getDoubleColumnType() + " ) > '" + upperBound + "' )";

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/OutlierAnalysisStore.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/OutlierAnalysisStore.java	2009-11-24 17:34:15 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/outlieranalysis/jdbc/OutlierAnalysisStore.java	2009-11-25 15:56:24 +0000
@@ -33,6 +33,7 @@
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.datavalue.DeflatedDataValue;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.period.Period;
 
 /**
  * @author Lars Helge Overland
@@ -44,5 +45,5 @@
     Double getAverage( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, OrganisationUnit organisationUnit );
     
     Collection<DeflatedDataValue> getDeflatedDataValues( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo,
-        OrganisationUnit organisationUnit, double lowerBound, double upperBound );
+        Collection<Period> periods, OrganisationUnit organisationUnit, double lowerBound, double upperBound );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisServiceTest.java'
--- dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisServiceTest.java	2009-11-24 17:53:40 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/MinMaxOutlierAnalysisServiceTest.java	2009-11-25 15:56:24 +0000
@@ -43,7 +43,6 @@
 import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
-import org.hisp.dhis.datavalue.DeflatedDataValue;
 import org.hisp.dhis.minmax.MinMaxDataElement;
 import org.hisp.dhis.minmax.MinMaxDataElementService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
@@ -201,7 +200,7 @@
 
         assertEquals( 2, result.size() );
         equals( result,
-            new OutlierValue( new DeflatedDataValue( dataValueA ), minMaxDataElement.getMin(), minMaxDataElement.getMax() ),
-            new OutlierValue( new DeflatedDataValue( dataValueB ), minMaxDataElement.getMin(), minMaxDataElement.getMax() ) );
+            new OutlierValue( dataValueA, minMaxDataElement.getMin(), minMaxDataElement.getMax() ),
+            new OutlierValue( dataValueB, minMaxDataElement.getMin(), minMaxDataElement.getMax() ) );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisServiceTest.java'
--- dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisServiceTest.java	2009-11-24 17:34:15 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/test/java/org/hisp/dhis/outlieranalysis/StdDevOutlierAnalysisServiceTest.java	2009-11-25 15:56:24 +0000
@@ -43,7 +43,6 @@
 import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
-import org.hisp.dhis.datavalue.DeflatedDataValue;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.MonthlyPeriodType;
@@ -187,7 +186,7 @@
         
         assertEquals( 2, result.size() );
         equals( result, 
-            new OutlierValue( new DeflatedDataValue( dataValueA ), lowerBound, upperBound ),
-            new OutlierValue( new DeflatedDataValue( dataValueB ), lowerBound, upperBound ) );
+            new OutlierValue( dataValueA, lowerBound, upperBound ),
+            new OutlierValue( dataValueB, lowerBound, upperBound ) );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java	2009-11-25 09:08:11 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java	2009-11-25 15:56:24 +0000
@@ -158,6 +158,7 @@
         return query.executeUpdate();    
     }
 
+    @Deprecated
     public DataValue getDataValue( Source source, DataElement dataElement, Period period )
     {
         Session session = sessionFactory.getCurrentSession();

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ConversionUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ConversionUtils.java	2009-11-23 11:51:03 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ConversionUtils.java	2009-11-25 15:56:24 +0000
@@ -30,8 +30,10 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -42,6 +44,7 @@
 {
     /**
      * Creates a collection of the identifiers of the objects passed as argument.
+     * The object are assumed to have a <code>int getId()</code> method.
      * 
      * @param clazz the clazz of the argument objects.
      * @param objects for which to get the identifiers.
@@ -68,6 +71,26 @@
             throw new RuntimeException( "Failed to convert objects", ex );
         }
     }
+    /**
+     * Returns the identifier of the argument object. The object is assumed to
+     * have a <code>int getId()</code> method.
+     * 
+     * @param object the object.
+     * @return the identifier of the argument object.
+     */
+    public static Integer getIdentifier( Object object )
+    {
+        try
+        {
+            Method method = object.getClass().getMethod( "getId", new Class[ 0 ] );
+            
+            return (Integer) method.invoke( object, new Object[ 0 ] );
+        }
+        catch ( Exception ex )
+        {
+            throw new RuntimeException( "Failed to convert object", ex );
+        }
+    }
     
     /**
      * Creates a collection of Integers out of a collection of Strings.
@@ -164,4 +187,23 @@
         
         return list;
     }
+    
+    /**
+     * Returns a Map based on an argument Collection of objects where the key is
+     * the object identifier and the value if the object itself.
+     * 
+     * @param collection the Collection of objects.
+     * @return a Map with identifier object pairs.
+     */
+    public static <T> Map<Integer, T> getIdentifierMap( Collection<T> collection )
+    {
+        Map<Integer, T> map = new HashMap<Integer, T>();
+        
+        for ( T object : collection )
+        {
+            map.put( getIdentifier( object ), object );
+        }
+        
+        return map;
+    }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/outlieranalysis/GetOutliersAction.java'
--- dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/outlieranalysis/GetOutliersAction.java	2009-11-24 14:30:46 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/outlieranalysis/GetOutliersAction.java	2009-11-25 15:56:24 +0000
@@ -27,7 +27,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -141,6 +140,10 @@
         this.fromDateString = fromDate.trim();
     }
 
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
     private String dataSetId;
 
     public void setDataset( String dataSet )
@@ -155,20 +158,6 @@
         this.dataElementsById = dataElementsById;
     }
 
-    private Collection<DataElement> dataElements;
-
-    public List<DataElement> getDataElements()
-    {
-        return new ArrayList<DataElement>( this.dataElements );
-    }
-    
-    private OrganisationUnit source;
-    
-    public OrganisationUnit getSource()
-    {
-        return source;
-    }
-
     private String outlierType;
 
     public void setOutlierType( String outlierType )
@@ -176,20 +165,6 @@
         this.outlierType = outlierType;
     }
 
-    public String getOutlierType()
-    {
-        if ( outlierType.equals( TYPE_MINMAX ) )
-        {
-            return "Min-max";
-        }
-        if ( outlierType.equals( TYPE_STDDEV ) )
-        {
-            return "Standard deviation";
-        }
-        
-        return "";
-    }
-
     private Double standardDeviation;
 
     public void setStandardDeviation( Double standardDeviation )
@@ -197,6 +172,10 @@
         this.standardDeviation = standardDeviation;
     }
 
+    // -------------------------------------------------------------------------
+    // Output
+    // -------------------------------------------------------------------------
+    
     private Collection<OutlierValue> outlierValues;
 
     public Collection<OutlierValue> getOutlierValues()
@@ -210,7 +189,7 @@
     {
         return searchTime;
     }
-
+    
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -219,9 +198,9 @@
     {
         long startTime = System.currentTimeMillis();
 
-        dataElements = dataElementService.getDataElements( ConversionUtils.getIntegerCollection( dataElementsById ) );
+        Collection<DataElement> dataElements = dataElementService.getDataElements( ConversionUtils.getIntegerCollection( dataElementsById ) );
 
-        source = selectionTreeManager.getSelectedOrganisationUnit();
+        OrganisationUnit organisationUnit = selectionTreeManager.getSelectedOrganisationUnit();
         
         DataSet dataSet = dataSetService.getDataSet( Integer.parseInt( dataSetId ) );
         
@@ -253,11 +232,11 @@
 
         if ( outlierType.equals( TYPE_MINMAX ) )
         {
-            outlierValues = minMaxOutlierAnalysisService.findOutliers( source, dataElements, periods, null );
+            outlierValues = minMaxOutlierAnalysisService.findOutliers( organisationUnit, dataElements, periods, null );
         }
         else if ( outlierType.equals( TYPE_STDDEV ) )
         {
-            outlierValues = stdDevOutlierAnalysisService.findOutliers( source, dataElements, periods, standardDeviation );
+            outlierValues = stdDevOutlierAnalysisService.findOutliers( organisationUnit, dataElements, periods, standardDeviation );
         }
         else
         {

=== modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties	2009-11-03 10:54:57 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/org/hisp/dhis/validationrule/i18n_module.properties	2009-11-25 15:56:24 +0000
@@ -85,7 +85,7 @@
 right_side_description= Right side description
 value= Value
 data_element= Data element
-organisation_unit	= Organisation unit
+organisation_unit= Organisation unit
 period= Period
 organisation_unit_only= Organisation unit only
 organisation_unit_with_children= Organisation unit with children
@@ -128,6 +128,7 @@
 std_dev	= Standard Deviation
 max	= Max
 min	= Min
+values_found = values found
 select_std_dev = Select number of standard deviations
 waiting_for_user_to_choose_dataset = Waiting for user to select a data set
 select_parent_organisation_unit = Select parent organisation unit

=== modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierForm.vm'
--- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierForm.vm	2009-11-24 14:30:46 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierForm.vm	2009-11-25 15:56:24 +0000
@@ -101,14 +101,14 @@
 	<tr>
 		<td colspan="2">
 			<select id="outlierType" name="outlierType" style="min-width:325px" onChange="chooseType()">
-				<option value ="minmax">$i18n.getString( "min_max" )</option>
-				<option value ="stddev">$i18n.getString( "std_dev" )</option>
+				<option value="stddev">$i18n.getString( "std_dev" )</option>
+                <option value="minmax">$i18n.getString( "min_max" )</option>
 			</select>
 		</td>
 	</tr>
 </table>
 
-<div id="stddevform" style="display:none">
+<div id="stddevform">
 <table>
 	## STANDARD DEVIATION INPUT FIELD
 	<tr>

=== modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierSearchResult.vm'
--- dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierSearchResult.vm	2009-10-10 14:26:24 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/webapp/dhis-web-validationrule/outlierSearchResult.vm	2009-11-25 15:56:24 +0000
@@ -9,14 +9,14 @@
 
 #else
 
-<span id="info">$i18n.getString( "found" ) $outlierValues.size() $i18n.getString( "values" ) ($searchTime ms).</span>
+<span id="info">$outlierValues.size() $i18n.getString( "values_found" ) ($searchTime ms).</span>
 
 <p><strong>$i18n.getString( "from_date" ):</strong> $fromDate <strong>$i18n.getString( "to_date" ):</strong> $toDate</p>
 
 <table class="mainPageTable" cellpadding="0">
 	<tr>
 		<th>$i18n.getString( "data_element" )</th>
-		<th>$i18n.getString( "org_unit" )</th>
+		<th>$i18n.getString( "organisation_unit" )</th>
 		<th>$i18n.getString( "period" )</th>
 		<th>$i18n.getString( "min" )</th>
 		<th style="width: 100px">$i18n.getString( "value" )</th>
@@ -38,18 +38,19 @@
 	
 		## data element
 		<td>
-			<span id="outlier[$count].name" title="$!encoder.htmlEncode( $dataElement.description )">
-				$outlierValue.getOutlier().getDataElement().getName()
+			<span id="outlier[$count].name"> ## title="$!encoder.htmlEncode( $dataElement.description )"
+				$outlierValue.dataElement.name
 			</span>
 		</td>
 		
+		## organisation unit
 		<td>
-			$outlierValue.getOutlier().getSource().getName()
+			$outlierValue.organisationUnit.name
 		</td>
 		
 		## period
 		<td>
-			$format.formatPeriod( $outlierValue.getOutlier().getPeriod() )
+			$format.formatPeriod( $outlierValue.period )
 		</td>
 		
 		## lower bound (min)
@@ -59,13 +60,13 @@
 		
 		## value
 		<td style="width:100px">
-			<input name="outliervalue" id="outlier[$count].value" value="$outlierValue.getOutlier().getValue()"
+			<input name="outliervalue" id="outlier[$count].value" value="$outlierValue.getValue()"
 				style="width: 95%; text-align: center;" tabindex="$count" type="text" onchange="editOutlierValue( $count )" />
-			<input type="hidden" id="outlier[$count].source" value="$outlierValue.getOutlier().getSource().getId()" />
-			<input type="hidden" id="outlier[$count].period" value="$outlierValue.getOutlier().getPeriod().getId()" />
-			<input type="hidden" id="outlier[$count].max" value="$outlierValue.getUpperBound()" />
-			<input type="hidden" id="outlier[$count].min" value="$outlierValue.getLowerBound()" />
-			<input type="hidden" id="outlier[$count].dataElement" value="$outlierValue.getOutlier().getDataElement().getId()" />
+			<input type="hidden" id="outlier[$count].source" value="$outlierValue.organisationUnit.id" />
+			<input type="hidden" id="outlier[$count].period" value="$outlierValue.period.id" />
+			<input type="hidden" id="outlier[$count].max" value="$outlierValue.upperBound" />
+			<input type="hidden" id="outlier[$count].min" value="$outlierValue.lowerBound" />
+			<input type="hidden" id="outlier[$count].dataElement" value="$outlierValue.dataElement.id" />
 		</td>
 		
 		## upper bound (max)