1 package net.sf.openrocket.file;
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.io.PrintWriter;
6 import java.util.ArrayList;
7 import java.util.Collections;
10 import net.sf.openrocket.aerodynamics.Warning;
11 import net.sf.openrocket.aerodynamics.WarningSet;
12 import net.sf.openrocket.document.Simulation;
13 import net.sf.openrocket.simulation.FlightData;
14 import net.sf.openrocket.simulation.FlightDataBranch;
15 import net.sf.openrocket.simulation.FlightDataType;
16 import net.sf.openrocket.simulation.FlightEvent;
17 import net.sf.openrocket.unit.Unit;
18 import net.sf.openrocket.util.TextUtil;
20 public class CSVExport {
23 * Exports the specified flight data branch into a CSV file.
25 * @param stream the stream to write to.
26 * @param simulation the simulation being exported.
27 * @param branch the branch to export.
28 * @param fields the fields to export (in appropriate order).
29 * @param units the units of the fields.
30 * @param fieldSeparator the field separator string.
31 * @param commentStarter the comment starting character(s).
32 * @param simulationComments whether to output general simulation comments.
33 * @param fieldComments whether to output field comments.
34 * @param eventComments whether to output comments for the flight events.
35 * @throws IOException if an I/O exception occurs.
37 public static void exportCSV(OutputStream stream, Simulation simulation,
38 FlightDataBranch branch, FlightDataType[] fields, Unit[] units,
39 String fieldSeparator, String commentStarter, boolean simulationComments,
40 boolean fieldComments, boolean eventComments) throws IOException {
42 if (fields.length != units.length) {
43 throw new IllegalArgumentException("fields and units lengths must be equal " +
44 "(" + fields.length + " vs " + units.length + ")");
48 PrintWriter writer = null;
51 writer = new PrintWriter(stream);
53 // Write the initial comments
54 if (simulationComments) {
55 writeSimulationComments(writer, simulation, branch, fields, commentStarter);
58 if (simulationComments && fieldComments) {
59 writer.println(commentStarter);
63 writer.print(commentStarter + " ");
64 for (int i = 0; i < fields.length; i++) {
65 writer.print(fields[i].getName() + " (" + units[i].getUnit() + ")");
66 if (i < fields.length - 1) {
67 writer.print(fieldSeparator);
73 writeData(writer, branch, fields, units, fieldSeparator,
74 eventComments, commentStarter);
81 } catch (Exception e) {
88 private static void writeData(PrintWriter writer, FlightDataBranch branch,
89 FlightDataType[] fields, Unit[] units, String fieldSeparator, boolean eventComments,
90 String commentStarter) {
92 // Number of data points
93 int n = branch.getLength();
95 // Flight events in occurrance order
96 List<FlightEvent> events = branch.getEvents();
97 Collections.sort(events);
98 int eventPosition = 0;
100 // List of field values
101 List<List<Double>> fieldValues = new ArrayList<List<Double>>();
102 for (FlightDataType t : fields) {
103 fieldValues.add(branch.get(t));
107 List<Double> time = branch.get(FlightDataType.TYPE_TIME);
108 if (eventComments && time == null) {
109 // If time information is not available, print events at beginning of file
110 for (FlightEvent e : events) {
111 printEvent(writer, e, commentStarter);
113 eventPosition = events.size();
117 // Loop over all data points
118 for (int pos = 0; pos < n; pos++) {
120 // Check for events to store
121 if (eventComments && time != null) {
122 double t = time.get(pos);
124 while ((eventPosition < events.size()) &&
125 (events.get(eventPosition).getTime() <= t)) {
126 printEvent(writer, events.get(eventPosition), commentStarter);
132 for (int i = 0; i < fields.length; i++) {
133 double value = fieldValues.get(i).get(pos);
134 writer.print(TextUtil.doubleToString(units[i].toUnit(value)));
135 if (i < fields.length - 1) {
136 writer.print(fieldSeparator);
143 // Store any remaining events
144 if (eventComments && time != null) {
145 while (eventPosition < events.size()) {
146 printEvent(writer, events.get(eventPosition), commentStarter);
154 private static void printEvent(PrintWriter writer, FlightEvent e,
155 String commentStarter) {
156 writer.println(commentStarter + " Event " + e.getType().name() +
157 " occurred at t=" + TextUtil.doubleToString(e.getTime()) + " seconds");
160 private static void writeSimulationComments(PrintWriter writer,
161 Simulation simulation, FlightDataBranch branch, FlightDataType[] fields,
162 String commentStarter) {
166 line = simulation.getName();
168 FlightData data = simulation.getSimulatedData();
170 switch (simulation.getStatus()) {
172 line += " (Up to date)";
176 line += " (Data loaded from a file)";
180 line += " (Data is out of date)";
184 line += " (Imported data)";
188 line += " (Not simulated yet)";
192 writer.println(commentStarter + " " + line);
195 writer.println(commentStarter + " " + branch.getLength() + " data points written for "
196 + fields.length + " variables.");
200 writer.println(commentStarter + " No simulation data available.");
203 WarningSet warnings = data.getWarningSet();
205 if (!warnings.isEmpty()) {
206 writer.println(commentStarter + " Simulation warnings:");
207 for (Warning w : warnings) {
208 writer.println(commentStarter + " " + w.toString());