MATSIM
DumpDataAtEndImpl.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * DumpDataAtEnd.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2009 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 package org.matsim.core.controler.corelisteners;
21 
22 import com.google.inject.Inject;
23 import com.google.inject.Singleton;
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.Logger;
26 import org.matsim.api.core.v01.Scenario;
31 import org.matsim.core.config.Config;
44 import org.matsim.core.utils.io.IOUtils;
45 import org.matsim.counts.Counts;
51 import org.matsim.lanes.Lanes;
60 
61 import java.util.Collections;
62 import java.util.Map;
63 
64 @Singleton
65 final class DumpDataAtEndImpl implements DumpDataAtEnd, ShutdownListener {
66  private static final Logger log = LogManager.getLogger( DumpDataAtEndImpl.class );
67 
68  @Inject
69  private Config config;
70 
71  @Inject
72  private ControllerConfigGroup controllerConfigGroup;
73 
74  @Inject
75  private VspExperimentalConfigGroup vspConfig;
76 
77  @Inject
78  private Network network;
79 
80  @Inject
81  private Population population;
82 
83  @Inject
84  private ActivityFacilities activityFacilities;
85 
86  @Inject
87  private Vehicles vehicles;
88 
89  @Inject(optional = true)
90  private TransitSchedule transitSchedule = null;
91 
92  @Inject(optional = true)
93  @Transit
94  private Vehicles transitVehicles = null;
95 
96  @Inject(optional = true)
97  private Counts<Link> counts = null;
98 
99  @Inject
100  private Households households;
101 
102  @Inject
103  private Lanes lanes;
104 
105  @Inject
106  private Scenario scenario;
107 
108  @Inject
109  private OutputDirectoryHierarchy controlerIO;
110 
111  @Inject
112  private Map<Class<?>,AttributeConverter<?>> attributeConverters = Collections.emptyMap();
113  // (yyyy Feels plausible to have them but how can they be set? And isn't there a more global way to set the attribute converters? kai, feb'24)
114 
115  @Override
116  public void notifyShutdown(ShutdownEvent event) {
117  if ( event.isUnexpected() ) {
118  return ;
119  }
120  dumpPlans();
121  dumpNetwork();
122  dumpConfig();
123  dumpFacilities();
124  dumpNetworkChangeEvents();
125 
126  dumpTransitSchedule();
127  dumpTransitVehicles();
128  dumpVehicles();
129  dumpHouseholds();
130  dumpLanes();
131  dumpCounts();
132 
133  if (!event.isUnexpected() && this.vspConfig.isWritingOutputEvents() && (this.controllerConfigGroup.getWriteEventsInterval()!=0)) {
134  dumpOutputEvents(event.getIteration());
135  }
136  dumpOutputTrips(event.getIteration());
137  dumpOutputLegs(event.getIteration());
138  dumpOutputActivities(event.getIteration());
139  dumpExperiencedPlans(event.getIteration());
140 
141  if (controllerConfigGroup.getCleanItersAtEnd() == ControllerConfigGroup.CleanIterations.delete) {
142  this.controlerIO.deleteIterationDirectory();
143  }
144  }
145 
146  private void dumpOutputEvents(int iteration) {
147  for (ControllerConfigGroup.EventsFileFormat format : this.controllerConfigGroup.getEventsFileFormats()) {
148  try{
149  Controler.DefaultFiles file;
150  switch (format) {
151  case xml:
152  file = Controler.DefaultFiles.events;
153  break;
154  case pb:
155  file = Controler.DefaultFiles.eventsPb;
156  break;
157  case json:
158  file = Controler.DefaultFiles.eventsJson;
159  break;
160  default:
161  continue;
162  }
163 
164  IOUtils.copyFile(this.controlerIO.getIterationFilename(iteration, file),
165  this.controlerIO.getOutputFilename(file));
166  } catch (Exception ee) {
167  LogManager.getLogger(this.getClass()).error("writing output events did not work; probably parameters were such that no events were "
168  + "generated in the final iteration");
169  }
170  }
171  }
172 
173  private void dumpOutputTrips(int iteration) {
174  try {
175  IOUtils.copyFile(this.controlerIO.getIterationFilename(iteration, Controler.DefaultFiles.tripscsv),
176  this.controlerIO.getOutputFilename(Controler.DefaultFiles.tripscsv));
177  } catch (Exception ee) {
178  LogManager.getLogger(this.getClass()).error("writing output trips did not work; probably parameters were such that no trips CSV were "
179  + "generated in the final iteration");
180  }
181  }
182 
183  private void dumpOutputActivities(int iteration) {
184  try {
185  IOUtils.copyFile(this.controlerIO.getIterationFilename(iteration, Controler.DefaultFiles.activitiescsv),
186  this.controlerIO.getOutputFilename(Controler.DefaultFiles.activitiescsv));
187  } catch (Exception ee) {
188  LogManager.getLogger(this.getClass()).error("writing output activities did not work; probably parameters were such that no activities CSV were "
189  + "generated in the final iteration");
190  }
191  }
192 
193  private void dumpOutputLegs(int iteration) {
194  try {
195  IOUtils.copyFile(this.controlerIO.getIterationFilename(iteration, Controler.DefaultFiles.legscsv),
196  this.controlerIO.getOutputFilename(Controler.DefaultFiles.legscsv));
197  } catch (Exception ee) {
198  LogManager.getLogger(this.getClass()).error("writing output legs did not work; probably parameters were such that no legs CSV were "
199  + "generated in the final iteration");
200  }
201  }
202 
203  private void dumpExperiencedPlans(int iteration) {
204  if (this.config.scoring().isWriteExperiencedPlans() ) {
205  try {
206  IOUtils.copyFile(this.controlerIO.getIterationFilename(iteration, Controler.DefaultFiles.experiencedPlans),
207  this.controlerIO.getOutputFilename(Controler.DefaultFiles.experiencedPlans));
208  } catch ( Exception ee ) {
209  LogManager.getLogger(this.getClass()).error("writing output experienced plans did not work; probably parameters were such that they "
210  + "were not generated in the final iteration", ee);
211  }
212  }
213  }
214 
215  private void dumpCounts() {
216  try {
217  if (this.counts != null ) {
218 // final String inputCRS = this.config.counts().getInputCRS();
219 // final String internalCRS = this.config.global().getCoordinateSystem();
220 
221 // if ( inputCRS == null ) {
222  new CountsWriter(this.counts).write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.counts));
223 // }
224 // else {
225 // log.info( "re-projecting counts from "+internalCRS+" back to "+inputCRS+" for export" );
226 //
227 // final CoordinateTransformation transformation =
228 // TransformationFactory.getCoordinateTransformation(
229 // internalCRS,
230 // inputCRS );
231 //
232 // new CountsWriter( transformation , this.counts).write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.counts));
233 // }
234  // we said at some point that we are no longer projecting back for the final output. For Counts, this was so far not
235  // adapted in this direction. I assume that the reason was that the CountsWriter took a transformation, not the
236  // coordinate string itself, and so it was not possible to automatically at the CRS string as attribute into the file.
237  // I adapted that now (I hope). kai, feb'24
238  }
239  } catch ( Exception ee ) {
240  log.error("Exception writing counts.", ee);
241  }
242  }
243 
244  private void dumpLanes() {
245  try {
246  if ( this.lanes!=null && !this.lanes.getLanesToLinkAssignments().isEmpty() ){
247  new LanesWriter( this.lanes ).write( this.controlerIO.getOutputFilename( Controler.DefaultFiles.lanes ) );
248  }
249  } catch ( Exception ee ) {
250  log.error("Exception writing lanes.", ee);
251  }
252  }
253 
254  private void dumpHouseholds() {
255  try {
256  HouseholdsWriterV10 writer = new HouseholdsWriterV10(this.households);
257  writer.putAttributeConverters(this.attributeConverters);
258  writer.writeFile(this.controlerIO.getOutputFilename(Controler.DefaultFiles.households));
259  } catch ( Exception ee ) {
260  log.error("Exception writing households.", ee);
261  }
262  }
263 
264  private void dumpVehicles() {
265  try {
266  new MatsimVehicleWriter(this.vehicles).writeFile(this.controlerIO.getOutputFilename(Controler.DefaultFiles.vehicles));
267  Vehicles allVehicles = VehicleUtils.getOrCreateAllvehicles( scenario );
268  if ( allVehicles!=null && !allVehicles.getVehicleTypes().isEmpty() ){
269  new MatsimVehicleWriter( allVehicles ).writeFile( this.controlerIO.getOutputFilename( Controler.DefaultFiles.allVehicles ) );
270  }
271  } catch ( Exception ee ) {
272  log.error("Exception writing vehicles.", ee);
273  }
274  }
275 
276  private void dumpTransitVehicles() {
277  try {
278  if (this.transitVehicles != null ) {
279  new MatsimVehicleWriter(this.transitVehicles).writeFile(this.controlerIO.getOutputFilename(Controler.DefaultFiles.transitVehicles));
280  }
281  } catch ( Exception ee ) {
282  log.error("Exception writing transit vehicles.", ee);
283  }
284  }
285 
286  private void dumpTransitSchedule() {
287  try {
288  if (this.transitSchedule != null ) {
289  new TransitScheduleWriter(this.transitSchedule).writeFile(this.controlerIO.getOutputFilename(Controler.DefaultFiles.transitSchedule));
290  }
291  } catch ( Exception ee ) {
292  log.error("Exception writing transit schedule.", ee);
293  }
294  }
295 
296  private void dumpNetworkChangeEvents() {
297  if (this.config.network().isTimeVariantNetwork()) {
298  new NetworkChangeEventsWriter().write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.changeEvents),
299  NetworkUtils.getNetworkChangeEvents(this.network));
300  }
301  }
302 
303  private void dumpFacilities() {
304  // dump facilities
305  try {
306  new FacilitiesWriter(this.activityFacilities).write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.facilities));
307  } catch ( Exception ee ) {
308  log.error("Exception writing facilities.", ee);
309  }
310  }
311 
312  private void dumpConfig() {
313  // dump config
314  new ConfigWriter(this.config).write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.config, ControllerConfigGroup.CompressionType.none));
315  new ConfigWriter(this.config, ConfigWriter.Verbosity.minimal).write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.configReduced, ControllerConfigGroup.CompressionType.none));
316  }
317 
318  private void dumpNetwork() {
319  // dump network
320  new NetworkWriter(this.network).write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.network));
321  }
322 
323  private void dumpPlans() {
324  // dump plans
325 
326  final PopulationWriter writer = new PopulationWriter(this.population, this.network);
327  writer.putAttributeConverters(this.attributeConverters);
328  writer.write(this.controlerIO.getOutputFilename(Controler.DefaultFiles.population));
329  }
330 
331 }