SDK Examples
Real-world examples demonstrating OptixLog SDK features.
Basic Metric Logging
Log scalar values during your simulation:
import optixlog
with optixlog.run("basic_metrics", config={"method": "basic"}) as client:
for step in range(100):
loss = calculate_loss()
accuracy = calculate_accuracy()
result = client.log(step=step, loss=loss, accuracy=accuracy)
if result:
print(f"Step {step}: loss={loss:.4f}, accuracy={accuracy:.4f}")Image Logging with Matplotlib
Old Way (15+ lines of boilerplate)
import matplotlib.pyplot as plt
from PIL import Image
from io import BytesIO
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
ax.set_title("My Plot")
# Manual conversion
buf = BytesIO()
fig.savefig(buf, format="png", dpi=150, bbox_inches="tight")
buf.seek(0)
img = Image.open(buf)
client.log_image("plot", img)
buf.close()
plt.close(fig)New Way (One line!)
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
ax.set_title("My Plot")
# One line!
result = client.log_matplotlib("plot", fig)
if result:
print(f"✓ Uploaded! URL: {result.url}")
plt.close(fig)Even Better: Create and Log in One Call
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Create and log in one line!
result = client.log_plot("sine_wave", x, y,
title="Sine Wave",
xlabel="X",
ylabel="Y")File Logging
Log CSV, HDF5, JSON, or any file type:
import numpy as np
with optixlog.run("file_logging") as client:
# Create and save CSV
data = np.array([[1, 2, 3], [4, 5, 6]])
np.savetxt("results.csv", data, delimiter=",")
# Log the file
result = client.log_file("results", "results.csv", "text/csv")
if result:
print(f"✓ Uploaded {result.file_size / 1024:.1f} KB")Parameter Sweeps
Systematically explore parameter spaces:
import optixlog
import numpy as np
wavelengths = np.linspace(1.3, 1.6, 20)
for wavelength in wavelengths:
with optixlog.run(
f"sweep_{wavelength:.2f}",
config={"wavelength": wavelength}
) as client:
# Run simulation
transmission = simulate(wavelength)
reflection = 1 - transmission
# Log results
client.log(step=0,
transmission=transmission,
reflection=reflection)
# Log spectrum plot
frequencies = get_frequencies()
client.log_plot("spectrum", frequencies, transmission,
title=f"Transmission (λ={wavelength})")MPI Parallel Simulations
Run distributed simulations with automatic process coordination:
import optixlog
import meep as mp
# Works automatically with MPI
# mpirun -n 4 python simulation.py
with optixlog.run("parallel_simulation",
config={"processes": 4}) as client:
# Only master process logs, workers are handled automatically
if client.is_master:
print(f"Master process: rank {client.rank}")
# Your simulation code
sim = mp.Simulation(...)
for step in range(100):
sim.run(until=1)
# Only master logs
if client.is_master:
power = calculate_power(sim)
client.log(step=step, power=power)Task-Based Workflow
Group multiple runs together for parameter sweeps:
import optixlog
# Create a task (via web UI or API)
task_id = "task_12345"
# Run multiple experiments linked to the same task
for param_value in [0.1, 0.2, 0.3]:
with optixlog.run(
f"experiment_{param_value}",
task_id=task_id,
config={"param": param_value}
) as client:
# Run experiment
result = run_experiment(param_value)
client.log(step=0, result=result)Real-World Meep Integration
Complete example from the demo:
import optixlog
import meep as mp
import numpy as np
import matplotlib.pyplot as plt
# Third harmonic generation sweep
nfreq = 400
logk = range(-3, 1)
with optixlog.run(
"third_harmonic_generation_sweep",
config={
"nfreq": nfreq,
"logk_range": list(logk),
"simulation": "third_harmonic_generation_sweep",
"cell_size_z": 100,
"resolution": 25,
},
create_project_if_not_exists=True
) as client:
tflux = np.zeros((nfreq, len(logk)))
sweep_ks = [10**lk for lk in logk]
for i, (lk, k_val) in enumerate(zip(logk, sweep_ks)):
freqs, tflux[:, i] = third_harmonic_generation(
k_val, nfreq=nfreq, flux_spectrum=True
)
# Log per sweep
client.log(
step=i,
log10_chi3=float(lk),
chi3=k_val,
sweep_index=i
)
# Save and log CSV
csv_data = np.zeros((nfreq, len(logk) + 1))
csv_data[:, 0] = freqs
for j in range(len(logk)):
csv_data[:, j + 1] = tflux[:, j]
np.savetxt("transmitted_power.csv", csv_data, delimiter=",")
client.log_file("transmitted_power", "transmitted_power.csv", "text/csv")
# Create and log plot
fig, ax = plt.subplots()
colors = ["bo-", "ro-", "go-", "co-"]
for j, color in enumerate(colors):
ax.semilogy(freqs, tflux[:, j], color)
ax.set_xlabel("frequency")
ax.set_ylabel("transmitted power (a.u.)")
ax.legend()
# Log plot with one line!
result = client.log_matplotlib("transmitted_power_plot", fig)
plt.close(fig)Batch Operations
Upload multiple metrics efficiently:
with optixlog.run("batch_demo") as client:
# Prepare metrics
metrics_list = []
for step in range(1000):
metrics_list.append({
"step": step,
"loss": calculate_loss(step),
"accuracy": calculate_accuracy(step)
})
# Upload in parallel
result = client.log_batch(metrics_list, max_workers=4)
print(f"✓ Uploaded {result.successful}/{result.total} metrics")
print(f" Success rate: {result.success_rate:.1f}%")Array Visualization
Convert numpy arrays to heatmaps:
import numpy as np
with optixlog.run("array_visualization") as client:
# Simulate field data
field = np.random.rand(100, 100)
# Convert to heatmap and log in one line!
result = client.log_array_as_image(
"field_snapshot",
field,
cmap='hot',
title="E-field Distribution"
)Multiple Plots Comparison
Compare multiple series on one plot:
with optixlog.run("comparison") as client:
steps = np.arange(100)
train_loss = calculate_train_loss(steps)
val_loss = calculate_val_loss(steps)
# Log multiple lines on one plot
result = client.log_multiple_plots("loss_comparison", [
(steps, train_loss, "Train"),
(steps, val_loss, "Validation"),
], title="Training vs Validation Loss")Query Previous Runs
Programmatically access your logged data:
import optixlog
# List runs
runs = optixlog.list_runs(
api_url="https://backend.optixlog.com",
api_key="your_key",
project="MyProject",
limit=10
)
for run in runs:
print(f"{run.name}: {run.run_id}")
# Get artifacts
artifacts = optixlog.get_artifacts(
api_url, api_key, run.run_id
)
print(f" {len(artifacts)} artifacts")
# Get metrics
metrics = optixlog.get_metrics(api_url, api_key, run.run_id)
print(f" {len(metrics)} metrics")
# Compare runs
comparison = optixlog.compare_runs(
api_url, api_key,
[run.run_id for run in runs[:3]]
)
print(f"Common metrics: {comparison.common_metrics}")Best Practices
Use Context Managers
Recommended:
with optixlog.run("my_experiment") as client:
client.log(step=0, loss=0.5)
# Automatic cleanupNot recommended:
client = optixlog.init("my_experiment")
client.log(step=0, loss=0.5)
# Manual cleanup neededUse Helper Methods
Recommended:
client.log_matplotlib("plot", fig) # One line!Not recommended:
# 15+ lines of PIL conversion codeCheck Return Values
result = client.log(step=0, loss=0.5)
if result and result.success:
print("✓ Logged successfully")
else:
print(f"✗ Failed: {result.error}")Use Batch Operations for Many Metrics
Recommended:
metrics_list = [{"step": i, "loss": losses[i]} for i in range(1000)]
client.log_batch(metrics_list) # Fast parallel uploadNot recommended:
for i in range(1000):
client.log(step=i, loss=losses[i]) # Slow sequential upload