Skip to content

Getting Started with Python Scripts

VGroshkov edited this page May 11, 2026 · 2 revisions

GeoHammer can run Python scripts directly on the currently opened survey file. Scripts are useful for tasks that are easier to express in Python than in the built-in processing chain — automated anomaly marking, gradient and gradiometer calculations, distance / depth / weight estimation, data correction, and so on. When a script finishes, its results (new columns, marks or filtered values) appear in the chart and on the map straight away.

Scripts live in the scripts folder next to the GeoHammer executable. Each script is a pair of files with the same base name: a .py file with the code and a small .json file that tells GeoHammer how to show the script in the interface.



Running a script

  1. Open a CSV or SEG-Y file in GeoHammer ("Open files" or drag & drop).
  2. Select the file in the file list so that its chart is active.
  3. In the right-hand processing panel switch to the "Scripts" tab.
  4. Pick a script from the "Select script" drop-down.
Screenshot 2026-04-21 at 11 17 26
  1. Fill in the parameters shown below the drop-down. Required fields are marked with a * next to their label, and the last values you used are pre-filled automatically.
  2. Click "Apply" to run the script on the selected file, or "Apply to All" to run it on every loaded file of the same sensor type.

While the script is running, the bottom status bar shows the last lines of its output, and the Scripts panel is locked until it finishes. New or modified columns, marks and traces are reloaded into the chart automatically.

Always save your file before running a script that adds new columns, so you can roll back to the original data if needed.



Script parameters

Each script defines its own parameters, but the fields always come from a short list of types:

  • Text fields — for names and free text.
  • Numeric fields — for whole numbers or decimals (e.g. a threshold in nT). May enforce a min/max range — values outside the range are rejected when "Apply" is pressed.
  • Check boxes — for on/off options such as "Override existing marks".
  • Folder pickers — open a folder dialog with the "Select" button. When left empty, most scripts save their output next to the input file.
  • Column selectors — drop-downs populated with the columns currently available in the opened CSV. They refresh automatically when you filter or process the data, so new columns like TMI_LPF appear as soon as they are created.
  • Enum drop-downs — a fixed list of allowed string options defined in the script's metadata. The first option is selected by default; on subsequent runs the previously chosen value is restored.


Script visibility

The Scripts drop-down is filtered by the current file's template. Each script declares the templates (MagNIMBUS, MagDrone R1/R3/R4, Medusa, SEG-Y, …) it was designed for, and only scripts that match the opened file appear in the list.

A script can also declare the special wildcard "csv" in its templates array. Scripts marked this way show up for any CSV file, regardless of its specific template name — useful for generic tools like decimation or column arithmetic. The wildcard can be combined with specific template names (for example ["csv", "MagNIMBUS"]) to cover both the generic CSV case and any non-CSV templates the script also supports.

If a script you expect to see is missing, open a file of the template it was made for, or add the template (or "csv") to the script's .json file. If the drop-down is empty, it usually means the current file has no template associated with it — see Template Format Specification for how templates are assigned.



Dependencies

The first time a script is executed, GeoHammer inspects the import statements in its .py file and installs any missing Python packages with pip. A requirements.txt file is not needed — the list is detected automatically.

A few things worth knowing:

  • Dependencies are installed into the Python interpreter selected in Settings → Python Executor Path, not into GeoHammer itself. When a virtual environment (venv, conda, …) is configured, the packages are placed inside that environment and nothing else on the system is touched.
  • An internet connection is only required on the first run. On subsequent runs the packages remain installed and the script starts immediately.
  • If a package is already present in the selected Python environment, the installation step is skipped and the existing version is used.
  • If the Python environment is broken — for example, a package is listed as installed but fails to import because of a partial upgrade, a mismatched binary, or a corrupted install — GeoHammer detects this after the regular install step and offers to reinstall the full set of script dependencies from scratch. Confirming the prompt re-runs pip install with --force-reinstall --no-cache-dir, which replaces every package the script needs with a clean copy and usually clears the issue without any manual intervention.
  • If installation fails (for example on a machine without internet), the log explains what happened. Missing libraries can then be installed manually — for example python -m pip install numpy pandas scipy — and the script can be re-run.

Most of the built-in scripts rely on NumPy, Pandas and SciPy. The RSS processing script additionally uses ObsPy for SEG-Y input/output, and some scripts use pyproj for coordinate projection.



Working with your data

Scripts never modify your original file directly. When "Apply" is pressed, GeoHammer makes a temporary copy of the currently opened file and hands that copy to the script. The script reads the copy, writes its results back into it, and only after it finishes does GeoHammer reload the modified copy into the chart.

Under the hood, every run follows the same pipeline:

  1. Dependency check. GeoHammer scans the script's import statements and makes sure every required package is available in the configured Python environment. Missing packages are installed with pip; broken environments trigger the force-reinstall flow described in Dependencies.
  2. Temporary copy. The currently opened file is saved to a fresh temporary file in the system temp directory, keeping the original name and extension. This copy — not the original — is the one the script will see.
  3. Command build. GeoHammer assembles a command line of the form <python> <scripts/script.py> <temp file> [--key value | --flag], where each parameter value from the Scripts panel is appended as --name value, and each boolean option is appended as a bare --flag only when it is checked.
  4. Process launch. The command is executed as a separate Python process. Its standard output is streamed to the bottom status bar, and the Scripts panel stays locked until the process exits. Cancelling the run interrupts the process and aborts the pipeline.
  5. Reload on success. When the process exits with code 0, GeoHammer reads the temporary file back and replaces the in-memory copy of the opened file with its contents, refreshing the chart, map and column list. If the exit code is non-zero, the temporary file is discarded and an error dialog with the last lines of output is shown.
  6. Cleanup. The temporary file is deleted once its contents have been reloaded (or immediately, on failure).

