Exemplo n.º 1
0
 def runTest(self):
     try:
         baddiveseg = SegmentDeco(3, 10 * 60, self.trimixtank1, 0)
         baddiveseg.check()
     except UnauthorizedMod:
         pass
     else:
         self.fail("should raise UnauthorizedMod")
Exemplo n.º 2
0
 def test_wrong_mod_2(self):
     """test wrong mod 2."""
     try:
         baddiveseg = SegmentDeco(3, 10 * 60, self.trimixtank1, 0)
         baddiveseg.check()
     except UnauthorizedMod:
         pass
     else:
         self.fail("should raise UnauthorizedMod")
Exemplo n.º 3
0
    def ascend(self, target_depth):
        """Ascend to target depth, decompressing if necessary.

        If inFinalAscent then gradient factors start changing,
        and automatic gas selection is made.

        This method is called by do_dive()

        :param float target_depth: in meter, target depth for the ascend

        :raises ModelException: <Exceptions from model>
        """
        force_deco_stop = False
        in_deco_cycle = False
        deco_stop_time = 0

        if self.in_final_ascent and settings.USE_OC_DECO:
            self.set_deco_gas(self.current_depth)

        if self.current_depth < target_depth:
            # going backwards !
            raise ProcessingError("Not allowed to ascend while descending !")

        # Set initial stop to be the next integral stop depth
        if self.current_depth % settings.STOP_DEPTH_INCREMENT > 0:
            # we are not on a stop depth already : go to the next stop depth
            next_stop_depth = (int(self.current_depth /
                                   settings.STOP_DEPTH_INCREMENT) *
                               settings.STOP_DEPTH_INCREMENT)
        else:
            next_stop_depth = int(self.current_depth -
                                  settings.STOP_DEPTH_INCREMENT)

        self.logger.debug("next_stop_depth: %s", next_stop_depth)
        # hack in case we are overshooting or hit last stop or any of
        # the other bizzar combinations ...
        if (next_stop_depth < target_depth or
                self.current_depth < settings.LAST_STOP_DEPTH):
            next_stop_depth = target_depth
            self.logger.debug("new next_stop_depth: %s", next_stop_depth)
        elif next_stop_depth == settings.LAST_STOP_DEPTH:
            self.logger.warning("next_stop_depth==LAST_STOP_DEPTH !")
            next_stop_depth = target_depth
            self.logger.debug("new next_stop_depth: %s", next_stop_depth)
        elif next_stop_depth < settings.LAST_STOP_DEPTH:
            next_stop_depth = settings.LAST_STOP_DEPTH
            self.logger.debug("new next_stop_depth: %s", next_stop_depth)

        # Initialise ascent segment start depth
        start_depth = self.current_depth
        in_ascent_cycle = True  # Start in free ascent

        # Initialise gradient factor for next (in this case first) stop depth
        self.model.gradient.set_gf_at_depth(next_stop_depth)

        # Remember maxM-Value and controlling compartment
        max_mv = self.model.m_value(depth_to_pressure(self.current_depth))
        control = self.model.control_compartment()

        while self.current_depth > target_depth:
            self.logger.debug("ascent from: %s, to: %s",
                              self.current_depth, next_stop_depth)
            # can we move to the proposed next stop depth ?
            model_ceiling = self.model.ceiling()
            self.logger.debug("model ceiling: %s", model_ceiling)
            while force_deco_stop or next_stop_depth < model_ceiling:
                in_deco_cycle = True
                # Only used for first entry into deco stop
                force_deco_stop = False
                if in_ascent_cycle:
                    # Finalise last ascent cycle as we are now decomp
                    if start_depth > self.current_depth:
                        # add ascent segment
                        self.logger.debug("Add AscDesc(1): start_depth:%s "
                                          "current_depth:%s",
                                          start_depth, self.current_depth)
                        self.output_segments.append(
                            SegmentAscDesc(start_depth,
                                           self.current_depth,
                                           settings.ASCENT_RATE,
                                           self.current_tank,
                                           self.pp_o2))
                    in_ascent_cycle = False

                # set m-value gradient under the following conditions:
                #   - if not in multilevel mode, then set it as soon as
                #     we do a decompression cycle
                #   - otherwise wait until we are finally
                #     surfacing before setting it
                if ((not settings.MULTILEVEL_MODE or self.in_final_ascent) and
                        (not self.model.gradient.gf_set)):
                    self.model.gradient.set_gf_slope_at_depth(
                        self.current_depth)
                    self.model.gradient.set_gf_at_depth(next_stop_depth)
                    self.logger.debug("...set m-value gradient: %s",
                                      self.model.gradient.gf)

                # calculate stop_time
                # if (deco_stop_time == 0 and
                #         self.run_time % settings.STOP_TIME_INCREMENT > 0):
                #     stop_time = (
                #         int(self.run_time / settings.STOP_TIME_INCREMENT) *
                #         settings.STOP_TIME_INCREMENT +
                #         settings.STOP_TIME_INCREMENT - self.run_time)
                #     print("+++++ ", stop_time)
                #     if stop_time == 0:
                #         stop_time = settings.STOP_TIME_INCREMENT  # in second
                # else:
                stop_time = settings.STOP_TIME_INCREMENT  # in second

                # execute the stop
                self.model.const_depth(depth_to_pressure(self.current_depth),
                                       stop_time,
                                       self.current_tank.f_he,
                                       self.current_tank.f_n2,
                                       self.pp_o2)

                deco_stop_time += stop_time
                # sanity check for infinite loop
                if deco_stop_time > 300000:
                    raise InfiniteDeco("Infinite deco error")

                model_ceiling = self.model.ceiling()

            # finished decompression loop
            if in_deco_cycle:
                self.logger.debug("...in deco cycle")
                # finalise the last deco cycle
                self.run_time += deco_stop_time
                self.logger.debug(
                    "update run time with deco time: %ss at %sm (runtime:%s)",
                    deco_stop_time, self.current_depth, self.run_time)
                if settings.FORCE_ALL_STOPS:
                    force_deco_stop = True

                # write deco segment
                deco_segment = SegmentDeco(self.current_depth,
                                           deco_stop_time,
                                           self.current_tank,
                                           self.pp_o2)
                deco_segment.mv_max = max_mv
                deco_segment.gf_used = self.model.gradient.gf
                deco_segment.control_compartment = control
                self.output_segments.append(deco_segment)
                in_deco_cycle = False
                deco_stop_time = 0

            if in_ascent_cycle:
                self.logger.debug("...in ascent cycle, do asc from %s to %s",
                                  self.current_depth, next_stop_depth)
                self.model.asc_desc(depth_to_pressure(self.current_depth),
                                    depth_to_pressure(next_stop_depth),
                                    -settings.ASCENT_RATE,
                                    self.current_tank.f_he,
                                    self.current_tank.f_n2,
                                    self.pp_o2)
                self.run_time += abs((float(self.current_depth) -
                                      float(next_stop_depth)) /
                                     float(settings.ASCENT_RATE))
                self.logger.debug("update run time : %ss", self.run_time)
            else:
                self.logger.debug("...in deco cycle, do asc from %s to %s",
                                  self.current_depth, next_stop_depth)
                self.model.asc_desc(depth_to_pressure(self.current_depth),
                                    depth_to_pressure(next_stop_depth),
                                    -settings.DECO_ASCENT_RATE,
                                    self.current_tank.f_he,
                                    self.current_tank.f_n2,
                                    self.pp_o2)
                self.run_time += abs((float(self.current_depth) -
                                      float(next_stop_depth)) /
                                     float(settings.DECO_ASCENT_RATE))
                self.logger.debug("update run time : %ss", self.run_time)
                self.output_segments.append(
                    SegmentAscDesc(self.current_depth,
                                   next_stop_depth,
                                   settings.DECO_ASCENT_RATE,
                                   self.current_tank,
                                   self.pp_o2))

            # now we moved up the the next depth
            self.current_depth = next_stop_depth
            max_mv = self.model.m_value(depth_to_pressure(self.current_depth))
            control = self.model.control_compartment()

            # Check and switch deco gas
            temp_tank = self.current_tank  # remember in case we switch
            if self.set_deco_gas(self.current_depth):  # True if we changed gas
                if in_ascent_cycle:
                    self.logger.debug("Add AscDesc(2): start_depth:%s, "
                                      "current_depth:%s",
                                      start_depth, self.current_depth)
                    self.output_segments.append(
                        SegmentAscDesc(start_depth,
                                       self.current_depth,
                                       settings.ASCENT_RATE,
                                       temp_tank,
                                       self.pp_o2))
                    start_depth = self.current_depth

            # set next rounded stop depth
            next_stop_depth = int(
                self.current_depth) - settings.STOP_DEPTH_INCREMENT

            self.logger.debug("next stop depth: %s, target depth: %s",
                              next_stop_depth, target_depth)

            # check in cas we are overshooting or hit last stop
            if (next_stop_depth < target_depth or
                    self.current_depth < settings.LAST_STOP_DEPTH):
                self.logger.debug("next_stop_depth (%s) < target_depth (%s)",
                                  next_stop_depth, target_depth)
                next_stop_depth = target_depth
            elif self.current_depth < settings.LAST_STOP_DEPTH:
                self.logger.debug("current_depth (%s) < LAST_STOP_DEPTH (%s)",
                                  self.current_depth,
                                  settings.LAST_STOP_DEPTH)
                next_stop_depth = target_depth
            elif (next_stop_depth < settings.LAST_STOP_DEPTH and
                  next_stop_depth > 0):
                self.logger.debug("next_stop_depth (%s) < "
                                  "settings.LAST_STOP_DEPTH (%s)",
                                  next_stop_depth, settings.LAST_STOP_DEPTH)
                next_stop_depth = target_depth

            if self.model.gradient.gf_set:  # update gf for next stop
                self.model.gradient.set_gf_at_depth(next_stop_depth)

        # are we still in ascent segment ?
        if in_ascent_cycle:
            self.logger.debug("Add AscDesc(3): start_depth:%s, "
                              "current_depth:%s",
                              start_depth, self.current_depth)
            self.output_segments.append(
                SegmentAscDesc(start_depth,
                               self.current_depth,
                               -settings.ASCENT_RATE,
                               self.current_tank,
                               self.pp_o2))
