def __init__(self, t_window, beta_multiplier, max_pos_tests_per_week_per_100k, intervention_times=None, init_active=False): """ Additional parameters: ---------------------- max_pos_test_per_week : int If the number of positive tests per week exceeds this number the measure becomes active intervention_times : list of floats List of points in time at which interventions can be changed. If 'None' interventions can be changed at any time init_active : bool If true measure is active in the first week of the simulation when there are no test counts yet """ super().__init__(t_window, beta_multiplier) self.max_pos_tests_per_week_per_100k = max_pos_tests_per_week_per_100k self.intervention_times = intervention_times self.intervention_history = InterLap() if init_active: self.intervention_history.update([ (t_window.left, t_window.left + 7 * 24 - EPS, True) ])
def build_interval_list(features): inter = InterLap() feature_coords = [[ feature.start - 1, feature.end - 1, [feature.attributes["copy_id"][0], feature] ] for feature in features] if len(feature_coords) > 0: inter.update(feature_coords) return inter
def getAED(query, reference): ''' function to calcuate annotation edit distance between two mRNA transcript coordinates AED = 1 - (SN + SP / 2) SN = fraction of ref predicted SP = fraction prediction overlapping the ref ''' def _length(listTup): len = 0 for i in listTup: l = abs(i[0] - i[1]) len += l return len #check if identical if query == reference: return '0.000' #make sure sorted rLen = _length(reference) refInterlap = InterLap(reference) RefPred = 0 QueryOverlap = 0 qLen = 0 for exon in query: qLen += abs(exon[0] - exon[1]) if exon in refInterlap: #exon overlaps at least partially with reference hit = list(refInterlap.find(exon)) for h in hit: diff = np.subtract( exon, h) #will return array of exon minus hit at each pos if diff[0] <= 0 and diff[ 1] >= 0: #then query exon covers ref exon cov = abs(h[0] - h[1]) QueryOverlap += cov elif diff[0] <= 0 and diff[ 1] < 0: # means query partial covers ref cov = abs(h[0] - exon[1]) QueryOverlap += cov elif diff[0] > 0 and diff[ 1] >= 0: #means query partial covers ref cov = abs(exon[0] - h[1]) QueryOverlap += cov elif diff[0] > 0 and diff[1] < 1: cov = abs(exon[0] - exon[1]) QueryOverlap += cov #calculate AED if qLen > 0 and rLen > 0: SP = QueryOverlap / float(qLen) SN = QueryOverlap / float(rLen) AED = 1 - ((SN + SP) / 2) else: AED = 0.000 return '{:.3f}'.format(AED)
def __init__(self, t_window, p_stay_home, max_pos_tests_per_week_per_100k, intervention_times=None, init_active=False): """ Additional parameters: ---------------------- max_pos_test_per_week : int If the number of positive tests per week exceeds this number the measure becomes active intervention_times : list of floats List of points in time at which measures can become active. If 'None' measures can be changed at any time """ super().__init__(t_window, p_stay_home) self.max_pos_tests_per_week_per_100k = max_pos_tests_per_week_per_100k self.intervention_times = intervention_times self.intervention_history = InterLap() if init_active: self.intervention_history.update([(t_window.left, t_window.left + 7 * 24 - EPS, True)])
def find(self, feature: Feature, fraction: Optional[float] = None) -> List[Feature]: def filter4Fraction(overlap_feature): if not fraction: return True overlap_in_bp = float(overlap_feature.get_overlap_in_bp_with(feature)) if len(feature) == 0: overlap_fraction_relative_to_feature = 0.0 else: overlap_fraction_relative_to_feature = overlap_in_bp / len(feature) if len(overlap_feature) == 0: overlap_fraction_relative_to_overlap_feature = 0.0 else: overlap_fraction_relative_to_overlap_feature = overlap_in_bp / len(overlap_feature) return max(overlap_fraction_relative_to_feature, overlap_fraction_relative_to_overlap_feature) >= fraction def toFeature(interval): return Feature(feature.chromosome, interval[0], interval[1], interval[2][FeatureSeq.NAME_ATTRIBUTE], interval[2][FeatureSeq.SCORE_ATTRIBUTE]) return list(filter(filter4Fraction, map(toFeature, self.chromosome2tree.get(feature.chromosome, InterLap()).find(feature.interval))))
def _find_contacts(self, mob_traces): """Find contacts in a given list `mob_traces` of `Visit`s""" # Group mobility traces by site mob_traces_at_site = defaultdict(list) for v in mob_traces: mob_traces_at_site[v.site].append(v) # dict of dict of list of contacts: # i.e. contacts[i][j][k] = "k-th contact from i to j" contacts = {i: defaultdict(InterLap) for i in range(self.num_people)} # For each site s for s in range(self.num_sites): if self.verbose: print('Checking site ' + str(s + 1) + '/' + str(self.num_sites), end='\r') if len(mob_traces_at_site[s]) == 0: continue # Init the interval overlap matcher inter = InterLap() inter.update(mob_traces_at_site[s]) # Match contacts for v in mob_traces_at_site[s]: v_time = (v.t_from, v.t_to) for vo in list(inter.find(other=v_time)): # Ignore contacts with same individual if v.indiv == vo.indiv: continue # Compute contact time c_t_from = max(v.t_from, vo.t_from) c_t_to = min(v.t_to, vo.t_to_shifted) if c_t_to > c_t_from: # Set contact tuple c = Contact(t_from=c_t_from, t_to=c_t_to, indiv_i=v.indiv, indiv_j=vo.indiv, id_tup=(v.id, vo.id), site=s, duration=c_t_to - c_t_from) # Add it to interlap contacts[v.indiv][vo.indiv].update([c]) return contacts
def _group_mob_traces_by_indiv(self, mob_traces): """Group `mob_traces` by individual for faster queries. Returns a dict of dict of Interlap of the form: mob_traces_dict[i] = "Interlap of visits of indiv i" """ mob_traces_dict = {i: InterLap() for i in range(self.num_people)} for v in mob_traces: mob_traces_dict[v.indiv].update([v]) return mob_traces_dict
def _group_mob_traces_by_site(self, mob_traces): """Group `mob_traces` by site for faster queries. Returns a dict of dict of Interlap of the form: mob_traces_dict[k] = "Interlap of visits at site k" """ mob_traces_dict = {k: InterLap() for k in range(self.num_sites)} for v in mob_traces: mob_traces_dict[v.site].update([v]) return mob_traces_dict
def _extract(information, genome, name): """Creates an intervalTree based on the information of the gtf line""" seqname = information["seqname"] start, end = int(information["start"]), int(information["end"]) genome.setdefault(seqname, InterLap()).add((start - 1, end, information)) gene_name = information["gene_name"] name.setdefault(gene_name[0], dict()).setdefault(gene_name, []).append(information)
def init_run(self, n_people, n_visits): """Init the measure for this run by sampling the outcome of each visit for each individual Parameters ---------- n_people : int Number of people in the population n_visits : int Maximum number of visits of an individual """ # Sample the outcome of the measure for each visit of each individual self.bernoulli_stay_home = np.random.binomial( 1, self.p_stay_home, size=(n_people, n_visits)) self.intervals_stay_home = [InterLap() for _ in range(n_people)] self._is_init = True
def simulate(self, max_time, seed=None): """ Simulate contacts between individuals in time window [0, max_time]. Parameters ---------- max_time : float Maximum time to simulate seed : int Random seed for mobility simulation Returns ------- contacts : list of list of tuples A list of namedtuples containing the list of all contacts as namedtuples ('time_start', 'indiv_j', 'duration'), where: - `time_start` is the time the contact started - 'indiv_j' is the id of the individual the contact was with - 'duration' is the duration of the contact """ self.max_time = max_time # Simulate mobility of each individuals to each sites if self.verbose: print(f'Simulate mobility for {max_time:.2f} time units... ', end='', flush=True) # simulate mobility traces all_mob_traces = self._simulate_mobility(max_time, seed) self.mob_traces_by_indiv = self._group_mob_traces_by_indiv( all_mob_traces) self.mob_traces_by_site = self._group_mob_traces_by_site( all_mob_traces) self.mob_traces = InterLap(ranges=all_mob_traces) # Initialize empty contact array self.contacts = { i: defaultdict(InterLap) for i in range(self.num_people) }
def read_exons(gtf, chrom, cutoff, coverage_array, exclude): genes = defaultdict(IntervalSet) splitters = defaultdict(IntervalSet) interlaps = [] split_iv = InterLap() # preempt any bugs by checking that we are getting a particular chrom assert gtf[0] == "|", ( "expecting a tabix query so we can handle chroms correctly") #f1 = open("selfchaincut.txt","a") #f2 = open("segdupscut.txt","a") #f3 = open("coveragecut.txt","a") for bed in exclude: # expecting a tabix query so we can handle chroms correctly a = "|tabix {bed} {chrom}".format(chrom=chrom, bed=bed) # any file that gets sent in will be used to split regions (just like # low-coverage). For example, we split on self-chains as well. #TODO: comment this block if you don't want any filtering by self-chains or segdups for toks in ( x.strip().split("\t") for x in ts.nopen(a) ): # adds self chains and segdups to splitters list, so that exons can be split, and they are removed from CCRs s, e = int(toks[1]), int(toks[2]) split_iv.add((s, e)) #if len(toks) > 3: # f1.write("\t".join(toks)+"\n") # self chain #else: # f2.write("\t".join(toks)+"\n") # segdups for toks in (x.rstrip('\r\n').split("\t") for x in ts.nopen(gtf) if x[0] != "#"): if toks[2] not in ("CDS", "stop_codon") or toks[1] not in ("protein_coding"): continue #if toks[0] != "1": break start, end = map(int, toks[3:5]) gene = toks[8].split('gene_name "')[1].split('"', 1)[0] assert start <= end, toks key = toks[0], gene #cutoff = 0.3 # find sections of exon under certain coverage. #TODO: comment this if we don't want coverage cutoff filtering if coverage_array[start - 1:end].min( ) < cutoff: # doesn't bother to run these operations if there is not one bp below the cutoff #splitters[key].add([(start - 1, end)]) #this takes out the whole exon for one section of poor coverage a = coverage_array[start - 1:end] #print str(start-1),end,a is_under, locs = False, [] # generates "locs" for each exon" if a[0] < cutoff: locs.append([start - 1]) is_under = True # so you can initialize is_under for pos, v in enumerate( a[1:], start=start ): #enumerates positions in the coverage array starting at the beginning of the exon if v < cutoff: if not is_under: is_under = True locs.append( [pos - 1] ) #start, coverage is in bed format, so pos-1 is necessary, since splitters are open left and right side else: if is_under: is_under = False locs[-1].append(pos) #end if is_under: locs[-1].append( end ) # in this case would end splitter at the end of the exon splitters[key].add(map(tuple, locs)) #for i in locs: # f3.write(chrom+"\t"+"\t".join(map(str,i))+"\n") for s, e in split_iv.find((start - 1, end)): splitters[key].add([(s, e)]) genes[key].add( [(start - 1, end)] ) # converts GTF exon coordinates to BED format (subtracts 1 from exon start) # sort by start so we can do binary search. genes = dict((k, sorted(v._vals)) for k, v in genes.iteritems()) #ends = dict((k, sorted(v)) for k, v in ends.iteritems()) splits, starts, ends = {}, {}, {} splitters = dict(splitters) for chrom_gene, sends in genes.iteritems(): starts[chrom_gene] = [s[0] for s in sends] ends[chrom_gene] = [s[1] for s in sends] if chrom_gene in splitters: splits[chrom_gene] = splitters[chrom_gene]._vals return starts, ends, splits
keep = False # from interval import interval from interlap import InterLap from interlap import Interval # This class can auto merge overlapped regions. # interlap really significantly increased the search speed. irange = Interval() with open(args['-r'], 'r') as inf: for line in inf: line = line.strip() if line: ss = line.split() irange.add([(float(ss[0]), float(ss[1]))]) inter = InterLap() inter.update(irange._as_tuples(irange)) #------------------------------------------------- for line in sys.stdin: line = line.strip() if line: ss = line.split() try: v = int(ss[colValue]) if keep: if inter.__contains__((v, v)): sys.stdout.write('%s\n' % (line)) else: if not (inter.__contains__((v, v))): sys.stdout.write('%s\n' % (line))
def find_contacts_of_indiv(self, indiv, tmin, tmax, tracing=False, p_reveal_visit=1.0): """ Finds all delta-contacts of person 'indiv' with any other individual after time 'tmin' and returns them as InterLap object. In the simulator, this function is called for `indiv` as infector. """ if tracing is True and self.beacon_config is None: # If function is used for contact tracing and there are no beacons, can only trace direct contacts extended_time_window = 0 else: # If used for infection simulation or used for tracing with beacons, capture also indirect contacts extended_time_window = self.delta contacts = InterLap() # iterate over all visits of `indiv` intersecting with the interval [tmin, tmax] infector_traces = self.mob_traces_by_indiv[indiv].find( (tmin, tmax if (tmax is not None) else np.inf)) for inf_visit in infector_traces: # coin flip of whether infector `indiv` reveals their visit if tracing is True and np.random.uniform( low=0.0, high=1.0) > p_reveal_visit: continue # find all contacts of `indiv` by querying visits of # other individuals during visit time of `indiv` at the same site # (including delta-contacts; if beacon_cache=0, delta-contacts get filtered out below) inf_visit_time = (inf_visit.t_from, inf_visit.t_to_shifted) concurrent_site_traces = self.mob_traces_by_site[ inf_visit.site].find(inf_visit_time) for visit in concurrent_site_traces: # ignore visits of `indiv` since it is not a contact if visit.indiv == inf_visit.indiv: continue # ignore if begin of visit is after tmax # this can happen if inf_visit starts just before tmax but continues way beyond tmax if visit.t_from > tmax: continue # Compute contact time c_t_from = max(visit.t_from, inf_visit.t_from) c_t_to = min(visit.t_to, inf_visit.t_to + extended_time_window) c_t_to_direct = min(visit.t_to, inf_visit.t_to) # only direct if c_t_to > c_t_from and c_t_to > tmin: c = Contact(t_from=c_t_from, t_to=c_t_to, indiv_i=visit.indiv, indiv_j=inf_visit.indiv, id_tup=(visit.id, inf_visit.id), site=inf_visit.site, duration=c_t_to - c_t_from, t_to_direct=c_t_to_direct) contacts.update([c]) return contacts
min_index = min(min_index, where) # print 'item %r, count %r, minind %r' % (item, count, min_index) return count, -min_index # pick the highest-count/earliest item return max(groups, key=_auxfun)[0] print(files) br = [] rr = [] bc = 0 #count bouke rc = 0 #count raoul for x in files: inter = InterLap() b = tgt.read_textgrid(mypath + x + "B.TextGrid").tiers[1] r = tgt.read_textgrid(mypath + x + "R.TextGrid").tiers[1] bc += len(b) rc += len(r) inter.add([convert_to_float(i) for i in r]) tot_overlaps = set() for i in b: interval = convert_to_float(i) overlaps = list(inter.find(interval)) #print(interval[2]) if (len(overlaps) > 0): overlaps = [tuple(x) for x in overlaps] for o in overlaps:
class UpperBoundCasesBetaMultiplier(BetaMultiplierMeasure): def __init__(self, t_window, beta_multiplier, max_pos_tests_per_week_per_100k, intervention_times=None, init_active=False): """ Additional parameters: ---------------------- max_pos_test_per_week : int If the number of positive tests per week exceeds this number the measure becomes active intervention_times : list of floats List of points in time at which interventions can be changed. If 'None' interventions can be changed at any time init_active : bool If true measure is active in the first week of the simulation when there are no test counts yet """ super().__init__(t_window, beta_multiplier) self.max_pos_tests_per_week_per_100k = max_pos_tests_per_week_per_100k self.intervention_times = intervention_times self.intervention_history = InterLap() if init_active: self.intervention_history.update([(t_window.left, t_window.left + 7 * 24 - EPS, True)]) def init_run(self, n_people, n_visits): self.scaled_test_threshold = self.max_pos_tests_per_week_per_100k / 100000 * n_people self._is_init = True @enforce_init_run def _is_measure_active(self, t, t_pos_tests): # If measures can only become active at 'intervention_times' if self.intervention_times is not None: # Find largest 'time' in intervention_times s.t. t > time intervention_times = np.asarray(self.intervention_times) idx = np.where(t - intervention_times > 0, t - intervention_times, np.inf).argmin() t = intervention_times[idx] t_in_history = list(self.intervention_history.find((t, t))) if t_in_history: is_active = t_in_history[0][2] else: is_active = self._are_cases_above_threshold(t, t_pos_tests) if is_active: self.intervention_history.update([(t, t+7*24 - EPS, True)]) return is_active @enforce_init_run def _are_cases_above_threshold(self, t, t_pos_tests): # Count positive tests in last 7 days from last intervention time tmin = t - 7 * 24 num_pos_tests = np.sum(np.greater(t_pos_tests, tmin) * np.less(t_pos_tests, t)) is_above_threshold = num_pos_tests > self.scaled_test_threshold return is_above_threshold @enforce_init_run def beta_factor(self, *, typ, t, t_pos_tests): """Returns the multiplicative factor for site type `typ` at time `t`. The factor is one if `t` is not in the active time window of the measure. """ if not self._in_window(t): return 1.0 is_measure_active = self._is_measure_active(t, t_pos_tests) return self.beta_multiplier[typ] if is_measure_active else 1.0
def findUTRs(cds, mrna, strand): ''' take list of list of CDS coordiantes and compare to list of list of mRNA coordinates to determine if 5 prime or 3 prime UTR exist ''' #supporting multiple transcripts, however, they are already matched up and sorted UTRs = [] for i in range(0, len(cds)): Fiveprime = False Threeprime = False refInterlap = InterLap(mrna[i]) if strand == '+': #look at first CDS for 5 prime and last CDS for 3 prime if cds[i][ 0] in refInterlap: #means it overlaps with mrNA (which it obviously should) hit = list(refInterlap.find(cds[i][0]))[0] loc = mrna[i].index( hit ) #if first exon, then compare, if not first then there is 5prime UTR if loc == 0: diff = np.subtract( cds[i][0], hit) #will return array of exon minus hit at each pos if diff[0] > 0: Fiveprime = True else: Fiveprime = True #check for 3 prime UTR if cds[i][-1] in refInterlap: hit = list(refInterlap.find(cds[i][-1]))[0] loc = mrna[i].index(hit) if len(mrna[i]) == loc + 1: diff = np.subtract( cds[i][-1], hit) #will return array of exon minus hit at each pos if diff[1] < 0: Threeprime = True else: Threeprime = True else: if cds[i][ 0] in refInterlap: #means it overlaps with mrNA (which it obviously should) hit = list(refInterlap.find(cds[i][0]))[0] loc = mrna[i].index( hit ) #if first exon, then compare, if not first then there is 5prime UTR if loc == 0: diff = np.subtract( cds[i][0], hit) #will return array of exon minus hit at each pos if diff[1] < 0: Fiveprime = True else: Fiveprime = True #check for 3 prime UTR if cds[i][-1] in refInterlap: hit = list(refInterlap.find(cds[i][-1]))[0] loc = mrna[i].index(hit) if len(mrna[i]) == loc + 1: diff = np.subtract( cds[i][-1], hit) #will return array of exon minus hit at each pos if diff[0] > 0: Threeprime = True else: Threeprime = True UTRs.append((Fiveprime, Threeprime)) return UTRs
def init_run(self, n_people): """Init the measure for this run. Sampling of Bernoulli of respecting the measure done online.""" self.intervals_isolated = [InterLap() for _ in range(n_people)] self._is_init = True
itvMap = {} #chr - >intervals. #irange = interval() with open(args['-r'], 'r') as inf: for line in inf: line = line.strip() if line: ss = line.split() if not (ss[0] in itvMap): itvMap[ss[0]] = Interval() itvMap[ss[0]].add([(float(ss[1]), float(ss[2])) ]) # auto merge region. checkMap = {} for k, v in itvMap.items(): inter = InterLap() inter.update(v._as_tuples(v)) checkMap[k] = inter # convert inverval to trees. # for i in inter: # print(i) #------------------------------------------------- # print(checkMap) for line in sys.stdin: line = line.strip() if line: if title: sys.stdout.write('%s\n' % (line)) title = False continue ss = line.split()
class UpperBoundCasesSocialDistancing(SocialDistancingForAllMeasure): def __init__(self, t_window, p_stay_home, max_pos_tests_per_week_per_100k, intervention_times=None, init_active=False): """ Additional parameters: ---------------------- max_pos_test_per_week : int If the number of positive tests per week exceeds this number the measure becomes active intervention_times : list of floats List of points in time at which measures can become active. If 'None' measures can be changed at any time """ super().__init__(t_window, p_stay_home) self.max_pos_tests_per_week_per_100k = max_pos_tests_per_week_per_100k self.intervention_times = intervention_times self.intervention_history = InterLap() if init_active: self.intervention_history.update([(t_window.left, t_window.left + 7 * 24 - EPS, True)]) def init_run(self, n_people, n_visits): super().init_run(n_people, n_visits) self.scaled_test_threshold = self.max_pos_tests_per_week_per_100k / 100000 * n_people def _is_measure_active(self, t, t_pos_tests): # If measures can only become active at 'intervention_times' if self.intervention_times is not None: # Find largest 'time' in intervention_times s.t. t > time intervention_times = np.asarray(self.intervention_times) idx = np.where(t - intervention_times > 0, t - intervention_times, np.inf).argmin() t = intervention_times[idx] t_in_history = list(self.intervention_history.find((t, t))) if t_in_history: is_active = t_in_history[0][2] else: is_active = self._are_cases_above_threshold(t, t_pos_tests) if is_active: self.intervention_history.update([(t, t + 7 * 24 - EPS, True)]) return is_active def _are_cases_above_threshold(self, t, t_pos_tests): # Count positive tests in last 7 days from last intervention time tmin = t - 7 * 24 num_pos_tests = np.sum(np.greater(t_pos_tests, tmin) * np.less(t_pos_tests, t)) is_above_threshold = num_pos_tests > self.scaled_test_threshold return is_above_threshold @enforce_init_run def is_contained(self, *, j, j_visit_id, t, t_pos_tests): """Indicate if individual `j` respects measure for visit `j_visit_id` """ if not self._in_window(t): return False is_home_now = self.bernoulli_stay_home[j, j_visit_id] return is_home_now and self._is_measure_active(t, t_pos_tests) @enforce_init_run def is_contained_prob(self, *, j, t, t_pos_tests): """Returns probability of containment for individual `j` at time `t` """ if not self._in_window(t): return 0.0 if self._is_measure_active(t, t_pos_tests): return self.p_stay_home return 0.0
def _find_mob_trace_overlaps(self, sites, mob_traces_at_site, infector_mob_traces_at_site, tmin, for_all_individuals): # decide way of storing depending on way the function is used (all or individual) # FIXME: this could be done in a cleaner way by calling this function several times in `_find_contacts` if for_all_individuals: # dict of dict of list of contacts: # i.e. contacts[i][j][k] = "k-th contact from i to j" contacts = { i: defaultdict(InterLap) for i in range(self.num_people) } else: contacts = InterLap() if self.verbose and for_all_individuals: print() # otherwise jupyter notebook looks ugly for s in sites: if self.verbose and for_all_individuals: print('Checking site ' + str(s + 1) + '/' + str(len(sites)), end='\r') if len(mob_traces_at_site[s]) == 0: continue # Init the interval overlap matcher inter = InterLap() inter.update(mob_traces_at_site[s]) # Match contacts # Iterate over each visit of the infector at site s for v_inf in infector_mob_traces_at_site[s]: # Skip if delta-contact ends before `tmin` if v_inf.t_to_shifted > tmin: v_time = (v_inf.t_from, v_inf.t_to_shifted) # Find any othe person that had overlap with this visit for v in list(inter.find(other=v_time)): # Ignore contacts with same individual if v.indiv == v_inf.indiv: continue # Compute contact time c_t_from = max(v.t_from, v_inf.t_from) c_t_to = min(v.t_to, v_inf.t_to_shifted) if c_t_to > c_t_from and c_t_to > tmin: # Init contact tuple # Note 1: Contact always considers delta overlap for `indiv_j` # (i.e. for `indiv_j` being the infector) # Note 2: Contact contains the delta-extended visit of `indiv_j` # (i.e. there is a `Contact` even when `indiv_j` never overlapped physically with `indiv_i`) # (i.e. need to adjust for that in dY_i integral) c = Contact(t_from=c_t_from, t_to=c_t_to, indiv_i=v.indiv, indiv_j=v_inf.indiv, id_tup=(v.id, v_inf.id), site=s, duration=c_t_to - c_t_from) # Add it to interlap if for_all_individuals: # Dictionary of all contacts contacts[v.indiv][v_inf.indiv].update([c]) else: # All contacts of (infector) 'indiv' only contacts.update([c]) return contacts
def from_json(fp, compute_contacts=True): """ Reach the from `fp` (.read()-supporting file-like object) that is expected to be JSON-formated from the `to_json` file. Parameters ---------- fp : object The input .read()-supporting file-like object compute_contacts : bool (optional, default: True) Indicate if contacts should be computed from the mobility traces. If True, then any `contact` key in `fp` will be ignored. If False, `fp` must have a contact` key. Return ------ sim : MobilitySimulator The loaded object """ # Read file into json dict data = json.loads(fp.read()) # Init object init_attrs = [ 'num_people', 'num_sites', 'delta', 'mob_mean', 'dur_mean', 'verbose' ] obj = MobilitySimulator(**{attr: data[attr] for attr in init_attrs}) # Set np.ndarray attributes for attr in ['home_loc', 'site_loc']: setattr(obj, attr, np.array(data[attr])) # Set list attributes for attr in ['visit_counts']: setattr(obj, attr, list(data[attr])) # Set `mob_traces` attribute into dict:defaultdict:InterLap setattr(obj, 'mob_traces', {i: defaultdict(InterLap) for i in range(obj.num_people)}) for indiv, traces_i in data['mob_traces'].items(): indiv = int(indiv) # JSON does not support int keys for site, visit_list in traces_i.items(): site = int(site) # JSON does not support int keys if len(visit_list) > 0: inter = InterLap() inter.update(list(map(lambda t: Visit(*t), visit_list))) obj.mob_traces[indiv][site] = inter # Set `contacts` attribute into dict:defaultdict:InterLap if compute_contacts: # Compute from `mob_traces` all_mob_traces = [] for i, traces_i in obj.mob_traces.items(): for j, inter in traces_i.items(): all_mob_traces.extend(inter._iset) # Compute contacts from mobility traces obj.contacts = obj._find_contacts(all_mob_traces) else: # Load from file setattr(obj, 'contacts', {i: defaultdict(InterLap) for i in range(obj.num_people)}) for indiv_i, contacts_i in data['contacts'].items(): indiv_i = int(indiv_i) # JSON does not support int keys for indiv_j, contact_list in contacts_i.items(): indiv_j = int(indiv_j) # JSON does not support int keys if len(contact_list) > 0: inter = InterLap() inter.update( list(map(lambda t: Contact(*t), contact_list))) obj.contacts[indiv_i][indiv_j] = inter return obj