Package com.opengamma.financial.view

Source Code of com.opengamma.financial.view.HistoricalViewEvaluationResultBuilder

/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.view;

import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.LocalDate;

import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.engine.calcnode.MissingValue;
import com.opengamma.engine.value.ComputedValue;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.engine.view.ViewCalculationConfiguration;
import com.opengamma.engine.view.ViewComputationResultModel;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.engine.view.ViewResultEntry;
import com.opengamma.engine.view.compilation.CompiledViewCalculationConfiguration;
import com.opengamma.engine.view.compilation.CompiledViewDefinition;
import com.opengamma.timeseries.TimeSeries;
import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries;
import com.opengamma.timeseries.date.localdate.ImmutableLocalDateObjectTimeSeries;
import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries;
import com.opengamma.timeseries.date.localdate.LocalDateObjectTimeSeries;
import com.opengamma.timeseries.date.localdate.LocalDateToIntConverter;

/* package */class HistoricalViewEvaluationResultBuilder {

  private static final Logger s_logger = LoggerFactory.getLogger(HistoricalViewEvaluationResultBuilder.class);

  // TODO: If the duration of the time series is high, or there are simply a large quantity then we could modify these builders to
  // write directly to the time series database instead (or batch up the points in internal arrays) and the result bundle will be
  // the identifiers of the time series that were written to the database

  /**
   * Builder for time-series where there is at most one result for a given date. Points may be added in any order, allowing the results to be executed in parallel.
   */
  private static class TimeSeriesBuilder {

    private final SortedMap<Integer, Object> _datedResultMap = new Int2ObjectRBTreeMap<Object>();

    public TimeSeriesBuilder() {
    }

    public TimeSeriesBuilder addPoint(final int date, final Object value) {
      if (_datedResultMap.put(date, value) != null) {
        throw new OpenGammaRuntimeException("Received multiple results for date " + date);
      }
      return this;
    }

    @SuppressWarnings("rawtypes")
    public TimeSeries makeTimeSeries() {
      if (_datedResultMap.isEmpty() || Iterables.get(_datedResultMap.values(), 0) instanceof Number) {
        return makeDoubleTimeSeries();
      } else {
        return makeObjectTimeSeries();
      }
    }

    private LocalDateDoubleTimeSeries makeDoubleTimeSeries() {
      int[] dates = new int[_datedResultMap.size()];
      double[] values = new double[_datedResultMap.size()];
      int i = 0;
      for (Map.Entry<Integer, Object> datedResult : _datedResultMap.entrySet()) {
        dates[i] = datedResult.getKey();
        values[i] = (Double) datedResult.getValue();
        i++;
      }
      return ImmutableLocalDateDoubleTimeSeries.of(dates, values);
    }

    private LocalDateObjectTimeSeries<?> makeObjectTimeSeries() {
      int[] dates = new int[_datedResultMap.size()];
      Object[] values = new Object[_datedResultMap.size()];
      int i = 0;
      for (Map.Entry<Integer, Object> datedResult : _datedResultMap.entrySet()) {
        dates[i] = datedResult.getKey();
        values[i] = datedResult.getValue();
        i++;
      }
      return ImmutableLocalDateObjectTimeSeries.of(dates, values);
    }
  }

  private static class ConfigurationResults {

    private Map<ValueSpecification, Set<ValueRequirement>> _requirements;
    private final Map<ValueRequirement, TimeSeriesBuilder> _results = new HashMap<ValueRequirement, TimeSeriesBuilder>();

    public ConfigurationResults(final Collection<ValueRequirement> requirements) {
      for (final ValueRequirement requirement : requirements) {
        _results.put(requirement, new TimeSeriesBuilder());
      }
    }

    public void setRequirements(final Map<ValueSpecification, Set<ValueRequirement>> requirements) {
      _requirements = requirements;
    }

    public void store(final int date, final ValueSpecification specification, final Object value) {
      final Set<ValueRequirement> requirements = _requirements.get(specification);
      if (requirements != null) {
        for (final ValueRequirement requirement : requirements) {
          final TimeSeriesBuilder builder = _results.get(requirement);
          if (builder == null) {
            s_logger.warn("View produced value {} for unrequested requirement {}", specification, requirement);
          } else {
            final TimeSeriesBuilder newBuilder = builder.addPoint(date, value);
            if (newBuilder != builder) {
              _results.put(requirement, newBuilder);
            }
          }
        }
      } else {
        s_logger.warn("View produced unrequested value {}", specification);
      }
    }

    public HistoricalViewEvaluationResult makeResult() {
      final HistoricalViewEvaluationResult results = new HistoricalViewEvaluationResult();
      for (final Map.Entry<ValueRequirement, TimeSeriesBuilder> result : _results.entrySet()) {
        results.addTimeSeries(result.getKey(), result.getValue().makeTimeSeries());
      }
      return results;
    }

  }

  private static class MarketData {

    private final TimeSeriesBuilder _builder = new TimeSeriesBuilder();
    private Collection<ValueSpecification> _alias;

  }

  private static class MarketDataResults extends HashMap<ValueSpecification, MarketData> {

    private static final long serialVersionUID = 1L;

    public void addMarketDataAlias(final ValueSpecification valueSpec, final Collection<ValueSpecification> aliasValueSpecs) {
      MarketData data = get(valueSpec);
      if (data == null) {
        data = new MarketData();
        put(valueSpec, data);
      }
      if (aliasValueSpecs != null) {
        if (data._alias == null) {
          data._alias = new ArrayList<ValueSpecification>(aliasValueSpecs);
        } else {
          data._alias.addAll(aliasValueSpecs);
        }
      }
    }

    public void store(final int date, final ValueSpecification specification, final Object value) {
      MarketData data = get(specification);
      if (data != null) {
        data._builder.addPoint(date, value);
      } else {
        s_logger.warn("View produced unrequested market data {}", specification);
      }
    }

    @SuppressWarnings("rawtypes")
    public HistoricalViewEvaluationMarketData makeResult() {
      final HistoricalViewEvaluationMarketData results = new HistoricalViewEvaluationMarketData();
      for (final Map.Entry<ValueSpecification, MarketData> result : entrySet()) {
        final TimeSeries timeSeries = result.getValue()._builder.makeTimeSeries();
        for (ValueSpecification alias : result.getValue()._alias) {
          results.addTimeSeries(alias, timeSeries);
        }
      }
      return results;
    }

  }

  private final Map<String, ConfigurationResults> _results = new HashMap<String, ConfigurationResults>();
  private final MarketDataResults _marketData;
  private boolean _compiled;

  public HistoricalViewEvaluationResultBuilder(final ViewDefinition viewDefinition, final boolean includeMarketData) {
    for (final ViewCalculationConfiguration calcConfig : viewDefinition.getAllCalculationConfigurations()) {
      final ConfigurationResults configResults = new ConfigurationResults(calcConfig.getSpecificRequirements());
      _results.put(calcConfig.getName(), configResults);
    }
    if (includeMarketData) {
      _marketData = new MarketDataResults();
    } else {
      _marketData = null;
    }
  }

  public synchronized void store(final CompiledViewDefinition viewDefinition) {
    if (!_compiled) {
      for (final CompiledViewCalculationConfiguration calcConfig : viewDefinition.getCompiledCalculationConfigurations()) {
        final ConfigurationResults configResults = _results.get(calcConfig.getName());
        configResults.setRequirements(calcConfig.getTerminalOutputSpecifications());
        if (_marketData != null) {
          for (Map.Entry<ValueSpecification, Collection<ValueSpecification>> marketDataAlias : calcConfig.getMarketDataAliases().entrySet()) {
            _marketData.addMarketDataAlias(marketDataAlias.getKey(), marketDataAlias.getValue());
          }
        }
      }
      _compiled = true;
    }
  }

  public synchronized void store(LocalDate resultsDate, ViewComputationResultModel results) {
    assert _compiled;
    final int date = LocalDateToIntConverter.convertToInt(resultsDate);
    for (final ViewResultEntry viewResult : results.getAllResults()) {
      final ComputedValue computedValue = viewResult.getComputedValue();
      final Object value = computedValue.getValue();
      if ((value != null) && !(value instanceof MissingValue)) {
        final ConfigurationResults configResults = _results.get(viewResult.getCalculationConfiguration());
        configResults.store(date, computedValue.getSpecification(), value);
      }
    }
    if (_marketData != null) {
      for (final ComputedValue computedValue : results.getAllMarketData()) {
        final Object value = computedValue.getValue();
        if ((value != null) && !(value instanceof MissingValue)) {
          _marketData.store(date, computedValue.getSpecification(), value);
        }
      }
    }
  }

  public synchronized Map<String, HistoricalViewEvaluationResult> getResults() {
    final Map<String, HistoricalViewEvaluationResult> results = Maps.newHashMapWithExpectedSize(_results.size());
    for (final Map.Entry<String, ConfigurationResults> result : _results.entrySet()) {
      results.put(result.getKey(), result.getValue().makeResult());
    }
    return results;
  }

  public synchronized HistoricalViewEvaluationMarketData getMarketData() {
    if (_marketData == null) {
      return null;
    }
    return _marketData.makeResult();
  }

}
TOP

Related Classes of com.opengamma.financial.view.HistoricalViewEvaluationResultBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.