Skip to content

Commit f7652f5

Browse files
authored
Merge branch 'master' into pythonic
2 parents 6968da9 + 0fdbc1e commit f7652f5

File tree

11 files changed

+290
-54
lines changed

11 files changed

+290
-54
lines changed

.github/workflows/publish_conda.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }}
2828
shell: bash -l {0}
2929
run: |
30-
conda install -c conda-forge conda-build netCDF4 numpy anaconda-client -y
30+
conda install -c conda-forge conda-build netCDF4>=1.5.4 numpy anaconda-client -y
3131
conda build -c anaconda -c conda-forge -c loop3d --output-folder conda conda
3232
conda install anaconda-client -y
3333
- name: upload windows

LoopProjectFile/DataCollection.py

Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Check Data Collection valid if present
66
def CheckDataCollectionValid(rootGroup, verbose=False):
77
"""
8-
**CheckDataCollectionValid** - Checks for valid data collection group data
8+
**CheckDataCollectionValid** - Checks for valid data collection group data
99
given a netCDF root node
1010
1111
Parameters
@@ -18,7 +18,7 @@ def CheckDataCollectionValid(rootGroup, verbose=False):
1818
Returns
1919
-------
2020
bool
21-
True if valid data collection formatting in project file, False
21+
True if valid data collection formatting in project file, False
2222
otherwise.
2323
2424
"""
@@ -53,6 +53,15 @@ def GetContactsGroup(rootGroup,verbose=False):
5353
else:
5454
return LoopProjectFileUtils.GetGroup(resp["value"],"Contacts",verbose)
5555

56+
# Get Drillhole group if present
57+
def GetDrillholesGroup(rootGroup,verbose=False):
58+
response = {"errorFlag":False}
59+
resp = GetDataCollectionGroup(rootGroup,verbose)
60+
if resp["errorFlag"]:
61+
return resp
62+
else:
63+
return LoopProjectFileUtils.GetGroup(resp["value"],"Drillholes",verbose)
64+
5665
def CreateObservationGroup(dataCollectionGroup):
5766
obGroup = dataCollectionGroup.createGroup("Observations")
5867
obGroup.createDimension("faultObservationIndex",None)
@@ -238,11 +247,12 @@ def SetContacts(root, data, append=False, verbose=False):
238247
else:
239248
dcGroup = resp["value"]
240249

250+
# Note contacts use a different group node "Contacts" hence we cannot use SetObservations function
241251
resp = GetContactsGroup(root)
242252
if resp["errorFlag"]:
243253
group = dcGroup.createGroup("Contacts")
244254
group.createDimension("index",None)
245-
contactObservationType_t = group.createCompoundType(LoopProjectFile.contactObservationType,'contactObservationType')
255+
contactObservationType_t = group.createCompoundType(LoopProjectFile.contactObservationType,'contactObservation')
246256
group.createVariable('contacts',contactObservationType_t,('index'),zlib=True,complevel=9)
247257
else:
248258
group = resp["value"]
@@ -260,9 +270,65 @@ def SetContacts(root, data, append=False, verbose=False):
260270
response = {"errorFlag":True,"errorString":errStr}
261271
return response
262272

