Package org.onebusaway.transit_data_federation.impl.realtime.history

Source Code of org.onebusaway.transit_data_federation.impl.realtime.history.RealTimeHistoryServiceImpl

/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.transit_data_federation.impl.realtime.history;

import java.util.Arrays;

import org.onebusaway.collections.Range;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.realtime.api.VehicleLocationRecord;
import org.onebusaway.transit_data_federation.services.blocks.BlockInstance;
import org.onebusaway.transit_data_federation.services.blocks.ScheduledBlockLocation;
import org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance;
import org.onebusaway.transit_data_federation.services.realtime.RealTimeHistoryService;
import org.onebusaway.transit_data_federation.services.realtime.ScheduleDeviationHistogram;
import org.onebusaway.transit_data_federation.services.realtime.ScheduleDeviationSamples;
import org.onebusaway.transit_data_federation.services.transit_graph.BlockStopTimeEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.BlockTripEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.StopTimeEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.TripEntry;
import org.onebusaway.utility.InterpolationLibrary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cern.colt.list.DoubleArrayList;
import cern.jet.random.Normal;
import cern.jet.random.engine.RandomEngine;
import cern.jet.stat.Descriptive;

@Component
public class RealTimeHistoryServiceImpl implements RealTimeHistoryService {

  private ScheduleDeviationHistoryDaoImpl _scheduleDeviationHistoryDao;

  private int _predictionLookahead = 20 * 60;

  private Normal _schedDevScaleParam = new Normal(0, 5 * 60,
      RandomEngine.makeDefault());

  @Autowired
  public void setScheduleDeviationHistoryDao(
      ScheduleDeviationHistoryDaoImpl scheduleDeviationHistoryDao) {
    _scheduleDeviationHistoryDao = scheduleDeviationHistoryDao;
  }

  public void setPredictionLookahead(int predictionLookahead) {
    _predictionLookahead = predictionLookahead;
  }

  @Override
  public ScheduleDeviationHistogram getScheduleDeviationHistogramForArrivalAndDepartureInstance(
      ArrivalAndDepartureInstance instance, int stepSizeInSeconds) {

    BlockTripEntry blockTrip = instance.getBlockTrip();
    TripEntry trip = blockTrip.getTrip();
    AgencyAndId tripId = trip.getId();

    ScheduleDeviationHistory history = _scheduleDeviationHistoryDao.getScheduleDeviationHistoryForTripId(tripId);
   
    if( history == null)
      return null;

    BlockStopTimeEntry blockStopTime = instance.getBlockStopTime();
    StopTimeEntry stopTime = blockStopTime.getStopTime();

    double[] values = getScheduleDeviationsForScheduleTime(history,
        stopTime.getDepartureTime());
    return createHistogramFromValues(values, stepSizeInSeconds);
  }

  @Override
  public ScheduleDeviationSamples sampleScheduleDeviationsForVehicle(
      BlockInstance instance, VehicleLocationRecord record,
      ScheduledBlockLocation scheduledBlockLocation) {
   
    if( true )
      return null;

    BlockTripEntry blockTrip = scheduledBlockLocation.getActiveTrip();
    TripEntry trip = blockTrip.getTrip();

    ScheduleDeviationHistory history = _scheduleDeviationHistoryDao.getScheduleDeviationHistoryForTripId(trip.getId());

    if (history == null)
      return null;

    ScheduleDeviationHistory resampledHistory = resampleHistory(history,
        scheduledBlockLocation.getScheduledTime(),
        record.getScheduleDeviation());

    DoubleArrayList scheduleTimes = new DoubleArrayList();
    DoubleArrayList mus = new DoubleArrayList();
    DoubleArrayList sigmas = new DoubleArrayList();

    for (int t = 0; t <= _predictionLookahead; t += 5 * 60) {

      int scheduleTime = scheduledBlockLocation.getScheduledTime() + t;
      double[] deviations = getScheduleDeviationsForScheduleTime(
          resampledHistory, scheduleTime);

      deviations = noNans(deviations);
      DoubleArrayList values = new DoubleArrayList(deviations);

      double mu = Descriptive.mean(values);
      double var = Descriptive.sampleVariance(values, mu);
      double sigma = Descriptive.sampleStandardDeviation(values.size(), var);

      scheduleTimes.add(scheduleTime);
      mus.add(mu);
      sigmas.add(sigma);
    }

    scheduleTimes.trimToSize();
    mus.trimToSize();
    sigmas.trimToSize();

    return new ScheduleDeviationSamples(scheduleTimes.elements(),
        mus.elements(), sigmas.elements());
  }

