Search in sources :

Example 6 with DimensionalItemObject

use of org.hisp.dhis.common.DimensionalItemObject in project dhis2-core by dhis2.

the class DefaultQueryPlanner method groupByPeriodType.

/**
     * If periods appear as dimensions in the given query; groups the query into
     * sub queries based on the period type of the periods. Sets the period type
     * name on each query. If periods appear as filters; replaces the period filter
     * with one filter for each period type. Sets the dimension names and filter
     * names respectively.
     */
@Override
public List<DataQueryParams> groupByPeriodType(DataQueryParams params) {
    List<DataQueryParams> queries = new ArrayList<>();
    if (params.isSkipPartitioning()) {
        queries.add(params);
    } else if (!params.getPeriods().isEmpty()) {
        ListMap<String, DimensionalItemObject> periodTypePeriodMap = PartitionUtils.getPeriodTypePeriodMap(params.getPeriods());
        for (String periodType : periodTypePeriodMap.keySet()) {
            DataQueryParams query = DataQueryParams.newBuilder(params).addOrSetDimensionOptions(PERIOD_DIM_ID, DimensionType.PERIOD, periodType.toLowerCase(), periodTypePeriodMap.get(periodType)).withPeriodType(periodType).build();
            queries.add(query);
        }
    } else if (!params.getFilterPeriods().isEmpty()) {
        DimensionalObject filter = params.getFilter(PERIOD_DIM_ID);
        ListMap<String, DimensionalItemObject> periodTypePeriodMap = PartitionUtils.getPeriodTypePeriodMap(filter.getItems());
        DataQueryParams.Builder query = DataQueryParams.newBuilder(params).removeFilter(PERIOD_DIM_ID).withPeriodType(// Using first period type
        periodTypePeriodMap.keySet().iterator().next());
        for (String periodType : periodTypePeriodMap.keySet()) {
            query.addFilter(new BaseDimensionalObject(filter.getDimension(), filter.getDimensionType(), periodType.toLowerCase(), filter.getDisplayName(), periodTypePeriodMap.get(periodType)));
        }
        queries.add(query.build());
    } else {
        queries.add(DataQueryParams.newBuilder(params).build());
        return queries;
    }
    if (queries.size() > 1) {
        log.debug(String.format("Split on period type: %d", queries.size()));
    }
    return queries;
}
Also used : DataQueryParams(org.hisp.dhis.analytics.DataQueryParams) DimensionalItemObject(org.hisp.dhis.common.DimensionalItemObject) BaseDimensionalObject(org.hisp.dhis.common.BaseDimensionalObject) ArrayList(java.util.ArrayList) ListMap(org.hisp.dhis.common.ListMap) BaseDimensionalObject(org.hisp.dhis.common.BaseDimensionalObject) DimensionalObject(org.hisp.dhis.common.DimensionalObject)

Example 7 with DimensionalItemObject

use of org.hisp.dhis.common.DimensionalItemObject in project dhis2-core by dhis2.

the class DefaultQueryPlanner method groupByDaysInPeriod.

/**
     * Groups the given query into sub queries based on the number of days in the
     * aggregation period. This only applies if the aggregation type is
     * {@link AggregationType#AVERAGE_SUM_INT} and the query has at least one period as 
     * dimension option. This is necessary since the number of days in the aggregation 
     * period is part of the expression for aggregating the value.
     * 
     * @param params the data query parameters.
     * @return a list of {@link DataQueryParams}.
     */
