Skip to content

Commit

Permalink
docs: adding m2l template
Browse files Browse the repository at this point in the history
  • Loading branch information
lachlangrose committed Feb 2, 2024
1 parent 48c1093 commit b2f8ea0
Show file tree
Hide file tree
Showing 2 changed files with 299 additions and 0 deletions.
297 changes: 297 additions & 0 deletions docs/source/_static/m2l_code_template.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "726a6e3b",
"metadata": {},
"source": [
"# Template for Map2Loop \n",
"<t> This is a basic template for the calling code that can be used to run Map2Loop. The output of the program will be a '.loop3d' file, which can be passed directly to LoopStructural to produce your 3D model. \n",
" <p> An attempt has been made to explain the code as much as possible. In your own notebook,\n",
" you may want to get rid of the explanatory comments (any lines starting with a '#', and text cells). This won't affect the program's functionality. "
]
},
{
"cell_type": "markdown",
"id": "1668d385",
"metadata": {},
"source": [
"## Before You Begin\n",
"<t> In order to run map2loop you will need the following files: \n",
" <br> 1. Polygon shapefile containing your lithologies\n",
" <br> 2. LineString shapefile containing your linear features (e.g. faults)\n",
" <br> 3. Point data shapefile containing orientation data\n",
" <br> 4. hjson file defining the attribute names used in your shapefiles\n",
" <p> If you need help setting up these files please refer to the map2loop examples which provide a step-by-step guide. "
]
},
{
"cell_type": "markdown",
"id": "03178a81",
"metadata": {},
"source": [
"## Setting up your notebook\n",
"<t> In order for your map2loop code to funtion correctly, you need to import all of the neccessary python libraries. In simple terms, imports allow different code modules to speak to eachother."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b4144cb3",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from map2loop.project import Project\n",
"from map2loop.m2l_enums import VerboseLevel\n",
"from map2loop.m2l_enums import Datatype\n",
"from map2loop.sampler import SamplerSpacing, SamplerDecimator\n",
"from map2loop.sorter import SorterUseHint, SorterUseNetworkX, SorterAgeBased, SorterAlpha\n",
"import time"
]
},
{
"cell_type": "markdown",
"id": "63c8a41f",
"metadata": {},
"source": [
"### Naming your .loop3d output file \n",
"<t> This format specifies that the output file will be saved in a new folder within the current directory (where ever you have saved your notebook). The new folder will be named whatever you specify in line 6 (<em> <strong>\"insert_output_folder_name_here\"</strong></em>). The generated loop3d file will be called <em> <strong>\"local_source.loop3d\"</strong></em>. \n",
"</t>\n",
"#### CHANGE: \n",
" <t> <em>(line 6): <strong>\"insert_output_folder_name_here\"</strong></em> to a project relevant name"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef6c73e1",
"metadata": {},
"outputs": [],
"source": [
"from datetime import datetime\n",
"nowtime=datetime.now().isoformat(timespec='minutes') \n",
"model_name=nowtime.replace(\":\",\"-\").replace(\"T\",\"-\")\n",
"\n",
"#The next line specifies the name of the output file and the folder containing all the data\n",
"loop_project_filename = os.path.join(\"insert_output_folder_name_here\", \"local_source.loop3d\")\n",
"\n",
"t0 = time.time()"
]
},
{
"cell_type": "markdown",
"id": "061c05aa",
"metadata": {},
"source": [
"### Defining the Model Extents \n",
"<t> You'll need to specify the extent of the area you want to model. This is defined as minimum and maximum x and y coordinates, where x is the latitude and y is the longitude. You also need to state the bounds of the model along the z axis. This is given as the number of meters above and below the surface that will be modeled. </t>\n",
"#### CHANGE: \n",
"<t>The numeric values assigned to variables accross lines 2 to 7, to match your region of interest."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cde7bc08",
"metadata": {},
"outputs": [],
"source": [
"bounding_box = {\n",
" \"minx\": 602635, #minimum latitude\n",
" \"miny\": 5852551, #minimum longitude\n",
" \"maxx\": 642618, #maximum latitude\n",
" \"maxy\": 5908499, #maximum longitude\n",
" \"base\": -2000, #meters modeled below the surface\n",
" \"top\": 1000, #meters modeled above the surface\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "5f363e90",
"metadata": {},
"source": [
"### Creating a Project Instance\n",
"<t> This is where all of the required files (e.g. shape files) are passed to map2loop.</t>\n",
"#### NOTE\n",
"<t> When passing local files to map2loop you need to specify the full file path. If you get an error concerning the path, you may need to use double backslashes in the path specification (e.g <em><strong> geology_filename = \"C:\\\\Users\\\\Bob\\\\Documents\\\\lithology.shp\",</strong> </em>) alternatively you can use a raw string command and continue to use single backslashes (e.g <em><strong>geology_filename = r\"C:\\Users\\Bob\\Documents\\lithology.shp\",</strong></em>)\n",
"</t>\n",
"#### CHANGE:\n",
"<t>Fill in the appropriate paths described in each string from lines 2 to 7.\n",
" <p> <em>(line 8): <strong>clut_filename</strong></em> is an <u>optional</u> variable. If you would like to assign colours to each unit using a csv file you'll need to specify the full path here, otherwise leave an empty string (i.e <strong><em>clut_filename = '',</em></strong> )\n",
" <p> <em>(line 9):</em> <strong><em>clut_file_legacy =True,</em></strong> if using legacy variable names in your hjson file (map2loop-2 and prior), <strong><em>clut_file_legacy = False, </em></strong>if you are using the current map2loop variable names in your hjson file (map2loop-3 onwards)\n",
" <p> <em>(line 11 and 14):</em> This is the folder name you specified in the \"Naming your .loop3d output file\" section above\n",
" <p> <em>(line 12):</em> Specify the projection (CRS) that your shapefiles use (e.g. <strong><em>working_projection = \"EPSG:28354\",</em></strong>)\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c7e96e35",
"metadata": {},
"outputs": [],
"source": [
"proj = Project( \n",
" geology_filename = 'enter the full path of your lithology polygon shape file here',\n",
" fault_filename = 'enter the full path of your linear features shape file here',\n",
" fold_filename = 'enter the full path of your linear features shape file here',\n",
" structure_filename = 'enter the full path of your orientation point data shape file here',\n",
" dtm_filename = 'au', #if the area is in Australia you can leave this as 'au', otherwise specify full path to DTM\n",
" config_filename = 'enter the full path of your hjson config file here',\n",
" clut_filename = 'OPTIONAL, enter the full path of the csv file specifying unit colours',\n",
" clut_file_legacy = True,\n",
" verbose_level = VerboseLevel.ALL, #can set this to VerboseLevel.NONE if you don't wan't any feedback from the program\n",
" tmp_path = \"insert_output_folder_name_here\", \n",
" working_projection = \"EPSG:code\",\n",
" bounding_box = bounding_box,\n",
" loop_project_filename = os.path.join(\"insert_output_folder_name_here\", \"local_source.loop3d\")\n",
")"
]
},
{
"cell_type": "markdown",
"id": "21923d03",
"metadata": {},
"source": [
"### Setting Sampling Distances\n",
"<t> You'll need to provide samping distances and minimums so that map2loop knows what resolution you'd like to model in.\n",
" </t>\n",
" #### CHANGE: \n",
" The numeric values for each of the following lines need to be altered to suit your case study.\n",
" <p> <em>(line 1): </em> sets the minimum fault length in meters. Map2Loop will ignore any faults below this numeric value\n",
" <p> <em>(line 2):</em> sets the sample spacing for geological contacts in meters\n",
" <p> <em>(line 3): </em>sets the sample decimator for structural measurements to sample every nth measurement\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "10c213ea",
"metadata": {},
"outputs": [],
"source": [
"proj.set_minimum_fault_length(2000.0)\n",
"proj.set_sampler(Datatype.GEOLOGY, SamplerSpacing(100.0))\n",
"proj.set_sampler(Datatype.STRUCTURE, SamplerDecimator(100))"
]
},
{
"cell_type": "markdown",
"id": "67dd9872",
"metadata": {},
"source": [
"### Selecting a Stratigraphic Column Sorter \n",
"<t> There are several different sorting algorithms that map2loop can use to calculate the stratigraphic column. Choosing the 'best' of these sorters may take some trial and error. There is also the option to allow map2loop to choose the best sorter, or to specify the correct stratigraphic sequence (see below or refer to the map2loop examples for more information). </t>\n",
" \n",
"<p> The commands for the different sorters you can choose from are listed below. Note if you want map2loop to select the best one, skip this step: </p>\n",
" \n",
" <p> <em><strong> proj.set_sorter(SorterUseNetworkX()) </strong></em>\n",
" <br> This sorts units based on their relationships, using a topological graph sorting algorithm. </p>\n",
" \n",
" <p> <em><strong> proj.set_sorter(SorterAgeBased()) </strong></em>\n",
" <br> This sorts units based on their minimum and maximum ages (if specified in the attributes table of the lithology shape file). </p>\n",
" \n",
" <p> <em><strong> proj.set_sorter(SorterAlpha()) </strong></em>\n",
" <br>This sorts units based on their adjacency (the algorithm uses the number of neighbouring units to do this). </p>\n",
" \n",
" <p> <em><strong> proj.set_sorter(SorterBeta()) </strong></em> --NOTE THIS MAY NOT BE WORKING YET\n",
" <br>This sorts units based on their adjacency (the algorithm uses egde length to calculate the order of units).\n",
" \n",
"</t>\n",
"\n",
"### Running your map2loop program\n",
" <t> Once you've selected a sorter (optional), you will need to run the program. There are 2 options to do this, depending on whether or not you have used one of the above sorters.\n",
" <p> <strong> (Option 1): <em>proj.run_all(take_best=True)</em> </strong>\n",
" <br> This itterates through the different sorters and selects the best based on the maximum basal contact length. Use this option if you want map2loop to calculate the 'best' sorter.\n",
" <p> <strong> (Option 2): <em>proj.run_all(take_best=False)</em> </strong>\n",
" <br> Use this option if you implemented any of the above sorters. The False flag ensures that the specified sorting algorithm is used rather than the calculated 'best' option. \n",
" \n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dc57baad",
"metadata": {},
"outputs": [],
"source": [
"proj.set_sorter(SorterAlpha())\n",
"proj.run_all(take_best=False)\n",
"\n",
"t1 = time.time()"
]
},
{
"cell_type": "markdown",
"id": "9324fe78",
"metadata": {},
"source": [
"## Alternative: Using a User Defined Stratigraphic Column\n",
"<p> Alternatively, you can run the program with a user defined stratigraphic column. If you decide to do this, you'll need to define the stratigraphic column with the youngest unit at the top and the oldest at the bottom as shown in the code below. \n",
" <p> To run the program use the command in line 9 below.\n",
" \n",
"Skip the 'Selecting a Stratigraphic Column Sorter' and 'Running your map2loop program' sections above. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "506be2ee",
"metadata": {},
"outputs": [],
"source": [
" column = [\n",
" # youngest\n",
" 'youngest_unit',\n",
" 'middle_unit',\n",
" 'oldest_unit',\n",
" # oldest\n",
" ]\n",
" \n",
"proj.run_all(user_defined_stratigraphic_column=column)\n",
"\n",
"t1 = time.time()"
]
},
{
"cell_type": "markdown",
"id": "51931333",
"metadata": {},
"source": [
"## Next Steps\n",
"<t> The expected output from map2loop is a '.loop3d' file. You can then pass this file to Loop Structural to produce your 3D model. </t>\n",
"\n",
"#### Checking the Contents of your .loop3d file\n",
"<t>\n",
" <p> If you'd like to inspect your loop3d output file via terminal (e.g. Anaconda Prompt) you can do this with the command <strong><em>ncdump loop3d_file_name.loop3d</em></strong> (e.g. <em>ncdump local_source.loop3d</em>). Ensure that you're in the correct working directory (i.e wherever you saved the loop3d file). You can change directories using the <strong><em>'cd' </em></strong>command. \n",
" To use the ncdump tool, you'll need to ensure that you have <strong><em>netcdf4</em></strong> installed in your environment. You can check this by using the command <strong> <em>'conda list'</em></strong> in your Anaconda environment and then scroll through the applications to see if it is installed. <p>\n",
" <strong> Note </strong> that the output of ncdump will appear as text within the terminal."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 2 additions & 0 deletions docs/source/user_guide/m2l_code_template.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Template for Map2Loop
=====================

`CLICK HERE TO DOWLOAD NOTEBOOK <../_static/m2l_code_template.ipynb>`_

This is a basic template for the calling code that can be used to run
Map2Loop. The output of the program will be a ‘.loop3d’ file, which can
be passed directly to LoopStructural to produce your 3D model.
Expand Down

0 comments on commit b2f8ea0

Please sign in to comment.