263-
#Extract contacts
273+
# Set drillhole observations
274+
def SetDrillholeObservations(root, data, append=False, verbose=False):
275+
"""
276+
**SetDrillholeObservations** - Saves a list of drillhole observaions in ((easting,northing,
277+
altitude),(easting,northing,altitude),formation,dip,dipDir) format into the netCDF Loop Project File
278+
279+
Parameters
280+
----------
281+
rootGroup: netCDF4.Group
282+
The root group node of a Loop Project File
283+
data: list of ((X,Y,Z),(X,Y,Z),formation,dip,dipDir)
284+
The data to save
285+
index: int
286+
The index of this data
287+
verbose: bool
288+
A flag to indicate a higher level of console logging (more if True)
289+
290+
Returns
291+
-------
292+
dict {"errorFlag","errorString"}
293+
errorString exist and contains error message only when errorFlag is
294+
True
295+
296+
"""
297+
response = {"errorFlag":False}
298+
resp = GetDataCollectionGroup(root)
299+
if resp["errorFlag"]:
300+
# Create Structural Models Group and add data shape based on project extents
301+
dcGroup = root.createGroup("DataCollection")
302+
else:
303+
dcGroup = resp["value"]
304+
305+
# Note drillholes use a different group node "Drillholes" hence we cannot use SetObservations function
306+
resp = GetDrillholesGroup(root)
307+
if resp["errorFlag"]:
308+
group = dcGroup.createGroup("Drillholes")
309+
group.createDimension("index",None)
310+
drillholeObservationType_t = group.createCompoundType(LoopProjectFile.drillholeObservationType,'drillholeObservation')
311+
group.createVariable('drillholeObservations',drillholeObservationType_t,('index'),zlib=True,complevel=9)
312+
else:
313+
group = resp["value"]
314+
315+
if group:
316+
drillholeObservationsLocation = group.variables['drillholeObservations']
317+
if append: index = group.dimensions['index'].size
318+
else: index = 0
319+
for i in data:
320+
drillholeObservationsLocation[index] = i
321+
index += 1
322+
else:
323+
errStr = "(ERROR) Failed to Create contacts group for contact setting"
324+
if verbose: print(errStr)
325+
response = {"errorFlag":True,"errorString":errStr}
326+
return response
327+
328+
#Extract contacts
264329
def GetContacts(root, indexList=[], indexRange=(0,0), keyword="", verbose=False):
265330
response = {"errorFlag":False}
331+
# Note contacts use a different group node "Contacts" hence we cannot use GetObservations function
266332
resp = GetContactsGroup(root)
267333
if resp["errorFlag"]: response = resp
268334
else:
@@ -307,6 +373,53 @@ def GetContacts(root, indexList=[], indexRange=(0,0), keyword="", verbose=False)
307373
response = {"errorFlag":True,"errorString":errStr}
308374
return response
309375

376+
#Extract drillhole observaions
377+
def GetDrillholeObservations(root, indexList=[], indexRange=(0,0), keyword="", verbose=False):
378+
response = {"errorFlag":False}
379+
# Note contacts use a different group node "Contacts" hence we cannot use GetObservations function
380+
resp = GetDrillholesGroup(root)
381+
if resp["errorFlag"]: response = resp
382+
else:
383+
group = resp["value"]
384+
data = []
385+
# Select all option
386+
if indexList==[] and len(indexRange) == 2 and indexRange[0] == 0 \
387+
and indexRange[1] == 0 and keyword == "":
388+
# Create list of observations as:
389+
# ((easting,northing,altitude),dipdir,dip,formation,layer)
390+
for i in range(0,group.dimensions['index'].size):
391+
data.append((group.variables.get('drillholeObservations')[i]))
392+
response["value"] = data
393+
# Select based on keyword and list of indices option
394+
elif keyword != "" and indexList != []:
395+
for i in indexList:
396+
if int(i) >= 0 and int(i) < group.dimensions['index'].size \
397+
and group.variables.get('layer')[i] == keyword:
398+
data.append((group.variables.get('drillholeObservations')[i]))
399+
response["value"] = data
400+
# Select based on keyword option
401+
elif keyword != "":
402+
for i in range(0,group.dimensions['index'].size):
403+
if group.variables.get('layer')[i] == keyword:
404+
data.append((group.variables.get('drillholeObservations')[i]))
405+
response["value"] = data
406+
# Select based on list of indices option
407+
elif indexList != []:
408+
for i in indexList:
409+
if int(i) >= 0 and int(i) < group.dimensions['index'].size:
410+
data.append((group.variables.get('drillholeObservations')[i]))
411+
response["value"] = data
412+
# Select based on indices range option
413+
elif len(indexRange) == 2 and indexRange[0] >= 0 and indexRange[1] >= indexRange[0]:
414+
for i in range(indexRange[0],indexRange[1]):
415+
if int(i) >= 0 and int(i) < group.dimensions['index'].size:
416+
data.append((group.variables.get('drillholeObservations')[i]))
417+
response["value"] = data
418+
else:
419+
errStr = "Non-implemented filter option"
420+
if verbose: print(errStr)
421+
response = {"errorFlag":True,"errorString":errStr}
422+
return response
310423

311424
#Set data collection (map2loop) configuration settings
312425
def SetConfiguration(root, data, verbose=False):

LoopProjectFile/ExtractedInformation.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ def GetStratigraphicInformationGroup(rootGroup,verbose=False):
4242
else:
4343
return LoopProjectFileUtils.GetGroup(resp["value"],"StratigraphicInformation",verbose)
4444