private List<DataQueryParams> groupByDaysInPeriod(DataQueryParams params) {
    List<DataQueryParams> queries = new ArrayList<>();
    if (params.getPeriods().isEmpty() || !params.isAggregationType(AggregationType.AVERAGE_SUM_INT)) {
        queries.add(DataQueryParams.newBuilder(params).build());
        return queries;
    }
    ListMap<Integer, DimensionalItemObject> daysPeriodMap = QueryPlannerUtils.getDaysPeriodMap(params.getPeriods());
    DimensionalObject periodDim = params.getDimension(PERIOD_DIM_ID);
    for (Integer days : daysPeriodMap.keySet()) {
        DataQueryParams query = DataQueryParams.newBuilder(params).addOrSetDimensionOptions(periodDim.getDimension(), periodDim.getDimensionType(), periodDim.getDimensionName(), daysPeriodMap.get(days)).build();
        queries.add(query);
    }
    if (queries.size() > 1) {
        log.debug(String.format("Split on days in period: %d", queries.size()));
    }
    return queries;
}
Also used : DataQueryParams(org.hisp.dhis.analytics.DataQueryParams) DimensionalItemObject(org.hisp.dhis.common.DimensionalItemObject) ArrayList(java.util.ArrayList) BaseDimensionalObject(org.hisp.dhis.common.BaseDimensionalObject) DimensionalObject(org.hisp.dhis.common.DimensionalObject)

Example 8 with DimensionalItemObject

use of org.hisp.dhis.common.DimensionalItemObject in project dhis2-core by dhis2.

the class DefaultQueryPlanner method splitByDimension.

// -------------------------------------------------------------------------
// Supportive methods
// -------------------------------------------------------------------------
/**
     * Splits the given list of queries in sub queries on the given dimension.
     */
private DataQueryGroups splitByDimension(DataQueryGroups queryGroups, String dimension, int optimalQueries) {
    int optimalForSubQuery = MathUtils.divideToFloor(optimalQueries, queryGroups.getLargestGroupSize());
    List<DataQueryParams> subQueries = new ArrayList<>();
    for (DataQueryParams query : queryGroups.getAllQueries()) {
        DimensionalObject dim = query.getDimension(dimension);
        List<DimensionalItemObject> values = null;
        if (dim == null || (values = dim.getItems()) == null || values.isEmpty()) {
            subQueries.add(DataQueryParams.newBuilder(query).build());
            continue;
        }
        List<List<DimensionalItemObject>> valuePages = new PaginatedList<>(values).setNumberOfPages(optimalForSubQuery).getPages();
        for (List<DimensionalItemObject> valuePage : valuePages) {
            DataQueryParams subQuery = DataQueryParams.newBuilder(query).withDimensionOptions(dim.getDimension(), valuePage).build();
            subQueries.add(subQuery);
        }
    }
    if (subQueries.size() > queryGroups.getAllQueries().size()) {
        log.debug(String.format("Split on dimension %s: %d", dimension, (subQueries.size() / queryGroups.getAllQueries().size())));
    }
    return DataQueryGroups.newBuilder().withQueries(subQueries).build();
}
Also used : DataQueryParams(org.hisp.dhis.analytics.DataQueryParams) DimensionalItemObject(org.hisp.dhis.common.DimensionalItemObject) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) PaginatedList(org.hisp.dhis.commons.collection.PaginatedList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) DimensionalObjectUtils.asTypedList(org.hisp.dhis.common.DimensionalObjectUtils.asTypedList) PaginatedList(org.hisp.dhis.commons.collection.PaginatedList) BaseDimensionalObject(org.hisp.dhis.common.BaseDimensionalObject) DimensionalObject(org.hisp.dhis.common.DimensionalObject)

Example 9 with DimensionalItemObject

use of org.hisp.dhis.common.DimensionalItemObject in project dhis2-core by dhis2.

the class DefaultQueryPlanner method groupByAggregationType.

/**
     * Groups the given query in sub queries based on the aggregation type of its
     * data elements. The aggregation type can be sum, average aggregation or
     * average disaggregation. Sum means that the data elements have sum aggregation
     * operator. Average aggregation means that the data elements have the average
     * aggregation operator and that the period type of the data elements have
     * higher or equal frequency than the aggregation period type. Average disaggregation
     * means that the data elements have the average aggregation operator and
     * that the period type of the data elements have lower frequency than the
     * aggregation period type. Average bool means that the data elements have the
     * average aggregation operator and the bool value type.
     * <p>
     * If no data elements are present, the aggregation type will be determined
     * based on the first data element in the first data element group in the
     * first data element group set in the query.
     * <p>
     * If the aggregation type is already set/overridden in the request, the
     * query will be returned unchanged. If there are no data elements or data
     * element group sets specified the aggregation type will fall back to sum.
     * 
     * @param params the data query parameters.
     * @return a list of {@link DataQueryParams}.
     */
