playground.ivt.utils.TripModeShares.java Source code

Java tutorial

Introduction

Here is the source code for playground.ivt.utils.TripModeShares.java

Source

/* *********************************************************************** *
 * project: org.matsim.*
 * TripModeShares.java
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 * copyright       : (C) 2013 by the members listed in the COPYING,        *
 *                   LICENSE and WARRANTY file.                            *
 * email           : info at matsim dot org                                *
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *   See also COPYING, LICENSE and WARRANTY file                           *
 *                                                                         *
 * *********************************************************************** */
package playground.ivt.utils;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.DefaultTableXYDataset;
import org.jfree.data.xy.XYSeries;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.Plan;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.events.ShutdownEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
import org.matsim.core.controler.listener.ShutdownListener;
import org.matsim.core.router.MainModeIdentifier;
import org.matsim.core.router.StageActivityTypes;
import org.matsim.core.router.TripRouter;
import org.matsim.core.router.TripStructureUtils;
import org.matsim.core.router.TripStructureUtils.Trip;
import org.matsim.core.utils.charts.ChartUtil;
import org.matsim.core.utils.io.IOUtils;
import org.matsim.core.utils.io.UncheckedIOException;

import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * @author thibautd
 */
@Singleton
public class TripModeShares implements IterationEndsListener, ShutdownListener {
    private final int graphWriteInterval;
    private final String pngFileName;
    private final Scenario scenario;
    private final MainModeIdentifier mainModeIdentifier;
    private final StageActivityTypes stageActivityTypes;

    private final BufferedWriter writer;
    private final History history = new History();

    @Inject
    public TripModeShares(final OutputDirectoryHierarchy outputDirectoryHierarchy, final Scenario scenario,
            final TripRouter tripRouter) {
        this(10, outputDirectoryHierarchy, scenario, tripRouter.getMainModeIdentifier(),
                tripRouter.getStageActivityTypes());
    }

    public TripModeShares(final int graphWriteInterval, final OutputDirectoryHierarchy outputDirectoryHierarchy,
            final Scenario scenario, final MainModeIdentifier mainModeIdentifier,
            final StageActivityTypes stageActivityTypes) {
        this.graphWriteInterval = graphWriteInterval;
        this.scenario = scenario;
        this.mainModeIdentifier = mainModeIdentifier;
        this.stageActivityTypes = stageActivityTypes;

        this.pngFileName = outputDirectoryHierarchy.getOutputFilename("tripModeShares.png");
        this.writer = IOUtils.getBufferedWriter(outputDirectoryHierarchy.getOutputFilename("tripModeShares.dat"));
        try {
            this.writer.write("iter\tmode\tnTrips");
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    @Override
    public void notifyIterationEnds(final IterationEndsEvent event) {
        recordHistory(event.getIteration());
        writeDataFile(event.getIteration());
        if (graphWriteInterval < 1 || event.getIteration() % graphWriteInterval == 0) {
            writePng();
        }
    }

    private void writePng() {
        final DefaultTableXYDataset dataset = new DefaultTableXYDataset();

        for (ModeHistory h : history.getHistories()) {
            final XYSeries series = new XYSeries(h.mode, false, false);

            for (int i : history.getIterations()) {
                series.add(i, h.getCount(i));
            }

            dataset.addSeries(series);
        }

        final ChartUtil chart = new WrapperChartUtil(
                ChartFactory.createStackedXYAreaChart("number of trips per mode", "iteration", "n trips", dataset,
                        PlotOrientation.VERTICAL, true, false, false));
        chart.addMatsimLogo();
        chart.saveAsPng(this.pngFileName, 800, 600);

    }

    private void writeDataFile(final int iteration) {
        for (ModeHistory h : history.getHistories()) {
            if (h.getLastIteration() != iteration)
                continue;

            try {
                writer.newLine();
                writer.write(iteration + "\t" + h.mode + "\t" + h.getLastCount());
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
        try {
            writer.flush();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    @Override
    public void notifyShutdown(final ShutdownEvent event) {
        writePng();
        try {
            writer.close();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    private void recordHistory(final int iteration) {
        for (Person person : scenario.getPopulation().getPersons().values()) {
            final Plan plan = person.getSelectedPlan();
            final List<Trip> trips = TripStructureUtils.getTrips(plan, stageActivityTypes);

            for (Trip t : trips) {
                history.increment(iteration, mainModeIdentifier.identifyMainMode(t.getTripElements()));
            }
        }
    }

    private static class History {
        private final Map<String, ModeHistory> histories = new TreeMap<String, ModeHistory>();
        private final Set<Integer> iterations = new TreeSet<Integer>();

        public Iterable<ModeHistory> getHistories() {
            return histories.values();
        }

        public void increment(final int iter, final String mode) {
            iterations.add(iter);
            get(mode).increment(iter);
        }

        public Iterable<Integer> getIterations() {
            return iterations;
        }

        private ModeHistory get(final String mode) {
            ModeHistory h = histories.get(mode);

            if (h == null) {
                h = new ModeHistory(mode);
                histories.put(mode, h);
            }

            return h;
        }
    }

    private static class ModeHistory {
        public final String mode;
        private final List<Integer> iterations = new ArrayList<Integer>();
        private int[] countPerIteration = new int[0];

        public ModeHistory(final String mode) {
            this.mode = mode;
        }

        private void increment(final int iteration) {
            notifyIteration(iteration);
            countPerIteration[countPerIteration.length - 1]++;
        }

        private void notifyIteration(final int iteration) {
            if (iterations.contains(iteration)) {
                if (iterations.indexOf(iteration) != iterations.size() - 1) {
                    throw new IllegalArgumentException(iteration + " is not the last element of " + iterations);
                }
                return;
            }

            iterations.add(iteration);
            countPerIteration = Arrays.copyOf(countPerIteration, countPerIteration.length + 1);
        }

        public int getLastIteration() {
            return iterations.get(iterations.size() - 1);
        }

        public int getLastCount() {
            return countPerIteration[countPerIteration.length - 1];
        }

        //public double[] getIterations() {
        //   final double[] array = new double[ iterations.size() ];

        //   int i = 0;
        //   for (int iter : iterations) {
        //      array[ i ] = iter;
        //      i++;
        //   }

        //   return array;
        //}

        //public double[] getCounts() {
        //   final double[] array = new double[ countPerIteration.length ];

        //   for (int i = 0; i < countPerIteration.length; i++) {
        //      array[ i ] = countPerIteration[ i ];
        //   }

        //   return array;
        //}

        public int getCount(final int iteration) {
            int c = 0;
            for (int iter : iterations) {
                if (iter == iteration)
                    return countPerIteration[c];
                c++;
            }
            return 0;
        }
    }
}