Пример #1
0
    def _set_state(self, state):
        """
        Set the state of the calculation.

        Set it in the DbCalcState to have also the uniqueness check.
        Moreover (except for the IMPORTED state) also store in the 'state'
        attribute, useful to know it also after importing, and for faster
        querying.

        .. todo:: Add further checks to enforce that the states are set
           in order?

        :param state: a string with the state. This must be a valid string,
          from ``aiida.common.datastructures.calc_states``.
        :raise: ModificationNotAllowed if the given state was already set.
        """
        super(JobCalculation, self)._set_state(state)

        from aiida.common.datastructures import sort_states
        from aiida.backends.djsite.db.models import DbCalcState

        if not self.is_stored:
            raise ModificationNotAllowed("Cannot set the calculation state "
                                         "before storing")

        if state not in calc_states:
            raise ValueError(
                "'{}' is not a valid calculation status".format(state))

        old_state = self.get_state()
        if old_state:
            state_sequence = [state, old_state]

            # sort from new to old: if they are equal, then it is a valid
            # advance in state (otherwise, we are going backwards...)
            if sort_states(state_sequence) != state_sequence:
                raise ModificationNotAllowed("Cannot change the state from {} "
                                             "to {}".format(old_state, state))

        try:
            with transaction.atomic():
                new_state = DbCalcState(dbnode=self.dbnode, state=state).save()
        except IntegrityError:
            raise ModificationNotAllowed(
                "Calculation pk= {} already transited through "
                "the state {}".format(self.pk, state))

        # For non-imported states, also set in the attribute (so that, if we
        # export, we can still see the original state the calculation had.
        if state != calc_states.IMPORTED:
            self._set_attr('state', state)
Пример #2
0
 def state(self):
     """
     Return the most recent state from DbCalcState
     """
     if not self.id:
         return None
     all_states = DbCalcState.query.filter(DbCalcState.dbnode_id == self.id).all()
     if all_states:
         #return max((st.time, st.state) for st in all_states)[1]
         return sort_states(((dbcalcstate.state, dbcalcstate.state.value)
                             for dbcalcstate in all_states),
                             use_key=True)[0]
     else:
         return None
Пример #3
0
    def get_state(self, from_attribute=False):
        """
        Get the state of the calculation.

        .. note:: this method returns the NOTFOUND state if no state
          is found in the DB.

        .. note:: the 'most recent' state is obtained using the logic in the
          ``aiida.common.datastructures.sort_states`` function.

        .. todo:: Understand if the state returned when no state entry is found
          in the DB is the best choice.

        :param from_attribute: if set to True, read it from the attributes
          (the attribute is also set with set_state, unless the state is set
          to IMPORTED; in this way we can also see the state before storing).

        :return: a string. If from_attribute is True and no attribute is found,
          return None. If from_attribute is False and no entry is found in the
          DB, return the "NOTFOUND" state.
        """
        from aiida.backends.djsite.db.models import DbCalcState
        if from_attribute:
            return self.get_attr('state', None)
        else:
            if not self.is_stored:
                return calc_states.NEW
            else:
                this_calc_states = DbCalcState.objects.filter(
                    dbnode=self).values_list('state', flat=True)
                if not this_calc_states:
                    return None
                else:
                    try:
                        most_recent_state = sort_states(this_calc_states)[0]
                    except ValueError as e:
                        raise DbContentError("Error in the content of the "
                                             "DbCalcState table ({})".format(
                            e.message))

                    return most_recent_state