def get_all_trajectories_rec_old(pomdp, policy, belief, use_fraction=True): """ This one first asks for an action, then looks for observations. for action in actions: for obs in observations: """ if pomdp.is_goal_belief(belief): # return [[]] actions = list(policy[belief].keys()) if len(actions) != 1: msg = 'Expected that a goal belief only had 1 action.' raise ValueError(msg) final_action = actions[0] belief1 = belief2 = belief ydist = pomdp.get_observations_dist_given_belief(belief1, use_fraction=use_fraction) # Just choose first final_y = list(ydist)[0] traj = [[dict(action=final_action, obs=final_y, belief=belief, belief1=belief1, ydist=ydist, belief2=belief2)]] return traj belief = frozendict2(belief) actions = policy[belief].keys() trajectories = [] for action in actions: assert belief in policy # evolve the belief given action belief1 = pomdp.evolve(belief, action, use_fraction=use_fraction) belief1 = frozendict2(belief1) # what's the dist of observation given the resulting belief ydist = pomdp.get_observations_dist_given_belief(belief1, use_fraction=use_fraction) for y, _ in ydist.items(): belief2 = pomdp.inference(belief=belief1, observations=y, use_fraction=use_fraction) if belief2 == belief: print('Found fixed point under optimal policy.') print(' - belief: %s' % belief) print(' - policy: %s' % policy[belief]) print(' - belief2: %s' % belief) raise ValueError() rest = get_all_trajectories_rec(pomdp, policy, belief2, use_fraction=use_fraction) for t1 in rest: traj = [dict(action=action, obs=y, belief=belief, belief1=belief1, ydist=ydist, belief2=belief2)] + t1 trajectories.append(traj) return trajectories
def __init__(self, states_names, decisions): """ Note that the commands cannot be tuples. """ self.states_names = states_names self.transitions = {} # (state, obs) -> state self.commands = {} # (state, obs) -> command for decision in decisions: actions = decision['action'] state = dict(decision['state']) # history = decision['history'] obs = state['last'] del state['last'] state = frozendict2(state) next_state, real_action = interpret_actions(state, actions) # warnings.warn('here we are assuming that commands are string') # assert isinstance(real_action, str) assert isinstance(next_state, dict) # # if isinstance(actions, tuple): # assert len(actions) == 2, "Otherwise more complicated" # # real_action = actions[0] # assert not isinstance(real_action, tuple) # rep_action = actions[1] # next_state = interpret(state, rep_action) # # if next_state == state: # print('Found info action %s, %s, %s -> %s' % # (state, obs, str(actions), next_state)) # print('But this transition does not work!') # raise ValueError() # # else: # real_action = actions # rep_action = None # next_state = state if state!=next_state: # print('Transition %s, %s -> %s' % (state , obs, next_state)) pass self.transitions[(state, obs)] = next_state self.commands[(state, obs)] = real_action self.state0 = frozendict2(dict([s, 0] for s in self.states_names)) self.decisions = decisions
def __init__(self, states_names, decisions): """ Note that the commands cannot be tuples. """ self.states_names = states_names self.transitions = {} # (state, obs) -> state self.commands = {} # (state, obs) -> command for decision in decisions: actions = decision['action'] state = dict(decision['state']) # history = decision['history'] obs = state['last'] del state['last'] state = frozendict2(state) next_state, real_action = interpret_actions(state, actions) # warnings.warn('here we are assuming that commands are string') # assert isinstance(real_action, str) assert isinstance(next_state, dict) # # if isinstance(actions, tuple): # assert len(actions) == 2, "Otherwise more complicated" # # real_action = actions[0] # assert not isinstance(real_action, tuple) # rep_action = actions[1] # next_state = interpret(state, rep_action) # # if next_state == state: # print('Found info action %s, %s, %s -> %s' % # (state, obs, str(actions), next_state)) # print('But this transition does not work!') # raise ValueError() # # else: # real_action = actions # rep_action = None # next_state = state if state != next_state: # print('Transition %s, %s -> %s' % (state , obs, next_state)) pass self.transitions[(state, obs)] = next_state self.commands[(state, obs)] = real_action self.state0 = frozendict2(dict([s, 0] for s in self.states_names)) self.decisions = decisions
def __setitem__(self, attrs, value): if not isinstance(attrs, dict): msg = 'Keys to this dictionary must be dicts' raise ValueError(msg) # Todo: check all strings frozen = frozendict2(**attrs) dict.__setitem__(self, frozen, value)
def f2(stats): distances = stats['distances'] key = frozendict2(i1=i1, i2=i2, d=d) if not key in distances: return None else: return distances[key]
def f2(stats): distances = stats['distances'] key = frozendict2(i1=i1, i2=i2, d=d) if not key in distances: return None else: return distances[key]
def __setitem__(self, attrs, value): if not isinstance(attrs, dict): msg = "Keys to this dictionary must be dicts" raise ValueError(msg) # Todo: check all strings frozen = frozendict2(**attrs) dict.__setitem__(self, frozen, value)
def inference(self, belief, observations, use_fraction=False): belief2 = dict() p_y = self.partition(observations=observations, state_dist=belief, use_fraction=use_fraction) if p_y == 0: msg = ('Tried to compute inference of p(x) given y but y ' 'cannot be generated by any x in p(x)') # msg += '\nBut p(y|x) is:\n\t%s ' % p # raise SimplePOMDP.ObsNotPossible(msg) for x, p_x in belief.items(): p_y_given_x = self.likelihood(observations=observations, state=x) p2 = p_x * p_y_given_x / p_y if p2 > 0: belief2[x] = p2 belief2 = frozendict2(belief2.items()) s = sum(belief2.values()) if not s == 1.0: msg = 'Expected %s, got %s. ' % (1.0, s) msg += '\n %s' % belief2 raise Exception(msg) return belief2
def get_decisions(trajectories): """ Returns list of dicts with fields action, state=dict(last=y) and history """ n = 0 for tr in trajectories: for i in range(len(tr)): action = tr[i]['action'] obs = tr[i]['obs'] history = tuple([yh['obs'] for yh in tr[:i]]) n += 1 # print('%03d: u = %s y = %s history %s' % (n, action, obs, len(history))) d = dict(action=action, state=frozendict2(last=obs), history=history) if 'agent_state' in tr[i]: d['agent_state'] = tr[i]['agent_state'] yield frozendict2(d)
def get_observations_dist(self, state): robot, intruder = state # @UnusedVariable # use perfect sensor to detect _, intruder_detected = list(IntruderPOMDPDec.get_observations_dist(self, state))[0] rf = self.get_simulated_rangefinder(robot, horizon=self.horizon) z = (rf, intruder_detected) return frozendict2({z:1})
def get_decisions(trajectories): """ Returns list of dicts with fields action, state=dict(last=y) and history """ n = 0 for tr in trajectories: for i in range(len(tr)): action = tr[i]['action'] obs = tr[i]['obs'] history = tuple([yh['obs'] for yh in tr[:i]]) n += 1 # print('%03d: u = %s y = %s history %s' % (n, action, obs, len(history))) d = dict(action=action, state=frozendict2(last=obs), history=history) if 'agent_state' in tr[i]: d['agent_state'] = tr[i]['agent_state'] yield frozendict2(d)
def get_all_trajectories_rec(pomdp, policy, belief, use_fraction=True): """ This one first generates an observation. for obs in observations: for action in actions: """ if pomdp.is_goal_belief(belief): return [[]] belief = frozendict2(belief) obs_dist = pomdp.get_observations_dist_given_belief( belief, use_fraction=use_fraction) trajectories = [] for obs, _ in obs_dist.items(): belief_given_obs = pomdp.inference(belief=belief, observations=obs, use_fraction=use_fraction) assert belief_given_obs in policy actions = policy[belief_given_obs].keys() for action in actions: belief_after_action = pomdp.evolve(belief_given_obs, action, use_fraction=use_fraction) if belief_after_action == belief: print('Found fixed point under optimal policy.') print(' - belief: %s' % belief) print(' - policy: %s' % policy[belief]) print(' - belief2: %s' % belief) raise ValueError() rest = get_all_trajectories_rec(pomdp, policy, belief_after_action, use_fraction=use_fraction) for t1 in rest: # desc = """ # From belief # we sampled obs # then belief1 = belief given obs # then we chose action # then belief2 = belief1 evolved with action. # """ warnings.warn('Need to chenage belief1,2 to meaningful names.') traj = [ dict(belief=belief, action=action, obs=obs, belief1=belief_given_obs, ydist=obs_dist, belief2=belief_after_action) ] + t1 trajectories.append(traj) return trajectories
def memoizer(f, obj, *args, **kwargs): if not '__cache' in obj.__dict__: obj.__dict__['__cache'] = {} if not f.__name__ in obj.__cache: obj.__cache[f.__name__] = {} cache = obj.__cache[f.__name__] if memoize_instance_show_initial_cache: if f.__cache_calls == 0 and len(cache) > 0: # first time we call it print('For %r I already have a cache of %d calls' % (f.__name__, len(cache))) for key in cache: print('- %s' % str(key)) f.__cache_calls += 1 def get_signature(): args_str = ",".join(str(x) for x in args) kwargs_str = ",".join('%s=%s' % (k, v) for k, v in kwargs.items()) signature = '%s:%s.%s(%s,%s)' % (obj.__class__.__name__, id(obj), f.__name__, args_str, kwargs_str) return signature key = (args, frozendict2(kwargs)) if key not in cache: c0 = time.clock() t0 = time.time() result = f(obj, *args, **kwargs) C = time.clock() - c0 T = time.time() - t0 cache[key] = result if memoize_instance_show_store: #print('STORE %s = %s' % (cache[key], get_signature())) perc = 100.0 * f.__cache_hits / f.__cache_calls n = len(cache) cache_size = sum([x.__sizeof__() for x in cache.values()]) if cache_size > memoize_instance_show_store_limit: print('compute time: clock: %sms wall: %sms' % (C * 1000, T * 1000)) print('cache(S): %5d stored %7d calls hits %3.3f%% size %s for %s' % (n, f.__cache_calls, perc, cache_size, f.__name__)) else: f.__cache_hits += 1 pass if f.__cache_calls % memoize_instance_stats_interval == 0: perc = 100.0 * f.__cache_hits / f.__cache_calls n = len(cache) print('cache(R): %5d stored %7d calls hits %3.3f%% for %s' % (n, f.__cache_calls, perc, f.__name__)) return cache[key]
def memoizer(f, obj, *args, **kwargs): if not '__cache' in obj.__dict__: obj.__dict__['__cache'] = {} if not f.__name__ in obj.__cache: obj.__cache[f.__name__] = {} cache = obj.__cache[f.__name__] if memoize_instance_show_initial_cache: if f.__cache_calls == 0 and len(cache) > 0: # first time we call it print('For %r I already have a cache of %d calls' % (f.__name__, len(cache))) for key in cache: print('- %s' % str(key)) f.__cache_calls += 1 def get_signature(): args_str = ",".join(str(x) for x in args) kwargs_str = ",".join('%s=%s' % (k, v) for k, v in kwargs.items()) signature = '%s:%s.%s(%s,%s)' % (obj.__class__.__name__, id(obj), f.__name__, args_str, kwargs_str) return signature key = (args, frozendict2(kwargs)) if key not in cache: c0 = time.clock() t0 = time.time() result = f(obj, *args, **kwargs) C = time.clock() - c0 T = time.time() - t0 cache[key] = result if memoize_instance_show_store: # print('STORE %s = %s' % (cache[key], get_signature())) perc = 100.0 * f.__cache_hits / f.__cache_calls n = len(cache) cache_size = sum([x.__sizeof__() for x in cache.values()]) if cache_size > memoize_instance_show_store_limit: print('compute time: clock: %sms wall: %sms' % (C * 1000, T * 1000)) print('cache(S): %5d stored %7d calls hits %3.3f%% size %s for %s' % (n, f.__cache_calls, perc, cache_size, f.__name__)) else: f.__cache_hits += 1 pass if f.__cache_calls % memoize_instance_stats_interval == 0: perc = 100.0 * f.__cache_hits / f.__cache_calls n = len(cache) print('cache(R): %5d stored %7d calls hits %3.3f%% for %s' % (n, f.__cache_calls, perc, f.__name__)) return cache[key]
def get_observations_dist(self, state): robot, intruder = state # @UnusedVariable # use perfect sensor to detect _, intruder_detected = list( IntruderPOMDPDec.get_observations_dist(self, state))[0] rf = self.get_simulated_rangefinder(robot, horizon=self.horizon) z = (rf, intruder_detected) return frozendict2({z: 1})
def make_key(self, f, args, kwargs): """ Returns an hashable key. We don't want to pickle functions, so we use their name. Might this have problems with decorators? TODO: investigate """ # TODO: use resolving names, so that equivalent calls # have the same signature key = (f.__name__, args, frozendict2(kwargs)) return key
def make_key(self, f, args, kwargs): """ Returns an hashable key. We don't want to pickle functions, so we use their name. Might this have problems with decorators? TODO: investigate """ # TODO: use resolving names, so that equivalent calls # have the same signature key = (f.__name__, args, frozendict2(kwargs)) return key
def __getitem__(self, attrs): if not isinstance(attrs, frozendict2): check_isinstance(attrs, dict) attrs = frozendict2(**attrs) try: return dict.__getitem__(self, attrs) except KeyError as e: msg = str(e) keys = self.keys() if keys: k = most_similar(self.keys(), attrs) msg += "\n The most similar key is: %s" % str(k) raise KeyError(msg)
def interpret_actions_one(state, rep_action): assert isinstance(state, dict), state assert isinstance(rep_action, str), rep_action assert '=' in rep_action, 'Invalid rep action %s (state %s)' % (rep_action, state) comp, value = rep_action.split('=') value = int(value) assert comp in state next_state = dict(**state) next_state[comp] = value next_state = frozendict2(next_state) return next_state
def __getitem__(self, attrs): if not isinstance(attrs, frozendict2): check_isinstance(attrs, dict) attrs = frozendict2(**attrs) try: return dict.__getitem__(self, attrs) except KeyError as e: msg = str(e) keys = self.keys() if keys: k = most_similar(self.keys(), attrs) msg += '\n The most similar key is: %s' % str(k) raise KeyError(msg)
def interpret_actions_one(state, rep_action): assert isinstance(state, dict), state assert isinstance(rep_action, str), rep_action assert '=' in rep_action, 'Invalid rep action %s (state %s)' % (rep_action, state) comp, value = rep_action.split('=') value = int(value) assert comp in state next_state = dict(**state) next_state[comp] = value next_state = frozendict2(next_state) return next_state
def get_all_trajectories_rec(pomdp, policy, belief, use_fraction=True): """ This one first generates an observation. for obs in observations: for action in actions: """ if pomdp.is_goal_belief(belief): return [[]] belief = frozendict2(belief) obs_dist = pomdp.get_observations_dist_given_belief(belief, use_fraction=use_fraction) trajectories = [] for obs, _ in obs_dist.items(): belief_given_obs = pomdp.inference(belief=belief, observations=obs, use_fraction=use_fraction) assert belief_given_obs in policy actions = policy[belief_given_obs].keys() for action in actions: belief_after_action = pomdp.evolve(belief_given_obs, action, use_fraction=use_fraction) if belief_after_action == belief: print('Found fixed point under optimal policy.') print(' - belief: %s' % belief) print(' - policy: %s' % policy[belief]) print(' - belief2: %s' % belief) raise ValueError() rest = get_all_trajectories_rec(pomdp, policy, belief_after_action, use_fraction=use_fraction) for t1 in rest: # desc = """ # From belief # we sampled obs # then belief1 = belief given obs # then we chose action # then belief2 = belief1 evolved with action. # """ warnings.warn('Need to chenage belief1,2 to meaningful names.') traj = [dict(belief=belief, action=action, obs=obs, belief1=belief_given_obs, ydist=obs_dist, belief2=belief_after_action)] + t1 trajectories.append(traj) return trajectories
def evolve(self, state_dist, action, use_fraction=False): self.is_state_dist(state_dist) if use_fraction: p2 = defaultdict(lambda: Fraction(0)) else: p2 = defaultdict(lambda: Fraction(0.0)) for s1, p_s1 in state_dist.items(): conditional = self.transition(s1, action) self.is_state_dist(conditional) for s2, p_s2 in conditional.items(): if p_s2 * p_s1 > 0: p2[s2] += p_s2 * p_s1 for s in list(p2): if p2[s] == 0: del p2[s] return frozendict2(p2)
def evolve(self, state_dist, action, use_fraction=False): self.is_state_dist(state_dist) if use_fraction: p2 = defaultdict(lambda:Fraction(0)) else: p2 = defaultdict(lambda:Fraction(0.0)) for s1, p_s1 in state_dist.items(): conditional = self.transition(s1, action) self.is_state_dist(conditional) for s2, p_s2 in conditional.items(): if p_s2 * p_s1 > 0: p2[s2] += p_s2 * p_s1 for s in list(p2): if p2[s] == 0: del p2[s] return frozendict2(p2)
def add(self, report, report_type, **kwargs): """ Adds a report to the collection. :param report: Promise of a Report object :param report_type: A string that describes the "type" of the report :param kwargs: str->str,int,float parameters used for grouping """ if not isinstance(report_type, str): msg = 'Need a string for report_type, got %r.' % describe_value(report_type) raise ValueError(msg) from compmake import Promise if not isinstance(report, Promise): msg = ('ReportManager is mean to be given Promise objects, ' 'which are the output of comp(). Obtained: %s' % describe_type(report)) raise ValueError(msg) # check the format is ok self._check_report_format(report_type, **kwargs) key = frozendict2(report=report_type, **kwargs) if key in self.allreports: msg = 'Already added report for %s' % key msg += '\n its values is %s' % self.allreports[key] msg += '\n new value would be %s' % report raise ValueError(msg) self.allreports[key] = report report_type_sane = report_type.replace('_', '') key_no_report = dict(**key) del key_no_report['report'] basename = self.html_resources_prefix + report_type_sane if key_no_report: basename += '-' + basename_from_key(key_no_report) dirname = os.path.join(self.outdir, report_type_sane) filename = os.path.join(dirname, basename) self.allreports_filename[key] = filename + '.html'
def remove_field(self, field): """ Returns a copy of this structure, where the given field is removed from the keys. Throws an error if removing the field would make the keys not unique. Also throws an error if the given field is not present in all keys.""" r = self.__class__() for key in self: if not field in key: msg = "Could not find field %r in key %r." % (field, key) raise ValueError(msg) key2 = frozendict2(key) del key2[field] if key2 in r: msg = ('Removing field %r from key %r would make it non unique.' % (field, key)) raise ValueError(msg) r[key2] = self[key] return r
def remove_field(self, field): """ Returns a copy of this structure, where the given field is removed from the keys. Throws an error if removing the field would make the keys not unique. Also throws an error if the given field is not present in all keys.""" r = self.__class__() for key in self: if not field in key: msg = "Could not find field %r in key %r." % (field, key) raise ValueError(msg) key2 = frozendict2(key) del key2[field] if key2 in r: msg = "Removing field %r from key %r would make it non unique." % ( field, key, ) raise ValueError(msg) r[key2] = self[key] return r
def inference(self, belief, observations, use_fraction=False): belief2 = dict() p_y = self.partition(observations=observations, state_dist=belief, use_fraction=use_fraction) if p_y == 0: msg = ('Tried to compute inference of p(x) given y but y ' 'cannot be generated by any x in p(x)') # msg += '\nBut p(y|x) is:\n\t%s ' % p # raise SimplePOMDP.ObsNotPossible(msg) for x, p_x in belief.items(): p_y_given_x = self.likelihood(observations=observations, state=x) p2 = p_x * p_y_given_x / p_y if p2 > 0: belief2[x] = p2 belief2 = frozendict2(belief2.items()) s = sum(belief2.values()) if not s == 1.0: msg = 'Expected %s, got %s. ' % (1.0, s) msg += '\n %s' % belief2 raise Exception(msg) return belief2
def get_all_states(self): state0 = frozendict2(dict([s, 0] for s in self.states_names)) states = set(self.transitions.values()) states.add(state0) return states
def __contains__(self, attrs): frozen = frozendict2(**attrs) return dict.__contains__(self, frozen)
def get(self, report_type, **kwargs): key = frozendict2(report=report_type, **kwargs) return self.allreports[key]
def __contains__(self, attrs): frozen = frozendict2(**attrs) return dict.__contains__(self, frozen)
def get_all_states(self): state0 = frozendict2(dict([s, 0] for s in self.states_names)) states = set(self.transitions.values()) states.add(state0) return states
def add(self, context, report, report_type: str, **kwargs): """ Adds a report to the collection. :param report: Promise of a Report object :param report_type: A string that describes the "type" of the report :param kwargs: str->str,int,float parameters used for grouping """ from quickapp.compmake_context import CompmakeContext assert isinstance(context, CompmakeContext) if not isinstance(report_type, str): msg = 'Need a string for report_type, got %r.' % describe_value( report_type) raise ValueError(msg) if not isinstance(report, Promise): msg = ('ReportManager is mean to be given Promise objects, ' 'which are the output of comp(). Obtained: %s' % describe_type(report)) raise ValueError(msg) # check the format is ok self._check_report_format(report_type, **kwargs) key = frozendict2(report=report_type, **kwargs) if key in self.allreports: msg = 'Already added report for %s' % key msg += '\n its values is %s' % self.allreports[key] msg += '\n new value would be %s' % report raise ValueError(msg) self.allreports[key] = report report_type_sane = report_type.replace('_', '') key_no_report = dict(**key) del key_no_report['report'] basename = self.html_resources_prefix + report_type_sane if key_no_report: basename += '-' + basename_from_key(key_no_report) dirname = os.path.join(self.outdir, report_type_sane) filename = os.path.join(dirname, basename) self.allreports_filename[key] = filename + '.html' write_singles = False if write_singles: is_root = context.currently_executing == ['root'] if not is_root: # Add also a single report independent of a global index # don't create the single report for the ones that are # defined in the root session filename_single = os.path.join(dirname, basename) + '_s.html' # filename_index_dyn = os.path.join(dirname, basename) + '_dyn.html' report_nid = self.html_resources_prefix + report_type_sane if key: report_nid += '-' + basename_from_key(key) write_job_id = jobid_minus_prefix(context, report.job_id + '-writes') # write_report_yaml(report_nid, report_job_id=report.job_id, # key=key, html_filename=filename_single, # report_html_indexed=filename_index_dyn) context.comp(write_report_single, report=report, report_nid=report_nid, report_html=filename_single, write_pickle=False, static_dir=self.static_dir, job_id=write_job_id)
def memoizer(f, *args, **kwargs): key = (args, frozendict2(kwargs)) if key not in cache: cache[key] = f(*args, **kwargs) #print('memoize: %s %d storage' % (obj, len(cache))) return cache[key]
def get_all_trajectories_rec_old(pomdp, policy, belief, use_fraction=True): """ This one first asks for an action, then looks for observations. for action in actions: for obs in observations: """ if pomdp.is_goal_belief(belief): # return [[]] actions = list(policy[belief].keys()) if len(actions) != 1: msg = 'Expected that a goal belief only had 1 action.' raise ValueError(msg) final_action = actions[0] belief1 = belief2 = belief ydist = pomdp.get_observations_dist_given_belief( belief1, use_fraction=use_fraction) # Just choose first final_y = list(ydist)[0] traj = [[ dict(action=final_action, obs=final_y, belief=belief, belief1=belief1, ydist=ydist, belief2=belief2) ]] return traj belief = frozendict2(belief) actions = policy[belief].keys() trajectories = [] for action in actions: assert belief in policy # evolve the belief given action belief1 = pomdp.evolve(belief, action, use_fraction=use_fraction) belief1 = frozendict2(belief1) # what's the dist of observation given the resulting belief ydist = pomdp.get_observations_dist_given_belief( belief1, use_fraction=use_fraction) for y, _ in ydist.items(): belief2 = pomdp.inference(belief=belief1, observations=y, use_fraction=use_fraction) if belief2 == belief: print('Found fixed point under optimal policy.') print(' - belief: %s' % belief) print(' - policy: %s' % policy[belief]) print(' - belief2: %s' % belief) raise ValueError() rest = get_all_trajectories_rec(pomdp, policy, belief2, use_fraction=use_fraction) for t1 in rest: traj = [ dict(action=action, obs=y, belief=belief, belief1=belief1, ydist=ydist, belief2=belief2) ] + t1 trajectories.append(traj) return trajectories
def memoizer(f, *args, **kwargs): key = (args, frozendict2(kwargs)) if key not in cache: cache[key] = f(*args, **kwargs) # print('memoize: %s %d storage' % (obj, len(cache))) return cache[key]
def get_state(self): return frozendict2(self.state)
def get_state(self): return frozendict2(self.state)
def add(self, context, report, report_type, **kwargs): """ Adds a report to the collection. :param report: Promise of a Report object :param report_type: A string that describes the "type" of the report :param kwargs: str->str,int,float parameters used for grouping """ from quickapp.compmake_context import CompmakeContext assert isinstance(context, CompmakeContext) if not isinstance(report_type, six.string_types): msg = 'Need a string for report_type, got %r.' % describe_value(report_type) raise ValueError(msg) if not isinstance(report, Promise): msg = ('ReportManager is mean to be given Promise objects, ' 'which are the output of comp(). Obtained: %s' % describe_type(report)) raise ValueError(msg) # check the format is ok self._check_report_format(report_type, **kwargs) key = frozendict2(report=report_type, **kwargs) if key in self.allreports: msg = 'Already added report for %s' % key msg += '\n its values is %s' % self.allreports[key] msg += '\n new value would be %s' % report raise ValueError(msg) self.allreports[key] = report report_type_sane = report_type.replace('_', '') key_no_report = dict(**key) del key_no_report['report'] basename = self.html_resources_prefix + report_type_sane if key_no_report: basename += '-' + basename_from_key(key_no_report) dirname = os.path.join(self.outdir, report_type_sane) filename = os.path.join(dirname, basename) self.allreports_filename[key] = filename + '.html' write_singles = False if write_singles: is_root = context.currently_executing == ['root'] if not is_root: # Add also a single report independent of a global index # don't create the single report for the ones that are # defined in the root session filename_single = os.path.join(dirname, basename) + '_s.html' # filename_index_dyn = os.path.join(dirname, basename) + '_dyn.html' report_nid = self.html_resources_prefix + report_type_sane if key: report_nid += '-' + basename_from_key(key) write_job_id = jobid_minus_prefix(context, report.job_id + '-writes') # write_report_yaml(report_nid, report_job_id=report.job_id, # key=key, html_filename=filename_single, # report_html_indexed=filename_index_dyn) context.comp(write_report_single, report=report, report_nid=report_nid, report_html=filename_single, write_pickle=False, static_dir=self.static_dir, job_id=write_job_id)
def get(self, report_type, **kwargs): key = frozendict2(report=report_type, **kwargs) return self.allreports[key]