  /****
   * Private
   ****/

  /**
   * @param history
   * @param distanceAlongBlock
   * @return
   */

  private double[] getScheduleDeviationsForScheduleTime(
      ScheduleDeviationHistory history, int scheduleTime) {

    double[] scheduleTimes = history.getScheduleTimes();
    double[][] scheduleDeviations = history.getScheduleDeviations();

    int index = Arrays.binarySearch(scheduleTimes, scheduleTime);

    if (index >= 0)
      return getColumn(scheduleDeviations, index);

    index = -(index + 1);

    if (index == scheduleTimes.length)
      return getColumn(scheduleDeviations, index - 1);
    if (index == 0)
      return getColumn(scheduleDeviations, 0);

    int numSamples = history.getNumberOfSamples();
    double[] values = new double[numSamples];

    for (int i = 0; i < numSamples; i++) {
      double fromKey = scheduleTimes[index - 1];
      double toKey = scheduleTimes[index];
      double fromValue = scheduleDeviations[i][index - 1];
      double toValue = scheduleDeviations[i][index];
      values[i] = InterpolationLibrary.interpolatePair(fromKey, fromValue,
          toKey, toValue, scheduleTime);
    }

    return values;
  }

  private double[] getColumn(double[][] values, int index) {
    double[] v = new double[values.length];
    for (int i = 0; i < values.length; i++)
      v[i] = values[i][index];
    return v;
  }

  private double[] noNans(double[] values) {
    DoubleArrayList vs = new DoubleArrayList();
    for (double v : values) {
      if (!Double.isNaN(v))
        vs.add(v);
    }
    vs.trimToSize();
    return vs.elements();
  }

  private ScheduleDeviationHistogram createHistogramFromValues(double[] values,
      int stepSizeInSeconds) {

    values = noNans(values);

    if (values.length == 0)
      return new ScheduleDeviationHistogram(new int[0], new int[0]);

    Range r = new Range();
    for (double v : values)
      r.addValue(v);

    if (r.getRange() == 0)
      return new ScheduleDeviationHistogram(new int[] {(int) values[0]},
          new int[] {values.length});
   
    int halfStep = stepSizeInSeconds / 2;

    int from = (int) (Math.floor((r.getMin()-halfStep) / stepSizeInSeconds) * stepSizeInSeconds) + halfStep;
    int to = (int) (Math.ceil((r.getMax()+halfStep) / stepSizeInSeconds) * stepSizeInSeconds) - halfStep;
    int columns = (to - from) / stepSizeInSeconds;

    int[] scheduleDeviations = new int[columns];
    int[] counts = new int[columns];

    for (int i = 0; i < columns; i++)
      scheduleDeviations[i] = from + stepSizeInSeconds * i + halfStep;

    for (double value : values) {
      int index = (int) ((value - from) / stepSizeInSeconds);
      counts[index]++;
    }

    return new ScheduleDeviationHistogram(scheduleDeviations, counts);
  }

  private ScheduleDeviationHistory resampleHistory(
      ScheduleDeviationHistory history, int scheduleTime, double activeDeviation) {

    double[] deviations = getScheduleDeviationsForScheduleTime(history,
        scheduleTime);

    CDFMap<Integer> cdf = new CDFMap<Integer>();
    for (int i = 0; i < deviations.length; i++) {
      double deviation = deviations[i];
      if (Double.isNaN(deviation))
        continue;
      double p = _schedDevScaleParam.apply(activeDeviation - deviation);
      cdf.put(p, i);
    }

    int numSamples = deviations.length;

    double[] scheduleTimes = history.getScheduleTimes();
    double[][] scheduleDeviations = history.getScheduleDeviations();

    double[][] sampledScheduleDeviations = new double[numSamples][];

    for (int i = 0; i < numSamples; i++) {
      int index = cdf.sample();
      sampledScheduleDeviations[i] = scheduleDeviations[index];
    }

    return new ScheduleDeviationHistory(history.getTripId(), scheduleTimes,
        sampledScheduleDeviations);
  }
}
TOP

Related Classes of org.onebusaway.transit_data_federation.impl.realtime.history.RealTimeHistoryServiceImpl

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.