#! /usr/bin/python3 # Last edited on 2021-06-03 05:16:37 by jstolfi import txt_write import txt_read import job_parms import move_parms import contour import move import path import path_hp import block import raster_example import hacks import contact import input_data import plot_data import sys from math import sqrt, sin, cos, log, exp, floor, ceil, inf, nan, pi parms = job_parms.typical_js() parms['solid_raster_width'] = 3.00 parms['contour_trace_width'] = 2.00 zstep = parms['slice_thickness'] mp_jump = move_parms.make_for_jumps(parms) mp_cont = move_parms.make_for_contours(parms) mp_fill = move_parms.make_for_fillings(parms) tol = 1.5e-5 # Because most numbers are written with 6 decimal fraction digits. def fbomb(die): # Returns {False} if die is {False}, else fails. assert not die return False # ---------------------------------------------------------------------- def compare_paths(oph0, oph1, die): # Chects if the paths have the same points, # modulo I/O roundoff errors. If {die} is false # returns {True} or {False} else fails if they are not; # sys.stderr.write("oph0: "); path.show(sys.stderr, oph0, True, 0,0,0); sys.stderr.write("\n") # sys.stderr.write("oph1: "); path.show(sys.stderr, oph1, True, 0,0,0); sys.stderr.write("\n") nmv = path.nelems(oph0) if path.nelems(oph1) != nmv: return fbomb(die) if not hacks.same_point(path.pini(oph0), path.pini(oph1), tol): return fbomb(die) for imv in range(nmv): omv0 = path.elem(oph0, imv) omv1 = path.elem(oph1, imv) if not hacks.same_point(move.pini(omv0), move.pini(omv1), tol): return fbomb(die) if not hacks.same_point(move.pfin(omv0), move.pfin(omv1), tol): return fbomb(die) return True # ---------------------------------------------------------------------- def compare_contacts(ct0, ct1, die): # Checks if the sides of the contacts are coincident traces, # modulo I/O roundoff errors. If {die} is false # returns {True} or {False} else fails if they are not; ends0 = contact.endpoints(ct0) ends1 = contact.endpoints(ct1) for ipt in range(2): if not hacks.same_point(ends0[ipt], ends1[ipt], tol): return fbomb(die) for isd in range(2): omv0 = contact.side(ct0, isd) omv1 = contact.side(ct1, isd) if not hacks.same_point(move.pini(omv0), move.pini(omv1), tol): return fbomb(die) if not hacks.same_point(move.pfin(omv0), move.pfin(omv1), tol): return fbomb(die) return True # ---------------------------------------------------------------------- def compare_contour_lists(OCRS, OCRS_re): ncr = len(OCRS) # Compare the original and readback contours: assert len(OCRS_re) == ncr # sys.stderr.write("OCRS_re = %s\n" % str(OCRS_re)) for icr in range(ncr): ocri = OCRS[icr] ocri_re = OCRS_re[icr] compare_paths(ocri, ocri_re, True) # Check if nesting information is the same: for jcr in range(ncr): ocrj = OCRS[jcr] ocrj_re = OCRS_re[jcr] ne = path.contour_nesting(ocri, ocrj) ne_re = path.contour_nesting(ocri_re, ocrj_re) assert ne == ne_re return # ---------------------------------------------------------------------- def compare_raster_lists(OPHS, OPHS_re): # Compare the original and readback rasters: OPHS = sorted(OPHS, key = path.pini) OPHS_re = sorted(OPHS_re, key = path.pini) nph = len(OPHS) assert len(OPHS_re) == nph for iph in range(nph): ophi = OPHS[iph] ophi_re = OPHS_re[iph] compare_paths(ophi, ophi_re, True) # Check if group information is the same: assert path_hp.get_group(ophi) == path_hp.get_group(ophi_re) # Check if contact lists are the same: for ksd in range(2): CTSik = path_hp.get_contacts(ophi, ksd) CTSik_re = path_hp.get_contacts(ophi_re, ksd) assert len(CTSik) == len(CTSik_re) # ??? Should check if contacts are the same. ??? # Check if link lists are the same: for krv in range(2): ophik = path.spin(ophi, krv) ophik_re = path.spin(ophi_re, krv) LKS = path_hp.get_links(ophik) LKS_re = path_hp.get_links(ophik_re) assert len(LKS) == len(LKS_re) # ??? Should check if link paths are the same. ??? return # ---------------------------------------------------------------------- def compare_contact_lists(CTS, CTS_re): # Compare the original and readback contacts: nct = len(CTS) CTS = sorted(CTS, key = contact.pmid) CTS_re = sorted(CTS_re, key = contact.pmid) for ict in range(nct): cti = CTS[ict] # sys.stderr.write("orig: "); contact.show(sys.stderr, cti, 0, 0); sys.stderr.write("\n") cti_re = CTS_re[ict] # sys.stderr.write("rere: "); contact.show(sys.stderr, cti_re, 0, 0); sys.stderr.write("\n") compare_contacts(cti, cti_re, True) return # ---------------------------------------------------------------------- def do_test_write(outname, OCRS, OPHS, CTS, Z, angle): outfolder = "tests/out/" fname_out = outfolder + outname + ".txt" sys.stderr.write("writing %s ...\n" % fname_out) wr = open(fname_out, "w") txt_write.write(wr, OCRS, OPHS, CTS, Z, angle) wr.close() sys.stderr.write("reading back %s ...\n" % fname_out) rd = open(fname_out, "r") OCRS_re, OPHS_re, CTS_re, Z_re = txt_read.read(rd, mp_cont, mp_fill, angle) rd.close() compare_contour_lists(OCRS, OCRS_re) compare_raster_lists(OPHS, OPHS_re) compare_contact_lists(CTS, CTS_re) # Compare the original and readback {Z} coordinate: assert abs(Z - Z_re) <= 1.5e-4 # Written with 5 decimals by {RP3}. # ??? Should validate output -- contours, links, contacts, etc. ??? BCS = [ block.from_paths((oph, path.rev(oph))) for oph in OPHS ] plot_data.plot_input(outfolder + outname, OCRS, BCS, CTS, mp_cont, None) return # ---------------------------------------------------------------------- def test_write_from_read(partname, islice, angle): sys.stderr.write("--- testing {write} from {txt_read_read} ---\n") infolder = "tests/in/2021-05-15-elis/" + partname + "/" sys.stderr.write("infolder = %s\n" % infolder) sys.stderr.write("partname = %s\n" % partname) sys.stderr.write("islice = %s\n" % islice) sys.stderr.write("angle = %s\n" % angle) tag = partname + "_" + ("%03d" % islice) fname_in = infolder + tag + ".txt" sys.stderr.write("reading %s ...\n" % fname_in) rd = open(fname_in, "r") OCRS, OPHS, CTS, Z = txt_read.read(rd, mp_cont, mp_fill, angle) rd.close() outname = "txt_write_TST_txt_" + tag do_test_write(outname, OCRS, OPHS, CTS, Z, angle) return # ---------------------------------------------------------------------- def test_write_synthetic(dsname, variant): sys.stderr.write("--- testing {write} of synthetic data ---\n") sys.stderr.write("dsname = %s\n" % dsname) sys.stderr.write("variant = %s\n" % variant) tag = dsname + "_" + variant OCRS, OPHS, CTS, Z = input_data.make_synthetic(dsname, variant, mp_cont, mp_fill) angle = 0 outname = "txt_write_TST_syn_" + tag do_test_write(outname, OCRS, OPHS, CTS, Z, angle) return # ---------------------------------------------------------------------- test_write_synthetic(dsname = "patch_array", variant = "2x1x27is") test_write_synthetic(dsname = "patch_array", variant = "3x1x27no") test_write_from_read(partname = "chain_link_2", islice = 2, angle = pi/2)