baghishov commited on
Commit
62ee830
·
verified ·
1 Parent(s): 0647f20

Wells outlined exactly: thin lines just outside the well cell on the map and the well column in the sections, so every cell of the well shows in full.

Browse files
Files changed (2) hide show
  1. app.py +2 -2
  2. backend.py +26 -18
app.py CHANGED
@@ -396,10 +396,10 @@ with gr.Blocks(title='ResFlow: 3D reservoir generation', theme=THEME, css=CSS, j
396
  img_xy = gr.Image(FIRST['xy'], **image)
397
  z_s = gr.Slider(0, B.Z - 1, value=B.Z // 2, step=1, label='Depth z (0 = base)')
398
  with gr.Column(scale=1, min_width=360):
399
- gr.Markdown('Section along x (XZ) at the y below; a darker column is a well.', elem_classes='cap')
400
  img_xz = gr.Image(FIRST['xz'], **image)
401
  y_s = gr.Slider(0, FIRST['y']['maximum'], value=FIRST['y']['value'], step=1, label='y of the XZ section')
402
- gr.Markdown('Section along y (YZ) at the x below; a darker column is a well.', elem_classes='cap')
403
  img_yz = gr.Image(FIRST['yz'], **image)
404
  x_s = gr.Slider(0, FIRST['x']['maximum'], value=FIRST['x']['value'], step=1, label='x of the YZ section')
405
  download = gr.File(FIRST['path'], label='Download (.npz: facies 1 = sand, active = inside the outline)')
 
396
  img_xy = gr.Image(FIRST['xy'], **image)
397
  z_s = gr.Slider(0, B.Z - 1, value=B.Z // 2, step=1, label='Depth z (0 = base)')
398
  with gr.Column(scale=1, min_width=360):
399
+ gr.Markdown('Section along x (XZ) at the y below; a well is the column between two dark lines.', elem_classes='cap')
400
  img_xz = gr.Image(FIRST['xz'], **image)
401
  y_s = gr.Slider(0, FIRST['y']['maximum'], value=FIRST['y']['value'], step=1, label='y of the XZ section')
402
+ gr.Markdown('Section along y (YZ) at the x below; a well is the column between two dark lines.', elem_classes='cap')
403
  img_yz = gr.Image(FIRST['yz'], **image)
404
  x_s = gr.Slider(0, FIRST['x']['maximum'], value=FIRST['x']['value'], step=1, label='x of the YZ section')
405
  download = gr.File(FIRST['path'], label='Download (.npz: facies 1 = sand, active = inside the outline)')
backend.py CHANGED
@@ -139,38 +139,46 @@ def _rgb(sl, active):
139
  return np.where(active[..., None], img, OUTSIDE_RGB).astype(np.uint8)
140
 
141
 
 
 
 
 
 
 
 
142
  def slice_image(field, active, axis, index, wells=(), scale=None):
143
  """RGB image of one section: axis 'z' gives a map view (x right, y up), 'y' an XZ and 'x' a
144
- YZ section (depth up). Cells outside the reservoir are white; a well is a one-pixel dark ring on the map,
145
- with its cells showing inside, and a darker column in a section. ``scale`` sets the pixels per cell of the
146
- map view."""
 
147
  nx, ny, nz = field.shape
148
  if axis == 'z':
149
  img = _rgb(field[:, :, index], active)[:, ::-1].transpose(1, 0, 2)
150
  k = scale or max(1, 512 // max(img.shape[:2]))
151
  img = np.kron(img, np.ones((k, k, 1), np.uint8))
152
- r = max(1, max(nx, ny) // 128)
153
- for x, y, _ in wells: # a one-pixel dark ring; the cells within r show inside
154
- row, col = ny - 1 - int(y), int(x)
155
- r0, r1 = max(0, row - r) * k, min(ny, row + r + 1) * k
156
- c0, c1 = max(0, col - r) * k, min(nx, col + r + 1) * k
157
- img[r0, c0:c1] = img[r1 - 1, c0:c1] = WELL_RGB
158
- img[r0:r1, c0] = img[r0:r1, c1 - 1] = WELL_RGB
159
- return _number_wells(img, [((ny - 1 - int(y)) * k + k // 2, int(x) * k + k // 2, (r + 0.5) * k)
160
  for x, y, _ in wells]) if len(wells) else img
161
  elif axis == 'y':
162
  img = _rgb(field[:, index, :], np.repeat(active[:, index, None], nz, 1))[:, ::-1].transpose(1, 0, 2)
163
- for x, y, _ in wells:
164
- if int(y) == index:
165
- img[:, int(x)] = (0.55 * img[:, int(x)] + 0.45 * WELL_RGB).astype(np.uint8)
166
  else:
167
  img = _rgb(field[index, :, :], np.repeat(active[index, :, None], nz, 1))[:, ::-1].transpose(1, 0, 2)
168
- for x, y, _ in wells:
169
- if int(x) == index:
170
- img[:, int(y)] = (0.55 * img[:, int(y)] + 0.45 * WELL_RGB).astype(np.uint8)
171
  kx = max(1, 1536 // img.shape[1]) # sections: about 1536 x 256 px (6:1) at any length
172
  kz = max(1, round(img.shape[1] * kx / 6 / img.shape[0]))
173
- return np.kron(img, np.ones((kz, kx, 1), np.uint8))
 
 
 
 
 
174
 
175
 
176
  MAP_INSIDE_RGB = np.array([217, 217, 217], np.uint8)
 
139
  return np.where(active[..., None], img, OUTSIDE_RGB).astype(np.uint8)
140
 
141
 
142
+ def _beside(lo, hi, w, n):
143
+ """Two slices, ``w`` pixels wide, just outside the pixel span [lo, hi) of an image ``n`` pixels across; at the
144
+ image edge the slice moves inside the span."""
145
+ return (slice(lo - w, lo) if lo >= w else slice(lo, lo + w),
146
+ slice(hi, hi + w) if hi + w <= n else slice(hi - w, hi))
147
+
148
+
149
  def slice_image(field, active, axis, index, wells=(), scale=None):
150
  """RGB image of one section: axis 'z' gives a map view (x right, y up), 'y' an XZ and 'x' a
151
+ YZ section (depth up). Cells outside the reservoir are white. A well is outlined by thin dark lines drawn
152
+ just outside the cells it conditions, and only those: a one-pixel ring around its cell on the map, a line
153
+ down each side of its column in a section, so every cell of the well shows in full. ``scale`` sets the
154
+ pixels per cell of the map view."""
155
  nx, ny, nz = field.shape
156
  if axis == 'z':
157
  img = _rgb(field[:, :, index], active)[:, ::-1].transpose(1, 0, 2)
158
  k = scale or max(1, 512 // max(img.shape[:2]))
159
  img = np.kron(img, np.ones((k, k, 1), np.uint8))
160
+ for x, y, _ in wells:
161
+ row, col = (ny - 1 - int(y)) * k, int(x) * k
162
+ top, bottom = _beside(row, row + k, 1, img.shape[0])
163
+ left, right = _beside(col, col + k, 1, img.shape[1])
164
+ rows, cols = slice(top.start, bottom.stop), slice(left.start, right.stop)
165
+ img[top, cols] = img[bottom, cols] = img[rows, left] = img[rows, right] = WELL_RGB
166
+ return _number_wells(img, [((ny - 1 - int(y)) * k + k // 2, int(x) * k + k // 2, k / 2 + 1)
 
167
  for x, y, _ in wells]) if len(wells) else img
168
  elif axis == 'y':
169
  img = _rgb(field[:, index, :], np.repeat(active[:, index, None], nz, 1))[:, ::-1].transpose(1, 0, 2)
170
+ marks = [int(x) for x, y, _ in wells if int(y) == index]
 
 
171
  else:
172
  img = _rgb(field[index, :, :], np.repeat(active[index, :, None], nz, 1))[:, ::-1].transpose(1, 0, 2)
173
+ marks = [int(y) for x, y, _ in wells if int(x) == index]
 
 
174
  kx = max(1, 1536 // img.shape[1]) # sections: about 1536 x 256 px (6:1) at any length
175
  kz = max(1, round(img.shape[1] * kx / 6 / img.shape[0]))
176
+ img = np.kron(img, np.ones((kz, kx, 1), np.uint8))
177
+ w = 1 if kx < 4 else 2 # the lines must survive the browser scaling the image down
178
+ for c in marks:
179
+ left, right = _beside(c * kx, (c + 1) * kx, w, img.shape[1])
180
+ img[:, left] = img[:, right] = WELL_RGB
181
+ return img
182
 
183
 
184
  MAP_INSIDE_RGB = np.array([217, 217, 217], np.uint8)