Exemple #1
0
    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
Exemple #2
0
 def runTest(self):
     try:
         baddiveseg = SegmentDive(150, 10 * 60, self.airtank, 0)
         baddiveseg.check()
     except UnauthorizedMod:
         pass
     else:
         self.fail("should raise UnauthorizedMod")
Exemple #3
0
 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")
Exemple #5
0
 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')
Exemple #6
0
 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()
Exemple #7
0
 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())
Exemple #8
0
 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")
Exemple #9
0
 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")
Exemple #10
0
    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()
Exemple #11
0
 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()
Exemple #12
0
 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()
Exemple #13
0
 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]))
Exemple #15
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
Exemple #16
0
    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