def count_onsets_in_bin_joint(I, tbin): """for non-disjoint time bin, returns - AS/Bout(I) time in bin, strict sense (intersected with bin) - counts, onset-based - I effective times in bin, onset-based - I effective endpoints in bin, onset-based """ # time in AS/Bout, strictly inside bin _I = Intervals(I).intersect(Intervals(tbin)).intervals I_times = np.diff(_I).T[0] if len(_I) > 0 else np.array([]) # effective time in AS/Bout, onset-sensitive I_times_eff = [] bin_start, bin_end = tbin cnt = 0 # onsets for start, end in I: if (start > bin_start and start < bin_end): I_times_eff.append(end - start) if cnt < 1: I_start = start I_end = end cnt +=1 if cnt == 0: np.testing.assert_allclose(np.array(I_times_eff).sum(), 0, rtol=1e-5) return I_times, 0, np.array([]), np.array([]) tbin_eff = np.array([[I_start, I_end]]) # I endpoints in bin return I_times, cnt, np.array(I_times_eff), tbin_eff
def count_onsets_in_bin_disjoint(I, tbins): """same for disjoint bin, e.g. LC """ # time in AS/Bout, strictly _I = Intervals(I).intersect(Intervals(tbins)).intervals I_times = np.diff(_I).T[0] if len(_I) > 0 else np.array([]) # time in AS/Bout, onset-based I_times_eff = [] cnt = 0 # counts, onset-based I_endpoints = [] # I endpoints in bin, onset-based for tbin in tbins: _, _cnt, _I_times_eff, _tbin_eff = count_onsets_in_bin_joint(I, tbin) cnt += _cnt if _cnt > 0: I_times_eff.extend(list(_I_times_eff)) I_endpoints.append(_tbin_eff) if cnt == 0: np.testing.assert_allclose(I_times, 0, rtol=1e-5) np.testing.assert_allclose(I_times_eff, 0, rtol=1e-5) return np.array([]), 0, np.array([]), np.array([]) if len(I_endpoints) == 1: tbin_eff = I_endpoints[0] # np.array elif len(I_endpoints) == 2: tbin_eff = np.vstack([I_endpoints[0], I_endpoints[1]]) return I_times, cnt, np.array(I_times_eff), tbin_eff
def check_ingestion_bouts_overlap(fbouts, dbouts): overlap = Intervals(fbouts).intersect(Intervals(dbouts)) # fdur, ddur = np.diff(f_bouts).T[0], np.diff(d_bouts).T[0] if not overlap.is_empty(): overlap_diff = np.diff(overlap.intervals).T[0] for n in xrange(len(overlap_diff)): logger.error("feeding and drinking bouts: found overlap at CT{} for {:02.3f}sec".format( hcm_time_to_ct_string_float(overlap.intervals[n, 0]), overlap_diff[n]))
def build_boxes(self): intervals = Intervals() intervals.interval_type = self.interval_type intervals.x = self.x intervals.start = self.start intervals.finish = self.finish intervals.resolution = self.resolution intervals.week_start = self.week_start box = Rectangle() box.y = self.y box.height = self.height box.border_rounding = self.box_rounding box.border_color = self.box_border_color box.border_width = self.box_border_width boxes = str() for i in intervals.get_intervals(): box.x = i[0] box.width = i[1] if i[4] is False: box.fill_color = self.ends else: box.fill_color = self.box_fill boxes += box.svg return boxes
def build_grid(self): intervals = Intervals() intervals.interval_type = self.interval_type intervals.x = self.x intervals.start = self.start intervals.finish = self.finish intervals.resolution = self.resolution intervals.week_start = self.week_start line = Line() line.y = self.y line.dy = self.y + self.height line.stroke_color = self.line_color line.stroke_width = self.line_width line.stroke_dasharray = self.line_dashing lines = str() for i in intervals.get_intervals(): line.x = i[0] line.dx = line.x lines += line.svg last_line = self.x + ((self.finish - self.start) * self.resolution) line.x = last_line line.dx = last_line lines += line.svg return lines
def get_timebin_in_recording_time(timebin, rec, ass): arr = None if timebin == '24H': arr = rec elif timebin in ['DC', 'LC']: arr = Intervals(get_timebins(timebin)[0]).intersect(Intervals(rec)).intervals elif timebin == 'AS24H': arr = ass elif timebin in ['ASDC', 'ASLC']: arr = Intervals(ass).intersect(Intervals(get_timebins(timebin[-2:])[0])).intervals return arr, np.diff(arr).sum()
def index_ingestion_bout_and_homebase_timestamps(t, idx, fbouts, dbouts): """returns a mask which excludes timestamps indexes corresponding to ingestion bouts and position at homebase """ i_fdb = Intervals(fbouts).union(Intervals(dbouts)) mask = np.ones(t.shape[0], dtype=bool) for timestamp in xrange(t.shape[0]): if i_fdb.contains(t[timestamp]): mask[timestamp] = False mask = mask & idx log_text = "locomotion: flagged {} events occurring at homebase and/or during ingestion bouts".format( mask.shape[0] - mask.sum()) return mask, log_text
def make_mode(self, n, mode): '''Re-arranges the intervals of this scale into a new scale''' # get the key distance to adjust all others by key_dist = self.intervals[mode - 1].distance adj_dist = [] # build a list of distances for i in range(len(self.intervals)): # find the interval index for this iteration with # respect to the requested mode step_idx = (i + (mode - 1)) % len(self.intervals) # pull out the distance for the interval and adjust # it by the distance of the mother-key's step step_dist = self.intervals[step_idx].distance - key_dist # constrain the distance to within the chromatic scale if step_dist < 0: step_dist += 12 # get the interval and add it to the list adj_dist.append(Intervals.by_distance(step_dist)) # create the scale and send it out return Scale(n, adj_dist)
def build_labels(self): intervals = Intervals() intervals.interval_type = self.interval_type intervals.x = self.x intervals.start = self.start intervals.finish = self.finish intervals.resolution = self.resolution intervals.week_start = self.week_start date = Date() date.week_start = self.week_start date.separator = self.separator date.date_format = self.date_format label = Text() label.text_y = self.y label.text_translate_y = self.text_y label.text_translate_x = self.text_x label.font_fill_color = self.font_fill label.font_size = self.font_size label.font_weight = self.font_weight label.font_family = self.font_family label.font_style = self.font_style labels = str() if self.label_type == 'hidden': label.text_visibility = 'hidden' for i in intervals.get_intervals(): label.text_x = i[0] if i[1] < self.min_label_width: label.text = str( ) # you could set visibility to hidden but more verbose elif self.label_type == 'count' and i[3] == 0: label.text = str( ) # you could set visibility to hidden but more verbose elif self.label_type == 'date': date.ordinal_date = i[2] label.text = date.get_date() else: label.text = i[3] # references count in intervals entry labels += label.svg return labels
def get_timebin_category(tbins, bin_type): """ assigns timebin to a category based on start and end times each time of day is coded with a number: - cat_code1, primary - 1 : LC, CT06-12 union CT24-06 - 2 : DC, CT12-18 - cat_code2, secondary - 1 : CT06-12, or last part of LC, or LC2 - 2 : CT12-18, or first part of DC, or DC1 - 3 : CT18-24, or second part of DC, or DC2 - 4 : CT24-06, or first part of LC, or LC1 categories are formed by pairing numbers for start and end. categories '13' (primary) and '14' (secondary) ought to be rare returns cateogry code, descriptions and proportion of time spent in DC and LC """ # seconds after midnight dc_start = 19 * 3600. # CT12 dc_mid = 25 * 3600. # CT18 dc_end = 31 * 3600. # CT24 starts, ends = np.array(tbins).T # primary, DC and LC bins = [0, dc_start, dc_end, 1000000] inds1 = np.array([np.digitize(x, bins) for x in [starts, ends]]).T inds1 = recode_indices1(inds1, bin_type) cat_code1 = [''.join(str(i) for i in ind) for ind in inds1] # secondary, day divided in 4 bins bins = [0, dc_start, dc_mid, dc_end, 1000000] inds2 = np.array([np.digitize(x, bins) for x in [starts, ends]]).T if not bin_type.startswith('AS'): inds2 = recode_inds2(inds2, bin_type) cat_code2 = [''.join(str(i) for i in ind) for ind in inds2] # proportions in LC and DC dc, lc = [Intervals(get_timebins('3cycles')[x]) for x in [1, 2]] return cat_code1, [AS_code_lookup['1'][x] for x in cat_code1], cat_code2, [AS_code_lookup['2'][x] for x in cat_code2], [ Intervals(x).intersect(dc).measure() / Intervals(x).measure() for x in tbins], [ Intervals(x).intersect(lc).measure() / Intervals(x).measure() for x in tbins]
def plus(self, element): if element.key == "!%s" % self.key or self.key == "!%s" % element.key: return Element([(Intervals({}), Formula(sympy.S(1.0)))], "t") if (self.key == "f"): key = element.key elif element.key == "f": key = self.key else: key = "(%s + %s)" % (self.key, element.key) combined = Element(self.list + element.list, key) # print self, " + ", element, " = ", sum return combined
def check_ingestion_position_concurrency(tset_raw, tset_at_loc, loc='F'): """ check device events and position at device concurrency returns array with corrected events and errors removed this function is not used starting May 8th, 2018 """ i_raw = Intervals(tset_raw) i_at_device = Intervals(tset_at_loc) i_true = i_raw.intersect(i_at_device) tset_errors = (i_raw - i_true).intervals # photobeam firing when mouse not at device np.testing.assert_almost_equal(np.diff(tset_raw).sum(), np.diff(tset_errors).sum() + np.diff(i_true.intervals).sum(), decimal=2) num_errors = len(tset_errors) tot = i_raw.intervals.shape[0] err_time = np.diff(tset_errors).sum() / 60. error_msg = "" if num_errors: # todo: check this is working. plot on rasters tset = i_true.intervals error_msg = "{}: {}/{} events removed, device firing while mouse not at device " \ "(total time involved={:.2f} min)".format(act_to_actlabel[loc], num_errors, tot, err_time) else: tset = tset_raw return tset, tset_errors, error_msg
# Tecott Lab HCM Data # working with AS/IS, IS Duration Thresholds (ISDT) # using class intervals objects # C. Hillar, Jan 2016 from __future__ import print_function, absolute_import, division import numpy as np from intervals import Intervals Events = Intervals([[-2, -1], [0, 1], [3, 5], [8, 11]]) ISDT = 2 # IST Threshold ECG = Events.copy().connect_gaps(ISDT) # connect gaps <= ISDT ETm = Events.copy().trim(ISDT) # trim inteversl <= ISDT print("Events (%d intervals):" % Events.num(), Events) # print ("Events connected gaps <= %1.3f:" % ISDT, # Events.copy().connect_gaps(ISDT)) print("Events trim intervals <= %1.3f:" % ISDT, Events.copy().trim(ISDT)) print("IS/AS computation version 1") IS1 = Events.complement().trim(ISDT) # complement is new object AS1 = IS1.complement() print("IS (%d):" % IS1.num(), IS1) print("AS (%d):" % AS1.num(), AS1) print("IS/AS computation version 2 (mathematically equivalent)") AS2 = Events.copy().connect_gaps(ISDT) # trim alters object IS2 = AS2.complement() print("AS2 (%d):" % AS2.num(), AS2) print("IS2 (%d):" % IS2.num(), IS2)
from intervals import Intervals from notes import Notes # read intervals out for reference peru = Intervals.by_distance(0) min2 = Intervals.by_distance(1) maj2 = Intervals.by_distance(2) min3 = Intervals.by_distance(3) maj3 = Intervals.by_distance(4) per4 = Intervals.by_distance(5) trit = Intervals.by_distance(6) per5 = Intervals.by_distance(7) min6 = Intervals.by_distance(8) maj6 = Intervals.by_distance(9) min7 = Intervals.by_distance(10) maj7 = Intervals.by_distance(11) class Scale(object): '''Defines a collection of intervals''' def __init__(self, n, inters): '''Creates a scale instance''' self.name = n self.intervals = inters def voice(self, key): '''Voices this scale in a particular key''' # get a chromatic list of notes chromatic = Scales.make_chromatic(key) steps = []
# Tecott Lab HCM Data # working with AS/IS, IS Duration Thresholds (ISDT) # using class intervals objects # C. Hillar, Jan 2016 from __future__ import print_function, absolute_import, division import numpy as np from intervals import Intervals Events = Intervals([[-2, -1], [0, 1], [3, 5], [8, 11]]) ISDT = 2 # IST Threshold ECG = Events.copy().connect_gaps(ISDT) # connect gaps <= ISDT ETm = Events.copy().trim(ISDT) # trim inteversl <= ISDT print("Events (%d intervals):" % Events.num(), Events) # print ("Events connected gaps <= %1.3f:" % ISDT, # Events.copy().connect_gaps(ISDT)) print("Events trim intervals <= %1.3f:" % ISDT, Events.copy().trim(ISDT)) print("IS/AS computation version 1") IS1 = Events.complement().trim(ISDT) # complement is new object AS1 = IS1.complement() print("IS (%d):" % IS1.num(), IS1) print("AS (%d):" % AS1.num(), AS1) print("IS/AS computation version 2 (mathematically equivalent)") AS2 = Events.copy().connect_gaps(ISDT) # trim alters object IS2 = AS2.complement() print("AS2 (%d):" % AS2.num(), AS2)
def intersect_arrays(arr1, arr2): return Intervals(arr1).intersect(Intervals(arr2)).intervals
def wipe_data_outside_CT6_30(I): bin_24h = get_CT_bins(bin_type='24H') stop return Intervals(I).intersect(Intervals(bin_24h)).intervals
def zero(self): return Element([(Intervals({}), Formula(self.neutral))], "f") # TODO empty intervals?
def one(self): return Element([(Intervals({}), Formula(sympy.S(1.0)))], "t")
def pos_value(self, a, key=None): m = re.search(r"w\((.*),.*,(.*)\)", str(a)) return Element( [(Intervals.create(m.group(2)), Formula.create(m.group(1)))], key)
def intersect_timeset_with_timebin(tset, tbin): return Intervals(tset).intersect( Intervals(tbin)).intervals # todo: try: Intervals(tset).intersect_with_interval(tbin[0], tbin[1] # faster
def neg_value(self, a, key=None): m = re.search(r"w\(.*,(.*),(.*)\)", str(a)) # TODO: aanpassing return Element([(Intervals({}), Formula.create(m.group(1)))], "!" + str(key))
for day in range(mice[mouse]): arr = np.load('data/intervals/%s/%s_strain%d_mouse%d_day%d.npy' % (event, event, i, mouse, day)) mices[mouse][day] = arr strain_intervals[i] = mices fmfs = first_mouse_first_strain = strain_intervals[0][0] nd = nday_this_mouse = len(fmfs) # number of AS (& time) are there on avg for this mouse per day cnts = np.zeros(nd) ttimesec = np.zeros(nd) for c, md in enumerate(fmfs): cnts[c] = md.shape[0] ttimesec[c] = Intervals(md).measure() # some Intervals functionality # print "%1.3f Active States (AS) (%1.3f sec on avg) per its %d days " % # (cnts.mean(), ttimesec.mean(), nd) # Turn this set of ASs into binary sequence bin_AS = binary_from_intervals(Intervals(fmfs[0])) plt.figure() plt.plot(bin_AS) plt.ylim([-.1, 1.1]) plt.xlabel('Time step from first AS [sec]') plt.ylabel('Active State (1) / Inactive State (0)') plt.title('Active States as binary sequence') ################################## # (3) Make position density first mouse first day ##################################