private List<DataQueryParams> groupByAggregationType(DataQueryParams params) {
    List<DataQueryParams> queries = new ArrayList<>();
    if (!params.getDataElements().isEmpty()) {
        ListMap<AggregationType, DimensionalItemObject> aggregationTypeDataElementMap = QueryPlannerUtils.getAggregationTypeDataElementMap(params);
        for (AggregationType aggregationType : aggregationTypeDataElementMap.keySet()) {
            DataQueryParams query = DataQueryParams.newBuilder(params).withDataElements(aggregationTypeDataElementMap.get(aggregationType)).withAggregationType(aggregationType).build();
            queries.add(query);
        }
    } else if (!params.getDataElementGroupSets().isEmpty()) {
        DimensionalObject degs = params.getDataElementGroupSets().get(0);
        DataElementGroup deg = (DataElementGroup) (degs.hasItems() ? degs.getItems().get(0) : null);
        AggregationType aggregationType = ObjectUtils.firstNonNull(params.getAggregationType(), SUM);
        if (deg != null && !deg.getMembers().isEmpty()) {
            PeriodType periodType = PeriodType.getPeriodTypeByName(params.getPeriodType());
            aggregationType = ObjectUtils.firstNonNull(params.getAggregationType(), deg.getAggregationType());
            aggregationType = QueryPlannerUtils.getAggregationType(deg.getValueType(), aggregationType, periodType, deg.getPeriodType());
        }
        DataQueryParams query = DataQueryParams.newBuilder(params).withAggregationType(aggregationType).build();
        queries.add(query);
    } else {
        DataQueryParams query = DataQueryParams.newBuilder(params).withAggregationType(ObjectUtils.firstNonNull(params.getAggregationType(), SUM)).build();
        queries.add(query);
    }
    if (queries.size() > 1) {
        log.debug(String.format("Split on aggregation type: %d", queries.size()));
    }
    return queries;
}
Also used : DataQueryParams(org.hisp.dhis.analytics.DataQueryParams) PeriodType(org.hisp.dhis.period.PeriodType) DimensionalItemObject(org.hisp.dhis.common.DimensionalItemObject) ArrayList(java.util.ArrayList) DataElementGroup(org.hisp.dhis.dataelement.DataElementGroup) AggregationType(org.hisp.dhis.analytics.AggregationType) BaseDimensionalObject(org.hisp.dhis.common.BaseDimensionalObject) DimensionalObject(org.hisp.dhis.common.DimensionalObject)

Example 10 with DimensionalItemObject

use of org.hisp.dhis.common.DimensionalItemObject in project dhis2-core by dhis2.

the class DefaultPredictorService method predict.

