completor 0.1.2__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
completor/parse.py CHANGED
@@ -169,15 +169,15 @@ def complete_records(record: list[str], keyword: str) -> list[str]:
169
169
  Returns:
170
170
  Completed list of strings.
171
171
  """
172
- if keyword == Keywords.WSEGVALV:
172
+ if keyword == Keywords.WELL_SEGMENTS_VALVE:
173
173
  return complete_wsegvalv_record(record)
174
174
 
175
175
  dict_ncolumns = {
176
- Keywords.WELSPECS: 17,
177
- Keywords.COMPDAT: 14,
178
- Keywords.WELSEGS_H: 12,
179
- Keywords.WELSEGS: 15,
180
- Keywords.COMPSEGS: 11,
176
+ Keywords.WELL_SPECIFICATION: 17,
177
+ Keywords.COMPLETION_DATA: 14,
178
+ Keywords.WELL_SEGMENTS_HEADER: 12,
179
+ Keywords.WELL_SEGMENTS: 15,
180
+ Keywords.COMPLETION_SEGMENTS: 11,
181
181
  }
182
182
  max_column = dict_ncolumns[keyword]
183
183
  ncolumn = len(record)
@@ -190,9 +190,10 @@ def complete_records(record: list[str], keyword: str) -> list[str]:
190
190
 
191
191
 
192
192
  def complete_wsegvalv_record(record: list[str]) -> list[str]:
193
- """Complete the WSEGVALV record.
193
+ """Complete the WELL_SEGMENTS_VALVE record.
194
194
 
195
- Columns DEFAULT_1 - DEFAULT_4, STATE and AC_MAX might not be provided and need to be filled in with default values.
195
+ Columns PIPE_DIAMETER, ABSOLUTE_PIPE_ROUGHNESS, PIPE_CROSS_SECTION_AREA, FLAG, and MAX_FLOW_CROSS_SECTIONAL_AREA
196
+ might not be provided and need to be filled in with default values.
196
197
 
197
198
  Args:
198
199
  record: List of strings.
@@ -200,9 +201,9 @@ def complete_wsegvalv_record(record: list[str]) -> list[str]:
200
201
  Returns:
201
202
  Completed list of strings.
202
203
  """
203
- WSEGVALV_COLUMNS = 10
204
- AC_INDEX = 3
205
- DEFAULT_STATE = "OPEN"
204
+ wsegvalv_columns = 10
205
+ ac_index = 3
206
+ default_state = "OPEN"
206
207
 
207
208
  if len(record) < 8:
208
209
  # add defaults
@@ -210,24 +211,24 @@ def complete_wsegvalv_record(record: list[str]) -> list[str]:
210
211
 
211
212
  if len(record) < 9:
212
213
  # append default state
213
- record.append(DEFAULT_STATE)
214
+ record.append(default_state)
214
215
 
215
- if len(record) < WSEGVALV_COLUMNS:
216
+ if len(record) < wsegvalv_columns:
216
217
  # append default ac_max
217
- record.append(record[AC_INDEX])
218
+ record.append(record[ac_index])
218
219
 
219
- if len(record) > WSEGVALV_COLUMNS:
220
- record = record[:WSEGVALV_COLUMNS]
220
+ if len(record) > wsegvalv_columns:
221
+ record = record[:wsegvalv_columns]
221
222
 
222
223
  return record
223
224
 
224
225
 
225
226
  def read_schedule_keywords(
226
- content: list[str], keywords: list[str], optional_keywords: list[str] = []
227
+ content: list[str], keywords: list[str], optional_keywords: list[str] | None = None
227
228
  ) -> tuple[list[ContentCollection], npt.NDArray[np.str_]]:
