#! /usr/bin/python3 import os, sys, re import html_gen as h from process_funcs import bash import html_report_funcs as hr last_edit = "Last edited on 2025-11-19 07:34:27 by stolfi" def main(): global last_edit title = "Repeated plant drawings" st = h.new_doc(title, "#eeffdd") h.section(st, 2, "Summary") h.parags(st, """This page shows are several pairs of plant drawings in the VMS that are significantly similar, in whole or in part. Not just the same plant, but the same pose and perspective. Typically, the good match exists only for some parts of the two plants (such as roots and leaves), while the other parts are completely different. The images on this page are from the Beinecke Library 2014 scans of the VMS.""") # Create {fig_data}, a list of triples {((f0_big,f0_sma), (f1_big,f1_sma), sect, capt)} # where {f0_big,f1_big)} are names of full-size images (minus the "images" dir), # {f0_sma,f1_sma} are names of their thumbnails, # {sect} is the section of the page where the pair should go, # and {capt} is a caption for the pair of images. plant_pairs = ( ("f1v", None, "2200x3300+0480+0348", "f102r1", (3,2), "1300x1170+3784+2172", 1, "Root, leaves; NO flower."), ("f18v", None, "2200x3400+0500+0310", "f102r2", (3,1), "1600x1100+5240+2470", 1, "Root; NO leaves, flower."), ("f19r", None, "2100x3300+0316+0400", "f102v1", (2,3), "0800x0800+1150+1780", 1, "Root, leaves (type 1 only); NO flowers."), ("f23r", None, "2260x3100+0200+0320", "f102r2", (3,2), "1100x1000+6800+2480", 1, "Root; NO leaves, flowers."), ("f37v", None, "2100x3500+0685+0200", "f102r1", (3,1), "1200x1500+2850+2080", 1, "Root, leaves; NO flower"), ("f32v", None, "2100x3600+0600+0140", "f102r2", (1,2), "1600x1100+6460+0320", 1, "Root, leaves, flower."), ("f47v", None, "2300x3500+0580+0210", "f102r2", (1,1), "1400x0800+5460+0240", 1, "Root, leaves; NO flower."), ("f48r", None, "2200x3200+0249+0162", "f89v3", (3,4), "1300x1300+2700+2440", 1, "Root, leaves; NO flowers."), ("f48v", None, "2100x3300+0585+0330", "f89v3", (1,5), "1000x1300+3000+0100", 1, "Root, leaves; NO flowers."), ("f39r", None, "2300x3400+0108+0292", "f95r2", None, "2200x3560+5340+0128", 2, "Root, leaves; NOT flower."), ("f51r", None, "1700x3300+0850+0400", "f99r", (3,1), "0200x0400+0490+1050", 3, "Root; NO leaves, flowers."), ("f90v1", None, "2300x3660+0500+0060", "f99v", (3,2), "0500x0500+0990+1600", 3, "Root; NO leaves, flowers."), ) if not os.path.exists(f"images/FB"): bash("cd images && ln -s ../FB") fig_data = [] for f0, IJ0, crop0, f1, IJ1, crop1, sect, capt in plant_pairs: sys.stderr.write(f"~~~ {f0} {IJ0} = {f1} {IJ1} ~~~\n") fig_spec = [] for fN, IJN, cropN in ((f0, IJ0, crop0,), (f1, IJ1, crop1)): if IJN == None: fN_big = f"{fN}.jpg" fN_sma = f"{fN}_sma.jpg" else: I, J = IJN fN_big = f"{fN}_{I}:{J}.jpg" fN_sma = f"{fN}_{I}:{J}_sma.jpg" if cropN == None: if not os.path.exists(f"images/{fN_big}"): bash(f"cd images && ln -s ../FB/{fN}.jpg {fN_big}") else: bash(f"cd images && convert ../FB/{fN}.jpg -crop '{cropN}' -normalize {fN_big}") bash(f"cd images && convert {fN_big} -resize '25%' -normalize {fN_sma}") fig_spec.append((fN_big, fN_sma)) fig_spec.append(sect) fig_spec.append(capt) fig_data.append(list(fig_spec)) # Output the sections: def add_section(title:str, preamble:str, section:int) -> None: # Appends a section to the page # with the give title and preamble text # containing the entries of {fig_data} with the # specified {section} field. nonlocal st, fig_data h.section(st, 2, title) h.parags(st, preamble) for f0_spec, f1_spec, sect, capt in fig_data: if sect == section: max_width = (st['text_width'] - 10)//2 max_height = 9999 link_f0_html = h.make_link(st, f"images/{f0_spec[0]}", None, f"images/{f0_spec[1]}", max_width, max_height) link_f1_html = h.make_link(st, f"images/{f1_spec[0]}", None, f"images/{f1_spec[1]}", max_width, max_height) link_pair_html = link_f0_html + "" + link_f1_html caption_f0_html = f"{f0_spec[0]}" caption_f1_html = f"{f1_spec[0]}" caption_f0_f1_html = caption_f0_html + "" + caption_f1_html caption_pair_html = capt caption_html = caption_f0_f1_html + f"" + caption_pair_html h.figure(st, link_pair_html, caption_html, centered = True) add_section("Matches between Herbal and Pharma", """These are matches between the Herbal sections ("hea", "heb") and the Pharma section ("pha"). The Pharma versions are all concentrated on two folios. Two matches are on page f89v3 (that spans panels v3 and v2). The rest are on folio f102, one on the verso side (panel f102v1), the others on the recto side (f102r1 and f102r2). In all cases, all the parts of the Pharma version (usually a root, sometimes with leaves) have a good match to the corresponding parts of the Herbal page, which however contains additional parts (like flowers or fruits) of unknown source. The Herbal f32v also matches its Pharma f102r2 version on the flower, besides root and leaves. However one should consider the possibility that the flower of the Pharma version is a later addition. The notation "_R:C" for Pharma pages means row R of plants from the top, plant number C from the left (both counting from 1).""", 1) add_section("Matches between Herbal pages", """These are matches between pages of the Herbal sections ("hea", "heb"). There seems to be only one confirmed so far.""", 2) add_section("Poor matches", """These are examples of plant pairs with parts that are similar, but not definite matches as considered above. It could be because the pose and/or perspective of the common parts (like f90v1) is not quite compatible with them having been copied from each other, or both from the same orignal drawing. It could also be because the parts are so simple and/or so small (like f51r) that the resemblance may be just a coincidence.""", 3) # h.parags(st, """""") # hr.clip_fig_parag(st, "f102v1 stain") # hr.clip_fig_parag(st, "f103r stain") h.output_doc(st, sys.stdout, 99, last_edit) return 0 # ---------------------------------------------------------------------- main()