45+
def GetDrillholeDescriptionGroup(rootGroup,verbose=False):
46+
response = {"errorFlag":False}
47+
resp = GetExtractedInformationGroup(rootGroup,verbose)
48+
if resp["errorFlag"]:
49+
return resp
50+
else:
51+
return LoopProjectFileUtils.GetGroup(resp["value"],"DrillholeInformation",verbose)
52+
4553
def GetEventLogGroup(rootGroup,verbose=False):
4654
response = {"errorFlag":False}
4755
resp = GetExtractedInformationGroup(rootGroup,verbose)
@@ -246,6 +254,91 @@ def GetStratigraphicLog(root, indexList=[], indexRange=(0,0), verbose=False):
246254
response = {"errorFlag":True,"errorString":errStr}
247255
return response
248256

257+
# Set drillhole log
258+
def SetDrillholeLog(root, data, append=False, verbose=False):
259+
"""
260+
**SetDrillholeLog** - Saves a list of drillholes in (collarId, name,
261+
location(X,Y,Z)) format into the netCDF Loop Project File
262+
263+
Parameters
264+
----------
265+
rootGroup: netCDF4.Group
266+
The root group node of a Loop Project File
267+
data: list of (collarId, name, location)
268+
The data to save
269+
append: bool
270+
Flag of whether to append new data to existing log
271+
verbose: bool
272+
A flag to indicate a higher level of console logging (more if True)
273+
274+
Returns
275+
-------
276+
dict {"errorFlag","errorString"}
277+
errorString exist and contains error message only when errorFlag is
278+
True
279+
280+
"""
281+
response = {"errorFlag":False}
282+
resp = GetExtractedInformationGroup(root)
283+
if resp["errorFlag"]:
284+
# Create Extracted Information Group as it doesn't exist
285+
eiGroup = root.createGroup("ExtractedInformation")
286+
else:
287+
eiGroup = resp["value"]
288+
289+
resp = GetStratigraphicInformationGroup(root)
290+
if resp["errorFlag"]:
291+
siGroup = eiGroup.createGroup("DrillholeInformation")
292+
siGroup.createDimension("index",None)
293+
drillholeDescriptionType_t = siGroup.createCompoundType(LoopProjectFile.drillholeDescriptionType,'DrillholeDescription')
294+
siGroup.createVariable('drillholeDescriptions',drillholeDescriptionType_t,('index'),zlib=True,complevel=9)
295+
else:
296+
siGroup = resp["value"]
297+
298+
if siGroup:
299+
drillholeDescriptionsLocation = siGroup.variables['drillholeDescriptions']
300+
index = 0
301+
if append: index = siGroup.dimensions['index'].size
302+
for i in data:
303+
drillholeDescriptionsLocation[index] = i
304+
index += 1
305+
else:
306+
errStr = "(ERROR) Failed to create drillhole description log group for setting drillhole data"
307+
if verbose: print(errStr)
308+
response = {"errorFlag":True,"errorString":errStr}
309+
return response
310+
311+
def GetDrillholeLog(root, indexList=[], indexRange=(0,0), verbose=False):
312+
response = {"errorFlag":False}
313+
resp = GetDrillholeDescriptionGroup(root)
314+
if resp["errorFlag"]: response = resp
315+
else:
316+
siGroup = resp["value"]
317+
data = []
318+
# Select all option
319+
if indexList==[] and len(indexRange) == 2 and indexRange[0] == 0 \
320+
and indexRange[1] == 0:
321+
# Select all
322+
for i in range(0,siGroup.dimensions['index'].size):
323+
data.append((siGroup.variables.get('drillholeDescriptions')[i]))
324+
response["value"] = data
325+
# Select based on list of indices option
326+
elif indexList != []:
327+
for i in indexList:
328+
if int(i) >= 0 and int(i) < siGroup.dimensions['index'].size:
329+
data.append((siGroup.variables.get('drillholeDescriptions')[i]))
330+
response["value"] = data
331+
# Select based on indices range option
332+
elif len(indexRange) == 2 and indexRange[0] >= 0 and indexRange[1] >= indexRange[0]:
333+
for i in range(indexRange[0],indexRange[1]):
334+
if int(i) >= 0 and int(i) < siGroup.dimensions['index'].size:
335+
data.append((siGroup.variables.get('drillholeDescriptions')[i]))
336+
response["value"] = data
337+
else:
338+
errStr = "Non-implemented filter option"
339+
if verbose: print(errStr)
340+
response = {"errorFlag":True,"errorString":errStr}
341+
return response
249342

250343
def SetEventRelationships(root, data, append=False, verbose=False):
251344
response = {"errorFlag":False}

0 commit comments

Comments
 (0)