def do_repetitive_dive(self): """do the actual dive. self.params is in the form: ((depth, time, interval), (depth, time, interval)) each couple of depth, time, interval is a full dive at the given depth interval is done before the dive. """ if not hasattr(self, 'name'): self.name = '%s:%s' % (self.params[0][0], self.params[0][1]) self.profiles = [] # repetive dive profiles. for param in self.params: if len(self.profiles) > 0: self.profiles.append( Dive([ SegmentDive(param[0], param[1] * 60, self.dive_tank, self.setpoint) ], self.all_tanks, self.profiles[-1])) self.profiles[-1].do_surface_interval(param[2] * 60) else: self.profiles.append( Dive([ SegmentDive(param[0], param[1] * 60, self.dive_tank, self.setpoint) ], self.all_tanks)) self.profiles[-1].do_dive() self.profile1 = self.profiles[-1] # save last dive
def runTest(self): try: baddiveseg = SegmentDive(150, 10 * 60, self.airtank, 0) baddiveseg.check() except UnauthorizedMod: pass else: self.fail("should raise UnauthorizedMod")
def setUp(self): """Init of the tests.""" super().setUp() self.dive_segs.append(SegmentDive(40, 130, self.txtravel, 0)) self.dive_segs.append(SegmentDive(40, 30, self.txhypo, 0)) self.dive_tank = self.txhypo self.all_tanks = [self.txtravel, self.txhypo, self.deco1] self.do_dive()
def test_wrong_mod_1(self): """test wrong mod 1.""" try: baddiveseg = SegmentDive(150, 10 * 60, self.airtank, 0) baddiveseg.check() except UnauthorizedMod: pass else: self.fail("should raise UnauthorizedMod")
def runTest(self): """Should raise an error.""" try: diveseg1 = SegmentDive(self.params[0][0], self.params[0][1] * 60, self.txhypo, 0) self.profile1 = Dive([ SegmentDive(40, 130, self.txtravel, 0), SegmentDive(40, 30, self.txhypo, 0), diveseg1 ], [self.txtravel, self.txhypo, self.deco1]) self.profile1.do_dive() except UnauthorizedMod: pass else: self.fail('should raise UnauthorizedMod')
def setUp(self): """Init of the tests.""" super().setUp() diveseg3 = SegmentDive(55, 30 * 60, self.airdouble, 0) self.profile1 = Dive([diveseg3], [self.airdouble, self.decoo2, self.deco2]) self.profile1.do_dive()
def runTest(self): """Not enought gas test""" diveseg1 = SegmentDive(60, 30 * 60, self.air12l, 0) self.profile1 = Dive([diveseg1], [self.air12l]) self.profile1.do_dive() self.assertEqual( self.profile1.tanks[0].check_rule(), False, 'Wrong tank status : it should fail the remaining ' 'gas rule test (result:%s)' % self.profile1.tanks[0].check_rule())
def runTest(self): """Run one test.""" try: diveseg1 = SegmentDive(self.params[0][0], self.params[0][1] * 60, self.airdouble, 0) self.profile1 = Dive([diveseg1], [self.airdouble]) self.profile1.do_dive() except UnauthorizedMod: pass else: self.fail("should raise UnauthorizedMod")
def runTest(self): """Run one test.""" try: self.setpoint = 1.2 self.dive_tank = self.ccair self.all_tanks = [self.ccair] diveseg1 = SegmentDive(self.params[0][0], self.params[0][1] * 60, self.dive_tank, self.setpoint) self.profile1 = Dive([diveseg1], self.all_tanks) self.profile1.do_dive() except UnauthorizedMod: pass else: self.fail("should raise UnauthorizedMod")
def do_dive(self): """do the actual dive. self.params is in the form ((depth, time), (depth, time)) each couple of depth, time is a segment of the same dive. """ if not hasattr(self, 'name'): self.name = '%s:%s' % (self.params[0][0], self.params[0][1]) for param in self.params: self.dive_segs.append( SegmentDive(param[0], param[1] * 60, self.dive_tank, self.setpoint)) self.profile1 = Dive(self.dive_segs, self.all_tanks) self.profile1.do_dive()
def setUp(self): """Init of the tests.""" super().setUp() diveseg1 = SegmentDive(30, 30 * 60, self.airtank, 0) self.profile1 = Dive([diveseg1], [self.airtank]) self.profile1.do_dive_without_exceptions()
def setUp(self): """Init of the tests.""" super().setUp() diveseg1 = SegmentDive(55, 30 * 60, self.txtank1, 1.4) self.profile1 = Dive([diveseg1], [self.txtank1, self.decoo2]) self.profile1.do_dive()
def setUp(self): """Init of the tests.""" super().setUp() diveseg2 = SegmentDive(20, 30 * 60, self.airtank, 0) self.profile1 = Dive([diveseg2], [self.airtank]) self.profile1.do_dive()
def check_configs_dives_section(self): """Check configs and change default settings values.""" config = self.config # dives = { 'dive1': { 'tanks': {}, # 'segments': {}, # 'surface_interval':0} } dives = {} dive_number = 1 # initialization while config.has_section('dive%s' % dive_number): section = 'dive%s' % dive_number dives[section] = { 'tanks': {}, 'segments': {}, 'surface_interval': 0 } for parameter_name, parameter_value in config.items(section): if parameter_name == 'surface_interval': dives[section]['surface_interval'] = safe_eval_calculator( parameter_value) elif parameter_name[0:4] == 'tank': # number = parameter_name[4:] (name, f_o2, f_he, volume, pressure, rule) = parameter_value.split(";") dives[section]['tanks'][name] = Tank( float(f_o2), float(f_he), max_ppo2=settings.DEFAULT_MAX_PPO2, tank_vol=float(safe_eval_calculator(volume)), tank_pressure=float(safe_eval_calculator(pressure)), tank_rule=rule) if dives[section]['tanks'] == {}: # no tank provided, try to get the previous tanks try: dives[section]['tanks'] = dives['dive%s' % (dive_number - 1)]['tanks'] except KeyError: print("Error : no tank provided for this dive !") sys.exit(0) for param_name, param_value in config.items(section): if param_name[0:7] == 'segment': # number = parameter_name[4:] (depth, time, tankname, setpoint) = param_value.split(";") try: dives[section]['segments'][param_name] = SegmentDive( float(safe_eval_calculator(depth)), float(safe_eval_calculator(time)), dives[section]['tanks'][tankname], float(setpoint)) except KeyError: print("Error : tank name (%s) in not found" " in tank list !" % tankname) sys.exit(0) except: raise dives[section]['segments'] = OrderedDict( sorted(dives[section]['segments'].items(), key=lambda t: t[0])) dive_number += 1 self.dives = OrderedDict(sorted(dives.items(), key=lambda t: t[0]))
def check_arguments(self, args): """Parse all command lines options. could also exit from program because of wrong arguments """ parsed_config_files = DipplannerConfigFiles(args.config_files) dives = parsed_config_files.dives if dives is None: dives = OrderedDict() if args.gflow: try: settings.GF_LOW = float( safe_eval_calculator(args.gflow.strip('%'))) / 100 except ValueError: self.parser.error("Error while parsing option gflow : %s" % args.gflow) if args.gfhigh: try: settings.GF_HIGH = float( safe_eval_calculator(args.gfhigh.strip('%'))) / 100 except ValueError: self.parser.error("Error while parsing option gfhigh: %s" % args.gfhigh) if args.water: if args.water.lower() == "sea": settings.WATER_DENSITY = settings.SEA_WATER_DENSITY if args.water.lower() == "fresh": settings.WATER_DENSITY = settings.FRESH_WATER_DENSITY if args.altitude: settings.AMBIANT_PRESSURE_SURFACE = altitude_to_pressure( args.altitude) if args.diveconsrate: try: settings.DIVE_CONSUMPTION_RATE = float( safe_eval_calculator(args.diveconsrate)) / 60 except ValueError: self.parser.error("Error while parsing option " "diveconsrate : %s" % args.diveconsrate) if args.decoconsrate: try: settings.DECO_CONSUMPTION_RATE = float( safe_eval_calculator(args.decoconsrate)) / 60 except ValueError: self.parser.error("Error while parsing option " "decoconsrate : %s" % args.decoconsrate) if args.descentrate: try: settings.DESCENT_RATE = float( safe_eval_calculator(args.descentrate)) / 60 except ValueError: self.parser.error("Error while parsing option " "descentrate : %s" % args.descentrate) if args.ascentrate: try: settings.ASCENT_RATE = float( safe_eval_calculator(args.ascentrate)) / 60 except ValueError: self.parser.error("Error while parsing option " "ascentrate : %s" % args.ascentrate) if args.deco_ascentrate: try: settings.DECO_ASCENT_RATE = float( safe_eval_calculator(args.deco_ascentrate)) / 60 except ValueError: self.parser.error("Error while parsing option " "deco_ascentrate : %s" % args.deco_ascentrate) if args.model: settings.DECO_MODEL = args.model if args.maxppo2: settings.DEFAULT_MAX_PPO2 = args.maxppo2 if args.minppo2: settings.DEFAULT_MIN_PPO2 = args.minppo2 if args.maxend: settings.DEFAULT_MAX_END = args.maxend if args.samegasfordeco: settings.USE_OC_DECO = False if args.forcesegmenttime: settings.RUN_TIME = False if args.depthcalcmethod in ('simple', 'complex'): settings.METHOD_FOR_DEPTH_CALCULATION = args.depthcalcmethod if args.travelswitch in ('late', 'early'): settings.TRAVEL_SWITCH = args.travelswitch if args.surfacetemp is not None: settings.SURFACE_TEMP = args.surfacetemp if args.ambiantpressureatsea: settings.AMBIANT_PRESSURE_SEA_LEVEL = args.ambiantpressureatsea if args.multilevel: settings.MULTILEVEL_MODE = True if args.automatictankrefill: settings.AUTOMATIC_TANK_REFILL = True if args.notankrefill: settings.AUTOMATIC_TANK_REFILL = False # try to find tank(s) and segment(s). # if found, add this dive to the (eventually) other dives defined # in config files. # this will be the last dive tanks = {} if args.tanks: for tank in args.tanks: (name, f_o2, f_he, volume, pressure, rule) = tank.split(";") tanks[name] = Tank( float(f_o2), float(f_he), max_ppo2=settings.DEFAULT_MAX_PPO2, tank_vol=float(safe_eval_calculator(volume)), tank_pressure=float(safe_eval_calculator(pressure)), tank_rule=rule) if tanks == {}: # no tank provided, try to get the previous tanks try: tanks = dives[list(dives.items())[-1][0]]['tanks'] except (KeyError, IndexError): self.parser.error("Error : no tank provided for this dive !") segments = OrderedDict() if args.segments: num_seg = 1 for seg in args.segments: (depth, time, tankname, setpoint) = seg.split(";") # looks for tank in tanks try: # seg_name = 'segment%s' % num_seg # print(seg_name) segments['segment%s' % num_seg] = SegmentDive( float(safe_eval_calculator(depth)), float(safe_eval_calculator(time)), tanks[tankname], float(setpoint)) except KeyError: self.parser.error( "Error : tank name (%s) in not found in tank list !" % tankname) num_seg += 1 segments = OrderedDict(sorted(segments.items(), key=lambda t: t[0])) if args.surfaceinterval: dives['diveCLI'] = { 'tanks': tanks, 'segments': segments, 'surface_interval': safe_eval_calculator(args.surfaceinterval) } else: dives['diveCLI'] = { 'tanks': tanks, 'segments': segments, 'surface_interval': 0 } if args.template: settings.TEMPLATE = args.template # returns self.args = args self.dives = dives
def do_dive(self): """Process the dive. :raises NothingToProcess: if there is no input segment to process :raises ModelException: <Exceptions from model> """ if self.is_dive_segments() is False: raise NothingToProcess # check the segments: for seg in self.input_segments: seg.check() run_time_flag = settings.RUN_TIME # sets initial state # # else: first_segment = self.input_segments[0] self.current_tank = first_segment.tank # Sort self.tanks based on MOD ? why ? see below ? self.tanks.sort() self.current_depth = 0.0 self.pp_o2 = first_segment.setpoint if self.pp_o2 == 0.0: self.is_closed_circuit = False else: self.is_closed_circuit = True self.in_final_ascent = False # check if tank for 1rst segment is suitable for descent (OC mode) if (not self.is_closed_circuit and self.input_segments[0].tank.get_min_od() > 0): # tank is not ok, we need to look for another better tank # at first, try to find a tank suitable # from 0m to depth of first segment self.logger.debug("bottom gaz not ok for descent") self.tanks.reverse() for tank in self.tanks: if tank.get_min_od() == 0: self.logger.debug( "This tank may be suitable:%s, mod:%s, end at d:%s", str(tank), tank.mod, tank.get_end_for_given_depth( self.input_segments[0].depth)) if (tank.mod >= self.input_segments[0].depth and tank.get_end_for_given_depth( self.input_segments[0].depth) < settings.DEFAULT_MAX_END): # ok we have a winner self.logger.info("Changed tank for descent to:%s", str(tank)) self.current_tank = tank break if self.current_tank == self.input_segments[0].tank: # not found : we need to stop in the descent # to switch from first gas # to bottom gas self.logger.debug("No directly usage tank found," " try to stop and change tank") for tank in self.tanks: if tank.get_min_od() == 0: self.logger.debug( "This tank may be suitable:%s, " "mod:%s, end at d:%s", str(tank), tank.mod, tank.get_end_for_given_depth( self.input_segments[0].depth)) if settings.TRAVEL_SWITCH == 'late': depth = min( tank.mod, tank.get_mod_for_given_end( settings.DEFAULT_MAX_END)) self.input_segments.insert( 0, SegmentDive(depth=depth, tank=self.input_segments[0].tank, time=0)) self.input_segments.insert( 0, SegmentDive(depth=depth, tank=tank, time=0)) self.current_tank = tank break else: # early depth = self.input_segments[0].tank.get_min_od( min_ppo2=settings.DEFAULT_MIN_PPO2) self.input_segments.insert( 0, SegmentDive(depth=depth, tank=self.input_segments[0].tank, time=0)) self.input_segments.insert( 0, SegmentDive(depth=depth, tank=tank, time=0)) self.current_tank = tank break self.tanks.sort() for seg in self.input_segments: if seg.type == 'const': # only dive segment allowed for input delta_depth = float(seg.depth) - float(self.current_depth) # Ascend or descend to dive segment, # using existing gas and ppO2 settings if delta_depth > 0.0: # descent self.model.asc_desc(depth_to_pressure(self.current_depth), depth_to_pressure(seg.depth), settings.DESCENT_RATE, self.current_tank.f_he, self.current_tank.f_n2, self.pp_o2) self.output_segments.append( SegmentAscDesc(self.current_depth, seg.depth, settings.DESCENT_RATE, self.current_tank, self.pp_o2)) self.run_time += abs( float(delta_depth) / (float(settings.DESCENT_RATE))) self.logger.debug( "descent time : %ss", float(delta_depth) / settings.DESCENT_RATE) else: # ascent # call ascend method of this class # for decompression calculation self.ascend(seg.depth) # we are now at the desired depth : process the dive segment self.current_depth = seg.depth # new depth self.pp_o2 = seg.setpoint self.current_tank = seg.tank if seg.time > 0: # only do this if it's not a waypoint if run_time_flag: run_time_flag = False # do this one only self.model.const_depth(depth_to_pressure(seg.depth), seg.time - self.run_time, self.current_tank.f_he, self.current_tank.f_n2, self.pp_o2) self.output_segments.append( SegmentDive(seg.depth, seg.time - self.run_time, self.current_tank, self.pp_o2)) self.metadata += "Dive to %s for %ss\n" % ( seg.depth, seg.time - self.run_time) self.logger.debug("Dive to %s for %ss", seg.depth, seg.time - self.run_time) # run_time = seg_time because it's # only done the first time self.run_time = seg.time self.logger.debug("update run time : %ss", self.run_time) else: self.model.const_depth(depth_to_pressure(seg.depth), seg.time, self.current_tank.f_he, self.current_tank.f_n2, self.pp_o2) self.output_segments.append( SegmentDive(seg.depth, seg.time, self.current_tank, self.pp_o2)) self.metadata += "Dive to %s for %ss\n" % (seg.depth, seg.time) self.logger.debug("Dive to %s for %ss", seg.depth, seg.time) self.run_time += seg.time self.logger.debug("update run time : %ss", self.run_time) else: # process waypoint self.output_segments.append( SegmentDive(seg.depth, seg.time, self.current_tank, self.pp_o2)) # all input segment are now processed: process to ascend to the surface self.in_final_ascent = True # ascend to the surface self.ascend(0.0) # for each output segment, recalculate runtime and update segments total_time = 0 for output_seg in self.output_segments: total_time += output_seg.time output_seg.run_time = total_time if total_time != self.run_time: self.logger.warning( "dive run_time (%ss) differs from" " all segments time (%ss)", self.run_time, total_time) # write metadata into the model self.model.metadata = self.metadata # recalculate the gas consumptions self.do_gas_calcs() # save the tanks parameters : next dives may use the same tanks, # but we need here to duplicate tank object within this dive in # order to save the tank parameters for this dive only saved_tanks = [] for tank in self.tanks: saved_tanks.append(copy.deepcopy(tank)) self.tanks = saved_tanks