def _check(vector, expected=None, exact=False): # Checks that the given vector: # * Encodes successfully (and to a particular string, if specified) # * Decodes successfully to exactly the same value (if specified) or to # within the expected tolerance (see below for what this tolerance is) # * Produces exactly the same string when the decoded value is reencoded # Returns the maximum absolute deviation between the given and decoded # vectors, and the tolerance to which it was compared. encoded = pack64(vector) if expected is not None: eq_(encoded, expected) decoded = unpack64(encoded) eq_(pack64(decoded), encoded) if not len(vector): deviation = 0.0 else: deviation = np.max(np.abs(decoded - vector)) if exact: tolerance = 0.0 else: # Generally pack64 guarantees a precision of 2 ** -17 times the largest # magnitude entry. However, we have to adjust for two details. # * The largest magnitude entry may be rounded for packing in such a # way that the precision is slightly less than that guarantee. # * The smallest positive number that can be packed at all is # 2 ** -40, so the absolute precision available for very small # vectors, regardless of the size of the vector, is 2 ** -41. tolerance = max(np.max(np.abs(vector)) / (2.0 ** 17 - 0.5), 2.0 ** -41) assert deviation <= tolerance return deviation, tolerance
def test_input_types(): # Both strings and bytestrings are unpackable assert np.all(unpack64('abcd') == unpack64(b'abcd')) # Anything that can be converted to a NumPy array is packable eq_(pack64([1.0, 2.0]), 'ZIAAQAA') eq_(pack64((1.0, 2.0)), 'ZIAAQAA') eq_(pack64(np.array([1.0, 2.0], dtype=np.float32)), 'ZIAAQAA') eq_(pack64(np.array([1.0, 2.0], dtype=np.float64)), 'ZIAAQAA') eq_(pack64(np.array([1.0, 2.0], dtype=np.int32)), 'ZIAAQAA')
def test_encoding(): assert pack64([]) == 'A' assert pack64([0.]) == 'AAAA' assert pack64([1.]) == 'YQAA' assert pack64([-1., 1.]) == 'YwAAQAA' assert pack64([2.**16, -1.]) == 'oQAA___' assert pack64([2.**16, 2**17-1]) == 'oQAAf__' assert pack64([2.**16, 2**17-0.2], rounded=False) == 'oQAAf__' assert pack64([2.**16, 2**17-0.2]) == 'pIAAQAA' assert pack64([2.**16, -2**17+0.2]) == 'pIAAwAA' assert pack64([2.**20, -1.]) == 'sQAAAAA'
def round_trip_check(vec): newvec = unpack64(pack64(vec, rounded=True)) if len(vec) == 0: precision = 0. maxdiff = 0. else: precision = np.max(np.abs(vec)) * (2**-17) + 2**-40 maxdiff = np.max(np.abs(newvec - vec)) assert np.allclose(newvec, vec, 1e-10, precision),\ "%s isn't close enough to %s; difference=%s, precision=%s" % (newvec, vec, maxdiff, precision)
def test_speed(): vectors = [np.random.normal(size=(i%40+1,)) for i in xrange(40)] start1 = time.time() for vec in vectors: reference_unpack64(reference_pack64(vec)) time_reference = (time.time() - start1)*1000 start2 = time.time() for vec in vectors: unpack64(pack64(vec)) time_ours = (time.time() - start2)*1000 assert time_ours < time_reference,\ "Took %4.4f ms. Time to beat: %4.4f ms." % (time_ours, time_reference)
def test_errors(): # Nonfinite values are rejected for value in (float('inf'), float('nan')): with assert_raises(ValueError): pack64([value]) # Out of range values are rejected; check near the edge of the range with assert_raises(OverflowError): pack64([(2.0 ** 17 - 0.5) * 2.0 ** 23]) _check([(2.0 ** 17 - 0.6) * 2.0 ** 23], expected='_f__') with assert_raises(OverflowError): # (This could actually be encoded as '_gAA'.) pack64([-(2.0 ** 17 - 0.5) * 2.0 ** 23]) _check([-(2.0 ** 17 - 0.6) * 2.0 ** 23], expected='_gAB') # Strings with bad lengths or characters are rejected for string in ('', 'xx', b'xx', '\U0001f43c', 'Hey!', 'panda', 'rutabaga'): with assert_raises(ValueError): unpack64(string) # Some (but not all) bad strings are accepted if error checking is disabled for string in ('xx', 'Hey!', 'panda'): unpack64(string, check=False) with assert_raises(ValueError): unpack64('rutabaga', check=False)
def write_xlsx(xlsx_name): output_dir = IPI.create_IPI_output_dir(pyvuka.get_output_directory()) filename = os.path.join(output_dir, xlsx_name) out_file = IPI.xlsx_out(filename) out_file.experiment = 'FORTEBIO' header = [ 'Plate', 'Sensor', 'Sensor_Protein', 'Solution_Protein', 'asymtope', 'kd', 'kd_error', 'ka', 'ka_error', 'Conc', 'Keq', 'Keq_error', 'Avg_Rsq', 'ipi-score (higher=better)', 'Comments', 'Plot_png', 'JSON' ] out_file.add_header(header) out_file.col_widths = [ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 58, 58 ] out_file.row_heights = 228 dm = pyvuka.get_datamatrix() for i in range(1, dm.length() + 1, 3): buffer_set = [i, i + 1, i + 2] comments = '' parameters = [ 'None' if val is None or np.isnan(val) or not np.isfinite(val) else float(val) for val in dm.buffer(buffer_set[-1]).fit.parameter.get() ] parameters_err = [ 'None' if val is None or np.isnan(val) or not np.isfinite(val) else float(val) for val in dm.buffer(buffer_set[-1]).fit.parameter_error.get() ] Rmax, kd, ka, Cp, m, c, x0, kds = parameters if len(parameters_err) != len(parameters): parameters_err = [1e6] * len(parameters) Rmax_err, kd_err, ka_err, Cp_err, m_err, c_err, x0_err, kds_err = parameters_err # catch div by zero try: KD = kd / ka except: KD = -1 comments = 'Fail : KD can not be calculated' try: KD_err = np.power( np.power(kd_err / kd, 2) + np.power(ka_err / ka, 2), 0.5) * KD except: KD_err = -1 # Check rsq values to ensure fit has been made, if fit fails, rsq is nan rsq_1 = [ -1 if np.isnan(val) or not np.isfinite(val) else float(val) for val in [dm.buffer(buffer_set[0]).fit.rsq.get()] ][0] rsq_2 = [ -1 if np.isnan(val) or not np.isfinite(val) else float(val) for val in [dm.buffer(buffer_set[1]).fit.rsq.get()] ][0] rsq_3 = [ -1 if np.isnan(val) or not np.isfinite(val) else float(val) for val in [dm.buffer(buffer_set[2]).fit.rsq.get()] ][0] avg_rsq = np.average([x for x in [rsq_1, rsq_2, rsq_3] if x >= 0]) if np.isnan(avg_rsq): avg_rsq = -1 comments = 'Fail : Insufficient s/n' # Check ipi-score values to ensure fit has been made, if fit fails, rsq is nan # score_1 = datamatrix[i].item['ipi_score'] 0nm conc score_2 = dm.buffer(buffer_set[1]).meta_dict['ipi_score'] score_3 = dm.buffer(buffer_set[2]).meta_dict['ipi_score'] avg_score = float(np.average([score_2, score_3])) if np.isnan(avg_score) or comments == 'Fail : Insufficient s/n': avg_score = -1 comments = 'Fail : Insufficient s/n' # Check ampplitude cutoff of 0.01, fail low amplitudes amplitudes = [ dm.buffer(buffer_set[0]).meta_dict['association_amp'], dm.buffer(buffer_set[1]).meta_dict['association_amp'], dm.buffer(buffer_set[2]).meta_dict['association_amp'] ] if max(amplitudes) < 0.01: comments = 'Fail : Insufficient association amplitude' # Check comments for fit failure. Remove model if fit failed if 'fail' in comments.lower(): for j in buffer_set: dm.buffer(j).model.x.clear() dm.buffer(j).model.y.clear() Cp = "{}, {}, {}".format(*[ dm.buffer(buffer_set[0]).fit.parameter.get()[3], dm.buffer(buffer_set[1]).fit.parameter.get()[3], dm.buffer(buffer_set[2]).fit.parameter.get()[3] ]) sensor_pro = dm.buffer(i).plot.series.name.get().split('on')[0].strip() sensor = dm.buffer(i).plot.series.name.get().split('on ')[1].split( ' ')[0].strip() sol_pro = dm.buffer(i).plot.series.name.get().split('vs')[1].split( '@')[0].strip() # construct xlsx line entry out_line = [ 'Plate', sensor, sensor_pro, sol_pro, c, kd, kd_err, ka, ka_err, Cp, KD, KD_err, avg_rsq, avg_score, comments, None, None ] LIMS_dict = {} plot_png = pyvuka.get_plot_as_bytestring([i, i + 1, i + 2], get_bytes=True, black_models=True) JSON = { 'data_x_1': pack64.pack64(dm.buffer(buffer_set[0]).data.x.get()), 'data_y_1': pack64.pack64(dm.buffer(buffer_set[0]).data.y.get()), 'model_x_1': pack64.pack64(dm.buffer(buffer_set[0]).model.x.get()), 'model_y_1': pack64.pack64(dm.buffer(buffer_set[0]).model.y.get()), 'data_x_2': pack64.pack64(dm.buffer(buffer_set[1]).data.x.get()), 'data_y_2': pack64.pack64(dm.buffer(buffer_set[1]).data.y.get()), 'model_x_2': pack64.pack64(dm.buffer(buffer_set[1]).model.x.get()), 'model_y_2': pack64.pack64(dm.buffer(buffer_set[1]).model.y.get()), 'data_x_3': pack64.pack64(dm.buffer(buffer_set[2]).data.x.get()), 'data_y_3': pack64.pack64(dm.buffer(buffer_set[2]).data.y.get()), 'model_x_3': pack64.pack64(dm.buffer(buffer_set[2]).model.x.get()), 'model_y_3': pack64.pack64(dm.buffer(buffer_set[2]).model.y.get()), 'plot_x_lines': str(dm.buffer(buffer_set[0]).plot.axis.x.lines.get()) } out_line[-2] = plot_png out_line[-1] = JSON for j in range(len(header)): key = header[j].lower() val = out_line[j] if '_png' not in key: if key == 'json': key = 'data_xy' LIMS_dict.update({key: val}) out_line[-1] = json.dumps(LIMS_dict) out_file.add_line(out_line) out_file.write_xlsx() return
def encoding_check(vec): a = reference_pack64(vec) b = pack64(vec, rounded=False) assert a == b,\ '%s should have encoded to %s, got %s' % (vec, a, b)