ResFlow-demo / make_examples.py
baghishov's picture
The meander belt strip (384 x 128) as before, now the first example; the square meander dropped.
4d115e9 verified
Raw History Blame Contribute Delete
3.78 kB
"""Precompute the demo's example reservoirs on the Space's GPU, through its /generate endpoint (same model and
sampler as the live demo). Needs a Hugging Face token (huggingface-cli login).
python make_examples.py NAME -> examples/NAME.npz"""
import io, json, sys, time
import urllib.request
import numpy as np
from huggingface_hub import get_token
from matplotlib.path import Path
SPACE = 'https://baghishov-resflow-demo.hf.space'
Z = 32
WELL_LOGS = { # as in backend.py: base (z = 0) to top, 1 sand, 0 mud
'Two sand bodies': [0] * 6 + [1] * 7 + [0] * 7 + [1] * 8 + [0] * 4,
'Thick sand at the base': [1] * 14 + [0] * 18,
}
HEADERS = {'Authorization': f'Bearer {get_token()}'}
def fetch(url, data=None):
req = urllib.request.Request(url, data=None if data is None else json.dumps(data).encode(),
headers={**HEADERS, 'Content-Type': 'application/json'})
return urllib.request.urlopen(req, timeout=900)
def call(api, data):
"""Run a Gradio API endpoint and return its output list."""
eid = json.load(fetch(f'{SPACE}/gradio_api/call/{api}', {'data': data}))['event_id']
event = None
with fetch(f'{SPACE}/gradio_api/call/{api}/{eid}') as r:
for line in (l.decode().rstrip('\n') for l in r):
if line.startswith('event:'):
event = line[6:].strip()
elif line.startswith('data:') and event in ('complete', 'error'):
if event == 'error':
raise RuntimeError(line)
return json.loads(line[5:])
raise RuntimeError('stream ended without a result')
def blob(nx, ny, seed=3):
"""An irregular reservoir outline: a smooth random closed curve."""
rng = np.random.default_rng(seed)
t = np.linspace(0, 2 * np.pi, 400)
r = 0.36 + sum(rng.uniform(0.02, 0.06) * np.cos(k * t + rng.uniform(0, 6.3)) for k in range(2, 6))
x, y = 0.5 + r * np.cos(t), 0.5 + 0.9 * r * np.sin(t)
gx, gy = np.meshgrid((np.arange(nx) + .5) / nx, (np.arange(ny) + .5) / ny, indexing='ij')
return Path(np.c_[x, y]).contains_points(np.c_[gx.ravel(), gy.ravel()]).reshape(nx, ny)
EX = {
'lobe_outline': dict(title='Deep-water lobes, irregular outline, two wells', label='Lobe (deep-water)', nx=256, ny=256,
azimuth=45.0, outline=True,
wells=[(96, 120, 'Two sand bodies'), (168, 104, 'Thick sand at the base')]),
'meander_strip': dict(title='Meander belt along flow', label='Meander (oxbow)', nx=384, ny=128, azimuth=0.0,
outline=False, wells=[]),
}
name = sys.argv[1]; e = EX[name]
wells = [(x, y, WELL_LOGS[log]) for x, y, log in e['wells']]
t = time.time()
out = call('generate', [e['label'], e['nx'], e['ny'], json.dumps(wells), 50, 0, json.dumps({'azimuth': e['azimuth']})])
z = np.load(io.BytesIO(fetch(out[0]['url']).read()))
f = z['facies']
params = {k: float(z[k]) for k in z.files if k not in ('facies', 'active', 'environment')}
for x, y, log in wells: # wells must be honoured exactly
assert (f[x, y] == np.array(log)).all(), f'well ({x}, {y}) not honoured'
active = blob(e['nx'], e['ny']) if e['outline'] else np.ones((e['nx'], e['ny']), bool)
np.savez_compressed(f'examples/{name}.npz', facies=f, active=active,
wells=np.array([[x, y] + list(log) for x, y, log in wells], np.int16).reshape(-1, 2 + Z),
meta=json.dumps({'title': e['title'], 'label': e['label'], 'nx': e['nx'], 'ny': e['ny'],
'params': params, 'steps': 50, 'seed': 0}))
print(f'{name}: {f.shape}, sand {f[active].mean():.2f}, wells honoured {len(wells)}, {time.time() - t:.0f}s', flush=True)