As a result:

  • If a script crashes, the file on disk is left untouched.
  • A script cannot modify any file in the project other than the copy it was given.
  • The changes that appear in the chart after a successful run are not saved to disk automatically — use "Save" or "Save to..." as usual to keep them.

Some scripts (for example the distance / depth / weight estimation scripts) additionally write a separate targets CSV into the folder selected in the "Output folder" parameter. That file is written directly and appears in the chosen folder as soon as the script completes.



Adding a new script

A custom script can be added to GeoHammer without rebuilding the application.

  1. Place my_script.py in the scripts/ folder next to GeoHammer. The script must accept the input file as its first argument and any other inputs as --name value or --flag, then write the result back to the same file path.

    # my_script.py
    import argparse
    import pandas as pd
    
    parser = argparse.ArgumentParser()
    parser.add_argument("file_path")
    parser.add_argument("--column", required=True)
    parser.add_argument("--threshold", type=float, required=True)
    parser.add_argument("--window", type=int, required=True)
    parser.add_argument("--algorithm", required=True)
    parser.add_argument("--clear-marks", action="store_true")
    args = parser.parse_args()
    
    df = pd.read_csv(args.file_path)
    # ... process df ...
    df.to_csv(args.file_path, index=False)
  2. Create a matching my_script.json in the same folder. It tells GeoHammer how the script should appear in the interface:

    {
      "filename": "my_script.py",
      "display_name": "My custom script",
      "parameters": [
        {
          "name": "column",
          "display_name": "Column name",
          "type": "COLUMN_NAME",
          "default_value": "TMI",
          "required": true
        },
        {
          "name": "threshold",
          "display_name": "Threshold (nT)",
          "type": "DOUBLE",
          "default_value": 5.0,
          "required": true
        },
        {
          "name": "window",
          "display_name": "Window size",
          "type": "INTEGER",
          "default_value": 10,
          "min": 2,
          "max": 500,
          "required": true
        },
        {
          "name": "algorithm",
          "display_name": "Algorithm",
          "type": "ENUM",
          "enum_values": ["MEDIAN", "MEAN", "INTERPOLATED"],
          "default_value": "MEDIAN",
          "required": true
        },
        {
          "name": "clear-marks",
          "display_name": "Override existing marks",
          "type": "BOOLEAN",
          "default_value": false,
          "required": false
        }
      ],
      "templates": ["csv", "MagNIMBUS"]
    }

    The top-level fields of the metadata file are:

    Field Type Required Description
    filename string yes Name of the .py file in the same scripts/ folder. Must match exactly, including the extension.
    display_name string yes Text shown in the "Select script" drop-down and as the title of the parameters block.
    parameters array yes Ordered list of parameter definitions. The order here is the order used in the Scripts panel. An empty array is allowed for scripts that take no options.
    templates array of strings yes File templates the script applies to (for example MagNIMBUS, MagDrone R3, Medusa). Use sgy for SEG-Y files, or the wildcard csv to make the script available for any CSV file regardless of its specific template. The wildcard can be combined with template names (e.g. ["csv", "MagNIMBUS"]). A script only appears in the drop-down when the opened file matches at least one of these entries.

    Each entry in parameters is an object with the following fields:

    Field Type Required Description
    name string yes Command-line flag name. GeoHammer passes the value as --<name> <value> (or just --<name> for boolean flags), so this should match the argument name declared in the Python script.
    display_name string yes Label shown next to the field in the Scripts panel.
    type enum yes One of STRING, INTEGER, DOUBLE, BOOLEAN, FILE_PATH, FOLDER_PATH, COLUMN_NAME, ENUM. Controls which UI control is rendered (text field, numeric field, check box, file / folder picker, column drop-down, or fixed-list drop-down) and how the value is validated.
    default_value same type as type no Initial value shown the first time the script is opened. Subsequent runs pre-fill the field with the last value you used instead. For ENUM parameters, the value must be one of enum_values; if it is missing or unknown, the first entry in enum_values is used as the default.
    required boolean no (defaults to false) When true, the field label is suffixed with * and "Apply" stays disabled until the field has a value.
    enum_values array of strings required for ENUM List of allowed string options for an ENUM parameter. Rendered as a drop-down in the Scripts panel. The selected value is passed to the script as --<name> <value>. Ignored for non-ENUM types.
    min number no Lower bound for INTEGER and DOUBLE parameters. When set, "Apply" rejects values below this bound with an error message. The allowed range is shown as a hint next to the field.
    max number no Upper bound for INTEGER and DOUBLE parameters. When set, "Apply" rejects values above this bound with an error message. The allowed range is shown as a hint next to the field.
  3. Open a file of the template listed in the metadata — the new script appears in the drop-down and is ready to use. A restart of GeoHammer is not required.

Tip: Reusable helpers can be placed in script_utils.py in the same folder and imported from any script.



Troubleshooting

Symptom What to check
"Python path is not found" Open Settings and make sure Python Executor Path points to a valid Python 3 interpreter.
Script fails with ModuleNotFoundError The required library is missing from the selected Python environment. Re-run the script (GeoHammer will try to install again) or install the library manually with python -m pip install <package>.
The Scripts drop-down is empty The opened file has no matching template. Open a file of a supported sensor, or add the template to the script's .json.
Script exits with an error The error dialog shows the last lines of the script output, which usually point at the cause. The full log is visible in the bottom status bar while the script is running.
"Script is already running for this file" GeoHammer runs only one script at a time per file. Wait for the current run to finish.
A new script does not appear in the drop-down Make sure my_script.py and my_script.json live in the same scripts/ folder, the filename in the JSON matches the .py file name, and the current file's template is listed under templates.

Clone this wiki locally