{"id":69,"date":"2026-07-24T17:48:50","date_gmt":"2026-07-24T17:48:50","guid":{"rendered":"https:\/\/cassiemdp.space\/blog\/?p=69"},"modified":"2026-07-24T20:52:55","modified_gmt":"2026-07-24T20:52:55","slug":"the-river-memory-generator","status":"publish","type":"post","link":"https:\/\/cassiemdp.space\/blog\/2026\/07\/24\/the-river-memory-generator\/","title":{"rendered":"The River Memory Generator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Thames, or Deshkan Ziibi, wasn&#8217;t chosen so much as it is part of where I work from already. My community, Oneida Nation of the Thames, camped on the banks of the river the night they arrived in Ontario. After years of broken land agreements and dispossession, my ancestors made their way to this area of Dish with One Spoon. The morning after they arrived, they were greeted by a soft covering of snow, the first gift from the river. Deshkan Ziibi is part of our identity as Onoyota&#8217;a:ka on these lands, and the RMG is one way I work alongside it.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS-1024x1024.png\" alt=\"\" class=\"wp-image-70\" style=\"width:393px;height:auto\" srcset=\"https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS-1024x1024.png 1024w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS-300x300.png 300w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS-150x150.png 150w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS-768x768.png 768w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS-1536x1536.png 1536w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/20250919_221219011_iOS.png 2000w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><em>input drawing for RMG<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Before the river enters, there&#8217;s a drawing. The source image is a pixel drawing I made of beadwork. Seven registers run horizontally across the canvas, each one repeating its own unit edge to edge: octagons, squares, a crossing line, a small skydome, a row of chevrons, a paired curl, and a scalloped baseline with points. The band sits in the upper-middle of a square field, with white above and below it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I drew these symbols from memory, thinking about the beadwork my mother would create when I was a child. I drew it rather than photographing beadwork or pulling an existing pattern because the drawing is already a relation before the river touches it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The drawing doesn&#8217;t change. Every run starts from the same file, so any difference between two outputs is the river&#8217;s doing and nothing else.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The River Memory Generator (RMG) is a Python script that runs natively on my laptop. When I call the script from the command prompt, it scrapes hourly observations from the Upper Thames River Conservation Authority (UTRCA) and rearranges the drawing according to what the river is doing at that moment. Flow and level come from Fanshawe; temperature comes from Dingman Creek. Flow determines how the drawing moves. Below a threshold of 7 m\u00b3\/s, the script runs three passes in sequence\u2014blocks of the image rotate around its centre, each row shifts sideways, and the blocks then drift outward\u2014so a calm river accumulates small displacements. Above the threshold, a single spin runs on its own, and the layering that held the drawing together on a calm day falls away. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if flow is not None and flow &gt;= VORTEX_FLOW_THRESHOLD:\n    distorted = vortex_by_flow(original, flow)\nelse:\n    distorted = whirlpool_by_flow(original, flow)\n    distorted = ripple_by_flow(distorted, flow)\n    distorted = drift_by_flow(distorted, flow)<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><em>Excerpts are abridged for legibility<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Flow is movement and force. Temperature governs repetition: warmer water divides the image into more horizontal bands, each one stamped over everything below it, so heat reads as insistence rather than intensity. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def repeat_by_temperature(image, temp):\n    slice_count = int(min(max(temp, 1), 30))\n    slice_height = height \/\/ slice_count\n    for i in range(slice_count):\n        slice_img = image.crop((0, i * slice_height, width, (i + 1) * slice_height))\n        for j in range(i, slice_count):\n            new_image.paste(slice_img, (0, j * slice_height))<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Level enters through a shuffle of the drawing&#8217;s ten vertical slices, seeded by a value that combines all three readings, with level weighted heaviest\u2014it is pressure and depth, felt through the other two rather than apart from them. Once the new image exists, the RMG blends it with the previous run at one-fifth opacity, so the river&#8217;s earlier state stays faintly visible beneath its current one. That&#8217;s the memory in the name: not a record, but a residue thin enough to be overwritten.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35-1024x1024.png\" alt=\"\" class=\"wp-image-73\" style=\"width:367px;height:auto\" srcset=\"https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35-1024x1024.png 1024w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35-300x300.png 300w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35-150x150.png 150w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35-768x768.png 768w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35-1536x1536.png 1536w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2025-09-21_16-35.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Output from September 21, 2025<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10-1024x1024.png\" alt=\"\" class=\"wp-image-74\" style=\"width:365px;height:auto\" srcset=\"https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10-1024x1024.png 1024w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10-300x300.png 300w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10-150x150.png 150w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10-768x768.png 768w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10-1536x1536.png 1536w, https:\/\/cassiemdp.space\/blog\/wp-content\/uploads\/2026\/07\/river_rearranged_2026-01-15_14-10.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Output from January 15, 2026<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">All three readings come from UTRCA&#8217;s public flood-forecasting pages, updated hourly: <a href=\"https:\/\/www.data-cwdv.ca\/ffw\/UTRCA\/docs\/UTRCA_QR.html\">flow<\/a> in cubic metres per second, <a href=\"https:\/\/www.data-cwdv.ca\/ffw\/UTRCA\/docs\/UTRCA_HG.html\">level<\/a> in metres, <a href=\"https:\/\/www.data-cwdv.ca\/ffw\/UTRCA\/docs\/UTRCA_TW.html\">water temperature<\/a> in degrees Celsius. The script reads the most recent posted value at the moment it runs, so a call at 9 a.m. and a call at noon draw on different observations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The form matters for what follows. Because the registers run horizontally and repeat, the script&#8217;s operations cut across them rather than along them. Temperature slices the image into horizontal bands and stamps each one downward, which preserves a register&#8217;s continuity while multiplying it. The vertical shuffle cuts the other way, breaking each register&#8217;s repeat at ten points and reassembling it out of order. The same drawing survives one operation and comes apart under the other. The white field above and below is where the displaced blocks land\u2014the block functions paste onto an empty canvas and clamp at its edges, so the emptiness is working space rather than margin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each run produces one image and one only. The river&#8217;s state at that hour is not recoverable from anywhere else, and the next call overwrites the file the current one will be blended into. What accumulates is not an archive but a sequence\u2014each image holding a fifth of the one before it, and that one holding a fifth of another, until the earliest states are present at weights too small to see.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The drawing is the part I made. The rest is the river&#8217;s, and I don&#8217;t get to know in advance what it will do with a pattern I drew from memory. Each call returns something I recognize and didn&#8217;t decide. That&#8217;s the arrangement the RMG exists to hold open.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Thames, or Deshkan Ziibi, wasn&#8217;t chosen so much as it is part of where I work from already. My community, Oneida Nation of the Thames, camped on the banks of the river the night they arrived in Ontario. After years of broken land agreements and dispossession, my ancestors made their way to this area [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30],"tags":[20,24,18,23,8,9,27,28,13,21,29,17,19,10,25],"class_list":["post-69","post","type-post","status-publish","format-standard","hentry","category-documentation","tag-beadwork","tag-data-scraping","tag-deshkan-ziibi","tag-generative-process","tag-luwa-wihe","tag-mfa","tag-oneida-nation-of-the-thames","tag-onoyotaaka","tag-pipeline","tag-python","tag-research-creation","tag-river-memory-generator","tag-thames-river","tag-thesis","tag-utrca"],"_links":{"self":[{"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/posts\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/comments?post=69"}],"version-history":[{"count":7,"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/posts\/69\/revisions"}],"predecessor-version":[{"id":79,"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/posts\/69\/revisions\/79"}],"wp:attachment":[{"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/media?parent=69"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/categories?post=69"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cassiemdp.space\/blog\/wp-json\/wp\/v2\/tags?post=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}