Exemplo n.º 4
0
    def ascend(self, target_depth):
        """Ascend to target depth, decompressing if necessary.
        If inFinalAscent then gradient factors start changing,
        and automatic gas selection is made.

        This method is called by do_dive()

        *Keyword Arguments:*
            :target_depth: (float) -- in meter, target depth for the ascend

        Returns:
        <nothing>

        Raise:
        <Exceptions from model>

        """
        force_deco_stop = False
        in_deco_cycle = False
        deco_stop_time = 0

        if self.in_final_ascent and settings.USE_OC_DECO:
            self.set_deco_gas(self.current_depth)

        if self.current_depth < target_depth:
            # going backwards !
            raise ProcessingError("Not allowed to ascend while descending !")

        # Set initial stop to be the next integral stop depth
        if self.current_depth % settings.STOP_DEPTH_INCREMENT > 0:
            # we are not on a stop depth already : go to the next stop depth
            # TODO : int() or round() ?
            next_stop_depth = int(float(self.current_depth) /
                                  float(settings.STOP_DEPTH_INCREMENT)) *\
                settings.STOP_DEPTH_INCREMENT
        else:
            next_stop_depth = int(self.current_depth -
                                  settings.STOP_DEPTH_INCREMENT)

        self.logger.debug("next_stop_depth: %s" % next_stop_depth)
        # hack in case we are overshooting or hit last stop or any of
        # the other bizzar combinations ...
        if next_stop_depth < target_depth or \
                self.current_depth < settings.LAST_STOP_DEPTH:
            next_stop_depth = target_depth
        elif next_stop_depth == settings.LAST_STOP_DEPTH:
            self.logger.warning("next_stop_depth==LAST_STOP_DEPTH !")
            next_stop_depth = target_depth  # TODO: bizarre...
        elif next_stop_depth < settings.LAST_STOP_DEPTH:
            next_stop_depth = settings.LAST_STOP_DEPTH

        start_depth = self.current_depth  # Initialise ascent
                                          # segment start depth
        in_ascent_cycle = True  # Start in free ascent

        # Initialise gradient factor for next (in this case first) stop depth
        self.model.gradient.set_gf_at_depth(next_stop_depth)

        # Remember maxM-Value and controlling compartment
        max_mv = self.model.m_value(depth_to_pressure(self.current_depth))
        control = self.model.control_compartment()

        while self.current_depth > target_depth:
            self.logger.debug("ascent -- debug : %s, %s" %
                              (self.current_depth, target_depth))
            # can we move to the proposed next stop depth ?
            model_ceiling = self.model.ceiling()
            self.logger.debug("model ceiling: %s" % model_ceiling)
            while force_deco_stop or next_stop_depth < model_ceiling:
                in_deco_cycle = True
                force_deco_stop = False  # Only used for first entry
                                         # into deco stop
                if in_ascent_cycle:  # Finalise last ascent cycle
                                     # as we are now decomp
                    if start_depth > self.current_depth:
                        # add ascent segment
                        #self.logger.debug("Add AscDesc(1): start_depth:%s, \
                        #                   current_depth:%s" % \
                        #                   (start_depth, self.current_depth))
                        self.output_segments.append(
                            SegmentAscDesc(start_depth,
                                           self.current_depth,
                                           settings.ASCENT_RATE,
                                           self.current_tank,
                                           self.pp_o2))
                    in_ascent_cycle = False
                    # TODO: start depth is not re-initialised after first use

                # set m-value gradient under the following conditions:
                #   - if not in multilevel mode, then set it as soon as
                #     we do a decompression cycle
                #   - otherwise wait until we are finally
                #     surfacing before setting it
                if (not settings.MULTILEVEL_MODE or self.in_final_ascent) and \
                        (not self.model.gradient.gf_set):
                    #self.logger.debug("...set m-value gradient")
                    self.model.gradient.set_gf_slope_at_depth(
                        self.current_depth)
                    self.model.gradient.set_gf_at_depth(next_stop_depth)

                #calculate stop_time
                if deco_stop_time == 0 and \
                        self.run_time % settings.STOP_TIME_INCREMENT > 0:
                    stop_time = int(self.run_time /
                                    settings.STOP_TIME_INCREMENT) * \
                        settings.STOP_TIME_INCREMENT + \
                        settings.STOP_TIME_INCREMENT - \
                        self.run_time
                    if stop_time == 0:
                        stop_time = settings.STOP_TIME_INCREMENT  # in second
                else:
                    stop_time = settings.STOP_TIME_INCREMENT  # in second

                # execute the stop
                self.model.const_depth(depth_to_pressure(self.current_depth),
                                       stop_time,
                                       self.current_tank.f_he,
                                       self.current_tank.f_n2,
                                       self.pp_o2)

                deco_stop_time += stop_time
                # sanity check for infinite loop
                if deco_stop_time > 300000:
                    raise InfiniteDeco("Infinite deco error")

                model_ceiling = self.model.ceiling()

            # finished decompression loop
            if in_deco_cycle:
                self.logger.debug("...in deco cycle")
                # finalise the last deco cycle
                self.run_time += deco_stop_time
                self.logger.debug("update run time : %ss" % self.run_time)
                if settings.FORCE_ALL_STOPS:
                    force_deco_stop = True

                # write deco segment
                deco_segment = SegmentDeco(self.current_depth,
                                           deco_stop_time,
                                           self.current_tank,
                                           self.pp_o2)
                deco_segment.mv_max = max_mv
                deco_segment.gf_used = self.model.gradient.gf
                deco_segment.control_compartment = control
                self.output_segments.append(deco_segment)
                in_deco_cycle = False
                deco_stop_time = 0
            elif in_ascent_cycle:
                #self.logger.debug("...in ascent cycle")
                # did not decompress, just ascend
                # TODO : if we enable this code always (not in elif,
                #        but direct) then
                #        model will ascend between deco stops, but ...
                #        this causes collateral damage to runtim calculations
                self.model.asc_desc(depth_to_pressure(self.current_depth),
                                    depth_to_pressure(next_stop_depth),
                                    settings.ASCENT_RATE,
                                    self.current_tank.f_he,
                                    self.current_tank.f_n2,
                                    self.pp_o2)
                self.run_time += abs(float(self.current_depth) -
                                     float(next_stop_depth)) / \
                    (float(settings.ASCENT_RATE))

                self.logger.debug("update run time : %ss" % self.run_time)
                # TODO: Issue here is that this ascent time is not accounted
                #       for in any segments unless it was in an ascent cycle

            #now we moved up the the next depth
            self.current_depth = next_stop_depth
            max_mv = self.model.m_value(depth_to_pressure(self.current_depth))
            control = self.model.control_compartment()

            # Check and switch deco gas
            temp_tank = self.current_tank  # remember in case we switch
            if self.set_deco_gas(self.current_depth):  # True if we changed gas
                if in_ascent_cycle:
                    self.logger.debug("Add AscDesc(2): start_depth:%s, "
                                      "current_depth:%s" %
                                      (start_depth, self.current_depth))
                    self.output_segments.append(
                        SegmentAscDesc(start_depth,
                                       self.current_depth,
                                       settings.ASCENT_RATE,
                                       temp_tank,
                                       self.pp_o2))
                    start_depth = self.current_depth

            # set next rounded stop depth
            next_stop_depth = int(self.current_depth) - \
                settings.STOP_DEPTH_INCREMENT

            self.logger.debug("next stop depth: %s, target: %s" %
                              (next_stop_depth, target_depth))

            # check in cas we are overshooting or hit last stop
            if next_stop_depth < target_depth or \
                    self.current_depth < settings.LAST_STOP_DEPTH:
                self.logger.debug("next_stop_depth (%s) < target_depth (%s)" %
                                  (next_stop_depth, target_depth))
                next_stop_depth = target_depth
            elif self.current_depth < settings.LAST_STOP_DEPTH:
                self.logger.debug("current_depth (%s) < LAST_STOP_DEPTH (%s)" %
                                  (self.current_depth,
                                   settings.LAST_STOP_DEPTH))
                next_stop_depth = target_depth
            # !!! BEGIN FORCE COMMENT (SEE BELOW)
            #elif next_stop_depth < settings.LAST_STOP_DEPTH:
            #  self.logger.debug("next_stop_depth (%s) < "
            #                    "settings.LAST_STOP_DEPTH (%s)" %
            #                    (next_stop_depth, settings.LAST_STOP_DEPTH))
            #  next_stop_depth = settings.LAST_STOP_DEPTH
            # !!! END FORCE COMMENT
            #TODO: j'ai commenté les lignes ci-dessus pour éviter
            #      une boucle infinie commprendre pourquoi elles existent...

            if self.model.gradient.gf_set:  # update gf for next stop
                self.model.gradient.set_gf_at_depth(next_stop_depth)

        # are we still in ascent segment ?
        if in_ascent_cycle:
            self.logger.debug("Add AscDesc(3): start_depth:%s, "
                              "current_depth:%s" %
                              (start_depth, self.current_depth))
            self.output_segments.append(
                SegmentAscDesc(start_depth,
                               self.current_depth,
                               settings.ASCENT_RATE,
                               self.current_tank,
                               self.pp_o2))
