public RouteDistancePerUserGroup() {
   super();
   this.sc =
       LoadMyScenarios.loadScenarioFromPlansNetworkAndConfig(plansFile, networkFile, configFile);
   this.usrGrpExtended = new UserGroupUtilsExtended();
   userGrpToBoxPlotData = new TreeMap<UserGroup, List<Double>>();
 }
  @Override
  public void preProcessData() {

    double simulationEndTime = LoadMyScenarios.getSimulationEndTime(this.configFile);
    this.handler = new TollInfoHandler(simulationEndTime, noOfTimeBin);

    EventsManager events = EventsUtils.createEventsManager();
    MatsimEventsReader reader = new MatsimEventsReader(events);
    events.addHandler(handler);
    reader.readFile(eventsFile);
  }
  public CongestionPricingComperator(String runScenario) {
    this.pricingScenario = runScenario;
    scenario = LoadMyScenarios.loadScenarioFromOutputDir(runDir + pricingScenario + "/");
    simulationEndTime = scenario.getConfig().qsim().getEndTime();
    int lastIt = scenario.getConfig().controler().getLastIteration();
    eventsFile = runDir + pricingScenario + "/ITERS/it." + lastIt + "/" + lastIt + ".events.xml.gz";

    //

    Config config = scenario.getConfig();
    vttsCar =
        ((config.planCalcScore().getModes().get(TransportMode.car).getMarginalUtilityOfTraveling()
                    / 3600)
                + (config.planCalcScore().getPerforming_utils_hr() / 3600))
            / (config.planCalcScore().getMarginalUtilityOfMoney());
  }
/** @author amit */
public class RouteDistancePerUserGroup {

  public RouteDistancePerUserGroup() {
    super();
    this.sc =
        LoadMyScenarios.loadScenarioFromPlansNetworkAndConfig(plansFile, networkFile, configFile);
    this.usrGrpExtended = new UserGroupUtilsExtended();
    userGrpToBoxPlotData = new TreeMap<UserGroup, List<Double>>();
  }

  private Logger logger = Logger.getLogger(RouteDistancePerUserGroup.class);
  private String outputDir =
      "../../../repos/runs-svn/detEval/emissionCongestionInternalization/output/1pct/run10/policies/eci/"; /*"./output/run2/";*/
  private String networkFile = outputDir + "/output_network.xml.gz"; // "/network.xml";
  private String plansFile = outputDir + "/output_plans.xml.gz"; // "/network.xml";
  private String configFile = outputDir + "/output_config.xml";
  private int lastIteration = LoadMyScenarios.getLastIteration(configFile);
  private String eventsFile =
      outputDir + "/ITERS/it." + lastIteration + "/" + lastIteration + ".events.xml.gz";
  private Scenario sc;
  private UserGroupUtilsExtended usrGrpExtended;
  private SortedMap<UserGroup, SortedMap<String, Double>> usrGrp2Mode2MeanDistance =
      new TreeMap<UserGroup, SortedMap<String, Double>>();
  private SortedMap<UserGroup, SortedMap<String, Double>> usrGrp2Mode2MedianDistance =
      new TreeMap<UserGroup, SortedMap<String, Double>>();
  private SortedMap<String, Map<Id<Person>, List<Double>>> mode2PersonId2RouteDist;
  private SortedMap<UserGroup, List<Double>> userGrpToBoxPlotData;
  private final String mainMode = TransportMode.car;

  public static void main(String[] args) {
    RouteDistancePerUserGroup routeDistUG = new RouteDistancePerUserGroup();
    routeDistUG.run();
  }

  private void run() {
    LegModeRouteDistanceDistributionHandler lmdfed =
        new LegModeRouteDistanceDistributionHandler(sc);

    EventsManager manager = EventsUtils.createEventsManager();
    MatsimEventsReader reader = new MatsimEventsReader(manager);
    manager.addHandler(lmdfed);
    reader.readFile(eventsFile);

    this.mode2PersonId2RouteDist = lmdfed.getMode2PersonId2TravelDistances();
    getUserGroupDistanceMeanAndMeadian();
    createBoxPlotData(lmdfed.getLegMode2PersonId2TotalTravelDistance().get(mainMode));
    writeResults(this.outputDir + "/analysis/");
  }

  public void writeResults(String outputFolder) {
    BufferedWriter writer =
        IOUtils.getBufferedWriter(
            outputFolder + "/usrGrp2TravelMode2MeanAndMedianRouteDistance.txt");
    try {
      writer.write("UserGroup \t travelMode \t MeanRouteDistance \t MedianRouteDistance \n");
      for (UserGroup ug : this.usrGrp2Mode2MeanDistance.keySet()) {
        for (String travelMode : this.usrGrp2Mode2MeanDistance.get(ug).keySet()) {
          writer.write(
              ug
                  + "\t"
                  + travelMode
                  + "\t"
                  + this.usrGrp2Mode2MeanDistance.get(ug).get(travelMode)
                  + "\t"
                  + this.usrGrp2Mode2MedianDistance.get(ug).get(travelMode)
                  + "\n");
        }
      }
      writer.close();
    } catch (Exception e) {
      throw new RuntimeException("Data is not written to a file.");
    }

    logger.info("Writing data for box plots for each user group.");
    try {
      String outputFile = outputFolder + "/boxPlot/";
      new File(outputFile).mkdirs();
      for (UserGroup ug : this.userGrpToBoxPlotData.keySet()) {
        writer = IOUtils.getBufferedWriter(outputFile + "/travelDistance_" + ug + ".txt");
        writer.write(ug + "\n");
        for (double d : this.userGrpToBoxPlotData.get(ug)) {
          writer.write(d + "\n");
        }
        writer.close();
      }

    } catch (Exception e) {
      throw new RuntimeException("Data is not written to a file.");
    }
    this.logger.info("Data writing is finished.");
  }

  private void createBoxPlotData(Map<Id<Person>, Double> map) {
    PersonFilter pf = new PersonFilter();

    for (UserGroup ug : UserGroup.values()) {
      Population relevantPop = pf.getPopulation(sc.getPopulation(), ug);
      userGrpToBoxPlotData.put(
          ug, this.usrGrpExtended.getTotalStatListForBoxPlot(map, relevantPop));
    }
  }

  private void getUserGroupDistanceMeanAndMeadian() {
    PersonFilter pf = new PersonFilter();
    for (UserGroup ug : UserGroup.values()) {
      Population pop = pf.getPopulation(sc.getPopulation(), ug);
      this.usrGrp2Mode2MeanDistance.put(
          ug, this.usrGrpExtended.calculateTravelMode2MeanFromLists(mode2PersonId2RouteDist, pop));
      this.usrGrp2Mode2MedianDistance.put(
          ug,
          this.usrGrpExtended.calculateTravelMode2MedianFromLists(mode2PersonId2RouteDist, pop));
    }
  }
}