use of org.hisp.dhis.common.BaseDimensionalObject in project dhis2-core by dhis2.
the class DefaultAnalyticsService method getAggregatedDataValueMap.
/**
* Returns a mapping between dimension items and values for the given data
* query and list of indicators. The dimensional items part of the indicator
* numerators and denominators are used as dimensional item for the aggregated
* values being retrieved.
*
* @param params the {@link DataQueryParams}.
* @param indicators the list of indicators.
* @return a dimensional items to aggregate values map.
*/
private Map<String, Double> getAggregatedDataValueMap(DataQueryParams params, List<Indicator> indicators) {
List<DimensionalItemObject> items = Lists.newArrayList(expressionService.getDimensionalItemObjectsInIndicators(indicators));
items = DimensionalObjectUtils.replaceOperandTotalsWithDataElements(items);
DimensionalObject dimension = new BaseDimensionalObject(DimensionalObject.DATA_X_DIM_ID, DimensionType.DATA_X, null, DISPLAY_NAME_DATA_X, items);
DataQueryParams dataSourceParams = DataQueryParams.newBuilder(params).replaceDimension(dimension).withIncludeNumDen(false).withSkipHeaders(true).withSkipMeta(true).build();
Grid grid = getAggregatedDataValueGridInternal(dataSourceParams);
return grid.getAsMap(grid.getWidth() - 1, DimensionalObject.DIMENSION_SEP);
}
use of org.hisp.dhis.common.BaseDimensionalObject in project dhis2-core by dhis2.
the class DefaultAnalyticsService method addDataElementOperandValues.
/**
* Adds data element operand values to the given grid.
*
* @param params the {@link DataQueryParams}.
* @param grid the grid.
* @param totalType the operand {@link DataElementOperand.TotalType}.
*/
private void addDataElementOperandValues(DataQueryParams params, Grid grid, DataElementOperand.TotalType totalType) {
List<DataElementOperand> operands = asTypedList(params.getDataElementOperands());
operands = operands.stream().filter(o -> totalType.equals(o.getTotalType())).collect(Collectors.toList());
if (operands.isEmpty()) {
return;
}
List<DimensionalItemObject> dataElements = Lists.newArrayList(DimensionalObjectUtils.getDataElements(operands));
List<DimensionalItemObject> categoryOptionCombos = Lists.newArrayList(DimensionalObjectUtils.getCategoryOptionCombos(operands));
List<DimensionalItemObject> attributeOptionCobos = Lists.newArrayList(DimensionalObjectUtils.getAttributeOptionCombos(operands));
//TODO check if data was dim or filter
DataQueryParams.Builder builder = DataQueryParams.newBuilder(params).removeDimension(DATA_X_DIM_ID).addDimension(new BaseDimensionalObject(DATA_X_DIM_ID, DimensionType.DATA_X, dataElements));
if (totalType.isCategoryOptionCombo()) {
builder.addDimension(new BaseDimensionalObject(CATEGORYOPTIONCOMBO_DIM_ID, DimensionType.CATEGORY_OPTION_COMBO, categoryOptionCombos));
}
if (totalType.isAttributeOptionCombo()) {
builder.addDimension(new BaseDimensionalObject(ATTRIBUTEOPTIONCOMBO_DIM_ID, DimensionType.ATTRIBUTE_OPTION_COMBO, attributeOptionCobos));
}
DataQueryParams operandParams = builder.build();
Map<String, Object> aggregatedDataMap = getAggregatedDataValueMapObjectTyped(operandParams);
aggregatedDataMap = AnalyticsUtils.convertDxToOperand(aggregatedDataMap, totalType);
for (Map.Entry<String, Object> entry : aggregatedDataMap.entrySet()) {
Object value = AnalyticsUtils.getRoundedValueObject(operandParams, entry.getValue());
grid.addRow().addValues(entry.getKey().split(DIMENSION_SEP)).addValue(value);
if (params.isIncludeNumDen()) {
grid.addNullValues(3);
}
}
}
use of org.hisp.dhis.common.BaseDimensionalObject in project dhis2-core by dhis2.
the class DefaultQueryPlanner method validate.
// -------------------------------------------------------------------------
// DefaultQueryPlanner implementation
// -------------------------------------------------------------------------
@Override
public void validate(DataQueryParams params) throws IllegalQueryException {
String violation = null;
if (params == null) {
throw new IllegalQueryException("Params cannot be null");
}
final List<DimensionalItemObject> dataElements = Lists.newArrayList(params.getDataElements());
params.getProgramDataElements().stream().forEach(pde -> dataElements.add(((ProgramDataElementDimensionItem) pde).getDataElement()));
final List<DataElement> nonAggDataElements = FilterUtils.inverseFilter(asTypedList(dataElements), AggregatableDataElementFilter.INSTANCE);
if (params.getDimensions().isEmpty()) {
violation = "At least one dimension must be specified";
}
if (!params.getDimensionsAsFilters().isEmpty()) {
violation = "Dimensions cannot be specified as dimension and filter simultaneously: " + params.getDimensionsAsFilters();
}
if (!params.hasPeriods() && !params.isSkipPartitioning() && !params.hasStartEndDate()) {
violation = "At least one period must be specified as dimension or filter";
}
if (params.hasPeriods() && params.hasStartEndDate()) {
violation = "Periods and start and end dates cannot be specified simultaneously";
}
if (!params.getFilterIndicators().isEmpty() && params.getFilterOptions(DATA_X_DIM_ID).size() > 1) {
violation = "Only a single indicator can be specified as filter";
}
if (!params.getFilterReportingRates().isEmpty() && params.getFilterOptions(DATA_X_DIM_ID).size() > 1) {
violation = "Only a single reporting rate can be specified as filter";
}
if (params.getFilters().contains(new BaseDimensionalObject(CATEGORYOPTIONCOMBO_DIM_ID))) {
violation = "Category option combos cannot be specified as filter";
}
if (!params.getDuplicateDimensions().isEmpty()) {
violation = "Dimensions cannot be specified more than once: " + params.getDuplicateDimensions();
}
if (!params.getAllReportingRates().isEmpty() && !params.containsOnlyDimensionsAndFilters(COMPLETENESS_DIMENSION_TYPES)) {
violation = "Reporting rates can only be specified together with dimensions of type: " + COMPLETENESS_DIMENSION_TYPES;
}
if (params.hasDimensionOrFilter(CATEGORYOPTIONCOMBO_DIM_ID) && params.getAllDataElements().isEmpty()) {
violation = "Assigned categories cannot be specified when data elements are not specified";
}
if (params.hasDimensionOrFilter(CATEGORYOPTIONCOMBO_DIM_ID) && (params.getAllDataElements().size() != params.getAllDataDimensionItems().size())) {
violation = "Assigned categories can only be specified together with data elements, not indicators or reporting rates";
}
if (!nonAggDataElements.isEmpty()) {
violation = "Data elements must be of a value and aggregation type that allow aggregation: " + getUids(nonAggDataElements);
}
if (params.isOutputFormat(OutputFormat.DATA_VALUE_SET)) {
if (!params.hasDimension(DATA_X_DIM_ID)) {
violation = "A data dimension 'dx' must be specified when output format is DATA_VALUE_SET";
}
if (!params.hasDimension(PERIOD_DIM_ID)) {
violation = "A period dimension 'pe' must be specified when output format is DATA_VALUE_SET";
}
if (!params.hasDimension(ORGUNIT_DIM_ID)) {
violation = "An organisation unit dimension 'ou' must be specified when output format is DATA_VALUE_SET";
}
}
if (violation != null) {
log.warn(String.format("Analytics validation failed: %s", violation));
throw new IllegalQueryException(violation);
}
}
use of org.hisp.dhis.common.BaseDimensionalObject in project dhis2-core by dhis2.
the class DefaultQueryPlanner method groupByStartEndDate.
@Override
public List<DataQueryParams> groupByStartEndDate(DataQueryParams params) {
List<DataQueryParams> queries = new ArrayList<>();
if (!params.getPeriods().isEmpty()) {
for (DimensionalItemObject item : params.getPeriods()) {
Period period = (Period) item;
DataQueryParams query = DataQueryParams.newBuilder(params).withStartDate(period.getStartDate()).withEndDate(period.getEndDate()).build();
BaseDimensionalObject staticPeriod = (BaseDimensionalObject) query.getDimension(PERIOD_DIM_ID);
staticPeriod.setDimensionName(period.getIsoDate());
staticPeriod.setFixed(true);
queries.add(query);
}
} else if (!params.getFilterPeriods().isEmpty()) {
Period period = (Period) params.getFilterPeriods().get(0);
DataQueryParams query = DataQueryParams.newBuilder(params).withStartDate(period.getStartDate()).withEndDate(period.getEndDate()).removeFilter(PERIOD_DIM_ID).build();
queries.add(query);
} else {
throw new IllegalQueryException("Query does not contain any period dimension items");
}
if (queries.size() > 1) {
log.debug(String.format("Split on period: %d", queries.size()));
}
return queries;
}
use of org.hisp.dhis.common.BaseDimensionalObject in project dhis2-core by dhis2.
the class DefaultAnalyticsService method getOrgUnitTargetMap.
// -------------------------------------------------------------------------
// Supportive methods
// -------------------------------------------------------------------------
/**
* Generates a mapping of permutations keys (organisation unit id or null)
* and mappings of organisation unit group and counts.
*
* @param params the {@link DataQueryParams}.
* @param indicators the indicators for which formulas to scan for organisation
* unit groups.
* @return a map of maps.
*/
private Map<String, Map<String, Integer>> getOrgUnitTargetMap(DataQueryParams params, Collection<Indicator> indicators) {
Set<OrganisationUnitGroup> orgUnitGroups = expressionService.getOrganisationUnitGroupsInIndicators(indicators);
if (orgUnitGroups.isEmpty()) {
return null;
}
DataQueryParams orgUnitTargetParams = DataQueryParams.newBuilder(params).pruneToDimensionType(DimensionType.ORGANISATION_UNIT).addDimension(new BaseDimensionalObject(DimensionalObject.ORGUNIT_GROUP_DIM_ID, null, new ArrayList<DimensionalItemObject>(orgUnitGroups))).withSkipPartitioning(true).build();
Map<String, Double> orgUnitCountMap = getAggregatedOrganisationUnitTargetMap(orgUnitTargetParams);
return DataQueryParams.getPermutationOrgUnitGroupCountMap(orgUnitCountMap);
}
Aggregations