Exemplo n.º 5
0
    def ascend(self, target_depth):
        """Ascend to target depth, decompressing if necessary.

        If inFinalAscent then gradient factors start changing,
        and automatic gas selection is made.

        This method is called by do_dive()

        :param float target_depth: in meter, target depth for the ascend

        :raises ModelException: <Exceptions from model>
        """
        force_deco_stop = False
        in_deco_cycle = False
        deco_stop_time = 0

        if self.in_final_ascent and settings.USE_OC_DECO:
            self.set_deco_gas(self.current_depth)

        if self.current_depth < target_depth:
            # going backwards !
            raise ProcessingError("Not allowed to ascend while descending !")

        # Set initial stop to be the next integral stop depth
        if self.current_depth % settings.STOP_DEPTH_INCREMENT > 0:
            # we are not on a stop depth already : go to the next stop depth
            next_stop_depth = (
                int(self.current_depth / settings.STOP_DEPTH_INCREMENT) *
                settings.STOP_DEPTH_INCREMENT)
        else:
            next_stop_depth = int(self.current_depth -
                                  settings.STOP_DEPTH_INCREMENT)

        self.logger.debug("next_stop_depth: %s", next_stop_depth)
        # hack in case we are overshooting or hit last stop or any of
        # the other bizzar combinations ...
        if (next_stop_depth < target_depth
                or self.current_depth < settings.LAST_STOP_DEPTH):
            next_stop_depth = target_depth
            self.logger.debug("new next_stop_depth: %s", next_stop_depth)
        elif next_stop_depth == settings.LAST_STOP_DEPTH:
            self.logger.warning("next_stop_depth==LAST_STOP_DEPTH !")
            next_stop_depth = target_depth
            self.logger.debug("new next_stop_depth: %s", next_stop_depth)
        elif next_stop_depth < settings.LAST_STOP_DEPTH:
            next_stop_depth = settings.LAST_STOP_DEPTH
            self.logger.debug("new next_stop_depth: %s", next_stop_depth)

        # Initialise ascent segment start depth
        start_depth = self.current_depth
        in_ascent_cycle = True  # Start in free ascent

        # Initialise gradient factor for next (in this case first) stop depth
        self.model.gradient.set_gf_at_depth(next_stop_depth)

        # Remember maxM-Value and controlling compartment
        max_mv = self.model.m_value(depth_to_pressure(self.current_depth))
        control = self.model.control_compartment()

        while self.current_depth > target_depth:
            self.logger.debug("ascent from: %s, to: %s", self.current_depth,
                              next_stop_depth)
            # can we move to the proposed next stop depth ?
            model_ceiling = self.model.ceiling()
            self.logger.debug("model ceiling: %s", model_ceiling)
            while force_deco_stop or next_stop_depth < model_ceiling:
                in_deco_cycle = True
                # Only used for first entry into deco stop
                force_deco_stop = False
                if in_ascent_cycle:
                    # Finalise last ascent cycle as we are now decomp
                    if start_depth > self.current_depth:
                        # add ascent segment
                        self.logger.debug(
                            "Add AscDesc(1): start_depth:%s "
                            "current_depth:%s", start_depth,
                            self.current_depth)
                        self.output_segments.append(
                            SegmentAscDesc(start_depth, self.current_depth,
                                           settings.ASCENT_RATE,
                                           self.current_tank, self.pp_o2))
                    in_ascent_cycle = False

                # set m-value gradient under the following conditions:
                #   - if not in multilevel mode, then set it as soon as
                #     we do a decompression cycle
                #   - otherwise wait until we are finally
                #     surfacing before setting it
                if ((not settings.MULTILEVEL_MODE or self.in_final_ascent)
                        and (not self.model.gradient.gf_set)):
                    self.model.gradient.set_gf_slope_at_depth(
                        self.current_depth)
                    self.model.gradient.set_gf_at_depth(next_stop_depth)
                    self.logger.debug("...set m-value gradient: %s",
                                      self.model.gradient.gf)

                # calculate stop_time
                # if (deco_stop_time == 0 and
                #         self.run_time % settings.STOP_TIME_INCREMENT > 0):
                #     stop_time = (
                #         int(self.run_time / settings.STOP_TIME_INCREMENT) *
                #         settings.STOP_TIME_INCREMENT +
                #         settings.STOP_TIME_INCREMENT - self.run_time)
                #     print("+++++ ", stop_time)
                #     if stop_time == 0:
                #         stop_time = settings.STOP_TIME_INCREMENT  # in second
                # else:
                stop_time = settings.STOP_TIME_INCREMENT  # in second

                # execute the stop
                self.model.const_depth(depth_to_pressure(self.current_depth),
                                       stop_time, self.current_tank.f_he,
                                       self.current_tank.f_n2, self.pp_o2)

                deco_stop_time += stop_time
                # sanity check for infinite loop
                if deco_stop_time > 300000:
                    raise InfiniteDeco("Infinite deco error")

                model_ceiling = self.model.ceiling()

            # finished decompression loop
            if in_deco_cycle:
                self.logger.debug("...in deco cycle")
                # finalise the last deco cycle
                self.run_time += deco_stop_time
                self.logger.debug(
                    "update run time with deco time: %ss at %sm (runtime:%s)",
                    deco_stop_time, self.current_depth, self.run_time)
                if settings.FORCE_ALL_STOPS:
                    force_deco_stop = True

                # write deco segment
                deco_segment = SegmentDeco(self.current_depth, deco_stop_time,
                                           self.current_tank, self.pp_o2)
                deco_segment.mv_max = max_mv
                deco_segment.gf_used = self.model.gradient.gf
                deco_segment.control_compartment = control
                self.output_segments.append(deco_segment)
                in_deco_cycle = False
                deco_stop_time = 0

            if in_ascent_cycle:
                self.logger.debug("...in ascent cycle, do asc from %s to %s",
                                  self.current_depth, next_stop_depth)
                self.model.asc_desc(depth_to_pressure(self.current_depth),
                                    depth_to_pressure(next_stop_depth),
                                    -settings.ASCENT_RATE,
                                    self.current_tank.f_he,
                                    self.current_tank.f_n2, self.pp_o2)
                self.run_time += abs(
                    (float(self.current_depth) - float(next_stop_depth)) /
                    float(settings.ASCENT_RATE))
                self.logger.debug("update run time : %ss", self.run_time)
            else:
                self.logger.debug("...in deco cycle, do asc from %s to %s",
                                  self.current_depth, next_stop_depth)
                self.model.asc_desc(depth_to_pressure(self.current_depth),
                                    depth_to_pressure(next_stop_depth),
                                    -settings.DECO_ASCENT_RATE,
                                    self.current_tank.f_he,
                                    self.current_tank.f_n2, self.pp_o2)
                self.run_time += abs(
                    (float(self.current_depth) - float(next_stop_depth)) /
                    float(settings.DECO_ASCENT_RATE))
                self.logger.debug("update run time : %ss", self.run_time)
                self.output_segments.append(
                    SegmentAscDesc(self.current_depth, next_stop_depth,
                                   settings.DECO_ASCENT_RATE,
                                   self.current_tank, self.pp_o2))

            # now we moved up the the next depth
            self.current_depth = next_stop_depth
            max_mv = self.model.m_value(depth_to_pressure(self.current_depth))
            control = self.model.control_compartment()

            # Check and switch deco gas
            temp_tank = self.current_tank  # remember in case we switch
            if self.set_deco_gas(self.current_depth):  # True if we changed gas
                if in_ascent_cycle:
                    self.logger.debug(
                        "Add AscDesc(2): start_depth:%s, "
                        "current_depth:%s", start_depth, self.current_depth)
                    self.output_segments.append(
                        SegmentAscDesc(start_depth, self.current_depth,
                                       settings.ASCENT_RATE, temp_tank,
                                       self.pp_o2))
                    start_depth = self.current_depth

            # set next rounded stop depth
            next_stop_depth = int(
                self.current_depth) - settings.STOP_DEPTH_INCREMENT

            self.logger.debug("next stop depth: %s, target depth: %s",
                              next_stop_depth, target_depth)

            # check in cas we are overshooting or hit last stop
            if (next_stop_depth < target_depth
                    or self.current_depth < settings.LAST_STOP_DEPTH):
                self.logger.debug("next_stop_depth (%s) < target_depth (%s)",
                                  next_stop_depth, target_depth)
                next_stop_depth = target_depth
            elif self.current_depth < settings.LAST_STOP_DEPTH:
                self.logger.debug("current_depth (%s) < LAST_STOP_DEPTH (%s)",
                                  self.current_depth, settings.LAST_STOP_DEPTH)
                next_stop_depth = target_depth
            elif (next_stop_depth < settings.LAST_STOP_DEPTH
                  and next_stop_depth > 0):
                self.logger.debug(
                    "next_stop_depth (%s) < "
                    "settings.LAST_STOP_DEPTH (%s)", next_stop_depth,
                    settings.LAST_STOP_DEPTH)
                next_stop_depth = target_depth

            if self.model.gradient.gf_set:  # update gf for next stop
                self.model.gradient.set_gf_at_depth(next_stop_depth)

        # are we still in ascent segment ?
        if in_ascent_cycle:
            self.logger.debug(
                "Add AscDesc(3): start_depth:%s, "
                "current_depth:%s", start_depth, self.current_depth)
            self.output_segments.append(
                SegmentAscDesc(start_depth, self.current_depth,
                               -settings.ASCENT_RATE, self.current_tank,
                               self.pp_o2))