Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Orca Uv Vis

ASecurity

Generate ORCA input files for TD-DFT UV-Vis calculations and parse/plot the resulting absorption spectrum. Use when the user asks about UV-Vis spectra, absorption spectra, TD-DFT calculations, excited state calculations in ORCA, or wants to plot results from an ORCA TD-DFT output file. Also trigger when the user mentions oscillator strengths, electronic transitions, or simulated UV-Vis.

199 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentpythongobashnodeapibackend

Works with

claude codeapi

Security Analysis

A96/100
mediumUses curl or wget to download content

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add Hello-QM/catgo-LRG --skill orca-uv-vis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Orca Uv Vis?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Orca Uv Vis
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hello-qm-orca-uv-vis/badge)](https://www.skillsdirectory.com/skills/hello-qm-orca-uv-vis)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: orca-uv-vis
description: Generate ORCA input files for TD-DFT UV-Vis calculations and parse/plot the resulting absorption spectrum. Use when the user asks about UV-Vis spectra, absorption spectra, TD-DFT calculations, excited state calculations in ORCA, or wants to plot results from an ORCA TD-DFT output file. Also trigger when the user mentions oscillator strengths, electronic transitions, or simulated UV-Vis.
---

# ORCA UV-Vis Calculation Pipeline

This skill covers two stages: generating an ORCA input file for a TD-DFT calculation, and post-processing the output to plot a Gaussian-broadened UV-Vis absorption spectrum.

**Scope:** Input generation, local post-processing, and (optionally) HPC submission via the CatGo workflow engine. The "Submitting to HPC" section below covers the proven Expanse flow. If the user is running on their own non-CatGo infrastructure, just generate the input file from the template in Stage 1 and skip the submission section.

**Target version:** ORCA 6.x. Output block layout in ORCA 5 is close but not identical; the parser below is written against the ORCA 6 format used by CatGo's own parser (`server/catgo/utils/orca_output.py::OrcaUvVisOutput`).

## Stage 1: Input Generation

Before generating the input file, ask the user for:

- XYZ geometry file path (assume already optimized; if the user hasn't optimized, route them to `orca-opt` first)
- Solvent for CPCM (e.g. hexane, water, ethanol, dichloromethane, acetonitrile)
- Charge and multiplicity (default to `0 1` if not specified)

Generate an ORCA input file with these fixed settings:

- Functional: `CAM-B3LYP`
- Basis set: `DEF2-TZVP`
- Full TD-DFT (not TDA)
- 30 roots
- CPCM solvation inline on the keyword line
- No RI / auxiliary basis
- No special SCF convergence tricks

Template:

```
!CAM-B3LYP DEF2-TZVP CPCM(HEXANE)
%TDDFT
   NROOTS   30
END
%output jsongbwfile True jsonpropfile True end
*XYZFILE 0 1 geometry.xyz
```

Substitute the user's solvent, charge, multiplicity, and XYZ path. If the user provides inline coordinates instead of a file, use `* XYZ <charge> <mult>` followed by the coordinates and close with `*`.

The `%output ... end` line makes ORCA emit the JSON files OPI's `Output.parse()` consumes during post-processing (Stage 2). Keep it.

### Building the `%tddft` block with OPI

OPI's `BlockTddft` exposes every TD-DFT knob (`nroots, iroot, irootmult, maxdim, maxiter, etol, rtol, tda, lrcpcm, cpcmeq, donto, saveunrnatorb, spinflip, soc, socgrad, triplets, ...`) as a typed Pydantic field. Bad keys raise at construction.

The catgo backend builds the route line, `%pal`, `%maxcore`, charge/multiplicity, and geometry from node params — it does **not** emit a `%TDDFT` block of its own. So OPI only contributes the `%tddft` and `%output` blocks here, which we paste into `extra_blocks` as text. Do **not** use `Calculator.write_input()` — that writes a full input file and would duplicate the route line / pal / geometry the backend already emits.

```python
from opi.input.blocks import BlockTddft, BlockOutput

tddft_block = BlockTddft(nroots=30, tda=False, triplets=False, donto=True)
output_block = BlockOutput(jsongbwfile=True, jsonpropfile=True)

extra_blocks_text = tddft_block.format_orca() + "\n" + output_block.format_orca()
# Pass extra_blocks_text into the node's `extra_blocks` param.
```

`format_orca()` emits exactly one `%...end` block per call. The result for the snippet above is:

```
%tddft
    nroots 30
    tda False
    donto True
    triplets False
end
%output
    jsonpropfile True
    jsongbwfile True
end
```

TD-DFT with 30 roots at def2-TZVP is expensive — tell the user this is a heavy calculation and that they should expect to run it on a cluster or at least overnight on a workstation, not on a laptop.

## Submitting to HPC (Expanse) — proven flow

Use this when the user wants the CatGo workflow engine to run the TD-DFT job
on Expanse. Skip if they only want the input file.

> **Use `catgo_workflow` (graph-based), NOT `catgo_workflow_engine` (task-based).**
> The graph-based tool auto-captures the viewer structure on `create`. Task-based
> `add_task` doesn't, so jobs fail with "No input structure provided". Param keys
> differ: graph-based uses `method`/`basis`, task-based uses `orca_method`/`orca_basis`.

### 1. Confirm structure is loaded and find session_id

```json
catgo_view(action: "get_state")
```

```bash
curl -s http://localhost:8000/api/hpc/connections
```

Copy the `session_id` for `host: login.expanse.sdsc.edu`.

### 2. Create the workflow

```json
catgo_workflow(action: "create", name: "UV-Vis CAM-B3LYP TD-DFT")
```

### 3. Add the TD-DFT node

Use the `orca_uvvis` node type, which has dedicated TD-DFT params (`nroots`, `triplets`, `tda`, `donto`, `solvation`, `solvent`, `calc_type`, `aux_basis`) plus the standard `dispersion` field. **Do NOT use `extra_keywords` or `extra_blocks` — they are NOT read by the engine and are silently dropped.**

```json
catgo_workflow(action: "batch", workflow_id: "<wf_id>", operations: [
  {"op": "add_node", "node_type": "orca_uvvis", "label": "tddft",
   "params": {
     "software": "orca",
     "method": "CAM-B3LYP",
     "basis": "def2-TZVP",
     "calc_type": "tddft",
     "nroots": 30,
     "tda": false,
     "triplets": false,
     "donto": true,
     "solvation": "CPCM",
     "solvent": "hexane",
     "dispersion": "D4",
     "charge": 0,
     "multiplicity": 1,
     "num_cores": 16,
     "max_core_mb": 4000
   }},
  {"op": "connect", "from_id": "<structure_input_id>", "to_id": "tddft",
   "from_handle": "structure", "to_handle": "structure"}
])
```

### Canonical UV-Vis node params (verified against [server/workflow/engines/orca.py:244-268](server/workflow/engines/orca.py#L244-L268))

| Parameter | Default | Description |
|---|---|---|
| `method` | CAM-B3LYP | Functional |
| `basis` | def2-TZVP | Basis set |
| `dispersion` | (none) | `D4` \| `D3BJ` \| `D3` |
| `calc_type` | tddft | `tddft` or `steom` (STEOM-DLPNO-CCSD) |
| `nroots` | 10 | Number of excited states |
| `tda` | true | Tamm-Dancoff approximation; pass `false` for full TD-DFT |
| `triplets` | false | Compute triplet states |
| `donto` | false | Natural transition orbitals |
| `solvation` | none | `CPCM` \| `none` |
| `solvent` | water | Any ORCA-recognised solvent name |
| `aux_basis` | def2-TZVP/C | Aux basis (used by STEOM path) |
| `num_cores` / `max_core_mb` | 4 / 4000 | |

### 4. Run with the full HPC run_config

TD-DFT with 30 roots at def2-TZVP is heavy — bump `walltime` and use `shared`
or `compute` (debug caps at 30 min). Read `server/templates/orca_generic.sh`
and pass its contents as `default_template`.

```json
catgo_workflow(action: "run", workflow_id: "<wf_id>", run_config: {
  "execution_mode": "hpc",
  "default_session_id": "<expanse_session_id>",
  "base_work_dir": "/expanse/lustre/projects/sdp126/jyang25/ORCA/catgo",
  "default_job_params": {
    "nodes": 1, "ntasks": 16, "cpus_per_task": 1,
    "walltime": "12:00:00", "partition": "shared"
  },
  "cluster_configs": {
    "<expanse_session_id>": {
      "account": "sdp126",
      "partition": "shared",
      "module_loads": "module load cpu/0.17.3b\nmodule load gcc/10.2.0/npcyll4\nexport PATH=$HOME/openmpi-4.1.8/bin:$PATH\nexport LD_LIBRARY_PATH=$HOME/openmpi-4.1.8/lib:$LD_LIBRARY_PATH",
      "orca_dir": "/home/jyang25/orca_6_1_1_RRP8",
      "default_template": "<contents of server/templates/orca_generic.sh>",
      "default_job_params": {
        "nodes": 1, "ntasks": 16, "cpus_per_task": 1,
        "walltime": "12:00:00", "partition": "shared"
      }
    }
  }
})
```

The local-scratch template stages I/O to `$TMPDIR/orca_$SLURM_JOB_ID` and copies
results back. Required on Expanse — Lustre kills ORCA's many-small-file I/O during
the 30-root TD-DFT response solver.

### 5. Monitor

```json
catgo_workflow(action: "status", workflow_id: "<wf_id>")
```

### 6. Pull files for post-processing

When status is COMPLETED, pull `ORCA.out` plus the JSON files OPI parses,
then run the parser/plotter from Stage 2 below against the local copy:

```bash
mkdir -p ./local_run
for f in ORCA.out ORCA.property.json ORCA.json; do
  curl -s -X POST http://localhost:8000/api/hpc/files/read-content \
    -H 'Content-Type: application/json' \
    -d "{\"session_id\":\"<expanse_session_id>\",\"file_path\":\"<work_dir>/$f\"}" \
    > ./local_run/$f
done
```

### Submission gotchas

- `catgo_workflow_engine.add_task` doesn't auto-attach the viewer structure → "No input structure provided".
- `partition=workq` (Shaheen default) is invalid on Expanse → use `debug`/`shared`/`compute`.
- `partition=debug` capped at 30 min — TD-DFT/30-roots almost always needs more.
- Missing `account=sdp126` → "Invalid account or account/partition combination".
- Missing `module_loads` + `orca_dir` → `orca` not on PATH; the response solver silently produces nothing.
- After re-connecting to Expanse, the session_id changes — re-discover via `/api/hpc/connections` and update both `default_session_id` and the `cluster_configs` key.

## Stage 2: Post-Processing

### Reading the Spectrum via OPI

OPI surfaces the absorption spectrum as `output.results_properties.geometries[-1].absorption_spectrum` — a `list[Spectrum]` keyed by `representation` (`"Length"` / `"Velocity"`) and `pointgroup`. This replaces the regex parser entirely:

- The `rfind`-vs-`find` STEOM-DLPNO-CCSD workaround is unnecessary; the model returns one entry per (representation, pointgroup) and you pick the one you want.
- The "STEOM rows have state labels, TD-DFT rows don't" branch is unnecessary; both produce the same `Spectrum` shape.
- Bonus: ECD rotational strengths come for free at `geometries[-1].ecd_spectrum`.

`Spectrum.excitationenergies` is a list of rows; columns are unnamed in the model but the order for ORCA 6.1.1 is fixed at `[energy_eV, energy_cm, wavelength_nm, fosc, |mu|^2]`. The shared helper exposes this as `UVVIS_COLS`.

### Reference Parser and Plotter

```python
import sys
sys.path.insert(0, ".claude/skills")  # for the _shared helper
import numpy as np
import matplotlib.pyplot as plt
from _shared.orca_opi import parse_local, UVVIS_COLS


def parse_orca_tddft(work_dir="./local_run"):
    out = parse_local(work_dir)
    spectra = out.results_properties.geometries[-1].absorption_spectrum
    if not spectra:
        raise ValueError("No absorption_spectrum block found — check ORCA.property.json")
    # Prefer length representation; fall back to whatever's first.
    target = next((s for s in spectra if s.representation == "Length"), spectra[0])

    wl_col = UVVIS_COLS["wavelength_nm"]
    f_col = UVVIS_COLS["fosc"]
    wavelengths = np.array([row[wl_col] for row in target.excitationenergies])
    fosc = np.array([row[f_col] for row in target.excitationenergies])
    return wavelengths, fosc


def gaussian(x, center, height, sigma=15):
    return height * np.exp(-0.5 * ((x - center) / sigma) ** 2)


def plot_uv_vis(wavelengths, fosc, output_png="uv_vis_spectrum.png"):
    x = np.linspace(200, 800, 2000)
    spectrum = sum(gaussian(x, w, f) for w, f in zip(wavelengths, fosc))
    peak = spectrum.max()
    if peak > 0:
        spectrum = spectrum / peak

    fig, ax = plt.subplots(figsize=(8, 5))
    ax.plot(x, spectrum, color="#2563eb", linewidth=1.5, label="Broadened")
    f_peak = fosc.max() if fosc.size and fosc.max() > 0 else 1.0
    ax.vlines(wavelengths, 0, fosc / f_peak, color="#ef4444", alpha=0.7, label="Transitions")
    ax.set_xlabel("Wavelength (nm)")
    ax.set_ylabel("Normalized Absorbance")
    ax.set_xlim(200, 800)
    ax.set_ylim(0, 1.05)
    ax.legend(loc="upper right", frameon=False)
    fig.tight_layout()
    fig.savefig(output_png, dpi=150)
    print(f"Spectrum saved to {output_png}")


if __name__ == "__main__":
    work_dir = sys.argv[1] if len(sys.argv) > 1 else "./local_run"
    png_name = sys.argv[2] if len(sys.argv) > 2 else "uv_vis_spectrum.png"
    wl, f = parse_orca_tddft(work_dir)
    plot_uv_vis(wl, f, png_name)
```

### Viewing the spectrum in the IDE

After `plot_uv_vis(...)` writes the PNG, surface it inline with the shared helper:

```python
from _shared.orca_opi import show_png
show_png("uv_vis_spectrum.png", "UV-Vis spectrum")
# prints `![UV-Vis spectrum](uv_vis_spectrum.png)`
```

Then **reply to the user with that markdown link** so Claude Code renders the figure inline in chat.

### Plotting Defaults

- Wavelength grid: 200–800 nm, 2000 points
- Gaussian broadening: σ = 15 nm in wavelength space (simple and visually reasonable for most organic chromophores; call out that eV-space broadening is more physically correct if the user cares about vibronic lineshapes)
- Envelope normalized to max = 1
- Sticks normalized by the maximum oscillator strength so they sit on the same axis as the envelope
- Figure size 8×5, DPI 150
- Colors: envelope `#2563eb` (blue), sticks `#ef4444` (red) — matches CatGo's red-TS / blue-accent conventions

### Requesting eV on the x-axis

If the user asks for eV instead of nm, convert via `E_eV = 1240 / wavelength_nm` and rebuild the x-grid from (e.g.) 1.5–6.5 eV. Broadening σ of ~0.3 eV is a sensible default in eV space.

Attribution

Hello-QMHello-QM
View sourceMore from Hello-QM →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →