def sort_bbn_nodes():
    from bbn import BeliefNetwork
    from dst import settings as dst_settings
    from copy import copy, deepcopy
    BBN = BeliefNetwork.from_bif(dst_settings.BBN_BIF)

    blank_node = {
        'cpt': {},
        'parents': [],
        'given': [],
        'variables': [],
        'tier': None
    }

    node_dict = {}
    sorted_dict = {
        '0': {}
    }
    for node_idx in BBN.probabilities:
        node = BBN.probabilities[node_idx]
        if not node_idx in node_dict.keys():
            node_dict[node_idx] = deepcopy(blank_node)
        node_dict[node_idx]['variables'] = BBN.variables[node_idx]
        if node['given']:
            node_givens = [(x, BBN.variables[x]) for x in node['given']]
        else:
            node_givens = []
        node_dict[node_idx]['cpt'] = build_cpt_dict(node['cpt'], node_givens, BBN.variables[node_idx])

        if node['given']:
            node_dict[node_idx]['given'] = node['given']

        for given_idx in node_dict[node_idx]['given']:
            if not given_idx in node_dict.keys():
                node_dict[given_idx] = deepcopy(blank_node)
            node_dict[given_idx]['parents'].append(node_idx)

    unsorted_nodes = node_dict.keys()
    while len(unsorted_nodes) > 0:
        unsorted_list = [x for x in unsorted_nodes]
        for node_idx in unsorted_nodes:
            if len(node_dict[node_idx]['parents']) == 0:
                node_dict[node_idx]['tier'] = 0
                unsorted_list.remove(node_idx)
                sorted_dict['0'][node_idx] = node_dict[node_idx]
            else:
                for parent_idx in node_dict[node_idx]['parents']:
                    if not node_dict[node_idx]['tier']:
                        if not node_dict[parent_idx]['tier'] == None:
                            node_tier = node_dict[parent_idx]['tier']+1
                            node_dict[node_idx]['tier'] = node_tier
                            unsorted_list.remove(node_idx)
                            if not str(node_tier) in sorted_dict.keys():
                                sorted_dict[str(node_tier)] = {}
                            sorted_dict[str(node_tier)][node_idx] = node_dict[node_idx]

        unsorted_nodes = unsorted_list

    return sorted_dict
 def test_from_bif(self):
     bn = BeliefNetwork.from_bif(self.bif)
     self.assertEquals(
         sorted(list(bn.variables.keys())),
         ['Cancer', 'Dyspnoea', 'Pollution', 'Smoker', 'Xray'])
     self.assertEquals(
         sorted(list(bn.probabilities.keys())),
         ['Cancer', 'Dyspnoea', 'Pollution', 'Smoker', 'Xray'])
def update_bbn_bif(obj, post):
    from bbn import BeliefNetwork
    from dst import settings as dst_settings
    BBN = BeliefNetwork.from_bif(dst_settings.BBN_BIF)

    for field_key in post.keys():
        if '-' in field_key:
            node_key, condition_code = field_key.split('-')
            if node_key in BBN.probabilities.keys():
                field_val = post[field_key]
                tuple_key = ()
                if len(condition_code) > 0:
                    for idx, given_key in enumerate(BBN.probabilities[node_key]['given']):
                        tuple_key += (BBN.variables[given_key][int(condition_code[idx])],)
                # assumes all variables are binary!!!
                tuple_key_0 = tuple_key + (BBN.variables[node_key][0],)
                tuple_key_1 = tuple_key + (BBN.variables[node_key][1],)
                BBN.probabilities[node_key]['cpt'][tuple_key_0] = round(float(field_val), 2)
                BBN.probabilities[node_key]['cpt'][tuple_key_1] = round(1-float(field_val), 2)
    BeliefNetwork.to_bif(BBN, dst_settings.BBN_BIF)

    obj.bif = get_bbn_nodes()
    obj.save()
def systemcheck():
    bn = BeliefNetwork.from_bif(settings.BBN_BIF)

    # Valid BBN?
    valid = bn.is_valid
    if not valid[0]:
        raise SystemCheckError("BBN from {} is not valid:\n  {}".format(
            settings.BBN_BIF, valid[1]))

    # special case, contains a hidden terminal node for pit score
    pitnode = '__overall_pit_restorability'
    if pitnode not in bn.hidden_nodes:
        raise SystemCheckError("Overall pit node `{}` required in bbn".format(pitnode))

    # the terminal nodes of the belief network match questions
    terminalnode_names = []
    for name, prob in bn.probabilities.items():
        if not prob['given'] and not name.startswith('__'):
            # it's a terminal node or "hidden" node without questions
            terminalnode_names.append(name)

    from survey.models import Question
    question_names = [q.name for q in Question.objects.all()]

    tnn = set(terminalnode_names)
    qn = set(question_names)

    diff = list(qn - tnn)
    if len(diff) > 0:
        raise SystemCheckError(
            "Extraneous questions without terminal nodes:\n\t%s" % diff)

    diff = list(tnn - qn)
    if len(diff) > 0:
        raise SystemCheckError(
            "Terminal nodes missing questions:\n\t%s" % diff)

    # Make sure choices are valid;
    # first choice in bn.variables must have value of 1.0
    # all others must have values bt 0 and 1
    for question in Question.objects.all():
        first = bn.variables[question.name][0]
        for choice in question.choices:
            if choice['value'] < 0.0 or choice['value'] > 1.0:
                raise SystemCheckError("`{}` has invalid values in choices "
                                       "(must be 0 to 1)".format(question.name))

            if choice['choice'] == first and choice['value'] != 1.0:
                raise SystemCheckError("`{}` has invaid values in choices; "
                                       "`{}` must be 1.0".format(question.name, first))
            # randomly alter the probability table
            #  (first the True cond the false at 1.0 - val)
            first = self.state.variables[var][0]
            last = self.state.variables[var][1]
            key = tuple(clist + [first])
            lastkey = tuple(clist + [last])
            val = self.state.probabilities[var]['cpt'][key]
            newval = val + random.choice([0.05, -0.05])
            if newval >= 0.0 and newval <= 1.0:
                valid_move = True
                self.state.probabilities[var]['cpt'][key] = newval
                self.state.probabilities[var]['cpt'][lastkey] = 1.0 - newval

if __name__ == "__main__":

    bn = BeliefNetwork.from_bif(INPUT_BIF)

    training_sites = {}
    sites_glob = os.path.abspath(
        os.path.join(os.path.dirname(__file__),
                     'optimization_files', 'training_sites', "*.txt"))
    user_datas = {}
    for training_site in glob.glob(sites_glob):
        socio_economic = site = landscape = None
        user_data = {}
        with open(training_site, 'r') as fh:
            for line in fh.readlines():
                key, val = line.split(',')
                val = float(val)
                try:
                    cond = bn.variables[key][0]  # assume first
    def test_to_bif(self):
        bn = BeliefNetwork.from_bif(self.bif)
        bn.to_bif(self.outbif)

        bn2 = BeliefNetwork.from_bif(self.outbif)
        self.assertEquals(bn2, bn)
from django.contrib.gis.db import models
from django.contrib.auth.models import User
from django.conf import settings
from jsonfield import JSONField
from django.core.validators import MaxValueValidator, MinValueValidator


from bbn import BeliefNetwork
BBN = BeliefNetwork.from_bif(settings.BBN_BIF)

class BaseModel(models.Model):
    notes = models.TextField(default='', blank=True)
    user = models.ForeignKey(User)
    date_created = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

    def __str__(self):
        return "{} `{}` by {}".format(self.__class__.__name__,
                                      self.name,
                                      self.user.username)

class BifSettings(BaseModel):
    bif = models.TextField(default='', blank=True)

    def __str__(self):
        return"{} by {}".format(self.__class__.__name__,
                                      self.user.username)