org.onebusaway.nyc.vehicle_tracking.utility.SensorModelVerificationMain.java Source code

Java tutorial

Introduction

Here is the source code for org.onebusaway.nyc.vehicle_tracking.utility.SensorModelVerificationMain.java

Source

/**
 * Copyright (c) 2011 Metropolitan Transportation Authority
 *
 * 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.nyc.vehicle_tracking.utility;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.onebusaway.container.ContainerLibrary;
import org.onebusaway.geospatial.model.CoordinatePoint;
import org.onebusaway.gtfs.csv.CsvEntityReader;
import org.onebusaway.gtfs.csv.ListEntityHandler;
import org.onebusaway.gtfs.csv.exceptions.CsvEntityIOException;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.JourneyPhaseSummaryLibrary;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.MotionModelImpl;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.Observation;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.rules.Context;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.rules.SensorModelRule;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.rules.SensorModelSupportLibrary;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.BlockState;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.EdgeState;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.JourneyPhaseSummary;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.JourneyStartState;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.JourneyState;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.MotionState;
import org.onebusaway.nyc.vehicle_tracking.impl.inference.state.VehicleState;
import org.onebusaway.nyc.vehicle_tracking.impl.particlefilter.SensorModelResult;
import org.onebusaway.nyc.vehicle_tracking.model.NycTestLocationRecord;
import org.onebusaway.nyc.vehicle_tracking.model.NycVehicleLocationRecord;
import org.onebusaway.nyc.vehicle_tracking.services.BaseLocationService;
import org.onebusaway.nyc.vehicle_tracking.services.DestinationSignCodeService;
import org.onebusaway.realtime.api.EVehiclePhase;
import org.onebusaway.transit_data_federation.services.AgencyAndIdLibrary;
import org.onebusaway.transit_data_federation.services.blocks.BlockCalendarService;
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.blocks.ScheduledBlockLocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;

public class SensorModelVerificationMain {

    private static DecimalFormat _format = new DecimalFormat("0.000");

    private static final String ARG_RULE = "rule";

    private MotionModelImpl _motionModel;

    private DestinationSignCodeService _dscService;

    private SensorModelSupportLibrary _sensorModelSupportLibrary;

    private List<File> _traces;

    private Collection<SensorModelRule> _rules;

    private BlockCalendarService _blockCalendarService;

    private ScheduledBlockLocationService _scheduledBlockLocationService;

    private JourneyPhaseSummaryLibrary _journeyStatePhaseLibrary = new JourneyPhaseSummaryLibrary();

    private BaseLocationService _baseLocationService;

    @Autowired
    public void setMotionModel(MotionModelImpl motionModel) {
        _motionModel = motionModel;
    }

    @Autowired
    public void setDestinationSignCodeService(DestinationSignCodeService destinationSignCodeService) {
        _dscService = destinationSignCodeService;
    }

    @Autowired
    public void setBaseLocationService(BaseLocationService baseLocationService) {
        _baseLocationService = baseLocationService;
    }

    @Autowired
    public void setSensorModelSupportLibrary(SensorModelSupportLibrary sensorModelSupportLibrary) {
        _sensorModelSupportLibrary = sensorModelSupportLibrary;
    }

    @Autowired
    public void setBlockCalendarService(BlockCalendarService blockCalendarService) {
        _blockCalendarService = blockCalendarService;
    }

    @Autowired
    public void setScheduledBlockLocationService(ScheduledBlockLocationService scheduledBlockLocationService) {
        _scheduledBlockLocationService = scheduledBlockLocationService;
    }

    public static void main(String[] args)
            throws ParseException, ClassNotFoundException, CsvEntityIOException, IOException {

        Options options = new Options();
        options.addOption(ARG_RULE, true, "sensor model rule class");
        GnuParser parser = new GnuParser();
        CommandLine cli = parser.parse(options, args);

        args = cli.getArgs();

        if (args.length != 2) {
            System.err.println("usage: data-sources.xml tracesPath");
            System.exit(-1);
        }

        ConfigurableApplicationContext context = ContainerLibrary.createContext(
                "classpath:org/onebusaway/nyc/vehicle_tracking/application-context.xml",
                "classpath:org/onebusaway/transit_data_federation/application-context.xml", args[0]);

        SensorModelVerificationMain m = new SensorModelVerificationMain();
        context.getAutowireCapableBeanFactory().autowireBean(m);

        Collection<SensorModelRule> rules = Collections.emptyList();

        if (cli.hasOption(ARG_RULE)) {
            Class<?> ruleClass = Class.forName(cli.getOptionValue(ARG_RULE));
            rules = Arrays.asList((SensorModelRule) context.getBean(ruleClass));
        } else {
            Map<String, SensorModelRule> rulesByName = context.getBeansOfType(SensorModelRule.class);
            rules = rulesByName.values();
        }

        m.setRules(rules);

        File tracePath = new File(args[1]);
        List<File> traces = new ArrayList<File>();
        getAllTraces(tracePath, traces);
        m.setTraces(traces);

        try {
            m.run();
        } catch (Throwable ex) {
            ex.printStackTrace();
            System.exit(-1);
        }

        System.exit(0);
    }

    public void setTraces(List<File> traces) {
        _traces = traces;
    }

    public void setRules(Collection<SensorModelRule> rules) {
        _rules = rules;
    }

    public void run() throws CsvEntityIOException, IOException {

        for (SensorModelRule rule : _rules) {

            System.out.println(rule);

            for (File trace : _traces) {

                System.out.println(trace);

                List<NycTestLocationRecord> records = readRecords(trace);

                VehicleState prevState = null;
                Observation prevObs = null;

                int index = 1;

                for (NycTestLocationRecord record : records) {
                    try {
                        Observation obs = getRecordAsObservation(record, prevObs);
                        VehicleState state = getRecordAsVehicleState(record, prevState, obs);

                        Context context = new Context(prevState, state, obs);
                        SensorModelResult result = rule.likelihood(_sensorModelSupportLibrary, context);

                        double p = result.getProbability();

                        if (p <= 0.1) {
                            String label = _format.format(p);
                            System.out.println(label + " " + index);

                            rule.likelihood(_sensorModelSupportLibrary, context);
                        }

                        prevObs = obs;
                        prevState = state;
                        index++;

                    } catch (Throwable ex) {
                        throw new IllegalStateException("problem with " + trace.getName() + " line " + index, ex);
                    }
                }
            }
        }

    }

    private static void getAllTraces(File tracePath, List<File> traces) {
        if (tracePath.isDirectory()) {
            for (File child : tracePath.listFiles())
                getAllTraces(child, traces);
        } else {
            String name = tracePath.getName();
            if (name.endsWith(".csv.gz") || name.endsWith(".csv")) {
                traces.add(tracePath);
            }
        }
    }

    private List<NycTestLocationRecord> readRecords(File path) throws CsvEntityIOException, IOException {

        InputStream in = new FileInputStream(path);
        if (path.getName().endsWith(".gz"))
            in = new GZIPInputStream(in);

        CsvEntityReader reader = new CsvEntityReader();

        ListEntityHandler<NycTestLocationRecord> handler = new ListEntityHandler<NycTestLocationRecord>();
        reader.addEntityHandler(handler);

        reader.readEntities(NycTestLocationRecord.class, in);

        in.close();

        return handler.getValues();
    }

    private Observation getRecordAsObservation(NycTestLocationRecord record, Observation prevObs) {

        String dsc = record.getDsc();
        String lastValidDestinationSignCode = null;

        if (dsc != null && !_dscService.isMissingDestinationSignCode(dsc)) {
            lastValidDestinationSignCode = dsc;
        } else if (prevObs != null) {
            lastValidDestinationSignCode = prevObs.getLastValidDestinationSignCode();
        }

        NycVehicleLocationRecord r = new NycVehicleLocationRecord();
        r.setBearing(0);
        r.setDestinationSignCode(record.getDsc());
        r.setLatitude(record.getLat());
        r.setLongitude(record.getLon());
        r.setTime(record.getTimestamp());
        r.setTimeReceived(record.getTimestamp());
        r.setVehicleId(new AgencyAndId("2008", record.getVehicleId()));

        CoordinatePoint location = new CoordinatePoint(record.getLat(), record.getLon());

        boolean atBase = _baseLocationService.getBaseNameForLocation(location) != null;
        boolean atTerminal = _baseLocationService.getTerminalNameForLocation(location) != null;
        boolean outOfService = lastValidDestinationSignCode == null
                || _dscService.isOutOfServiceDestinationSignCode(lastValidDestinationSignCode)
                || _dscService.isUnknownDestinationSignCode(lastValidDestinationSignCode);

        return new Observation(record.getTimestamp(), r, lastValidDestinationSignCode, atBase, atTerminal,
                outOfService, prevObs);
    }

    private VehicleState getRecordAsVehicleState(NycTestLocationRecord record, VehicleState prevState,
            Observation obs) {

        EdgeState edgeState = null;

        MotionState motionState = createMotionState(prevState, obs);

        BlockState blockState = createBlockState(record, prevState, obs);

        JourneyState journeyState = createJourneyState(record, prevState, obs);

        List<JourneyPhaseSummary> summaries = _journeyStatePhaseLibrary.extendSummaries(prevState, blockState,
                journeyState, obs);

        return new VehicleState(edgeState, motionState, blockState, journeyState, summaries, obs);
    }

    private MotionState createMotionState(VehicleState prevState, Observation obs) {
        if (prevState == null)
            return _motionModel.updateMotionState(obs);
        return _motionModel.updateMotionState(prevState, obs);
    }

    private BlockState createBlockState(NycTestLocationRecord record, VehicleState prevState, Observation obs) {

        String blockId = record.getActualBlockId();

        if (blockId == null)
            return null;

        long serviceDate = record.getActualServiceDate();

        AgencyAndId bid = AgencyAndIdLibrary.convertFromString(blockId);

        BlockInstance blockInstance = _blockCalendarService.getBlockInstance(bid, serviceDate);

        if (blockInstance == null)
            throw new IllegalStateException("bad");

        double d = record.getActualDistanceAlongBlock();

        ScheduledBlockLocation location = _scheduledBlockLocationService
                .getScheduledBlockLocationFromDistanceAlongBlock(blockInstance.getBlock(), d);

        return new BlockState(blockInstance, location, obs.getLastValidDestinationSignCode());
    }

    private JourneyState createJourneyState(NycTestLocationRecord record, VehicleState prevState, Observation obs) {
        String phase = record.getActualPhase();
        JourneyState journeyState = getTransitionJourneyStates(prevState, obs, EVehiclePhase.valueOf(phase));
        return journeyState;
    }

    public JourneyState getTransitionJourneyStates(VehicleState parentState, Observation obs, EVehiclePhase phase) {

        switch (phase) {
        case AT_BASE:
            return JourneyState.atBase();
        case DEADHEAD_BEFORE:
            return JourneyState.deadheadBefore(getJourneyStart(parentState, obs));
        case LAYOVER_BEFORE:
            return JourneyState.layoverBefore();
        case IN_PROGRESS:
            return JourneyState.inProgress();
        case DEADHEAD_DURING:
            return JourneyState.deadheadDuring(getJourneyStart(parentState, obs));
        case LAYOVER_DURING:
            return JourneyState.layoverDuring();
        case DEADHEAD_AFTER:
            return JourneyState.deadheadAfter();
        case LAYOVER_AFTER:
            return JourneyState.layoverAfter();
        default:
            throw new IllegalStateException("unknown journey state: " + phase);
        }
    }

    private CoordinatePoint getJourneyStart(VehicleState parentState, Observation obs) {
        if (parentState == null)
            return obs.getLocation();
        JourneyState js = parentState.getJourneyState();
        if (js == null)
            return obs.getLocation();
        JourneyStartState start = js.getData();
        if (start == null)
            return obs.getLocation();
        return start.getJourneyStart();
    }
}