228
229
  """Read schedule keywords or all keywords in table format.
229
230
 
230
- E.g. WELSPECS, COMPDAT, WELSEGS, COMPSEGS, WSEGVALV.
231
+ E.g. WELL_SPECIFICATION, COMPLETION_DATA, WELL_SEGMENTS, COMPLETION_SEGMENTS, WELL_SEGMENTS_VALVE.
231
232
 
232
233
  Args:
233
234
  content: List of strings. Lines from the schedule file.
@@ -244,7 +245,8 @@ def read_schedule_keywords(
244
245
  content = deepcopy(content)
245
246
  used_index = np.asarray([-1])
246
247
  collections = []
247
- # get the contents correspond to the list_keywords
248
+ optional_keywords = [] if optional_keywords is None else optional_keywords
249
+ # get the contents that correspond with the list_keywords
248
250
  for keyword in keywords + optional_keywords:
249
251
  start_index, end_index = locate_keyword(content, keyword, take_first=False)
250
252
  if start_index[0] == end_index[0] and keyword not in optional_keywords:
@@ -254,7 +256,7 @@ def read_schedule_keywords(
254
256
  used_index = np.append(used_index, np.arange(start, end + 1))
255
257
  keyword_content = [_create_record(content, keyword, irec, start) for irec in range(start + 1, end)]
256
258
  collection = ContentCollection(keyword_content, name=keyword)
257
- if keyword in [Keywords.WELSEGS, Keywords.COMPSEGS]:
259
+ if keyword in [Keywords.WELL_SEGMENTS, Keywords.COMPLETION_SEGMENTS]:
258
260
  # remove string characters
259
261
  collection.well = remove_string_characters(keyword_content[0][0])
260
262
  collections.append(collection)
@@ -276,58 +278,58 @@ def _create_record(content: list[str], keyword: str, irec: int, start: int) -> l
276
278
  record = unpack_records(record)
277
279
  # complete records
278
280
  record = complete_records(
279
- record, Keywords.WELSEGS_H if keyword == Keywords.WELSEGS and irec == start + 1 else keyword
281
+ record, Keywords.WELL_SEGMENTS_HEADER if keyword == Keywords.WELL_SEGMENTS and irec == start + 1 else keyword
280
282
  )
281
283
  return record
282
284
 
283
285
 
284
286
  def get_welsegs_table(collections: list[ContentCollection]) -> tuple[pd.DataFrame, pd.DataFrame]:
285
- """Return dataframe table of WELSEGS.
287
+ """Return dataframe table of WELL_SEGMENTS.
286
288
 
287
289
  Args:
288
290
  collections: ContentCollection class.
289
291
 
290
292
  Returns:
291
- header_table - The header of WELSEGS.
292
- record_table - The record of WELSEGS.
293
+ header_table - The header of WELL_SEGMENTS.
294
+ record_table - The record of WELL_SEGMENTS.
293
295
 
294
296
  Raises:
295
- ValueError: If collection does not contain the 'WELSEGS' keyword.
297
+ ValueError: If collection does not contain the 'WELL_SEGMENTSWELL_SEGMENTS' keyword.
296
298
  """
297
299
  header_columns = [
298
300
  Headers.WELL,
299
- Headers.SEGMENTTVD,
300
- Headers.SEGMENTMD,
301
- Headers.WBVOLUME,
301
+ Headers.TRUE_VERTICAL_DEPTH,
302
+ Headers.MEASURED_DEPTH,
303
+ Headers.WELLBORE_VOLUME,
302
304
  Headers.INFO_TYPE,
303
- Headers.PDROPCOMP,
304
- Headers.MPMODEL,
305
- Headers.ITEM_8,
306
- Headers.ITEM_9,
307
- Headers.ITEM_10,
308
- Headers.ITEM_11,
309
- Headers.ITEM_12,
305
+ Headers.PRESSURE_DROP_COMPLETION,
306
+ Headers.MULTIPHASE_FLOW_MODEL,
307
+ Headers.X_COORDINATE_TOP_SEGMENT,
308
+ Headers.Y_COORDINATE_TOP_SEGMENT,
309
+ Headers.THERMAL_CONDUCTIVITY_CROSS_SECTIONAL_AREA,
310
+ Headers.VOLUMETRIC_HEAT_CAPACITY_PIPE_WALL,
311
+ Headers.THERMAL_CONDUCTIVITY_PIPE_WALL,
310
312
  ]
311
313
  content_columns = [
312
314
  Headers.WELL,
313
315
  Headers.TUBING_SEGMENT,
314
316
  Headers.TUBING_SEGMENT_2,
315
- Headers.TUBINGBRANCH,
317
+ Headers.TUBING_BRANCH,
316
318
  Headers.TUBING_OUTLET,
317
- Headers.TUBINGMD,
318
- Headers.TUBINGTVD,
319
+ Headers.TUBING_MEASURED_DEPTH,
320
+ Headers.TRUE_VERTICAL_DEPTH,
319
321
  Headers.TUBING_INNER_DIAMETER,
320
322
  Headers.TUBING_ROUGHNESS,
321
- Headers.CROSS,
322
- Headers.VSEG,
323
- Headers.ITEM_11,
324
- Headers.ITEM_12,
325
- Headers.ITEM_13,
326
- Headers.ITEM_14,
327
- Headers.ITEM_15,
323
+ Headers.FLOW_CROSS_SECTIONAL_AREA,
324
+ Headers.SEGMENT_VOLUME,
325
+ Headers.X_COORDINATE_LAST_SEGMENT,
326
+ Headers.Y_COORDINATE_LAST_SEGMENT,
327
+ Headers.THERMAL_CONDUCTIVITY_CROSS_SECTIONAL_AREA,
328
+ Headers.VOLUMETRIC_HEAT_CAPACITY_PIPE_WALL,
329
+ Headers.THERMAL_CONDUCTIVITY_PIPE_WALL,
328
330
  ]
