def test_EngineSet(): """Tests behaviour of FuelEngineSet""" engine = DummyEngine(1.2e5, 1.0e-5) # input = thrust rate thrust_rate = np.linspace(0.0, 1.0, 20) for engine_count in [1, 2, 3, 4]: engine_set = FuelEngineSet(engine, engine_count) flight_point = FlightPoint(mach=0.0, altitude=0.0, engine_setting=1, thrust_rate=thrust_rate) engine_set.compute_flight_points(flight_point) assert_allclose(flight_point.sfc, engine.max_sfc * thrust_rate) assert_allclose(flight_point.thrust, engine.max_thrust * engine_count * thrust_rate) # input = thrust thrust = np.linspace(0.0, engine.max_thrust, 30) for engine_count in [1, 2, 3, 4]: engine_set = FuelEngineSet(engine, engine_count) flight_point = FlightPoint(mach=0.0, altitude=0.0, engine_setting=1, thrust=thrust) engine_set.compute_flight_points(flight_point) assert_allclose(flight_point.thrust_rate, thrust / engine_count / engine.max_thrust) assert_allclose(flight_point.sfc, engine.max_sfc * flight_point.thrust_rate)
def test_breguet_cruise(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) segment = BreguetCruiseSegment( target=FlightPoint(ground_distance=5.0e5), propulsion=propulsion, reference_area=120.0, polar=polar, engine_setting=EngineSetting. CRUISE, # The engine model does not use this setting ) flight_points = segment.compute_from( FlightPoint(time=10000.0, mass=70000.0, altitude=10000.0, mach=0.78)) print_dataframe(flight_points) first_point = flight_points.iloc[0] last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with CruiseSegment and 0.05s as # time step assert_allclose(first_point.altitude, 10000.0) assert_allclose(first_point.true_airspeed, 233.6, atol=0.1) assert first_point.engine_setting == EngineSetting.CRUISE assert_allclose(last_point.ground_distance, 500000.0) assert_allclose(last_point.altitude, 10000.0) assert_allclose(last_point.time, 12141.0, rtol=1e-2) assert_allclose(last_point.true_airspeed, 233.6, atol=0.1) assert_allclose(last_point.mass, 69568.0, rtol=1e-4) assert last_point.engine_setting == EngineSetting.CRUISE
def test_optimal_cruise(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) segment = OptimalCruiseSegment( target=FlightPoint(ground_distance=5.0e5), propulsion=propulsion, reference_area=120.0, polar=polar, engine_setting=EngineSetting.CRUISE, ) flight_points = segment.compute_from( FlightPoint(mass=70000.0, time=1000.0, ground_distance=1e5, mach=0.78)) print_dataframe(flight_points) first_point = flight_points.iloc[0] last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.05s as time step assert_allclose(first_point.altitude, 9156.0, atol=1.0) assert_allclose(first_point.true_airspeed, 236.4, atol=0.1) assert_allclose(first_point.CL, polar.optimal_cl) assert_allclose(first_point.CL, polar.optimal_cl) assert first_point.engine_setting == EngineSetting.CRUISE assert_allclose(last_point.ground_distance, 600000.0) assert_allclose(last_point.CL, polar.optimal_cl) assert_allclose(last_point.altitude, 9196.0, atol=1.0) assert_allclose(last_point.time, 3115.0, rtol=1e-2) assert_allclose(last_point.true_airspeed, 236.3, atol=0.1) assert_allclose(last_point.mass, 69577.0, rtol=1e-4) assert last_point.engine_setting == EngineSetting.CRUISE
def _compute_breguet(self, inputs, outputs): """ Computes mission using simple Breguet formula at altitude==100m and Mach 0.1 (but max L/D ratio is assumed anyway) Useful only for initiating the computation. :param inputs: OpenMDAO input vector :param outputs: OpenMDAO output vector """ propulsion_model = FuelEngineSet( self._engine_wrapper.get_model(inputs), inputs["data:geometry:propulsion:engine:count"] ) high_speed_polar = self._get_initial_polar(inputs) distance = np.asscalar( np.sum(self._mission_wrapper.get_route_ranges(inputs, self.options["mission_name"])) ) altitude = 100.0 cruise_mach = 0.1 breguet = BreguetCruiseSegment( FlightPoint(ground_distance=distance), propulsion=propulsion_model, polar=high_speed_polar, use_max_lift_drag_ratio=True, ) start_point = FlightPoint( mass=inputs[self._mission_vars.TOW.value], altitude=altitude, mach=cruise_mach ) flight_points = breguet.compute_from(start_point) end_point = FlightPoint.create(flight_points.iloc[-1]) outputs[self._mission_vars.NEEDED_BLOCK_FUEL.value] = start_point.mass - end_point.mass
def test_climb_fixed_altitude_at_constant_TAS(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) # initialisation then change instance attributes segment = AltitudeChangeSegment( target=FlightPoint(altitude=10000.0), propulsion=propulsion, reference_area=120.0, polar=polar, engine_setting=EngineSetting.CLIMB, ) # not constant TAS order, as it is the default segment.thrust_rate = 1.0 segment.time_step = 2.0 flight_points = segment.compute_from( FlightPoint(altitude=5000.0, mass=70000.0, true_airspeed=150.0)) # Test with dict last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.altitude, 10000.0) assert_allclose(last_point.true_airspeed, 150.0) assert_allclose(last_point.time, 143.5, rtol=1e-2) assert_allclose(last_point.mass, 69713.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 20943.0, rtol=1e-3) assert last_point.engine_setting == EngineSetting.CLIMB
def test_climb_fixed_altitude_at_constant_EAS(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) flight_points = AltitudeChangeSegment( target=FlightPoint(altitude=10000.0, equivalent_airspeed="constant"), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=1.0, time_step=2.0, engine_setting=EngineSetting. CRUISE, # The engine model does not use this setting ).compute_from( FlightPoint(altitude=5000.0, mass=70000.0, equivalent_airspeed=100.0)) first_point = flight_points.iloc[0] last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.altitude, 10000.0) assert_allclose(last_point.equivalent_airspeed, 100.0) assert_allclose(last_point.time, 145.2, rtol=1e-2) assert_allclose(first_point.true_airspeed, 129.0, atol=0.1) assert_allclose(last_point.true_airspeed, 172.3, atol=0.1) assert_allclose(last_point.mass, 69710.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 20915.0, rtol=1e-3) assert last_point.engine_setting == EngineSetting.CRUISE
def get_model(self, inputs) -> IPropulsion: return FuelEngineSet( DummyEngine( inputs["data:propulsion:dummy_engine:max_thrust"], inputs["data:propulsion:dummy_engine:max_sfc"], ), inputs["data:geometry:propulsion:engine_count"], )
def test_ranged_route(low_speed_polar, high_speed_polar, cleanup): engine = DummyEngine(1e5, 2.0e-5) propulsion = FuelEngineSet(engine, 2) total_distance = 2.0e6 kwargs = dict(propulsion=propulsion, reference_area=120.0) initial_climb = InitialClimbPhase(**kwargs, polar=low_speed_polar, thrust_rate=1.0, name="initial_climb", time_step=0.2) climb = ClimbPhase( **kwargs, polar=high_speed_polar, thrust_rate=0.8, target_altitude="mach", maximum_mach=0.78, name="climb", time_step=5.0, ) cruise = CruiseSegment( **kwargs, target=FlightPoint(ground_distance=0.0), polar=high_speed_polar, engine_setting=EngineSetting.CRUISE, name=FlightPhase.CRUISE.value, ) descent = DescentPhase( **kwargs, polar=high_speed_polar, thrust_rate=0.05, target_altitude=1500.0 * foot, name=FlightPhase.DESCENT.value, time_step=5.0, ) flight_calculator = RangedRoute([initial_climb, climb], cruise, [descent], total_distance) assert flight_calculator.cruise_speed == ("mach", 0.78) start = FlightPoint(true_airspeed=150.0 * knot, altitude=100.0 * foot, mass=70000.0, ground_distance=100000.0) flight_points = flight_calculator.compute_from(start) # plot_flight(flight_points, "test_ranged_flight.png") assert_allclose( flight_points.iloc[-1].ground_distance, total_distance + start.ground_distance, atol=flight_calculator.distance_accuracy, )
def test_acceleration_not_enough_thrust(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) segment = SpeedChangeSegment( target=FlightPoint(true_airspeed=250.0), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=0.1, ) assert len( segment.compute_from( FlightPoint(altitude=5000.0, true_airspeed=150.0, mass=70000.0)))
def test_climb_not_enough_thrust(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) segment = AltitudeChangeSegment( target=FlightPoint(altitude=10000.0, true_airspeed="constant"), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=0.1, ) assert (len( segment.compute_from( FlightPoint(altitude=5000.0, true_airspeed=150.0, mass=70000.0))) == 1)
def _compute_mission(self, inputs, outputs): """ Computes mission using time-step integration. :param inputs: OpenMDAO input vector :param outputs: OpenMDAO output vector """ propulsion_model = FuelEngineSet( self._engine_wrapper.get_model(inputs), inputs["data:geometry:propulsion:engine:count"]) reference_area = inputs["data:geometry:wing:area"] self._mission_wrapper.propulsion = propulsion_model self._mission_wrapper.reference_area = reference_area end_of_takeoff = FlightPoint( time=0.0, mass=inputs[self._mission_vars.TOW.value], true_airspeed=inputs[self._mission_vars.TAKEOFF_V2.value], altitude=inputs[self._mission_vars.TAKEOFF_ALTITUDE.value] + 35 * foot, ground_distance=0.0, ) self.flight_points = self._mission_wrapper.compute( inputs, outputs, end_of_takeoff) # Final ================================================================ end_of_mission = FlightPoint.create(self.flight_points.iloc[-1]) zfw = end_of_mission.mass - self._mission_wrapper.get_reserve( self.flight_points, self.options["mission_name"]) outputs[self._mission_vars.BLOCK_FUEL.value] = ( inputs[self._mission_vars.TOW.value] + inputs[self._mission_vars.TAKEOFF_FUEL.value] + inputs[self._mission_vars.TAXI_OUT_FUEL.value] - zfw) if self.options["is_sizing"]: outputs["data:weight:aircraft:sizing_block_fuel"] = outputs[ self._mission_vars.BLOCK_FUEL.value] def as_scalar(value): if isinstance(value, np.ndarray): return np.asscalar(value) return value self.flight_points = self.flight_points.applymap(as_scalar) if self.options["out_file"]: self.flight_points.to_csv(self.options["out_file"])
def test_hold(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 2.0e-5), 2) segment = HoldSegment(target=FlightPoint(time=3000.0), propulsion=propulsion, reference_area=120.0, polar=polar) flight_points = segment.compute_from( FlightPoint(altitude=500.0, equivalent_airspeed=250.0, mass=60000.0), ) last_point = flight_points.iloc[-1] assert_allclose(last_point.time, 3000.0) assert_allclose(last_point.altitude, 500.0) assert_allclose(last_point.equivalent_airspeed, 250.0, atol=0.1) assert_allclose(last_point.mass, 57776.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 768323.0, rtol=1.0e-3)
def test_taxi(): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) segment = TaxiSegment(target=FlightPoint(time=500.0), propulsion=propulsion, thrust_rate=0.1) flight_points = segment.compute_from( FlightPoint(altitude=10.0, true_airspeed=10.0, mass=50000.0, time=10000.0), ) last_point = flight_points.iloc[-1] assert_allclose(last_point.altitude, 10.0, atol=1.0) assert_allclose(last_point.time, 10500.0, rtol=1e-2) assert_allclose(last_point.true_airspeed, 10.0, atol=0.1) assert_allclose(last_point.mass, 49973.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 5000.0)
def test_climb_and_cruise_at_optimal_flight_level(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 3.0e-5), 2) reference_area = 120.0 segment = ClimbAndCruiseSegment( target=FlightPoint( ground_distance=10.0e6, altitude=AltitudeChangeSegment.OPTIMAL_FLIGHT_LEVEL), propulsion=propulsion, reference_area=reference_area, polar=polar, engine_setting=EngineSetting.CRUISE, climb_segment=AltitudeChangeSegment( target=FlightPoint(), propulsion=propulsion, reference_area=reference_area, polar=polar, thrust_rate=0.9, engine_setting=EngineSetting.CLIMB, ), ) flight_points = segment.compute_from( FlightPoint(mass=70000.0, altitude=8000.0, mach=0.78, ground_distance=1.0e6)) first_point = flight_points.iloc[0] last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 1.0s as time step assert_allclose(first_point.altitude, 8000.0) assert_allclose(first_point.thrust_rate, 0.9) assert_allclose(first_point.true_airspeed, 240.3, atol=0.1) assert first_point.engine_setting == EngineSetting.CLIMB assert_allclose(flight_points.mach, 0.78) assert_allclose(last_point.altitude, 9753.6) assert_allclose(last_point.ground_distance, 11.0e6) assert_allclose(last_point.time, 42659.0, rtol=1e-3) assert_allclose(last_point.true_airspeed, 234.4, atol=0.1) assert_allclose(last_point.mass, 48874.0, rtol=1e-4) assert last_point.engine_setting == EngineSetting.CRUISE
def test_descent_to_fixed_altitude_at_constant_EAS(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) flight_points = AltitudeChangeSegment( target=FlightPoint(altitude=5000.0, equivalent_airspeed="constant"), propulsion=propulsion, reference_area=100.0, polar=polar, thrust_rate=0.1, time_step=2.0, ).compute_from(FlightPoint(altitude=10000.0, equivalent_airspeed=200.0, mass=70000.0)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.altitude, 5000.0) assert_allclose(last_point.equivalent_airspeed, 200.0) assert_allclose(last_point.time, 821.4, rtol=1e-2) assert_allclose(last_point.mass, 69910.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 243155.0, rtol=1e-3)
def test_acceleration_to_mach(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) flight_points = SpeedChangeSegment( target=FlightPoint(mach=0.8), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=1.0, time_step=0.2, ).compute_from( FlightPoint(altitude=1000.0, true_airspeed=150.0, mass=70000.0)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.time, 138.0, rtol=1e-2) assert_allclose(last_point.altitude, 1000.0) assert_allclose(last_point.mach, 0.8, atol=1e-5) assert_allclose(last_point.mass, 69862.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 29470.0, rtol=1e-3)
def test_climb_optimal_flight_level_at_fixed_mach(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) flight_points = AltitudeChangeSegment( target=FlightPoint(altitude=AltitudeChangeSegment.OPTIMAL_FLIGHT_LEVEL, mach="constant"), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=1.0, time_step=2.0, ).compute_from(FlightPoint(altitude=5000.0, mach=0.82, mass=70000.0)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(flight_points.mach, 0.82) assert_allclose(last_point.altitude / foot, 32000.0, atol=0.1) assert_allclose(last_point.time, 77.5, rtol=1e-2) assert_allclose(last_point.true_airspeed, 246.44, rtol=1e-4) assert_allclose(last_point.mass, 69843.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 19179.0, rtol=1e-3)
def test_descent_to_fixed_EAS_at_constant_mach(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) flight_points = AltitudeChangeSegment( target=FlightPoint(equivalent_airspeed=150.0, mach="constant"), propulsion=propulsion, reference_area=100.0, polar=polar, thrust_rate=0.1, # time_step=5.0, # we use default time step ).compute_from(FlightPoint(altitude=10000.0, mass=70000.0, mach=0.78)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.equivalent_airspeed, 150.0) assert_allclose(last_point.mach, 0.78) assert_allclose(last_point.time, 343.6, rtol=1e-2) assert_allclose(last_point.altitude, 8654.0, atol=1.0) assert_allclose(last_point.true_airspeed, 238.1, atol=0.1) assert_allclose(last_point.mass, 69962.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 81042.0, rtol=1e-3)
def test_climb_optimal_altitude_at_fixed_TAS(polar): propulsion = FuelEngineSet(DummyEngine(1.0e5, 1.0e-5), 2) flight_points = AltitudeChangeSegment( target=FlightPoint(altitude=AltitudeChangeSegment.OPTIMAL_ALTITUDE, true_airspeed="constant"), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=1.0, time_step=2.0, ).compute_from( FlightPoint(altitude=5000.0, true_airspeed=250.0, mass=70000.0)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.altitude, 10085.0, atol=0.1) assert_allclose(last_point.true_airspeed, 250.0) assert_allclose(last_point.time, 84.1, rtol=1e-2) assert_allclose(last_point.mach, 0.8359, rtol=1e-4) assert_allclose(last_point.mass, 69832.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 20401.0, rtol=1e-3)
def test_deceleration_not_enough_thrust(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) segment = SpeedChangeSegment( target=FlightPoint(true_airspeed=150.0), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=0.1, time_step=1.0, ) segment.time_step = 1.0 flight_points = segment.compute_from( FlightPoint(altitude=5000.0, true_airspeed=250.0, mass=70000.0)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.time, 315.8, rtol=1e-2) assert_allclose(last_point.altitude, 5000.0) assert_allclose(last_point.true_airspeed, 150.0) assert_allclose(last_point.mass, 69982.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 62804.0, rtol=1e-3)
def test_cruise_at_constant_altitude(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) segment = CruiseSegment( target=FlightPoint(ground_distance=5.0e5), propulsion=propulsion, reference_area=120.0, polar=polar, ) flight_points = segment.compute_from( FlightPoint(mass=70000.0, altitude=10000.0, mach=0.78)) first_point = flight_points.iloc[0] last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.05s as time step assert_allclose(first_point.altitude, 10000.0) assert_allclose(first_point.true_airspeed, 233.6, atol=0.1) assert_allclose(last_point.ground_distance, 500000.0) assert_allclose(last_point.altitude, 10000.0) assert_allclose(last_point.time, 2141.0, rtol=1e-2) assert_allclose(last_point.true_airspeed, 233.6, atol=0.1) assert_allclose(last_point.mass, 69568.0, rtol=1e-4)
def test_acceleration_to_EAS(polar): propulsion = FuelEngineSet(DummyEngine(0.5e5, 1.0e-5), 2) flight_points = SpeedChangeSegment( target=FlightPoint(equivalent_airspeed=250.0), propulsion=propulsion, reference_area=120.0, polar=polar, thrust_rate=1.0, time_step=0.2, engine_setting=EngineSetting. CRUISE, # The engine model does not use this setting ).compute_from( FlightPoint(altitude=1000.0, true_airspeed=150.0, mass=70000.0)) last_point = flight_points.iloc[-1] # Note: reference values are obtained by running the process with 0.01s as time step assert_allclose(last_point.time, 128.2, rtol=1e-2) assert_allclose(last_point.altitude, 1000.0) assert_allclose(last_point.true_airspeed, 262.4, atol=1e-1) assert_allclose(last_point.mass, 69872.0, rtol=1e-4) assert_allclose(last_point.ground_distance, 26868.0, rtol=1e-3) assert last_point.engine_setting == EngineSetting.CRUISE
def _compute_mission(self, inputs, outputs): """ Computes mission using time-step integration. :param inputs: OpenMDAO input vector :param outputs: OpenMDAO output vector """ propulsion_model = FuelEngineSet( self._engine_wrapper.get_model(inputs), inputs["data:geometry:propulsion:engine:count"]) reference_area = inputs["data:geometry:wing:area"] self._mission_wrapper.propulsion = propulsion_model self._mission_wrapper.reference_area = reference_area self._compute_taxi_out(inputs, outputs, propulsion_model) end_of_takeoff = FlightPoint( time=0.0, mass=inputs[self._mission_vars.TOW], true_airspeed=inputs[self._mission_vars.TAKEOFF_V2], altitude=inputs[self._mission_vars.TAKEOFF_ALTITUDE] + 35 * foot, ground_distance=0.0, ) self.flight_points = self._mission_wrapper.compute( inputs, outputs, end_of_takeoff) # Final ================================================================ end_of_mission = FlightPoint.create(self.flight_points.iloc[-1]) reserve = self._mission_wrapper.get_reserve( self.flight_points, self.options["mission_name"]) zfw = end_of_mission.mass - reserve reserve_name = self._mission_wrapper.get_reserve_variable_name() if reserve_name in outputs: outputs[reserve_name] = reserve outputs[self._mission_vars.NEEDED_BLOCK_FUEL] = ( inputs[self._mission_vars.TOW] + inputs[self._mission_vars.TAKEOFF_FUEL] + outputs[self._mission_vars.TAXI_OUT_FUEL] - zfw) outputs[self._mission_vars.NEEDED_FUEL_AT_TAKEOFF] = ( outputs[self._mission_vars.NEEDED_BLOCK_FUEL] - inputs[self._mission_vars.TAKEOFF_FUEL] - outputs[self._mission_vars.TAXI_OUT_FUEL]) if self.options["is_sizing"]: outputs["data:weight:aircraft:sizing_block_fuel"] = outputs[ self._mission_vars.NEEDED_BLOCK_FUEL] outputs[ "data:weight:aircraft:sizing_onboard_fuel_at_takeoff"] = outputs[ self._mission_vars.NEEDED_FUEL_AT_TAKEOFF] def as_scalar(value): if isinstance(value, np.ndarray): return np.asscalar(value) return value self.flight_points = self.flight_points.applymap(as_scalar) rename_dict = { field_name: "%s [%s]" % (field_name, unit) for field_name, unit in FlightPoint.get_units().items() } self.flight_points.rename(columns=rename_dict, inplace=True) if self.options["out_file"]: self.flight_points.to_csv(self.options["out_file"])