dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #18350
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 7702: Reimplemented std dev and min-max data analysis. Improves performance.
------------------------------------------------------------
revno: 7702
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2012-07-25 15:18:48 +0200
message:
Reimplemented std dev and min-max data analysis. Improves performance.
removed:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/validation/
dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/validation/MinMaxValuesGenerationService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxValueMap.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/validation/
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/validation/DefaultMinMaxValuesGenerationService.java
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/RemoveMinMaxValueAction.java
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidationForm.js
added:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/MinMaxDataAnalysisService.java
dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/DataAnalysisStoreTest.java
dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/batchhandler/MinMaxDataElementBatchHandler.java
dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/filter/DataElementTypeFilter.java
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisService.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisStore.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementService.java
dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementStore.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/FollowupAnalysisService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/jdbc/JdbcDataAnalysisStore.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/DefaultMinMaxDataElementService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/hibernate/HibernateMinMaxDataElementStore.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java
dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisServiceTest.java
dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisServiceTest.java
dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java
dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/objectmapper/DeflatedDataValueNameMinMaxRowMapper.java
dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java
dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java
dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml
dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/utils/FormUtils.java
dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GenerateMinMaxValuesAction.java
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GetMinMaxValidationParamsAction.java
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidation.js
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/minMaxValidation.vm
dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/dataanalysis/GetAnalysisAction.java
dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/META-INF/dhis/beans.xml
--
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/dataanalysis/DataAnalysisService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisService.java 2011-02-10 23:09:13 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisService.java 2012-07-25 13:18:48 +0000
@@ -36,15 +36,13 @@
/**
* @author Dag Haavi Finstad
- * @version $Id: StdDevOutlierAnalysisService.java 882 2009-05-14 23:09:31Z
- * daghf $
*/
public interface DataAnalysisService
{
String ID = DataAnalysisService.class.getName();
- int MAX_OUTLIERS = 500;
+ final int MAX_OUTLIERS = 500;
- Collection<DeflatedDataValue> analyse( OrganisationUnit organisationUnit, Collection<DataElement> dataElements,
+ Collection<DeflatedDataValue> analyse( Collection<OrganisationUnit> organisationUnits, Collection<DataElement> dataElements,
Collection<Period> periods, Double stdDevFactor );
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisStore.java 2012-07-20 07:29:46 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/DataAnalysisStore.java 2012-07-25 13:18:48 +0000
@@ -28,6 +28,8 @@
*/
import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -40,6 +42,8 @@
*/
public interface DataAnalysisStore
{
+ final String ID = DataAnalysisStore.class.getName();
+
/**
* Calculates the standard deviation of the DataValues registered for the given
* data element, category option combo and organisation unit.
@@ -49,7 +53,7 @@
* @param organisationUnit the OrganisationUnit.
* @return the standard deviation.
*/
- Double getStandardDeviation( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, OrganisationUnit organisationUnit );
+ Map<Integer, Double> getStandardDeviation( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Set<Integer> organisationUnits );
/**
* Calculates the average of the DataValues registered for the given
@@ -60,7 +64,10 @@
* @param organisationUnit the OrganisationUnit.
* @return the average.
*/
- Double getAverage( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, OrganisationUnit organisationUnit );
+ Map<Integer, Double> getAverage( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Set<Integer> organisationUnits );
+
+ Collection<DeflatedDataValue> getMinMaxViolations( Collection<DataElement> dataElements, Collection<DataElementCategoryOptionCombo> categoryOptionCombos,
+ Collection<Period> periods, Collection<OrganisationUnit> organisationUnits, int limit );
/**
* Returns a collection of DeflatedDataValues for the given input.
@@ -74,7 +81,7 @@
* @return
*/
Collection<DeflatedDataValue> getDeflatedDataValues( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo,
- Collection<Period> periods, OrganisationUnit organisationUnit, int lowerBound, int upperBound );
+ Collection<Period> periods, Map<Integer, Integer> lowerBoundMap, Map<Integer, Integer> upperBoundMap );
/**
* Returns a collection of DeflatedDataValues which are marked for followup.
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/MinMaxDataAnalysisService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/MinMaxDataAnalysisService.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataanalysis/MinMaxDataAnalysisService.java 2012-07-25 13:18:48 +0000
@@ -0,0 +1,13 @@
+package org.hisp.dhis.dataanalysis;
+
+import java.util.Collection;
+
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+
+public interface MinMaxDataAnalysisService
+ extends DataAnalysisService
+{
+ void generateMinMaxValues( Collection<OrganisationUnit> organisationUnits,
+ Collection<DataElement> dataElements, Double stdDevFactor );
+}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java 2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java 2012-07-25 13:18:48 +0000
@@ -27,11 +27,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import java.util.Collection;
+
import org.hisp.dhis.concept.Concept;
import org.hisp.dhis.hierarchy.HierarchyViolationException;
-import java.util.Collection;
-
/**
* @author Abyot Asalefew
* @version $Id$
@@ -419,7 +419,7 @@
* @return a collection of all DataElementCategories, or an empty collection.
*/
Collection<DataElementCategory> getDataElementCategorysByConcept( Concept concept );
-
+
int getDataElementCategoryCount();
int getDataElementCategoryCountByName( String name );
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementService.java 2012-07-01 07:12:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementService.java 2012-07-25 13:18:48 +0000
@@ -62,4 +62,6 @@
void removeMinMaxDataElements( DataElement dataElement );
void removeMinMaxDataElements( DataElementCategoryOptionCombo optionCombo );
+
+ void removeMinMaxDataElements( Collection<DataElement> dataElements, Collection<OrganisationUnit> organisationUnits );
}
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementStore.java 2012-07-01 07:12:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/MinMaxDataElementStore.java 2012-07-25 13:18:48 +0000
@@ -54,4 +54,6 @@
void delete( DataElement dataElement );
void delete( DataElementCategoryOptionCombo optionCombo );
+
+ void delete( Collection<DataElement> dataElements, Collection<OrganisationUnit> organisationUnits );
}
=== removed directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/validation'
=== removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/validation/MinMaxValuesGenerationService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/validation/MinMaxValuesGenerationService.java 2010-04-29 04:33:47 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/minmax/validation/MinMaxValuesGenerationService.java 1970-01-01 00:00:00 +0000
@@ -1,51 +0,0 @@
-package org.hisp.dhis.minmax.validation;
-
-/*
- * Copyright (c) 2004-2009, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.Collection;
-
-import org.hisp.dhis.dataelement.DataElement;
-import org.hisp.dhis.datavalue.DeflatedDataValue;
-import org.hisp.dhis.minmax.MinMaxDataElement;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.period.Period;
-
-/**
- * @author Chau Thu Tran
- * @version $Id$
- */
-public interface MinMaxValuesGenerationService
-{
- String ID = MinMaxValuesGenerationService.class.getName();
-
- Collection<MinMaxDataElement> getMinMaxValues( OrganisationUnit organisationUnit,
- Collection<DataElement> dataElements, Double stdDevFactor );
-
- Collection<DeflatedDataValue> findOutliers( OrganisationUnit organisationUnit, Collection<Period> periods,
- Collection<MinMaxDataElement> minMaxDataElements );
-}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/FollowupAnalysisService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/FollowupAnalysisService.java 2010-04-08 11:10:09 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/FollowupAnalysisService.java 2012-07-25 13:18:48 +0000
@@ -40,6 +40,10 @@
public class FollowupAnalysisService
implements DataAnalysisService
{
+ // -------------------------------------------------------------------------
+ // Dependencies
+ // -------------------------------------------------------------------------
+
private DataAnalysisStore dataAnalysisStore;
public void setDataAnalysisStore( DataAnalysisStore dataAnalysisStore )
@@ -47,8 +51,12 @@
this.dataAnalysisStore = dataAnalysisStore;
}
+ // -------------------------------------------------------------------------
+ // DataAnalysisService implementation
+ // -------------------------------------------------------------------------
+
@Override
- public Collection<DeflatedDataValue> analyse( OrganisationUnit organisationUnit,
+ public Collection<DeflatedDataValue> analyse( Collection<OrganisationUnit> organisationUnits,
Collection<DataElement> dataElements, Collection<Period> periods, Double stdDevFactor )
{
return dataAnalysisStore.getDataValuesMarkedForFollowup();
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisService.java 2011-02-10 23:09:13 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisService.java 2012-07-25 13:18:48 +0000
@@ -27,116 +27,130 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.amplecode.quick.BatchHandler;
+import org.amplecode.quick.BatchHandlerFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
import org.hisp.dhis.datavalue.DeflatedDataValue;
+import org.hisp.dhis.jdbc.batchhandler.MinMaxDataElementBatchHandler;
import org.hisp.dhis.minmax.MinMaxDataElement;
import org.hisp.dhis.minmax.MinMaxDataElementService;
import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.period.Period;
+import org.hisp.dhis.system.filter.DataElementTypeFilter;
+import org.hisp.dhis.system.util.ConversionUtils;
+import org.hisp.dhis.system.util.Filter;
+import org.hisp.dhis.system.util.FilterUtils;
+import org.hisp.dhis.system.util.MathUtils;
/**
- * @author Dag Haavi Finstad
* @author Lars Helge Overland
*/
public class MinMaxOutlierAnalysisService
- implements DataAnalysisService
+ implements MinMaxDataAnalysisService
{
+ private static final Log log = LogFactory.getLog( MinMaxOutlierAnalysisService.class );
+
+ private static final Filter<DataElement> DATALEMENT_INT_FILTER = new DataElementTypeFilter( DataElement.VALUE_TYPE_INT );
+
// -------------------------------------------------------------------------
// Dependencies
// -------------------------------------------------------------------------
+
+ private DataAnalysisStore dataAnalysisStore;
+ public void setDataAnalysisStore( DataAnalysisStore dataAnalysisStore )
+ {
+ this.dataAnalysisStore = dataAnalysisStore;
+ }
+
private MinMaxDataElementService minMaxDataElementService;
public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
{
this.minMaxDataElementService = minMaxDataElementService;
}
-
- private OrganisationUnitService organisationUnitService;
-
- public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
- {
- this.organisationUnitService = organisationUnitService;
- }
-
- private DataAnalysisStore dataAnalysisStore;
-
- public void setDataAnalysisStore( DataAnalysisStore dataAnalysisStore )
- {
- this.dataAnalysisStore = dataAnalysisStore;
- }
-
- // -------------------------------------------------------------------------
- // MinMaxOutlierAnalysisService implementation
- // -------------------------------------------------------------------------
-
- public final Collection<DeflatedDataValue> analyse( OrganisationUnit organisationUnit,
+
+ private BatchHandlerFactory batchHandlerFactory;
+
+ public void setBatchHandlerFactory( BatchHandlerFactory batchHandlerFactory )
+ {
+ this.batchHandlerFactory = batchHandlerFactory;
+ }
+
+ // -------------------------------------------------------------------------
+ // DataAnalysisService implementation
+ // -------------------------------------------------------------------------
+
+ public Collection<DeflatedDataValue> analyse( Collection<OrganisationUnit> organisationUnits,
Collection<DataElement> dataElements, Collection<Period> periods, Double stdDevFactor )
{
- Collection<OrganisationUnit> units = organisationUnitService.getOrganisationUnitWithChildren( organisationUnit.getId() );
-
- Collection<DeflatedDataValue> outlierCollection = new ArrayList<DeflatedDataValue>();
-
- loop : for ( OrganisationUnit unit : units )
- {
- MinMaxValueMap map = getMinMaxValueMap( minMaxDataElementService.getMinMaxDataElements( unit, dataElements ) );
-
- for ( DataElement dataElement : dataElements )
+ FilterUtils.filter( dataElements, DATALEMENT_INT_FILTER );
+
+ Set<DataElementCategoryOptionCombo> categoryOptionCombos = new HashSet<DataElementCategoryOptionCombo>();
+
+ for ( DataElement dataElement : dataElements )
+ {
+ categoryOptionCombos.addAll( dataElement.getCategoryCombo().getOptionCombos() );
+ }
+
+ log.info( "Starting min-max analysis, no of data elements: " + dataElements.size() + ", no of org units: " + organisationUnits.size() );
+
+ return dataAnalysisStore.getMinMaxViolations( dataElements, categoryOptionCombos, periods, organisationUnits, MAX_OUTLIERS );
+ }
+
+ public void generateMinMaxValues( Collection<OrganisationUnit> organisationUnits,
+ Collection<DataElement> dataElements, Double stdDevFactor )
+ {
+ log.info( "Starting min-max value generation, no of data elements: " + dataElements.size() + ", no of org units: " + organisationUnits.size() );
+
+ Set<Integer> orgUnitIds = new HashSet<Integer>( ConversionUtils.getIdentifiers( OrganisationUnit.class, organisationUnits ) );
+
+ minMaxDataElementService.removeMinMaxDataElements( dataElements, organisationUnits );
+
+ log.info( "Deleted existing min-max values" );
+
+ BatchHandler<MinMaxDataElement> batchHandler = batchHandlerFactory.createBatchHandler( MinMaxDataElementBatchHandler.class ).init();
+
+ for ( DataElement dataElement : dataElements )
+ {
+ if ( dataElement.getType().equals( DataElement.VALUE_TYPE_INT ) )
{
- if ( dataElement.getType().equals( DataElement.VALUE_TYPE_INT ) )
- {
- Collection<DataElementCategoryOptionCombo> categoryOptionCombos = dataElement.getCategoryCombo().getOptionCombos();
-
- for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryOptionCombos )
+ Collection<DataElementCategoryOptionCombo> categoryOptionCombos = dataElement.getCategoryCombo().getOptionCombos();
+
+ for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryOptionCombos )
+ {
+ Map<Integer, Double> standardDeviations = dataAnalysisStore.getStandardDeviation( dataElement, categoryOptionCombo, orgUnitIds );
+
+ Map<Integer, Double> averages = dataAnalysisStore.getAverage( dataElement, categoryOptionCombo, standardDeviations.keySet() );
+
+ for ( Integer unit : averages.keySet() )
{
- outlierCollection.addAll( findOutliers( unit, dataElement, categoryOptionCombo, periods, map ) );
+ Double stdDev = standardDeviations.get( unit );
+ Double avg = averages.get( unit );
- if ( outlierCollection.size() > MAX_OUTLIERS )
+ if ( stdDev != null && avg != null )
{
- break loop;
+ int min = (int) MathUtils.getLowBound( stdDev, stdDevFactor, avg );
+ int max = (int) MathUtils.getHighBound( stdDev, stdDevFactor, avg );
+
+ OrganisationUnit source = new OrganisationUnit();
+ source.setId( unit );
+
+ batchHandler.addObject( new MinMaxDataElement( source, dataElement, categoryOptionCombo, min, max, true ) );
}
- }
+ }
}
}
}
-
- return outlierCollection;
-
- //TODO improve performance by joining datavalue with minmaxdataelement
- }
-
- // -------------------------------------------------------------------------
- // Supportive methods
- // -------------------------------------------------------------------------
-
- private Collection<DeflatedDataValue> findOutliers( OrganisationUnit organisationUnit, DataElement dataElement,
- DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, MinMaxValueMap map )
- {
- MinMaxDataElement minMaxDataElement = map.get( organisationUnit, dataElement, categoryOptionCombo );
-
- if ( minMaxDataElement != null )
- {
- return dataAnalysisStore.getDeflatedDataValues( dataElement, categoryOptionCombo, periods,
- organisationUnit, minMaxDataElement.getMin(), minMaxDataElement.getMax() );
- }
-
- return new ArrayList<DeflatedDataValue>();
- }
-
- private MinMaxValueMap getMinMaxValueMap( Collection<MinMaxDataElement> minMaxDataElements )
- {
- MinMaxValueMap map = new MinMaxValueMap();
-
- for ( MinMaxDataElement element : minMaxDataElements )
- {
- map.put( element );
- }
-
- return map;
+
+ batchHandler.flush();
}
}
=== removed file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxValueMap.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxValueMap.java 2011-05-05 21:14:56 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/MinMaxValueMap.java 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
-package org.hisp.dhis.dataanalysis;
-
-/*
- * Copyright (c) 2004-${year}, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.HashMap;
-
-import org.hisp.dhis.dataelement.DataElement;
-import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
-import org.hisp.dhis.minmax.MinMaxDataElement;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-
-/**
- * @author Lars Helge Overland
- */
-public class MinMaxValueMap
- extends HashMap<String, MinMaxDataElement>
-{
- /**
- * Determines if a de-serialized file is compatible with this class.
- */
- private static final long serialVersionUID = -6046170950071436264L;
-
- private static final String SEP = "-";
-
- public void put( MinMaxDataElement element )
- {
- final String key = element.getSource().getId() + SEP + element.getDataElement().getId() + SEP + element.getOptionCombo().getId();
-
- super.put( key, element );
- }
-
- public MinMaxDataElement get( OrganisationUnit source, DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo )
- {
- return super.get( source.getId() + SEP + dataElement.getId() + SEP + categoryOptionCombo.getId() );
- }
-}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisService.java 2011-06-12 08:42:59 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisService.java 2012-07-25 13:18:48 +0000
@@ -27,26 +27,31 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import static org.hisp.dhis.system.util.MathUtils.isEqual;
-
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
-import org.hisp.dhis.common.AggregatedValue;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
import org.hisp.dhis.datavalue.DeflatedDataValue;
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;
+import org.hisp.dhis.system.util.MathUtils;
/**
- * @author Dag Haavi Finstad
* @author Lars Helge Overland
*/
public class StdDevOutlierAnalysisService
implements DataAnalysisService
{
+ private static final Log log = LogFactory.getLog( StdDevOutlierAnalysisService.class );
+
// -------------------------------------------------------------------------
// Dependencies
// -------------------------------------------------------------------------
@@ -58,23 +63,17 @@
this.dataAnalysisStore = dataAnalysisStore;
}
- private OrganisationUnitService organisationUnitService;
-
- public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
- {
- this.organisationUnitService = organisationUnitService;
- }
-
- // -------------------------------------------------------------------------
- // OutlierAnalysisService implementation
- // -------------------------------------------------------------------------
-
- public final Collection<DeflatedDataValue> analyse( OrganisationUnit organisationUnit,
+ // -------------------------------------------------------------------------
+ // DataAnalysisService implementation
+ // -------------------------------------------------------------------------
+
+ public final Collection<DeflatedDataValue> analyse( Collection<OrganisationUnit> organisationUnits,
Collection<DataElement> dataElements, Collection<Period> periods, Double stdDevFactor )
{
- Collection<OrganisationUnit> units = organisationUnitService.getOrganisationUnitWithChildren( organisationUnit
- .getId() );
+ Set<Integer> units = new HashSet<Integer>( ConversionUtils.getIdentifiers( OrganisationUnit.class, organisationUnits ) );
+ log.info( "Starting std dev analysis, no of org units: " + organisationUnits.size() + ", factor: " + stdDevFactor );
+
Collection<DeflatedDataValue> outlierCollection = new ArrayList<DeflatedDataValue>();
loop : for ( DataElement dataElement : dataElements )
@@ -88,43 +87,36 @@
for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryOptionCombos )
{
- for ( OrganisationUnit unit : units )
+ Map<Integer, Double> standardDeviations = dataAnalysisStore.getStandardDeviation( dataElement, categoryOptionCombo, units );
+
+ Map<Integer, Double> averages = dataAnalysisStore.getAverage( dataElement, categoryOptionCombo, standardDeviations.keySet() );
+
+ Map<Integer, Integer> lowBoundMap = new HashMap<Integer, Integer>();
+ Map<Integer, Integer> highBoundMap = new HashMap<Integer, Integer>();
+
+ for ( Integer unit : averages.keySet() )
{
- outlierCollection.addAll( findOutliers( unit, dataElement, categoryOptionCombo, periods,
- stdDevFactor ) );
+ Double stdDev = standardDeviations.get( unit );
+ Double avg = averages.get( unit );
- if ( outlierCollection.size() > MAX_OUTLIERS )
+ if ( stdDev != null && avg != null )
{
- break loop;
+ lowBoundMap.put( unit, (int) MathUtils.getLowBound( stdDev, stdDevFactor, avg ) );
+ highBoundMap.put( unit, (int) MathUtils.getHighBound( stdDev, stdDevFactor, avg ) );
}
}
+
+ outlierCollection.addAll( dataAnalysisStore.getDeflatedDataValues( dataElement, categoryOptionCombo, periods,
+ lowBoundMap, highBoundMap ) );
+
+ if ( outlierCollection.size() > MAX_OUTLIERS )
+ {
+ break loop;
+ }
}
}
}
return outlierCollection;
}
-
- // -------------------------------------------------------------------------
- // Supportive methods
- // -------------------------------------------------------------------------
-
- private Collection<DeflatedDataValue> findOutliers( OrganisationUnit organisationUnit, DataElement dataElement,
- DataElementCategoryOptionCombo categoryOptionCombo, Collection<Period> periods, Double stdDevFactor )
- {
- Double stdDev = dataAnalysisStore.getStandardDeviation( dataElement, categoryOptionCombo, organisationUnit );
-
- if ( !isEqual( stdDev, AggregatedValue.ZERO ) ) // No values found or no outliers exist when 0.0
- {
- Double avg = dataAnalysisStore.getAverage( dataElement, categoryOptionCombo, organisationUnit );
-
- double deviation = stdDev * stdDevFactor;
- Double lowerBound = avg - deviation;
- Double upperBound = avg + deviation;
- return dataAnalysisStore.getDeflatedDataValues( dataElement, categoryOptionCombo, periods,
- organisationUnit, lowerBound.intValue(), upperBound.intValue() );
- }
-
- return new ArrayList<DeflatedDataValue>();
- }
}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/jdbc/JdbcDataAnalysisStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/jdbc/JdbcDataAnalysisStore.java 2012-07-23 12:33:49 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataanalysis/jdbc/JdbcDataAnalysisStore.java 2012-07-25 13:18:48 +0000
@@ -27,13 +27,17 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import java.sql.ResultSet;
-import java.sql.SQLException;
+import static org.hisp.dhis.common.AggregatedValue.ZERO;
+import static org.hisp.dhis.system.util.ConversionUtils.getIdentifiers;
+import static org.hisp.dhis.system.util.MathUtils.isEqual;
+import static org.hisp.dhis.system.util.TextUtils.getCommaDelimitedString;
+
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
-import org.amplecode.quick.StatementHolder;
-import org.amplecode.quick.StatementManager;
-import org.amplecode.quick.mapper.ObjectMapper;
import org.hisp.dhis.dataanalysis.DataAnalysisStore;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -45,6 +49,7 @@
import org.hisp.dhis.system.util.ConversionUtils;
import org.hisp.dhis.system.util.TextUtils;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.rowset.SqlRowSet;
/**
* @author Lars Helge Overland
@@ -56,13 +61,6 @@
// Dependencies
// -------------------------------------------------------------------------
- private StatementManager statementManager;
-
- public void setStatementManager( StatementManager statementManager )
- {
- this.statementManager = statementManager;
- }
-
private StatementBuilder statementBuilder;
public void setStatementBuilder( StatementBuilder statementBuilder )
@@ -81,63 +79,156 @@
// OutlierAnalysisStore implementation
// -------------------------------------------------------------------------
- public Double getStandardDeviation( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, OrganisationUnit organisationUnit )
- {
- final String sql = statementBuilder.getStandardDeviation( dataElement.getId(), categoryOptionCombo.getId(), organisationUnit.getId() );
-
- return statementManager.getHolder().queryForDouble( sql );
- }
-
- public Double getAverage( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, OrganisationUnit organisationUnit )
- {
- final String sql = statementBuilder.getAverage( dataElement.getId(), categoryOptionCombo.getId(), organisationUnit.getId() );
-
- return statementManager.getHolder().queryForDouble( sql );
+ public Map<Integer, Double> getStandardDeviation( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Set<Integer> organisationUnits )
+ {
+ final String sql =
+ "select ou.organisationunitid, " +
+ "(select stddev_pop( cast( value as " + statementBuilder.getDoubleColumnType() + " ) ) " +
+ "from datavalue where dataelementid = " + dataElement.getId() + " " +
+ "and categoryoptioncomboid = " + categoryOptionCombo.getId() + " " +
+ "and sourceid = ou.organisationunitid) as deviation " +
+ "from organisationunit ou " +
+ "where ou.organisationunitid in (" + getCommaDelimitedString( organisationUnits ) + ")";
+
+ Map<Integer, Double> map = new HashMap<Integer, Double>();
+
+ SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
+
+ while ( rowSet.next() )
+ {
+ Object stdDev = rowSet.getObject( "deviation" );
+
+ if ( stdDev != null && !isEqual( (Double) stdDev, ZERO ) )
+ {
+ map.put( rowSet.getInt( "organisationunitid" ), (Double) stdDev );
+ }
+ }
+
+ return map;
+ }
+
+ public Map<Integer, Double> getAverage( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo, Set<Integer> organisationUnits )
+ {
+ final String sql =
+ "select ou.organisationunitid, " +
+ "(select avg( cast( value as " + statementBuilder.getDoubleColumnType() + " ) ) " +
+ "from datavalue where dataelementid = " + dataElement.getId() + " " +
+ "and categoryoptioncomboid = " + categoryOptionCombo.getId() + " " +
+ "and sourceid = ou.organisationunitid) as average " +
+ "from organisationunit ou " +
+ "where ou.organisationunitid in (" + getCommaDelimitedString( organisationUnits ) + ")";
+
+ Map<Integer, Double> map = new HashMap<Integer, Double>();
+
+ SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
+
+ while ( rowSet.next() )
+ {
+ Object avg = rowSet.getObject( "average" );
+
+ if ( avg != null )
+ {
+ map.put( rowSet.getInt( "organisationunitid" ), (Double) avg );
+ }
+ }
+
+ return map;
+ }
+
+ public Collection<DeflatedDataValue> getMinMaxViolations( Collection<DataElement> dataElements, Collection<DataElementCategoryOptionCombo> categoryOptionCombos,
+ Collection<Period> periods, Collection<OrganisationUnit> organisationUnits, int limit )
+ {
+ String dataElementIds = getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) );
+ String organisationUnitIds = getCommaDelimitedString( getIdentifiers( OrganisationUnit.class, organisationUnits ) );
+ String periodIds = getCommaDelimitedString( getIdentifiers( Period.class, periods ) );
+ String categoryOptionComboIds = getCommaDelimitedString( getIdentifiers( DataElementCategoryOptionCombo.class, categoryOptionCombos ) );
+
+ Map<Integer, String> optionComboMap = getCategoryOptionComboMap( categoryOptionCombos );
+
+ //TODO persist name on category option combo and use join to improve performance
+
+ String sql =
+ "select dv.dataelementid, dv.periodid, dv.sourceid, dv.categoryoptioncomboid, dv.value, dv.storedby, dv.lastupdated, " +
+ "dv.comment, dv.followup, ou.name as sourcename, de.name as dataelementname, pt.name as periodtypename, pe.startdate, pe.enddate, mm.minvalue, mm.maxvalue " +
+ "from datavalue dv " +
+ "join minmaxdataelement mm on ( dv.dataelementid = mm.dataelementid and dv.categoryoptioncomboid = mm.categoryoptioncomboid and dv.sourceid = mm.sourceid ) " +
+ "join dataelement de on dv.dataelementid = de.dataelementid " +
+ "join period pe on dv.periodid = pe.periodid " +
+ "join periodtype pt on pe.periodtypeid = pt.periodtypeid " +
+ "join organisationunit ou on dv.sourceid = ou.organisationunitid " +
+ "where dv.dataelementid in (" + dataElementIds + ") " +
+ "and dv.categoryoptioncomboid in (" + categoryOptionComboIds + ") " +
+ "and dv.periodid in (" + periodIds + ") " +
+ "and dv.sourceid in (" + organisationUnitIds + ") and ( " +
+ "cast( dv.value as " + statementBuilder.getDoubleColumnType() + " ) < mm.minvalue " +
+ "or cast( dv.value as " + statementBuilder.getDoubleColumnType() + " ) > mm.maxvalue )" +
+ statementBuilder.limitRecord( 0, limit );
+
+ return jdbcTemplate.query( sql, new DeflatedDataValueNameMinMaxRowMapper( null, null, optionComboMap ) );
}
public Collection<DeflatedDataValue> getDeflatedDataValues( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo,
- Collection<Period> periods, OrganisationUnit organisationUnit, int lowerBound, int upperBound )
+ Collection<Period> periods, Map<Integer, Integer> lowerBoundMap, Map<Integer, Integer> upperBoundMap )
{
- final StatementHolder holder = statementManager.getHolder();
-
- final ObjectMapper<DeflatedDataValue> mapper = new ObjectMapper<DeflatedDataValue>();
-
- final String periodIds = TextUtils.getCommaDelimitedString( ConversionUtils.getIdentifiers( Period.class, periods ) );
-
- final String sql = statementBuilder.getDeflatedDataValues( dataElement.getId(), dataElement.getName(), categoryOptionCombo.getId(),
- periodIds, organisationUnit.getId(), organisationUnit.getName(), lowerBound, upperBound );
-
- try
- {
- final ResultSet resultSet = holder.getStatement().executeQuery( sql );
-
- return mapper.getCollection( resultSet, new DeflatedDataValueNameMinMaxRowMapper() );
- }
- catch ( SQLException ex )
- {
- throw new RuntimeException( "Failed to get deflated data values", ex );
- }
- finally
- {
- holder.close();
- }
+ if ( lowerBoundMap == null || lowerBoundMap.isEmpty() )
+ {
+ return new HashSet<DeflatedDataValue>();
+ }
+
+ String periodIds = TextUtils.getCommaDelimitedString( ConversionUtils.getIdentifiers( Period.class, periods ) );
+
+ String sql =
+ "select dv.dataelementid, dv.periodid, dv.sourceid, dv.categoryoptioncomboid, dv.value, dv.storedby, dv.lastupdated, " +
+ "dv.comment, dv.followup, ou.name as sourcename, " +
+ "'" + dataElement.getName() + "' as dataelementname, pt.name as periodtypename, pe.startdate, pe.enddate, " +
+ "'" + categoryOptionCombo.getName() + "' as categoryoptioncomboname " +
+ "from datavalue dv " +
+ "join period pe on dv.periodid = pe.periodid " +
+ "join periodtype pt on pe.periodtypeid = pt.periodtypeid " +
+ "join organisationunit ou on dv.sourceid = ou.organisationunitid " +
+ "where dv.dataelementid = " + dataElement.getId() + " " +
+ "and dv.categoryoptioncomboid = " + categoryOptionCombo.getId() + " " +
+ "and dv.periodid in (" + periodIds + ") and ( ";
+
+ for ( Integer organisationUnit : lowerBoundMap.keySet() )
+ {
+ sql += "( dv.sourceid = " + organisationUnit + " " +
+ "and ( cast( dv.value as " + statementBuilder.getDoubleColumnType() + " ) < " + lowerBoundMap.get( organisationUnit ) + " " +
+ "or cast( dv.value as " + statementBuilder.getDoubleColumnType() + " ) > " + upperBoundMap.get( organisationUnit ) + " ) ) or ";
+ }
+
+ sql = sql.substring( 0, ( sql.length() - 3 ) ) + " )";
+
+ return jdbcTemplate.query( sql, new DeflatedDataValueNameMinMaxRowMapper( lowerBoundMap, upperBoundMap, null ) );
}
public Collection<DeflatedDataValue> getDataValuesMarkedForFollowup()
{
final String sql =
- "SELECT dv.dataelementid, dv.periodid, dv.sourceid, dv.categoryoptioncomboid, dv.value, " +
- "dv.storedby, dv.lastupdated, dv.comment, dv.followup, mm.minvalue, mm.maxvalue, de.name AS dataelementname, " +
+ "select dv.dataelementid, dv.periodid, dv.sourceid, dv.categoryoptioncomboid, dv.value, " +
+ "dv.storedby, dv.lastupdated, dv.comment, dv.followup, mm.minvalue, mm.maxvalue, de.name as dataelementname, " +
"pe.startdate, pe.enddate, pt.name AS periodtypename, ou.name AS sourcename, cc.categoryoptioncomboname " +
- "FROM datavalue AS dv " +
- "LEFT JOIN minmaxdataelement AS mm ON (dv.sourceid = mm.sourceid AND dv.dataelementid = mm.dataelementid AND dv.categoryoptioncomboid = mm.categoryoptioncomboid) " +
- "JOIN dataelement AS de ON (dv.dataelementid = de.dataelementid) " +
- "JOIN period AS pe ON (dv.periodid = pe.periodid) " +
- "JOIN periodtype AS pt ON (pe.periodtypeid = pt.periodtypeid) " +
- "LEFT JOIN organisationunit AS ou ON (ou.organisationunitid = dv.sourceid) " +
- "LEFT JOIN _categoryoptioncomboname AS cc ON (dv.categoryoptioncomboid = cc.categoryoptioncomboid) " +
- "WHERE dv.followup=true";
+ "from datavalue dv " +
+ "left join minmaxdataelement mm on (dv.sourceid = mm.sourceid and dv.dataelementid = mm.dataelementid and dv.categoryoptioncomboid = mm.categoryoptioncomboid) " +
+ "join dataelement de on dv.dataelementid = de.dataelementid " +
+ "join period pe on dv.periodid = pe.periodid " +
+ "join periodtype pt on pe.periodtypeid = pt.periodtypeid " +
+ "left join organisationunit ou on ou.organisationunitid = dv.sourceid " +
+ "left join _categoryoptioncomboname cc on dv.categoryoptioncomboid = cc.categoryoptioncomboid " +
+ "where dv.followup = true";
return jdbcTemplate.query( sql, new DeflatedDataValueNameMinMaxRowMapper() );
- }
+ }
+
+ private Map<Integer, String> getCategoryOptionComboMap( Collection<DataElementCategoryOptionCombo> categoryOptionCombos )
+ {
+ Map<Integer, String> map = new HashMap<Integer, String>();
+
+ for ( DataElementCategoryOptionCombo coc : categoryOptionCombos )
+ {
+ map.put( coc.getId(), coc.getName() );
+ }
+
+ return map;
+ }
}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java 2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java 2012-07-25 13:18:48 +0000
@@ -501,7 +501,7 @@
updateDataElementCategoryCombo( categoryCombo );
}
-
+
public int getDataElementCategoryCount()
{
return dataElementCategoryStore.getCount();
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/DefaultMinMaxDataElementService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/DefaultMinMaxDataElementService.java 2012-07-01 07:12:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/DefaultMinMaxDataElementService.java 2012-07-25 13:18:48 +0000
@@ -111,4 +111,9 @@
{
minMaxDataElementStore.delete( optionCombo );
}
+
+ public void removeMinMaxDataElements( Collection<DataElement> dataElements, Collection<OrganisationUnit> organisationUnits )
+ {
+ minMaxDataElementStore.delete( dataElements, organisationUnits );
+ }
}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/hibernate/HibernateMinMaxDataElementStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/hibernate/HibernateMinMaxDataElementStore.java 2012-07-01 07:12:58 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/hibernate/HibernateMinMaxDataElementStore.java 2012-07-25 13:18:48 +0000
@@ -101,4 +101,13 @@
getQuery( hql ).setEntity( "optionCombo", optionCombo ).executeUpdate();
}
+
+ public void delete( Collection<DataElement> dataElements, Collection<OrganisationUnit> organisationUnits )
+ {
+ String hql = "delete from MinMaxDataElement m where m.dataElement in (:dataElements) and m.source in (:organisationUnits)";
+
+ getQuery( hql ).
+ setParameterList( "dataElements", dataElements ).
+ setParameterList( "organisationUnits", organisationUnits ).executeUpdate();
+ }
}
=== removed directory 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/validation'
=== removed file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/validation/DefaultMinMaxValuesGenerationService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/validation/DefaultMinMaxValuesGenerationService.java 2011-06-12 08:42:59 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/minmax/validation/DefaultMinMaxValuesGenerationService.java 1970-01-01 00:00:00 +0000
@@ -1,122 +0,0 @@
-package org.hisp.dhis.minmax.validation;
-
-/*
- * Copyright (c) 2004-2009, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import static org.hisp.dhis.system.util.MathUtils.isEqual;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.hisp.dhis.common.AggregatedValue;
-import org.hisp.dhis.dataanalysis.DataAnalysisStore;
-import org.hisp.dhis.dataelement.DataElement;
-import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
-import org.hisp.dhis.datavalue.DeflatedDataValue;
-import org.hisp.dhis.minmax.MinMaxDataElement;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.period.Period;
-
-/**
- * @author Chau Thu Tran
- * @version $Id$
- */
-public class DefaultMinMaxValuesGenerationService
- implements MinMaxValuesGenerationService
-{
- // -------------------------------------------------------------------------
- // Dependency
- // -------------------------------------------------------------------------
-
- private DataAnalysisStore dataAnalysisStore;
-
- public void setDataAnalysisStore( DataAnalysisStore dataAnalysisStore )
- {
- this.dataAnalysisStore = dataAnalysisStore;
- }
-
- // -------------------------------------------------------------------------
- // Action Implementation
- // -------------------------------------------------------------------------
-
- public final Collection<MinMaxDataElement> getMinMaxValues( OrganisationUnit organisationUnit,
- Collection<DataElement> dataElements, Double stdDevFactor )
- {
- Collection<MinMaxDataElement> minMaxDataElements = new ArrayList<MinMaxDataElement>();
-
- for ( DataElement dataElement : dataElements )
- {
- if ( dataElement.getType().equals( DataElement.VALUE_TYPE_INT ) )
- {
- Collection<DataElementCategoryOptionCombo> categoryOptionCombos = dataElement.getCategoryCombo()
- .getOptionCombos();
-
- for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryOptionCombos )
- {
- Double stdDev = dataAnalysisStore.getStandardDeviation( dataElement, categoryOptionCombo,
- organisationUnit );
-
- if ( !isEqual( stdDev, AggregatedValue.ZERO ) ) // No values found or no
- {
- Double avg = dataAnalysisStore.getAverage( dataElement, categoryOptionCombo, organisationUnit );
-
- double deviation = stdDev * stdDevFactor;
- Double lowerBound = avg - deviation;
- Double upperBound = avg + deviation;
-
- MinMaxDataElement minMaxDataElement = new MinMaxDataElement();
- minMaxDataElement.setDataElement( dataElement );
- minMaxDataElement.setOptionCombo( categoryOptionCombo );
- minMaxDataElement.setSource( organisationUnit );
- minMaxDataElement.setMin( lowerBound.intValue() );
- minMaxDataElement.setMax( upperBound.intValue() );
-
- minMaxDataElements.add( minMaxDataElement );
- }
- }
- }
- }
-
- return minMaxDataElements;
- }
-
- public Collection<DeflatedDataValue> findOutliers( OrganisationUnit organisationUnit, Collection<Period> periods,
- Collection<MinMaxDataElement> minMaxDataElements )
- {
- Set<DeflatedDataValue> result = new HashSet<DeflatedDataValue>();
-
- for ( MinMaxDataElement minMaxs : minMaxDataElements )
- {
- result.addAll( dataAnalysisStore.getDeflatedDataValues( minMaxs.getDataElement(), minMaxs.getOptionCombo(),
- periods, organisationUnit, minMaxs.getMin(), minMaxs.getMax() ) );
- }
-
- return result;
- }
-}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java 2012-07-20 11:41:57 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java 2012-07-25 13:18:48 +0000
@@ -27,7 +27,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import static org.hisp.dhis.i18n.I18nUtils.*;
+import static org.hisp.dhis.i18n.I18nUtils.getCountByName;
+import static org.hisp.dhis.i18n.I18nUtils.getObjectsBetween;
+import static org.hisp.dhis.i18n.I18nUtils.getObjectsBetweenByName;
+import static org.hisp.dhis.i18n.I18nUtils.getObjectsByName;
+import static org.hisp.dhis.i18n.I18nUtils.i18n;
import static org.hisp.dhis.system.util.MathUtils.expressionIsTrue;
import static org.hisp.dhis.system.util.MathUtils.getRounded;
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml 2012-07-23 12:33:49 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml 2012-07-25 13:18:48 +0000
@@ -187,8 +187,7 @@
<property name="cacheable" value="true" />
</bean>
- <bean id="org.hisp.dhis.dataanalysis.jdbc.DataAnalysisStore" class="org.hisp.dhis.dataanalysis.jdbc.JdbcDataAnalysisStore">
- <property name="statementManager" ref="statementManager" />
+ <bean id="org.hisp.dhis.dataanalysis.DataAnalysisStore" class="org.hisp.dhis.dataanalysis.jdbc.JdbcDataAnalysisStore">
<property name="statementBuilder" ref="statementBuilder" />
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
@@ -397,18 +396,17 @@
</bean>
<bean id="org.hisp.dhis.dataanalysis.StdDevOutlierAnalysisService" class="org.hisp.dhis.dataanalysis.StdDevOutlierAnalysisService">
- <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
- <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.jdbc.DataAnalysisStore" />
+ <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.DataAnalysisStore" />
</bean>
<bean id="org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService" class="org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService">
- <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
- <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
- <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.jdbc.DataAnalysisStore" />
+ <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.DataAnalysisStore" />
+ <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
+ <property name="batchHandlerFactory" ref="batchHandlerFactory" />
</bean>
<bean id="org.hisp.dhis.dataanalysis.FollowupAnalysisService" class="org.hisp.dhis.dataanalysis.FollowupAnalysisService">
- <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.jdbc.DataAnalysisStore" />
+ <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.DataAnalysisStore" />
</bean>
<bean id="dataAnalysisServiceProvider" class="org.hisp.dhis.common.ServiceProvider">
@@ -876,12 +874,6 @@
</property>
</bean>
- <!-- Min/Max validation -->
-
- <bean id="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" class="org.hisp.dhis.minmax.validation.DefaultMinMaxValuesGenerationService">
- <property name="dataAnalysisStore" ref="org.hisp.dhis.dataanalysis.jdbc.DataAnalysisStore" />
- </bean>
-
<!-- AOP definitions -->
<aop:config>
@@ -906,11 +898,6 @@
<aop:before pointcut="execution( * org.hisp.dhis.attribute.AttributeService.delete*(..) )" method="intercept" />
</aop:aspect>
- <aop:aspect ref="statementInterceptor">
- <aop:around pointcut="execution( * org.hisp.dhis.dataanalysis.DataAnalysisService.analyse(..) )"
- method="intercept" />
- </aop:aspect>
-
<!-- <aop:aspect ref="i18nTranslationInterceptor"> <aop:after-returning pointcut="execution( * org.hisp.dhis.dataelement.DataElementService.get*(..)
)" method="intercept" returning="object"/> <aop:after-returning pointcut="execution( * org.hisp.dhis.dataelement.DataElementCategoryService.get*(..)
)" method="intercept" returning="object"/> <aop:after-returning pointcut="execution( * org.hisp.dhis.indicator.IndicatorService.get*(..)
=== added file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/DataAnalysisStoreTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/DataAnalysisStoreTest.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/DataAnalysisStoreTest.java 2012-07-25 13:18:48 +0000
@@ -0,0 +1,179 @@
+package org.hisp.dhis.dataanalysis;
+
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hisp.dhis.DhisTest;
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.dataelement.DataElementService;
+import org.hisp.dhis.dataset.DataSetService;
+import org.hisp.dhis.datavalue.DataValueService;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.period.MonthlyPeriodType;
+import org.hisp.dhis.period.Period;
+import org.hisp.dhis.period.PeriodService;
+import org.junit.Test;
+
+import static junit.framework.Assert.*;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class DataAnalysisStoreTest
+ extends DhisTest
+{
+ private DataAnalysisStore dataAnalysisStore;
+
+ private DataElement dataElementA;
+ private DataElement dataElementB;
+
+ private DataElementCategoryCombo categoryCombo;
+
+ private DataElementCategoryOptionCombo categoryOptionCombo;
+
+ private Period periodA;
+ private Period periodB;
+ private Period periodC;
+ private Period periodD;
+ private Period periodE;
+ private Period periodF;
+ private Period periodG;
+ private Period periodH;
+ private Period periodI;
+ private Period periodJ;
+
+ private OrganisationUnit organisationUnitA;
+ private OrganisationUnit organisationUnitB;
+
+ private Set<Integer> organisationUnits;
+
+ // ----------------------------------------------------------------------
+ // Fixture
+ // ----------------------------------------------------------------------
+
+ @Override
+ public void setUpTest()
+ {
+ dataAnalysisStore = (DataAnalysisStore) getBean( DataAnalysisStore.ID );
+
+ dataElementService = (DataElementService) getBean( DataElementService.ID );
+
+ categoryService = (DataElementCategoryService) getBean( DataElementCategoryService.ID );
+
+ dataSetService = (DataSetService) getBean( DataSetService.ID );
+
+ organisationUnitService = (OrganisationUnitService) getBean( OrganisationUnitService.ID );
+
+ dataValueService = (DataValueService) getBean( DataValueService.ID );
+
+ periodService = (PeriodService) getBean( PeriodService.ID );
+
+ categoryCombo = categoryService.getDataElementCategoryComboByName( DataElementCategoryCombo.DEFAULT_CATEGORY_COMBO_NAME );
+
+ dataElementA = createDataElement( 'A', categoryCombo );
+ dataElementB = createDataElement( 'B', categoryCombo );
+
+ dataElementService.addDataElement( dataElementA );
+ dataElementService.addDataElement( dataElementB );
+
+ categoryOptionCombo = categoryService.getDefaultDataElementCategoryOptionCombo();
+
+ periodA = createPeriod( new MonthlyPeriodType(), getDate( 2000, 3, 1 ), getDate( 2000, 3, 31 ) );
+ periodB = createPeriod( new MonthlyPeriodType(), getDate( 2000, 4, 1 ), getDate( 2000, 4, 30 ) );
+ periodC = createPeriod( new MonthlyPeriodType(), getDate( 2000, 5, 1 ), getDate( 2000, 5, 30 ) );
+ periodD = createPeriod( new MonthlyPeriodType(), getDate( 2000, 6, 1 ), getDate( 2000, 6, 30 ) );
+ periodE = createPeriod( new MonthlyPeriodType(), getDate( 2000, 7, 1 ), getDate( 2000, 7, 30 ) );
+ periodF = createPeriod( new MonthlyPeriodType(), getDate( 2000, 8, 1 ), getDate( 2000, 8, 30 ) );
+ periodG = createPeriod( new MonthlyPeriodType(), getDate( 2000, 9, 1 ), getDate( 2000, 9, 30 ) );
+ periodH = createPeriod( new MonthlyPeriodType(), getDate( 2000, 10, 1 ), getDate( 2000, 10, 30 ) );
+ periodI = createPeriod( new MonthlyPeriodType(), getDate( 2000, 11, 1 ), getDate( 2000, 11, 30 ) );
+ periodJ = createPeriod( new MonthlyPeriodType(), getDate( 2000, 12, 1 ), getDate( 2000, 12, 30 ) );
+
+ organisationUnitA = createOrganisationUnit( 'A' );
+ organisationUnitB = createOrganisationUnit( 'B' );
+
+ organisationUnitService.addOrganisationUnit( organisationUnitA );
+ organisationUnitService.addOrganisationUnit( organisationUnitB );
+
+ organisationUnits = new HashSet<Integer>();
+ organisationUnits.add( organisationUnitA.getId() );
+ organisationUnits.add( organisationUnitB.getId() );
+ }
+
+ @Override
+ public boolean emptyDatabaseAfterTest()
+ {
+ return true;
+ }
+
+ // ----------------------------------------------------------------------
+ // Business logic tests
+ // ----------------------------------------------------------------------
+
+ @Test
+ public void getGetStdDev()
+ {
+ dataValueService.addDataValue( createDataValue( dataElementA, periodA, organisationUnitA, "5", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodB, organisationUnitA, "2", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodC, organisationUnitA, "1", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodD, organisationUnitA, "12", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodE, organisationUnitA, "10", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodF, organisationUnitA, "7", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodG, organisationUnitA, "52", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodH, organisationUnitA, "23", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodI, organisationUnitA, "3", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodJ, organisationUnitA, "15", categoryOptionCombo ) );
+
+ assertEquals( 14.49, dataAnalysisStore.getStandardDeviation( dataElementA, categoryOptionCombo, organisationUnits ).get( organisationUnitA.getId() ), 0.01 );
+ assertNull( dataAnalysisStore.getStandardDeviation( dataElementA, categoryOptionCombo, organisationUnits ).get( organisationUnitB.getId() ) );
+ }
+
+ @Test
+ public void getGetAvg()
+ {
+ dataValueService.addDataValue( createDataValue( dataElementA, periodA, organisationUnitA, "5", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodB, organisationUnitA, "2", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodC, organisationUnitA, "1", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodD, organisationUnitA, "12", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodE, organisationUnitA, "10", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodF, organisationUnitA, "7", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodG, organisationUnitA, "52", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodH, organisationUnitA, "23", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodI, organisationUnitA, "3", categoryOptionCombo ) );
+ dataValueService.addDataValue( createDataValue( dataElementA, periodJ, organisationUnitA, "15", categoryOptionCombo ) );
+
+ assertEquals( 13, dataAnalysisStore.getAverage( dataElementA, categoryOptionCombo, organisationUnits ).get( organisationUnitA.getId() ), 0.01 );
+ assertNull( dataAnalysisStore.getAverage( dataElementA, categoryOptionCombo, organisationUnits ).get( organisationUnitB.getId() ) );
+ }
+}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisServiceTest.java 2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/MinMaxOutlierAnalysisServiceTest.java 2012-07-25 13:18:48 +0000
@@ -27,6 +27,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import static junit.framework.Assert.assertEquals;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -41,6 +43,7 @@
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;
@@ -48,13 +51,15 @@
import org.hisp.dhis.period.MonthlyPeriodType;
import org.hisp.dhis.period.Period;
import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.system.util.ListUtils;
import org.junit.Test;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.rowset.SqlRowSet;
/**
* @author eirikmi
* @version $Id: MinMaxOutlierAnalysisServiceTest.java 883 2009-05-15 00:42:45Z daghf $
*/
-@SuppressWarnings( "unused" )
public class MinMaxOutlierAnalysisServiceTest
extends DhisTest
{
@@ -93,6 +98,8 @@
private MinMaxDataElement minMaxDataElement;
+ private JdbcTemplate jdbcTemplate;
+
// ----------------------------------------------------------------------
// Fixture
// ----------------------------------------------------------------------
@@ -101,6 +108,8 @@
public void setUpTest()
throws Exception
{
+ jdbcTemplate = (JdbcTemplate) getBean( "jdbcTemplate" );
+
minMaxOutlierAnalysisService = (DataAnalysisService) getBean( "org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService" );
dataElementService = (DataElementService) getBean( DataElementService.ID );
@@ -166,10 +175,6 @@
@Test
public void testGetFindOutliers()
{
- // testvalues = [5, 5, -5, -5, 10, -10, 13, -13, 41, -41]
- // mean(testvalues) = 0.0
- // std(testvalues) = 20.0
-
dataValueA = createDataValue( dataElementA, periodI, organisationUnitA, "41", categoryOptionCombo );
dataValueB = createDataValue( dataElementA, periodJ, organisationUnitA, "-41", categoryOptionCombo );
@@ -188,14 +193,21 @@
minMaxDataElement = new MinMaxDataElement( organisationUnitA, dataElementA, categoryOptionCombo, -40, 40, false );
minMaxDataElementService.addMinMaxDataElement( minMaxDataElement );
+ SqlRowSet rowSet = jdbcTemplate.queryForRowSet( "select mm.minvalue from minmaxdataelement mm" );
+
+ while ( rowSet.next() )
+ {
+ System.out.println( "min value " + rowSet.getInt( "minvalue" ) );
+ }
+
Collection<Period> periods = new ArrayList<Period>();
periods.add( periodI );
periods.add( periodJ );
periods.add( periodA );
periods.add( periodE );
- //Collection<DeflatedDataValue> result = minMaxOutlierAnalysisService.findOutliers( organisationUnitA, dataElementsA, periods, null );
+ Collection<DeflatedDataValue> result = minMaxOutlierAnalysisService.analyse( ListUtils.getCollection( organisationUnitA ), dataElementsA, periods, null );
- //assertEquals( 2, result.size() );
+ assertEquals( 2, result.size() );
}
}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisServiceTest.java 2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataanalysis/StdDevOutlierAnalysisServiceTest.java 2012-07-25 13:18:48 +0000
@@ -27,6 +27,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -41,16 +44,17 @@
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;
import org.hisp.dhis.period.Period;
import org.hisp.dhis.period.PeriodService;
+import org.hisp.dhis.system.util.ListUtils;
import org.junit.Test;
/**
- * @author eirikmi
- * @version $Id: StdDevOutlierAnalysisServiceTest.java 883 2009-05-15 00:42:45Z daghf $
+ * @author Lars Helge Overland
*/
@SuppressWarnings( "unused" )
public class StdDevOutlierAnalysisServiceTest
@@ -84,7 +88,7 @@
private Period periodJ;
private OrganisationUnit organisationUnitA;
-
+
// ----------------------------------------------------------------------
// Fixture
// ----------------------------------------------------------------------
@@ -93,7 +97,7 @@
public void setUpTest()
{
stdDevOutlierAnalysisService = (DataAnalysisService) getBean( "org.hisp.dhis.dataanalysis.StdDevOutlierAnalysisService" );
-
+
dataElementService = (DataElementService) getBean( DataElementService.ID );
categoryService = (DataElementCategoryService) getBean( DataElementCategoryService.ID );
@@ -121,7 +125,7 @@
dataElementsA.add( dataElementA );
dataElementsA.add( dataElementB );
- categoryOptionCombo = categoryCombo.getOptionCombos().iterator().next();
+ categoryOptionCombo = categoryService.getDefaultDataElementCategoryOptionCombo();
periodA = createPeriod( new MonthlyPeriodType(), getDate( 2000, 3, 1 ), getDate( 2000, 3, 31 ) );
periodB = createPeriod( new MonthlyPeriodType(), getDate( 2000, 4, 1 ), getDate( 2000, 4, 30 ) );
@@ -152,10 +156,6 @@
@Test
public void testGetFindOutliers()
{
- // testvalues = [5, 5, -5, -5, 10, -10, 13, -13, 71, -71]
- // mean(testvalues) = 0.0
- // std(testvalues) = 34.51
-
dataValueA = createDataValue( dataElementA, periodI, organisationUnitA, "71", categoryOptionCombo );
dataValueB = createDataValue( dataElementA, periodJ, organisationUnitA, "-71", categoryOptionCombo );
@@ -177,11 +177,16 @@
periods.add( periodA );
periods.add( periodE );
- //Collection<DeflatedDataValue> result = stdDevOutlierAnalysisService.findOutliers( organisationUnitA, dataElementsA, periods, stdDevFactor );
-
- //double lowerBound = -34.51 * stdDevFactor;
- //double upperBound = 34.51 * stdDevFactor;
+ Collection<DeflatedDataValue> values = stdDevOutlierAnalysisService.analyse( ListUtils.getCollection( organisationUnitA ), dataElementsA, periods, stdDevFactor );
+
+ double lowerBound = -34.51 * stdDevFactor;
+ double upperBound = 34.51 * stdDevFactor;
+
+ DeflatedDataValue valueA = new DeflatedDataValue( dataValueA );
+ DeflatedDataValue valueB = new DeflatedDataValue( dataValueB );
- //assertEquals( 2, result.size() );
+ assertEquals( 2, values.size() );
+ assertTrue( values.contains( valueA ) );
+ assertTrue( values.contains( valueB ) );
}
}
=== added file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/batchhandler/MinMaxDataElementBatchHandler.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/batchhandler/MinMaxDataElementBatchHandler.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/batchhandler/MinMaxDataElementBatchHandler.java 2012-07-25 13:18:48 +0000
@@ -0,0 +1,110 @@
+package org.hisp.dhis.jdbc.batchhandler;
+
+/*
+ * Copyright (c) 2004-${year}, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.amplecode.quick.JdbcConfiguration;
+import org.amplecode.quick.batchhandler.AbstractBatchHandler;
+import org.hisp.dhis.minmax.MinMaxDataElement;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class MinMaxDataElementBatchHandler
+ extends AbstractBatchHandler<MinMaxDataElement>
+{
+ // -------------------------------------------------------------------------
+ // Constructor
+ // -------------------------------------------------------------------------
+
+ public MinMaxDataElementBatchHandler( JdbcConfiguration config )
+ {
+ super( config, false, true );
+ }
+
+ @Override
+ protected void setTableName()
+ {
+ statementBuilder.setTableName( "minmaxdataelement" );
+ }
+
+ @Override
+ protected void setAutoIncrementColumn()
+ {
+ statementBuilder.setAutoIncrementColumn( "minmaxdataelementid" );
+ }
+
+ @Override
+ protected void setIdentifierColumns()
+ {
+ statementBuilder.setIdentifierColumn( "minmaxdataelementid" );
+ }
+
+ @Override
+ protected void setIdentifierValues( MinMaxDataElement dataElement )
+ {
+ statementBuilder.setIdentifierValue( dataElement.getId() );
+ }
+
+ @Override
+ protected void setUniqueColumns()
+ {
+ statementBuilder.setUniqueColumn( "sourceid" );
+ statementBuilder.setUniqueColumn( "dataelementid" );
+ statementBuilder.setUniqueColumn( "categoryoptioncomboid" );
+ }
+
+ @Override
+ protected void setUniqueValues( MinMaxDataElement dataElement )
+ {
+ statementBuilder.setUniqueValue( dataElement.getSource().getId() );
+ statementBuilder.setUniqueValue( dataElement.getDataElement().getId() );
+ statementBuilder.setUniqueValue( dataElement.getOptionCombo().getId() );
+ }
+
+ @Override
+ protected void setColumns()
+ {
+ statementBuilder.setColumn( "sourceid" );
+ statementBuilder.setColumn( "dataelementid" );
+ statementBuilder.setColumn( "categoryoptioncomboid" );
+ statementBuilder.setColumn( "minvalue" );
+ statementBuilder.setColumn( "maxvalue" );
+ statementBuilder.setColumn( "generated" );
+ }
+
+ @Override
+ protected void setValues( MinMaxDataElement dataElement )
+ {
+ statementBuilder.setValue( dataElement.getSource().getId() );
+ statementBuilder.setValue( dataElement.getDataElement().getId() );
+ statementBuilder.setValue( dataElement.getOptionCombo().getId() );
+ statementBuilder.setValue( dataElement.getMin() );
+ statementBuilder.setValue( dataElement.getMax() );
+ statementBuilder.setValue( dataElement.isGenerated() );
+ }
+}
=== modified file 'dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java'
--- dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java 2012-07-23 12:56:20 +0000
+++ dhis-2/dhis-support/dhis-support-jdbc/src/main/java/org/hisp/dhis/jdbc/statementbuilder/MySQLStatementBuilder.java 2012-07-25 13:18:48 +0000
@@ -102,7 +102,6 @@
+ destDataElementId + ", d1.categoryoptioncomboid = " + destCategoryOptionComboId
+ " WHERE d1.dataelementid = " + sourceDataElementId + " AND d1.categoryoptioncomboid = "
+ sourceCategoryOptionComboId + " AND d2.dataelementid IS NULL";
-
}
@Override
=== added file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/filter/DataElementTypeFilter.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/filter/DataElementTypeFilter.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/filter/DataElementTypeFilter.java 2012-07-25 13:18:48 +0000
@@ -0,0 +1,50 @@
+package org.hisp.dhis.system.filter;
+
+/*
+ * Copyright (c) 2004-${year}, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.system.util.Filter;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class DataElementTypeFilter
+ implements Filter<DataElement>
+{
+ private String type;
+
+ public DataElementTypeFilter( String type )
+ {
+ this.type = type;
+ }
+
+ public boolean retain( DataElement object )
+ {
+ return object != null && type.equals( object.getType() );
+ }
+}
=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/objectmapper/DeflatedDataValueNameMinMaxRowMapper.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/objectmapper/DeflatedDataValueNameMinMaxRowMapper.java 2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/objectmapper/DeflatedDataValueNameMinMaxRowMapper.java 2012-07-25 13:18:48 +0000
@@ -29,6 +29,7 @@
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Map;
import org.amplecode.quick.mapper.RowMapper;
import org.hisp.dhis.datavalue.DeflatedDataValue;
@@ -61,6 +62,21 @@
public class DeflatedDataValueNameMinMaxRowMapper
implements RowMapper<DeflatedDataValue>, org.springframework.jdbc.core.RowMapper<DeflatedDataValue>
{
+ private Map<Integer, Integer> minMap;
+ private Map<Integer, Integer> maxMap;
+ private Map<Integer, String> optionComboMap;
+
+ public DeflatedDataValueNameMinMaxRowMapper()
+ {
+ }
+
+ public DeflatedDataValueNameMinMaxRowMapper( Map<Integer, Integer> minMap, Map<Integer, Integer> maxMap, Map<Integer, String> optionComboMap )
+ {
+ this.minMap = minMap;
+ this.maxMap = maxMap;
+ this.optionComboMap = optionComboMap;
+ }
+
public DeflatedDataValue mapRow( ResultSet resultSet )
throws SQLException
{
@@ -75,15 +91,15 @@
value.setTimestamp( resultSet.getDate( "lastupdated" ) );
value.setComment( resultSet.getString( "comment" ) );
value.setFollowup( resultSet.getBoolean( "followup" ) );
- value.setMin( resultSet.getInt( "minvalue" ) );
- value.setMax( resultSet.getInt( "maxvalue" ) );
+ value.setMin( minMap != null ? minMap.get( value.getSourceId() ) : resultSet.getInt( "minvalue" ) );
+ value.setMax( maxMap != null ? maxMap.get( value.getSourceId() ) : resultSet.getInt( "maxvalue" ) );
value.setDataElementName( resultSet.getString( "dataelementname" ) );
value.setPeriod(
resultSet.getString( "periodtypename" ),
resultSet.getString( "startdate" ),
resultSet.getString( "enddate" ) );
value.setSourceName( resultSet.getString( "sourcename" ) );
- value.setCategoryOptionComboName( resultSet.getString( "categoryoptioncomboname" ) );
+ value.setCategoryOptionComboName( optionComboMap != null ? optionComboMap.get( value.getCategoryOptionComboId() ) : resultSet.getString( "categoryoptioncomboname" ) );
return value;
}
=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java 2012-07-20 11:41:57 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java 2012-07-25 13:18:48 +0000
@@ -339,4 +339,34 @@
return null;
}
}
+
+ /**
+ * Returns the lower bound for the given standard deviation, number of standard
+ * deviations and average.
+ *
+ * @param stdDev the standard deviation.
+ * @param stdDevNo the number of standard deviations.
+ * @param average the average.
+ * @return a double.
+ */
+ public static double getLowBound( double stdDev, double stdDevNo, double average )
+ {
+ double deviation = stdDev * stdDevNo;
+ return average - deviation;
+ }
+
+ /**
+ * Returns the high bound for the given standard deviation, number of standard
+ * deviations and average.
+ *
+ * @param stdDev the standard deviation.
+ * @param stdDevNo the number of standard deviations.
+ * @param average the average.
+ * @return a double.
+ */
+ public static double getHighBound( double stdDev, double stdDevFactor, double average )
+ {
+ double deviation = stdDev * stdDevFactor;
+ return average + deviation;
+ }
}
=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java 2012-02-16 19:58:55 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java 2012-07-25 13:18:48 +0000
@@ -27,8 +27,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import com.opensymphony.xwork2.Action;
-import org.apache.commons.collections.CollectionUtils;
+import static org.hisp.dhis.system.util.ListUtils.getCollection;
+
+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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hisp.dhis.dataanalysis.DataAnalysisService;
@@ -36,21 +43,16 @@
import org.hisp.dhis.dataset.DataSetService;
import org.hisp.dhis.datavalue.DeflatedDataValue;
import org.hisp.dhis.expression.ExpressionService;
-import org.hisp.dhis.minmax.MinMaxDataElement;
-import org.hisp.dhis.minmax.MinMaxDataElementService;
-import org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService;
import org.hisp.dhis.organisationunit.OrganisationUnit;
import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.period.Period;
import org.hisp.dhis.period.PeriodService;
import org.hisp.dhis.period.PeriodType;
-import org.hisp.dhis.setting.SystemSettingManager;
-import org.hisp.dhis.system.util.ListUtils;
import org.hisp.dhis.validation.ValidationResult;
import org.hisp.dhis.validation.ValidationRule;
import org.hisp.dhis.validation.ValidationRuleService;
-import java.util.*;
+import com.opensymphony.xwork2.Action;
/**
* @author Margrethe Store
@@ -86,13 +88,6 @@
this.periodService = periodService;
}
- private DataAnalysisService stdDevOutlierAnalysisService;
-
- public void setStdDevOutlierAnalysisService( DataAnalysisService stdDevOutlierAnalysisService )
- {
- this.stdDevOutlierAnalysisService = stdDevOutlierAnalysisService;
- }
-
private DataAnalysisService minMaxOutlierAnalysisService;
public void setMinMaxOutlierAnalysisService( DataAnalysisService minMaxOutlierAnalysisService )
@@ -100,27 +95,6 @@
this.minMaxOutlierAnalysisService = minMaxOutlierAnalysisService;
}
- private SystemSettingManager systemSettingManager;
-
- public void setSystemSettingManager( SystemSettingManager systemSettingManager )
- {
- this.systemSettingManager = systemSettingManager;
- }
-
- private MinMaxValuesGenerationService minMaxValuesGenerationService;
-
- public void setMinMaxValuesGenerationService( MinMaxValuesGenerationService minMaxValuesGenerationService )
- {
- this.minMaxValuesGenerationService = minMaxValuesGenerationService;
- }
-
- private MinMaxDataElementService minMaxDataElementService;
-
- public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
- {
- this.minMaxDataElementService = minMaxDataElementService;
- }
-
private DataSetService dataSetService;
public void setDataSetService( DataSetService dataSetService )
@@ -196,7 +170,6 @@
// Action implementation
// -------------------------------------------------------------------------
- @SuppressWarnings( "unchecked" )
public String execute()
throws Exception
{
@@ -215,28 +188,8 @@
// Min-max and outlier analysis
// ---------------------------------------------------------------------
- Collection<MinMaxDataElement> minmaxs = minMaxDataElementService.getMinMaxDataElements( orgUnit,
- dataSet.getDataElements() );
-
- if ( minmaxs == null )
- {
- Double factor = (Double) systemSettingManager.getSystemSetting(
- SystemSettingManager.KEY_FACTOR_OF_DEVIATION, 2.0 );
-
- Collection<DeflatedDataValue> stdDevs = stdDevOutlierAnalysisService.analyse( orgUnit,
- dataSet.getDataElements(), ListUtils.getCollection( period ), factor );
-
- Collection<DeflatedDataValue> minMaxs = minMaxOutlierAnalysisService.analyse( orgUnit,
- dataSet.getDataElements(), ListUtils.getCollection( period ), null );
-
- dataValues = CollectionUtils.union( stdDevs, minMaxs );
- }
- else
- {
- dataValues = minMaxValuesGenerationService.findOutliers( orgUnit, ListUtils.getCollection( period ),
- minmaxs );
- }
-
+ dataValues = minMaxOutlierAnalysisService.analyse( getCollection( orgUnit ), dataSet.getDataElements(), getCollection( period ), null );
+
log.debug( "Number of outlier values: " + dataValues.size() );
// ---------------------------------------------------------------------
=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml 2012-02-21 18:45:10 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml 2012-07-25 13:18:48 +0000
@@ -105,12 +105,7 @@
<property name="validationRuleService" ref="org.hisp.dhis.validation.ValidationRuleService" />
<property name="expressionService" ref="org.hisp.dhis.expression.ExpressionService" />
<property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
- <property name="stdDevOutlierAnalysisService" ref="org.hisp.dhis.dataanalysis.StdDevOutlierAnalysisService" />
<property name="minMaxOutlierAnalysisService" ref="org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService" />
- <property name="minMaxValuesGenerationService"
- ref="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" />
- <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
- <property name="systemSettingManager" ref="org.hisp.dhis.setting.SystemSettingManager" />
<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
<property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
</bean>
=== modified file 'dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/utils/FormUtils.java'
--- dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/utils/FormUtils.java 2012-04-11 09:59:20 +0000
+++ dhis-2/dhis-web/dhis-web-light/src/main/java/org/hisp/dhis/light/utils/FormUtils.java 2012-07-25 13:18:48 +0000
@@ -47,14 +47,11 @@
import org.hisp.dhis.datavalue.DataValueService;
import org.hisp.dhis.datavalue.DeflatedDataValue;
import org.hisp.dhis.expression.ExpressionService;
-import org.hisp.dhis.minmax.MinMaxDataElement;
-import org.hisp.dhis.minmax.MinMaxDataElementService;
-import org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService;
-import org.hisp.dhis.setting.SystemSettingManager;
import org.hisp.dhis.organisationunit.OrganisationUnit;
import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.period.CalendarPeriodType;
import org.hisp.dhis.period.Period;
+import org.hisp.dhis.setting.SystemSettingManager;
import org.hisp.dhis.system.filter.OrganisationUnitWithDataSetsFilter;
import org.hisp.dhis.system.filter.PastAndCurrentPeriodFilter;
import org.hisp.dhis.system.util.FilterUtils;
@@ -128,20 +125,6 @@
this.systemSettingManager = systemSettingManager;
}
- private MinMaxValuesGenerationService minMaxValuesGenerationService;
-
- public void setMinMaxValuesGenerationService( MinMaxValuesGenerationService minMaxValuesGenerationService )
- {
- this.minMaxValuesGenerationService = minMaxValuesGenerationService;
- }
-
- private MinMaxDataElementService minMaxDataElementService;
-
- public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
- {
- this.minMaxDataElementService = minMaxDataElementService;
- }
-
private ValidationRuleService validationRuleService;
public void setValidationRuleService( ValidationRuleService validationRuleService )
@@ -166,29 +149,17 @@
{
Map<String, DeflatedDataValue> validationErrorMap = new HashMap<String, DeflatedDataValue>();
- Collection<MinMaxDataElement> minmaxs = minMaxDataElementService.getMinMaxDataElements( organisationUnit,
- dataElements );
- Collection<DeflatedDataValue> deflatedDataValues;
-
- if ( minmaxs == null )
- {
- Double factor = (Double) systemSettingManager.getSystemSetting(
- SystemSettingManager.KEY_FACTOR_OF_DEVIATION, 2.0 );
-
- Collection<DeflatedDataValue> stdDevs = stdDevOutlierAnalysisService.analyse( organisationUnit,
- dataElements, ListUtils.getCollection( period ), factor );
-
- Collection<DeflatedDataValue> minMaxs = minMaxOutlierAnalysisService.analyse( organisationUnit,
- dataElements, ListUtils.getCollection( period ), null );
-
- deflatedDataValues = CollectionUtils.union( stdDevs, minMaxs );
- }
- else
- {
- deflatedDataValues = minMaxValuesGenerationService.findOutliers( organisationUnit,
- ListUtils.getCollection( period ), minmaxs );
- }
-
+ Double factor = (Double) systemSettingManager.getSystemSetting(
+ SystemSettingManager.KEY_FACTOR_OF_DEVIATION, 2.0 );
+
+ Collection<DeflatedDataValue> stdDevs = stdDevOutlierAnalysisService.analyse( ListUtils.getCollection( organisationUnit ),
+ dataElements, ListUtils.getCollection( period ), factor );
+
+ Collection<DeflatedDataValue> minMaxs = minMaxOutlierAnalysisService.analyse( ListUtils.getCollection( organisationUnit ),
+ dataElements, ListUtils.getCollection( period ), null );
+
+ Collection<DeflatedDataValue> deflatedDataValues = CollectionUtils.union( stdDevs, minMaxs );
+
for ( DeflatedDataValue deflatedDataValue : deflatedDataValues )
{
String key = String.format( "DE%dOC%d", deflatedDataValue.getDataElementId(),
=== modified file 'dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml 2012-07-23 09:58:04 +0000
+++ dhis-2/dhis-web/dhis-web-light/src/main/resources/META-INF/dhis/beans.xml 2012-07-25 13:18:48 +0000
@@ -28,10 +28,6 @@
ref="org.hisp.dhis.dataanalysis.StdDevOutlierAnalysisService" />
<property name="minMaxOutlierAnalysisService"
ref="org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService" />
- <property name="minMaxValuesGenerationService"
- ref="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" />
- <property name="minMaxDataElementService"
- ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
<property name="systemSettingManager" ref="org.hisp.dhis.setting.SystemSettingManager" />
<property name="validationRuleService"
ref="org.hisp.dhis.validation.ValidationRuleService" />
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GenerateMinMaxValuesAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GenerateMinMaxValuesAction.java 2012-05-17 16:47:13 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GenerateMinMaxValuesAction.java 2012-07-25 13:18:48 +0000
@@ -28,16 +28,18 @@
*/
import java.util.Collection;
+import java.util.HashSet;
+import org.hisp.dhis.dataanalysis.MinMaxDataAnalysisService;
+import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataset.DataSet;
import org.hisp.dhis.dataset.DataSetService;
import org.hisp.dhis.i18n.I18n;
-import org.hisp.dhis.minmax.MinMaxDataElement;
import org.hisp.dhis.minmax.MinMaxDataElementService;
-import org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService;
-import org.hisp.dhis.setting.SystemSettingManager;
import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.oust.manager.SelectionTreeManager;
+import org.hisp.dhis.setting.SystemSettingManager;
import com.opensymphony.xwork2.Action;
@@ -53,73 +55,82 @@
private DataSetService dataSetService;
- private MinMaxValuesGenerationService minMaxValuesGenerationService;
-
- private MinMaxDataElementService minMaxDataElementService;
-
- private SystemSettingManager systemSettingManager;
-
- private SelectionTreeManager selectionTreeManager;
-
- // -------------------------------------------------------------------------------------------------
- // Input
- // -------------------------------------------------------------------------------------------------
-
- private Integer[] dataSets;
-
- private String message;
-
- private I18n i18n;
-
- // -------------------------------------------------------------------------------------------------
- // Setters
- // -------------------------------------------------------------------------------------------------
-
public void setDataSetService( DataSetService dataSetService )
{
this.dataSetService = dataSetService;
}
- public void setMinMaxValuesGenerationService( MinMaxValuesGenerationService minMaxValuesGenerationService )
- {
- this.minMaxValuesGenerationService = minMaxValuesGenerationService;
- }
-
- public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
- {
- this.minMaxDataElementService = minMaxDataElementService;
- }
+ private SystemSettingManager systemSettingManager;
public void setSystemSettingManager( SystemSettingManager systemSettingManager )
{
this.systemSettingManager = systemSettingManager;
}
+
+ private SelectionTreeManager selectionTreeManager;
public void setSelectionTreeManager( SelectionTreeManager selectionTreeManager )
{
this.selectionTreeManager = selectionTreeManager;
}
- public void setMessage( String message )
- {
- this.message = message;
- }
-
- public String getMessage()
- {
- return message;
- }
+ private MinMaxDataAnalysisService dataAnalysisService;
+
+ public void setDataAnalysisService( MinMaxDataAnalysisService dataAnalysisService )
+ {
+ this.dataAnalysisService = dataAnalysisService;
+ }
+
+ private MinMaxDataElementService minMaxDataElementService;
+
+ public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
+ {
+ this.minMaxDataElementService = minMaxDataElementService;
+ }
+
+ private OrganisationUnitService organisationUnitService;
+
+ public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
+ {
+ this.organisationUnitService = organisationUnitService;
+ }
+
+ private I18n i18n;
public void setI18n( I18n i18n )
{
this.i18n = i18n;
}
- public void setDataSets( Integer[] dataSets )
+ // -------------------------------------------------------------------------------------------------
+ // Input
+ // -------------------------------------------------------------------------------------------------
+
+ private Collection<Integer> dataSets;
+
+ public void setDataSets( Collection<Integer> dataSets )
{
this.dataSets = dataSets;
}
+ private boolean remove = false;
+
+ public void setRemove( boolean remove )
+ {
+ this.remove = remove;
+ }
+
+ // -------------------------------------------------------------------------------------------------
+ // Output
+ // -------------------------------------------------------------------------------------------------
+
+ private String message;
+
+ public String getMessage()
+ {
+ return message;
+ }
+
// -------------------------------------------------------------------------------------------------
// Action implementation
// -------------------------------------------------------------------------------------------------
@@ -128,51 +139,37 @@
public String execute()
throws Exception
{
- Collection<OrganisationUnit> orgUnits = selectionTreeManager.getReloadedSelectedOrganisationUnits();
+ OrganisationUnit unit = selectionTreeManager.getReloadedSelectedOrganisationUnit();
- if ( orgUnits == null || orgUnits.size() == 0 )
+ if ( unit == null )
{
message = i18n.getString( "not_choose_organisation" );
return INPUT;
}
- Double factor = (Double) systemSettingManager.getSystemSetting( SystemSettingManager.KEY_FACTOR_OF_DEVIATION,
- 2.0 );
+ Collection<OrganisationUnit> orgUnits = organisationUnitService.getOrganisationUnitWithChildren( unit.getId() );
+
+ Double factor = (Double) systemSettingManager.
+ getSystemSetting( SystemSettingManager.KEY_FACTOR_OF_DEVIATION, 2.0 );
+ Collection<DataElement> dataElements = new HashSet<DataElement>();
+
for ( Integer dataSetId : dataSets )
{
DataSet dataSet = dataSetService.getDataSet( dataSetId );
-
- for ( OrganisationUnit orgUnit : orgUnits )
- {
- if ( orgUnit.getDataSets().contains( dataSet ) )
- {
- Collection<MinMaxDataElement> minMaxDataElements = (Collection<MinMaxDataElement>) minMaxValuesGenerationService
- .getMinMaxValues( orgUnit, dataSet.getDataElements(), factor );
-
- for ( MinMaxDataElement minMaxDataElement : minMaxDataElements )
- {
- MinMaxDataElement minMaxValue = minMaxDataElementService.getMinMaxDataElement(
- minMaxDataElement.getSource(), minMaxDataElement.getDataElement(), minMaxDataElement
- .getOptionCombo() );
-
- if ( minMaxValue != null )
- {
- minMaxValue.setMax( minMaxDataElement.getMax() );
- minMaxValue.setMin( minMaxDataElement.getMin() );
- minMaxDataElementService.updateMinMaxDataElement( minMaxValue );
- }
- else
- {
- minMaxDataElement.setGenerated( true );
- minMaxDataElementService.addMinMaxDataElement( minMaxDataElement );
- }
- }
- }
- }
- }
-
- message = i18n.getString( "generate_values_success" );
+ dataElements.addAll( dataSet.getDataElements() );
+ }
+
+ if ( remove )
+ {
+ minMaxDataElementService.removeMinMaxDataElements( dataElements, orgUnits );
+ }
+ else
+ {
+ dataAnalysisService.generateMinMaxValues( orgUnits, dataElements, factor );
+ }
+
+ message = i18n.getString( "done" );
return SUCCESS;
}
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GetMinMaxValidationParamsAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GetMinMaxValidationParamsAction.java 2012-05-17 16:47:13 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/GetMinMaxValidationParamsAction.java 2012-07-25 13:18:48 +0000
@@ -27,8 +27,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
import org.hisp.dhis.dataset.DataSet;
import org.hisp.dhis.dataset.DataSetService;
@@ -56,9 +59,9 @@
// Output
// -------------------------------------------------------------------------
- private Collection<DataSet> dataSets;
+ private List<DataSet> dataSets;
- public Collection<DataSet> getDataSets()
+ public List<DataSet> getDataSets()
{
return dataSets;
}
@@ -70,7 +73,9 @@
public String execute()
throws Exception
{
- dataSets = dataSetService.getAllDataSets();
+ dataSets = new ArrayList<DataSet>( dataSetService.getAllDataSets() );
+
+ Collections.sort( dataSets, IdentifiableObjectNameComparator.INSTANCE );
return SUCCESS;
}
=== removed file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/RemoveMinMaxValueAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/RemoveMinMaxValueAction.java 2012-05-17 16:47:13 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/java/org/hisp/dhis/dataadmin/action/minmaxvalidation/RemoveMinMaxValueAction.java 1970-01-01 00:00:00 +0000
@@ -1,172 +0,0 @@
-package org.hisp.dhis.dataadmin.action.minmaxvalidation;
-
-/*
- * Copyright (c) 2004-2012, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.Collection;
-
-import org.hisp.dhis.dataset.DataSet;
-import org.hisp.dhis.dataset.DataSetService;
-import org.hisp.dhis.i18n.I18n;
-import org.hisp.dhis.minmax.MinMaxDataElement;
-import org.hisp.dhis.minmax.MinMaxDataElementService;
-import org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService;
-import org.hisp.dhis.setting.SystemSettingManager;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.oust.manager.SelectionTreeManager;
-
-import com.opensymphony.xwork2.Action;
-
-/**
- * @author Chau Thu Tran
- */
-public class RemoveMinMaxValueAction
- implements Action
-{
- // -------------------------------------------------------------------------------------------------
- // Dependencies
- // -------------------------------------------------------------------------------------------------
-
- private DataSetService dataSetService;
-
- private MinMaxValuesGenerationService minMaxValuesGenerationService;
-
- private MinMaxDataElementService minMaxDataElementService;
-
- private SystemSettingManager systemSettingManager;
-
- private SelectionTreeManager selectionTreeManager;
-
- // -------------------------------------------------------------------------------------------------
- // Input
- // -------------------------------------------------------------------------------------------------
-
- private Integer[] dataSets;
-
- private String message;
-
- private I18n i18n;
-
- // -------------------------------------------------------------------------------------------------
- // Setters
- // -------------------------------------------------------------------------------------------------
-
- public void setSelectionTreeManager( SelectionTreeManager selectionTreeManager )
- {
- this.selectionTreeManager = selectionTreeManager;
- }
-
- public void setSystemSettingManager( SystemSettingManager systemSettingManager )
- {
- this.systemSettingManager = systemSettingManager;
- }
-
- public void setDataSetService( DataSetService dataSetService )
- {
- this.dataSetService = dataSetService;
- }
-
- public void setMessage( String message )
- {
- this.message = message;
- }
-
- public String getMessage()
- {
- return message;
- }
-
- public void setI18n( I18n i18n )
- {
- this.i18n = i18n;
- }
-
- public void setMinMaxValuesGenerationService( MinMaxValuesGenerationService minMaxValuesGenerationService )
- {
- this.minMaxValuesGenerationService = minMaxValuesGenerationService;
- }
-
- public void setMinMaxDataElementService( MinMaxDataElementService minMaxDataElementService )
- {
- this.minMaxDataElementService = minMaxDataElementService;
- }
-
- public void setDataSets( Integer[] dataSets )
- {
- this.dataSets = dataSets;
- }
-
- // -------------------------------------------------------------------------------------------------
- // Action implementation
- // -------------------------------------------------------------------------------------------------
-
- @Override
- public String execute()
- throws Exception
- {
- Collection<OrganisationUnit> orgUnits = selectionTreeManager.getReloadedSelectedOrganisationUnits();
-
- if ( orgUnits == null || orgUnits.size() == 0 )
- {
- message = i18n.getString( "not_choose_organisation" );
- return INPUT;
- }
-
- Double factor = (Double) systemSettingManager.getSystemSetting( SystemSettingManager.KEY_FACTOR_OF_DEVIATION, 2.0 );
-
- for ( Integer dataSetId : dataSets )
- {
- DataSet dataSet = dataSetService.getDataSet( dataSetId );
-
- for ( OrganisationUnit orgUnit : orgUnits )
- {
- if ( orgUnit.getDataSets().contains( dataSet ) )
- {
- Collection<MinMaxDataElement> minMaxDataElements = (Collection<MinMaxDataElement>) minMaxValuesGenerationService
- .getMinMaxValues( orgUnit, dataSet.getDataElements(), factor );
-
- for ( MinMaxDataElement minMaxDataElement : minMaxDataElements )
- {
- MinMaxDataElement minMaxValue = minMaxDataElementService.getMinMaxDataElement(
- minMaxDataElement.getSource(), minMaxDataElement.getDataElement(), minMaxDataElement.getOptionCombo() );
-
- if ( minMaxValue != null )
- {
- minMaxValue.setMax( minMaxDataElement.getMax() );
- minMaxValue.setMin( minMaxDataElement.getMin() );
- minMaxDataElementService.deleteMinMaxDataElement( minMaxValue );
- }
- }
- }
- }
- }
-
- message = i18n.getString( "remove_values_success" );
-
- return SUCCESS;
- }
-}
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml 2012-04-26 18:32:46 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/META-INF/dhis/beans.xml 2012-07-25 13:18:48 +0000
@@ -149,34 +149,12 @@
<bean id="org.hisp.dhis.dataadmin.action.minmaxvalidation.GenerateMinMaxValuesAction"
class="org.hisp.dhis.dataadmin.action.minmaxvalidation.GenerateMinMaxValuesAction">
- <property name="selectionTreeManager">
- <ref bean="org.hisp.dhis.oust.manager.SelectionTreeManager" />
- </property>
- <property name="dataSetService">
- <ref bean="org.hisp.dhis.dataset.DataSetService" />
- </property>
- <property name="minMaxValuesGenerationService"
- ref="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" />
- <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
- <property name="systemSettingManager">
- <ref bean="org.hisp.dhis.setting.SystemSettingManager" />
- </property>
- </bean>
-
- <bean id="org.hisp.dhis.dataadmin.action.minmaxvalidation.RemoveMinMaxValueAction"
- class="org.hisp.dhis.dataadmin.action.minmaxvalidation.RemoveMinMaxValueAction">
- <property name="selectionTreeManager">
- <ref bean="org.hisp.dhis.oust.manager.SelectionTreeManager" />
- </property>
- <property name="dataSetService">
- <ref bean="org.hisp.dhis.dataset.DataSetService" />
- </property>
- <property name="minMaxValuesGenerationService"
- ref="org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService" />
- <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
- <property name="systemSettingManager">
- <ref bean="org.hisp.dhis.setting.SystemSettingManager" />
- </property>
+ <property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
+ <property name="systemSettingManager" ref="org.hisp.dhis.setting.SystemSettingManager" />
+ <property name="selectionTreeManager" ref="org.hisp.dhis.oust.manager.SelectionTreeManager" />
+ <property name="dataAnalysisService" ref="org.hisp.dhis.dataanalysis.MinMaxOutlierAnalysisService" />
+ <property name="minMaxDataElementService" ref="org.hisp.dhis.minmax.MinMaxDataElementService" />
+ <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
</bean>
<!-- Sql View -->
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties 2012-06-28 07:00:06 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/org/hisp/dhis/dataadmin/i18n_module.properties 2012-07-25 13:18:48 +0000
@@ -306,4 +306,7 @@
aggregated_data_set_completeness=Aggregated data set completeness
show_sql_view=Show SQL view
financial_yearly=Financial Yearly
-update_option = Update option
\ No newline at end of file
+update_option=Update option
+removing_min_max_values=Removing min-max values
+generating_min_max_values=Generating min-max values
+done=Done
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml 2012-06-08 02:43:59 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/resources/struts.xml 2012-07-25 13:18:48 +0000
@@ -219,22 +219,8 @@
<!-- Min/Max validation -->
<action name="generateMinMaxValue" class="org.hisp.dhis.dataadmin.action.minmaxvalidation.GenerateMinMaxValuesAction">
- <result name="success" type="velocity-xml">
- /dhis-web-maintenance-dataadmin/responseSuccess.vm
- </result>
- <result name="input" type="velocity-xml">
- /dhis-web-maintenance-dataadmin/responseError.vm
- </result>
- <param name="requiredAuthorities">F_GENERATE_MIN_MAX_VALUES</param>
- </action>
-
- <action name="removeMinMaxValue" class="org.hisp.dhis.dataadmin.action.minmaxvalidation.RemoveMinMaxValueAction">
- <result name="success" type="velocity-xml">
- /dhis-web-maintenance-dataadmin/responseSuccess.vm
- </result>
- <result name="input" type="velocity-xml">
- /dhis-web-maintenance-dataadmin/responseError.vm
- </result>
+ <result name="success" type="velocity-xml">/dhis-web-maintenance-dataadmin/responseSuccess.vm</result>
+ <result name="input" type="velocity-xml">/dhis-web-maintenance-dataadmin/responseError.vm</result>
<param name="requiredAuthorities">F_GENERATE_MIN_MAX_VALUES</param>
</action>
@@ -242,7 +228,7 @@
<result name="success" type="velocity">/main.vm</result>
<param name="page">/dhis-web-maintenance-dataadmin/minMaxValidation.vm</param>
<param name="menu">/dhis-web-maintenance-dataadmin/menu.vm</param>
- <param name="javascripts">javascript/minMaxValidation.js, javascript/minMaxValidationForm.js </param>
+ <param name="javascripts">javascript/minMaxValidation.js</param>
<param name="requiredAuthorities">F_GENERATE_MIN_MAX_VALUES</param>
</action>
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidation.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidation.js 2012-02-24 08:44:29 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidation.js 2012-07-25 13:18:48 +0000
@@ -1,51 +1,54 @@
-function generateMinMaxValue(){
-
+
+function modifyMinMaxValues( remove )
+{
var datasetIds = "";
var datasetField = byId( 'dataSetIds' );
- for (var i = 0; i < datasetField.options.length; i++)
- {
- if (datasetField.options[ i ].selected)
+
+ if ( $( "#dataSetIds :selected" ).length == 0 )
+ {
+ setHeaderDelayMessage( i18n_not_choose_dataset );
+ return;
+ }
+
+ for ( var i = 0; i < datasetField.options.length; i++ )
+ {
+ if ( datasetField.options[ i ].selected )
{
- datasetIds+= "dataSets=" + datasetField.options[ i ].value + "&";
+ datasetIds+= "dataSets=" + datasetField.options[ i ].value + "&";
}
}
+ if ( remove )
+ {
+ setHeaderWaitMessage( i18n_removing_min_max_values );
+ }
+ else
+ {
+ setHeaderWaitMessage( i18n_generating_min_max_values );
+ }
+
+ disableButtons();
+
$.ajax({
type: "POST",
url: "generateMinMaxValue.action",
data: datasetIds,
dataType: "xml",
- success: function(xmlObject){
- xmlObject = xmlObject.getElementsByTagName( 'message' )[0];
- showSuccessMessage (xmlObject.firstChild.nodeValue);
- }
- });
-}
-
-//-----------------------------------------------------------------------------------
-// Organisation Tree
-//-----------------------------------------------------------------------------------
-
-function removeMinMaxValue(){
-
- var datasetIds = "";
- var datasetField = byId( 'dataSetIds' );
- for (var i = 0; i < datasetField.options.length; i++)
- {
- if (datasetField.options[ i ].selected)
- {
- datasetIds+= "dataSets=" + datasetField.options[ i ].value + "&";
- }
- }
-
- $.ajax({
- type: "POST",
- url: "removeMinMaxValue.action",
- data: datasetIds,
- dataType: "xml",
- success: function(xmlObject){
- xmlObject = xmlObject.getElementsByTagName( 'message' )[0];
- showSuccessMessage (xmlObject.firstChild.nodeValue);
- }
- });
+ success: function(xmlObject)
+ {
+ enableButtons();
+ xmlObject = xmlObject.getElementsByTagName( 'message' )[0];
+ setHeaderDelayMessage(xmlObject.firstChild.nodeValue);
+ }
+ });
+}
+
+function disableButtons()
+{
+ $( ":button" ).attr( "disabled", "disabled" );
+}
+
+function enableButtons()
+{
+ $( ":button" ).removeAttr( "disabled" );
}
\ No newline at end of file
=== removed file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidationForm.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidationForm.js 2011-04-11 12:08:16 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/javascript/minMaxValidationForm.js 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-jQuery(document).ready(function() {
- validation2("minMaxGeneratingForm", function() {
- if (isGenerate) {
- generateMinMaxValue();
- } else {
- removeMinMaxValue();
- }
- }, {
- 'rules' : getValidationRules("minMax")
- });
-});
-
-var isGenerate = true;
-var numberOfSelects = 0;
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/minMaxValidation.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/minMaxValidation.vm 2012-04-16 12:26:55 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataadmin/src/main/webapp/dhis-web-maintenance-dataadmin/minMaxValidation.vm 2012-07-25 13:18:48 +0000
@@ -1,9 +1,9 @@
<script type="text/javascript" src="javascript/minMaxValidationForm.js"></script>
<script type="text/javascript">
- var i18n_loading = '$encoder.jsEncode( $i18n.getString( "loading" ) )';
- var levelMustBeInt = '$encoder.jsEncode( $i18n.getString( "level_must_be_int" ) )';
var i18n_not_choose_dataset = '$encoder.jsEncode( $i18n.getString( "not_choose_dataset" ) )';
var i18n_not_choose_organisation = '$encoder.jsEncode( $i18n.getString( "not_choose_organisation" ) )';
+ var i18n_generating_min_max_values = '$encoder.jsEncode( $i18n.getString( "generating_min_max_values" ) )';
+ var i18n_removing_min_max_values = '$encoder.jsEncode( $i18n.getString( "removing_min_max_values" ) )';
</script>
<h3>$i18n.getString( "min_max_value_generation" ) #openHelp( "minMaxValueGeneration" )</h3>
@@ -12,7 +12,7 @@
<table>
<tr>
<th colspan="2">$i18n.getString('available_dataset')</th>
- <td rowspan="2">#organisationUnitSelectionTree( false, true, true ) </td>
+ <td rowspan="2">#organisationUnitSelectionTree( false, false, true ) </td>
</tr>
<tr>
<td colspan="2" rowspan="2">
@@ -26,14 +26,9 @@
</tr>
<tr>
<td>
- <input type="submit" id="saveButton" onclick="javascipt: isGenerate = true;" style="width:10em" value="$i18n.getString( 'generate' )">
- <input type="submit" id="removeButton" onclick="javascipt: isGenerate = false;" style="width:10em" value="$i18n.getString( 'remove' )"/>
- <input type="button" style="width:10em" onClick="window.location.href='index.action'" value="$i18n.getString( 'back' )"/>
+ <input type="button" onclick="javascipt:modifyMinMaxValues( false )" style="width:10em" value="$i18n.getString( 'generate' )">
+ <input type="button" onclick="javascipt:modifyMinMaxValues( true )" style="width:10em" value="$i18n.getString( 'remove' )"/>
</td>
</tr>
</table>
</form>
-
-<span id="info" style="display:none;top:70px;right:5px;position:fixed;" onclick="hideById(this.id)"></span>
-
-<span id="message"></span>
=== modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/dataanalysis/GetAnalysisAction.java'
--- dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/dataanalysis/GetAnalysisAction.java 2011-03-02 00:23:51 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/java/org/hisp/dhis/validationrule/action/dataanalysis/GetAnalysisAction.java 2012-07-25 13:18:48 +0000
@@ -41,6 +41,7 @@
import org.hisp.dhis.datavalue.DeflatedDataValue;
import org.hisp.dhis.i18n.I18nFormat;
import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
import org.hisp.dhis.oust.manager.SelectionTreeManager;
import org.hisp.dhis.period.Period;
import org.hisp.dhis.period.PeriodService;
@@ -91,6 +92,13 @@
this.dataSetService = dataSetService;
}
+ private OrganisationUnitService organisationUnitService;
+
+ public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
+ {
+ this.organisationUnitService = organisationUnitService;
+ }
+
private I18nFormat format;
public void setFormat( I18nFormat format )
@@ -175,8 +183,12 @@
{
Set<DataElement> dataElements = new HashSet<DataElement>();
Collection<Period> periods = null;
- OrganisationUnit unit = selectionTreeManager.getReloadedSelectedOrganisationUnit();;
+ OrganisationUnit unit = selectionTreeManager.getReloadedSelectedOrganisationUnit();
+ Collection<OrganisationUnit> orgUnits = organisationUnitService.getOrganisationUnitWithChildren( unit.getId() );
+
+ // TODO filter periods with data element period type
+
if ( fromDate != null && toDate != null && dataSets != null )
{
periods = periodService.getPeriodsBetweenDates( format.parseDate( fromDate ), format.parseDate( toDate ) );
@@ -186,9 +198,9 @@
dataElements.addAll( dataSetService.getDataSet( Integer.parseInt( id ) ).getDataElements() );
}
-
log.info( "From date: " + fromDate + ", To date: " + toDate + ", Organisation unit: " + unit
+ ", Std dev: " + standardDeviation + ", Key: " + key );
+
log.info( "Nr of data elements: " + dataElements.size() + " Nr of periods: " + periods.size() );
}
@@ -196,7 +208,7 @@
if ( service != null ) // Follow-up analysis has no input params
{
- dataValues = service.analyse( unit, dataElements, periods, standardDeviation );
+ dataValues = service.analyse( orgUnits, dataElements, periods, standardDeviation );
maxExceeded = dataValues.size() > DataAnalysisService.MAX_OUTLIERS;
}
=== modified file 'dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/META-INF/dhis/beans.xml 2012-01-22 06:34:56 +0000
+++ dhis-2/dhis-web/dhis-web-validationrule/src/main/resources/META-INF/dhis/beans.xml 2012-07-25 13:18:48 +0000
@@ -239,6 +239,7 @@
<property name="selectionTreeManager" ref="org.hisp.dhis.oust.manager.SelectionTreeManager" />
<property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
+ <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
</bean>
<bean id="org.hisp.dhis.validationrule.action.dataanalysis.EditDataValueAction" class="org.hisp.dhis.validationrule.action.dataanalysis.EditDataValueAction"