329
331
  for collection in collections:
330
- if collection.name == Keywords.WELSEGS:
332
+ if collection.name == Keywords.WELL_SEGMENTS:
331
333
  header_collection = np.asarray(collection[:1])
332
334
  record_collection = np.asarray(collection[1:])
333
335
  # add additional well column on the second collection
@@ -346,7 +348,7 @@ def get_welsegs_table(collections: list[ContentCollection]) -> tuple[pd.DataFram
346
348
  header_table = pd.DataFrame(header_table, columns=header_columns)
347
349
  record_table = pd.DataFrame(record_table, columns=content_columns)
348
350
  except NameError as err:
349
- raise ValueError("Collection does not contain the 'WELSEGS' keyword") from err
351
+ raise ValueError(f"Collection does not contain the '{Keywords.WELL_SEGMENTS}' keyword") from err
350
352
 
351
353
  # replace string component " or ' in the columns
352
354
  header_table = remove_string_characters(header_table)
@@ -355,16 +357,16 @@ def get_welsegs_table(collections: list[ContentCollection]) -> tuple[pd.DataFram
355
357
 
356
358
 
357
359
  def get_welspecs_table(collections: list[ContentCollection]) -> pd.DataFrame:
358
- """Return dataframe table of WELSPECS.
360
+ """Return dataframe table of WELL_SPECIFICATION.
359
361
 
360
362
  Args:
361
363
  collections: ContentCollection class.
362
364
 
363
365
  Returns:
364
- WELSPECS table.
366
+ WELL_SPECIFICATION table.
365
367
 
366
368
  Raises:
367
- ValueError: If collection does not contain the 'WELSPECS' keyword.
369
+ ValueError: If collection does not contain the 'WELL_SPECIFICATION' keyword.
368
370
  """
369
371
  columns = [
370
372
  Headers.WELL,
@@ -376,18 +378,18 @@ def get_welspecs_table(collections: list[ContentCollection]) -> pd.DataFrame:
376
378
  Headers.DR,
377
379
  Headers.FLAG,
378
380
  Headers.SHUT,
379
- Headers.CROSS,
381
+ Headers.FLOW_CROSS_SECTIONAL_AREA,
380
382
  Headers.PRESSURE_TABLE,
381
- Headers.DENSCAL,
383
+ Headers.DENSITY_CALCULATION_TYPE,
382
384
  Headers.REGION,
383
- Headers.ITEM_14,
384
- Headers.ITEM_15,
385
- Headers.ITEM_16,
386
- Headers.ITEM_17,
385
+ Headers.RESERVED_HEADER_1,
386
+ Headers.RESERVED_HEADER_2,
387
+ Headers.WELL_MODEL_TYPE,
388
+ Headers.POLYMER_MIXING_TABLE_NUMBER,
387
389
  ]
388
390
  welspecs_table = None
389
391
  for collection in collections:
390
- if collection.name == Keywords.WELSPECS:
392
+ if collection.name == Keywords.WELL_SPECIFICATION:
391
393
  the_collection = np.asarray(collection)
392
394
  if welspecs_table is None:
393
395
  welspecs_table = np.copy(the_collection)
@@ -395,7 +397,7 @@ def get_welspecs_table(collections: list[ContentCollection]) -> pd.DataFrame:
395
397
  welspecs_table = np.row_stack((welspecs_table, the_collection))
396
398
 
397
399
  if welspecs_table is None:
398
- raise ValueError("Collection does not contain the 'WELSPECS' keyword")
400
+ raise ValueError(f"Collection does not contain the '{Keywords.WELL_SPECIFICATION}' keyword")
399
401
 
400
402
  welspecs_table = pd.DataFrame(welspecs_table, columns=columns)
401
403
  # replace string component " or ' in the columns
@@ -404,27 +406,27 @@ def get_welspecs_table(collections: list[ContentCollection]) -> pd.DataFrame:
404
406
 
405
407
 
406
408
  def get_compdat_table(collections: list[ContentCollection]) -> pd.DataFrame:
407
- """Return dataframe table of COMPDAT.
409
+ """Return dataframe table of COMPLETION_DATA.
408
410
 
409
411
  Args:
410
412
  collections: ContentCollection class.
411
413
 
412
414
  Returns:
413
- COMPDAT table.
415
+ COMPLETION_DATA table.
414
416
 
415
417
  Raises:
416
- ValueError: If a collection does not contain the 'COMPDAT' keyword.
418
+ ValueError: If a collection does not contain the 'COMPLETION_DATA' keyword.
417
419
  """
418
420
  compdat_table = None
419
421
  for collection in collections:
420
- if collection.name == Keywords.COMPDAT:
422
+ if collection.name == Keywords.COMPLETION_DATA:
421
423
  the_collection = np.asarray(collection)
422
424
  if compdat_table is None:
423
425
  compdat_table = np.copy(the_collection)
424
426
  else:
425
427
  compdat_table = np.row_stack((compdat_table, the_collection))
426
428
  if compdat_table is None:
427
- raise ValueError("Collection does not contain the 'COMPDAT' keyword")
429
+ raise ValueError(f"Collection does not contain the '{Keywords.COMPLETION_DATA}' keyword")
428
430
  compdat_table = pd.DataFrame(
429
431
  compdat_table,
430
432
  columns=[
@@ -436,35 +438,33 @@ def get_compdat_table(collections: list[ContentCollection]) -> pd.DataFrame:
436
438
  Headers.STATUS,
437
439
  Headers.SATURATION_FUNCTION_REGION_NUMBERS,
438
440
  Headers.CONNECTION_FACTOR,
439
- Headers.DIAMETER,
440
- Headers.FORAMTION_PERMEABILITY_THICKNESS,
441
+ Headers.WELL_BORE_DIAMETER,
442
+ Headers.FORMATION_PERMEABILITY_THICKNESS,
441
443
  Headers.SKIN,
442
- Headers.DFACT,
444
+ Headers.D_FACTOR,
443
445
  Headers.COMPDAT_DIRECTION,
444
446
  Headers.RO,
445
447
  ],
446
448
  )
447
- # replace string component " or ' in the columns
448
- compdat_table = remove_string_characters(compdat_table)
449
- return compdat_table
449
+ return remove_string_characters(compdat_table)
450
450
 
451
451
 
452
452
  def get_compsegs_table(collections: list[ContentCollection]) -> pd.DataFrame:
453
- """Return data frame table of COMPSEGS.
453
+ """Return data frame table of COMPLETION_SEGMENTS.
454
454
 
455
455
  Args:
456
456
  collections: ContentCollection class.
457
457
 
458
458
  Returns:
459
- COMPSEGS table.
459
+ COMPLETION_SEGMENTS table.
460
460
 
461
461
  Raises:
462
- ValueError: If collection does not contain the 'COMPSEGS' keyword.
462
+ ValueError: If collection does not contain the 'COMPLETION_SEGMENTS' keyword.
463
463
 
464
464
  """
465
465
  compsegs_table = None
466
466
  for collection in collections:
467
- if collection.name == Keywords.COMPSEGS:
467
+ if collection.name == Keywords.COMPLETION_SEGMENTS:
468
468
  the_collection = np.asarray(collection[1:])
469
469
  # add additional well column
470
470
  well_column = np.full(the_collection.shape[0], collection.well)
@@ -475,7 +475,7 @@ def get_compsegs_table(collections: list[ContentCollection]) -> pd.DataFrame:
475
475
  compsegs_table = np.row_stack((compsegs_table, the_collection))
476
476
 
477
477
  if compsegs_table is None:
478
- raise ValueError("Collection does not contain the 'COMPSEGS' keyword")
478
+ raise ValueError(f"Collection does not contain the '{Keywords.COMPLETION_SEGMENTS}' keyword")
479
479
 
480
480
  compsegs_table = pd.DataFrame(
481
481
  compsegs_table,
@@ -489,8 +489,8 @@ def get_compsegs_table(collections: list[ContentCollection]) -> pd.DataFrame:
489
489
  Headers.END_MEASURED_DEPTH,
490
490
  Headers.COMPSEGS_DIRECTION,
491
491
  Headers.ENDGRID,
492
- Headers.PERFDEPTH,
493
- Headers.THERM,
492
+ Headers.PERFORATION_DEPTH,
493
+ Headers.THERMAL_CONTACT_LENGTH,
494
494
  Headers.SEGMENT,
495
495
  ],
496
496
  )
@@ -500,17 +500,30 @@ def get_compsegs_table(collections: list[ContentCollection]) -> pd.DataFrame:
500
500
 
501
501
 
502
502
  def get_wsegvalv_table(collections: list[ContentCollection]) -> pd.DataFrame:
503
- """Return a dataframe of WSEGVALV.
503
+ """Return a dataframe of WELL_SEGMENTS_VALVE.
504
504
 
505
505
  Args:
506
506
  collections: ContentCollection class.
507
507
 
508
508
  Returns:
509
- WSEGVALV table.
509
+ WELL_SEGMENTS_VALVE table.
510
510
  """
511
- columns = ["WELL", "SEGMENT", "CD", "AC", "DEFAULT_1", "DEFAULT_2", "DEFAULT_3", "DEFAULT_4", "STATE", "AC_MAX"]
511
+ columns = [
512
+ Headers.WELL,
513
+ Headers.SEGMENT,
514
+ Headers.FLOW_COEFFICIENT,
515
+ Headers.FLOW_CROSS_SECTIONAL_AREA,
516
+ Headers.ADDITIONAL_PIPE_LENGTH_FRICTION_PRESSURE_DROP,
517
+ Headers.PIPE_DIAMETER,
518
+ Headers.ABSOLUTE_PIPE_ROUGHNESS,
519
+ Headers.PIPE_CROSS_SECTION_AREA,
520
+ Headers.FLAG,
521
+ Headers.MAX_FLOW_CROSS_SECTIONAL_AREA,
522
+ ]
512
523
 
513
- wsegvalv_collections = [np.asarray(collection) for collection in collections if collection.name == "WSEGVALV"]
524
+ wsegvalv_collections = [
525
+ np.asarray(collection) for collection in collections if collection.name == Keywords.WELL_SEGMENTS_VALVE
526
+ ]
514
527
  wsegvalv_table = np.vstack(wsegvalv_collections)
515
528
 
516
529
  if wsegvalv_table.size == 0:
@@ -519,16 +532,16 @@ def get_wsegvalv_table(collections: list[ContentCollection]) -> pd.DataFrame:
519
532
  wsegvalv_table = pd.DataFrame(wsegvalv_table, columns=columns)
520
533
  wsegvalv_table = wsegvalv_table.astype(
521
534
  {
522
- "WELL": "string",
523
- "SEGMENT": "int",
524
- "CD": "float",
525
- "AC": "float",
526
- "DEFAULT_1": "string",
527
- "DEFAULT_2": "string",
528
- "DEFAULT_3": "string",
529
- "DEFAULT_4": "string",
530
- "STATE": "string",
531
- "AC_MAX": "float",
535
+ Headers.WELL: "string",
536
+ Headers.SEGMENT: "int",
537
+ Headers.FLOW_COEFFICIENT: "float",
538
+ Headers.FLOW_CROSS_SECTIONAL_AREA: "float",
539
+ Headers.ADDITIONAL_PIPE_LENGTH_FRICTION_PRESSURE_DROP: "string",
540
+ Headers.PIPE_DIAMETER: "string",
541
+ Headers.ABSOLUTE_PIPE_ROUGHNESS: "string",
542
+ Headers.PIPE_CROSS_SECTION_AREA: "string",
543
+ Headers.FLAG: "string",
544
+ Headers.MAX_FLOW_CROSS_SECTIONAL_AREA: "float",
532
545
  }
533
546
  )
534
547
  return remove_string_characters(wsegvalv_table)
@@ -570,9 +583,7 @@ def remove_string_characters(df: pd.DataFrame | str, columns: list[str] | None =
570
583
  iterator = [] if columns is None else columns
571
584
  for column in iterator:
572
585
  try:
573
- df.iloc[:, column] = remove_quotes(df.iloc[:, column].str)
574
- except ValueError:
575
- df[column] = remove_quotes(df[column].str)
586
+ df.isetitem(column, remove_quotes(df.iloc[:, column].str))
576
587
  except AttributeError:
577
588
  # Some dataframes contains numeric data, which we ignore
578
589
  pass