BDMS-227-231-additional-well-info-transfer-scripts#258
Conversation
…bles to `util.py`. Maps the `LU_AquiferClass` and `LU_AquiferType` lookup tables to the lexicon.
…logic_formation`.
…31-additional-well-info-transfer-scripts # Conflicts: # schemas/aquifer_system.py
…formation transfers. Add stratigraphy_transfer.py to handle detailed lithology log import, create well-formation associations, and update formation lithology fields from stratigraphy data. This script is essential for linking wells to geologic formations with depth intervals.
jacob-a-brown
left a comment
There was a problem hiding this comment.
Overall I think it looks good! Just left a few comments
…phy transfer - Changed log level from 'warning' to 'critical' in the depth validation section - Added error tracking and clearer error messages.
…ystem transfer - Changed log level from 'warning' to 'critical' in the depth validation section - Added error tracking
…s to well transfer - Implement _extract_aquifer_type_codes() to parse compound codes (e.g., "FC" -> Fractured + Confined) - Add get_or_create_aquifer() helper to manage unique aquifer system records - Add get_or_create_formation() helper to manage geologic formation records - Integrate aquifer association logic in `transfer_wells()` to create ThingAquiferAssociation and AquiferType records - Integrate formation association logic to create ThingGeologicFormationAssociation records with depth data - Support lexicon mapping for both AqClass (aquifer name) and AquiferType (characteristics) fields - Add comprehensive error handling and logging for aquifer/formation associations This enables proper tracking of wells' aquifer systems with multiple type characteristics and their associated geologic formations, preserving all source data from NM_Aquifer.
|
Made some updates to
|
- Set primary_type placeholder to "Unknown" instead of None when creating an aquifer_system in `well_transfer.py`
…ations - Updated the logic so that a formation association is created only if valid well depth data exist.
…th AMMP It is assumed that the first recorded type of a compound type is the primary type of the aquifer.
…r-scripts # Conflicts: # transfers/well_transfer.py
| if row.WellDepth and not isna(row.WellDepth) | ||
| else 100.0 | ||
| ) | ||
| # Onlyl create association if valid well depth data exists |
There was a problem hiding this comment.
good validation to check 👍
| # Create association using actual well depth | ||
| top_depth = 0.0 | ||
| bottom_depth = float(row.WellDepth) | ||
|
|
||
| formation_assoc = ThingGeologicFormationAssociation( | ||
| thing=well, | ||
| geologic_formation=formation, | ||
| top_depth=top_depth, | ||
| bottom_depth=bottom_depth, | ||
| ) |
There was a problem hiding this comment.
An issue that comes to mind (and we just discussed) is: what should be done if the well record has a formation zone but doesn't have anything in the stratigraphy table? this will create associations indicating that the full well is that zone (top depth = 0 and bottom depth = well depth). perhaps we can store WellData.FormationZone in a field called nma_formation_zone? This will ensure the strictness of Ocotillo but also preserve legacy data if/when it is wanted.
There was a problem hiding this comment.
This is a thoughtful comment. I've added a formation_completion_code field to the Thing model and I've updated this section so it simply records which formation the well was completed in. ThingGeologicFormationAssociation records are no longer being created via the well transfer, they are only being created via the stratigraphy transfer.
There was a problem hiding this comment.
Should the formation_completion_code be included in the geologic_formations field in the response? That is, added to the list of geologic formations a well passes through? Or should it be its own field to indicate this is where the well was completed?
On that note, @chasetmartin the step in the feature file says "And the response should include the formation as the formation zone of well completion." Should we return all geologic formations associated with the well, or just the formation in which the well was completed?
There was a problem hiding this comment.
If we are just returning the formation in which the well terminates I the following steps will need to be taken:
- update the response schema
- update the testing data
- update the test for
the response should include the formation as the formation zone of well completion
There was a problem hiding this comment.
I think the formation_completion_code should be its own field. I think there is value in distinguishing between what formation a well is completed in and what formations the borehole passes through.
There was a problem hiding this comment.
@jacob-a-brown @ksmuczynski So just so I understand the question, there are multiple formations associated with a well in NMAquifer?
There was a problem hiding this comment.
they're in the stratigraphy table (though there's also the field FormationZone for where the well terminates)
There was a problem hiding this comment.
Ah yeah ok, the feature file was just referencing that FormationZone termination field, so Kelsey's suggestion above seems like a good plan.
…s in `well_transfer.py` The current implementation for creating a Formation Association was problematic for the following reasons: 1. The FormationZone field from the WellData csv indicates completion zone, not the entire well stratigraphy 2. Setting top_depth = 0.0 incorrectly implies: * The formation starts at ground surface * The well only penetrates one formation * The entire well depth is within that single formation 3. ThingGeologicFormationAssociation = currently implies full stratigraphic column with depth intervals 4. Forcing FormationZone into a depth-based association creates misleading data Implementation - Added `formation_completion_code` Field to Thing Model - This provides a clear separation between `formation_completion_code` = "What formation is the well completed in" and `formation_associations` = "What formations does the borehole pass through?" - Updated well_transfer.py so that `ThingGeologicFormationAssociation` records are only being created from the Stratigraphy.csv (they were previously being created from WellData, too).
…on_code` to a well.
|
Made some updates to Context:
Updates:
|
There was a problem hiding this comment.
I think that it looks good - I just have one minor comment. The last thing to do is add the new transfer scripts to transfers/transfer.py and make sure the transfers are working (and do some spot checking between Ocotillo and NM_Aquifer to make sure the data is being transferred and persisted as expected)
Added aquifer systems, geologic formations, and stratigraphy transfers.
Why
This PR addresses the following problem / context:
The purpose of this PR is to make these intermediate updates available to @jacob-a-brown as we continue to co-work on the main BDMS-227 task.
How
Implementation summary - the following was changed / added / removed:
Transfer Scripts
aquifer_system_transfer.pyto transfer aquifer systems from LU_AquiferClass (creates aquifer names with placeholder primary_type)geologic_formation_transfer.pyto transfer formation codes from LU_Formations (stores only formation_code, ignores legacy MEANING values)stratigraphy_transfer.pyto transfer detailed lithology logs from Stratigraphy.csv and createThingGeologicFormationAssociationrecords (creates associations with depth intervals and updates formation lithology)well_transfer.pyto:WellData.AqClasscodes to aquifer names using lexicon mapperAquiferTypecodes (e.g., "FC" → ["F", "C"])AquiferTyperecords for each characteristicprimary_typefrom "Unknown" to actual observed typeAqClassby falling back to aquifer type nameThingAquiferAssociationrecords linking wells to aquifer systemsUtility Updates:
lexicon_mapperto includeLU_AquiferClass(CODE → aquifer name mapping)lexicon_mapperto includeLU_Lithology(ABBREVIATION → TERM mapping)LU_Lithologywhich uses ABBREVIATION/TERM instead of CODE/MEANING columnsTransfer Workflow:
aquifer_system_transfer.py- Creates named aquifer systems (e.g., "Ogallala Aquifer")geologic_formation_transfer.py- Creates formation code records (e.g., "121ALVM")well_transfer.py- Creates wells, aquifer associations, AquiferType records.stratigraphy_transfer.py- Creates geologic formation associations with depth intervals and lithologyNotes
Any special considerations, workarounds, or follow-up work to note?
Follow-up work:
formations.jsonfile with USGS formation code-to-name mappings for APIDesign Decisions:
GeologicFormation.lithologypopulated during stratigraphy transfer, not formation transfer, since lithology varies by location