// -------------------------------------------------------------------------
// Predictor run
// -------------------------------------------------------------------------
@Override
public int predict(Predictor predictor, Date startDate, Date endDate) {
    log.info("Predicting for " + predictor.getName() + " from " + startDate.toString() + " to " + endDate.toString());
    Expression generator = predictor.getGenerator();
    Expression skipTest = predictor.getSampleSkipTest();
    DataElement outputDataElement = predictor.getOutput();
    Set<String> aggregates = expressionService.getAggregatesInExpression(generator.getExpression());
    Map<String, Double> constantMap = constantService.getConstantMap();
    List<Period> outputPeriods = getPeriodsBetweenDates(predictor.getPeriodType(), startDate, endDate);
    ListMap<Period, Period> samplePeriodsMap = getSamplePeriodsMap(outputPeriods, predictor);
    Set<Period> allSamplePeriods = samplePeriodsMap.uniqueValues();
    Set<DataElementOperand> dataElementOperands = getDataElementOperands(aggregates, skipTest);
    User currentUser = currentUserService.getCurrentUser();
    DataElementCategoryOptionCombo outputOptionCombo = predictor.getOutputCombo() == null ? categoryService.getDefaultDataElementCategoryOptionCombo() : predictor.getOutputCombo();
    List<OrganisationUnit> orgUnits = organisationUnitService.getOrganisationUnitsAtOrgUnitLevels(predictor.getOrganisationUnitLevels(), currentUser.getOrganisationUnits());
    int predictionCount = 0;
    for (OrganisationUnit orgUnit : orgUnits) {
        MapMapMap<Period, String, DimensionalItemObject, Double> dataMap = dataElementOperands.isEmpty() ? null : dataValueService.getDataElementOperandValues(dataElementOperands, allSamplePeriods, orgUnit);
        applySkipTest(dataMap, skipTest, constantMap);
        for (Period period : outputPeriods) {
            ListMapMap<String, String, Double> aggregateSampleMap = getAggregateSamples(dataMap, aggregates, samplePeriodsMap.get(period), constantMap);
            for (String aoc : aggregateSampleMap.keySet()) {
                ListMap<String, Double> aggregateValueMap = aggregateSampleMap.get(aoc);
                Double value = expressionService.getExpressionValue(generator, new HashMap<>(), constantMap, null, period.getDaysInPeriod(), aggregateValueMap);
                if (value != null && !value.isNaN() && !value.isInfinite()) {
                    writeDataValue(outputDataElement, period, orgUnit, outputOptionCombo, categoryService.getDataElementCategoryOptionCombo(aoc), value.toString(), currentUser.getUsername());
                    predictionCount++;
                }
            }
        }
    }
    log.info("Generated " + predictionCount + " predictions for " + predictor.getName() + " from " + startDate.toString() + " to " + endDate.toString());
    return predictionCount;
}
Also used : DataElementOperand(org.hisp.dhis.dataelement.DataElementOperand) OrganisationUnit(org.hisp.dhis.organisationunit.OrganisationUnit) User(org.hisp.dhis.user.User) Period(org.hisp.dhis.period.Period) DataElement(org.hisp.dhis.dataelement.DataElement) DimensionalItemObject(org.hisp.dhis.common.DimensionalItemObject) Expression(org.hisp.dhis.expression.Expression) DataElementCategoryOptionCombo(org.hisp.dhis.dataelement.DataElementCategoryOptionCombo)

Aggregations

DimensionalItemObject (org.hisp.dhis.common.DimensionalItemObject)55 ArrayList (java.util.ArrayList)15 DataQueryParams (org.hisp.dhis.analytics.DataQueryParams)15 DimensionalObject (org.hisp.dhis.common.DimensionalObject)15 BaseDimensionalObject (org.hisp.dhis.common.BaseDimensionalObject)14 Test (org.junit.Test)12 Period (org.hisp.dhis.period.Period)11 ListMap (org.hisp.dhis.common.ListMap)10 DataElement (org.hisp.dhis.dataelement.DataElement)10 DhisSpringTest (org.hisp.dhis.DhisSpringTest)7 BaseDimensionalItemObject (org.hisp.dhis.common.BaseDimensionalItemObject)7 DataElementOperand (org.hisp.dhis.dataelement.DataElementOperand)7 HashMap (java.util.HashMap)6 List (java.util.List)6 OrganisationUnit (org.hisp.dhis.organisationunit.OrganisationUnit)6 PeriodType (org.hisp.dhis.period.PeriodType)6 SqlRowSet (org.springframework.jdbc.support.rowset.SqlRowSet)5 Matcher (java.util.regex.Matcher)4 Grid (org.hisp.dhis.common.Grid)4 HashSet (java.util.HashSet)3