Repository navigation
v0.8.0
All SRIM outputs as pandas DataFrames (incl. per-ion positions, trajectories, backscattered/transmitted/sputtered atoms and full cascades), editable run.yaml run specs with pysrim2 run, and export to Parquet/HDF5/CSV.
Added
-
CI reports, informationally, the
RANGE_3Ddigest of the same spec and seed on Linux (wine), Windows and in the container (therepro-reportjob compares Linux and Windows; the container digest is listed separately); same-platform reruns are asserted identical (tests/integration/test_reproducibility.py). Observed: Linux (wine) and the container are bit-identical, native Windows gives the same summary but different per-ion detail (seedocs/run-spec.md). -
.df(a pandas DataFrame, first columndepth_A, columns named with SRIM units) and.metadataonIoniz,Vacancy,NoVacancy,EnergyToRecoils,PhononsandRange;Results.to_dataframes(include=None)returns them as a dict. -
srim.output.Range3DreadsRANGE_3D.txt(per-ion final positions) into a DataFrame with columnsion,depth_A,y_A,z_A;Results.range3dholds it (Noneif the file is absent) andResults.to_dataframes()includes it. -
Range.summaryreturns the range and straggling values SRIM prints in theRANGE.txtheader (depth, lateral, radial, skewness, kurtosis).srim.analysis.implant_summary(df)computes the same quantities from the per-ion positions ofRange3D(standard deviations withddof=1). -
srim.output.EXYZ,Backscat,TransmitandSputterreadEXYZ.txt,BACKSCAT.txt,TRANSMIT.txtandSPUTTER.txtinto DataFrames (ion,atomic_number,energy_eV,depth_A,y_A,z_A,cos_x,cos_y,cos_z; EXYZ:ion,energy_keV,depth_A,y_A,z_A,electronic_stopping_eV_per_A,last_recoil_energy_eV);Results.exyz,.backscat,.transmit,.sputterhold them (Noneif absent; parsed on first access, streaming, so large files are cheap to open) andto_dataframes()returns them. A zero-byte event file gives an empty frame and a warning. They replace the stubs. EXYZ parser based on work by philis-johan. Fixtures generated with real SRIM intest_files/outputs-0.8/. -
Collision.iter_events()streamsCOLLISON.txtline by line as flat event dicts (ion,kind=ionfor a collision of the primary ion orrecoilfor a cascade recoil,energy_keV,depth_A,y_A,z_A,atom,recoil_energy_eV,target_displacements,target_vacancies,target_replacements,target_interstitials, plusatomic_number,electronic_stopping_eV_per_A,vacancy,replacement);Collision.dfcollects them into a DataFrame chunk-wise.Results.collision(lazy,Noneif absent) andResults.to_dataframes(include=["collision"])expose them;to_dataframes()leavescollisionout by default (opt-in like the exports, sinceCOLLISON.txtcan be several GB). -
Results.to_parquet(directory),.to_hdf5(path)and.to_csv(directory)export the tables (optionally selected withinclude=;collisiononly on request) with metadata: the table's.metadata, pysrim2 version, export time and an optional runspec(sourceis the file name only; Parquet: schema keypysrim2; HDF5: node attributepysrim2; CSV:metadata.yaml).Collision.to_parquet(path, chunk_rows=100_000)(also achunk_rowsargument of theResults.to_*methods) andCollision.to_csvstream the cascade events in chunks, so memory stays small for hugeCOLLISON.txtfiles. New optional extraspysrim2[parquet](pyarrow) andpysrim2[hdf5](PyTables);Collision.metadata. Thespecargument of the exports accepts aRunSpec(stored as its mapping) or a dict; anything else raisesTypeError. -
run.yaml:srim.spec.RunSpec(andIonSpec,LayerSpec,ElementSpec) describes a run with units in the key names (energy_keV,thickness_nm,density_g_cm3,angle_deg, ...), validates it with errors naming the dotted key (SpecError), and round-trips to a byte-identicalTRIM.IN.TRIM.to_spec(),TRIM.from_spec(),TRIM.to_yaml(),TRIM.from_yaml(); the seed is always recorded.TRIM.run()writesrun.yamlwith provenance (pysrim2 version, SRIM SHA-256, platform, backend, start/end time, host) next to the outputs (write_spec=Falseto skip),TRIM.copy_output_filescopies it, andResults.specis the defaultspecof theto_parquet/to_hdf5/to_csvexports (no host name). Seedocs/run-spec.md. -
Documentation: new pages
docs/dataframes.md(every column,Range.summary,implant_summary,iter_events),docs/export.md, and a full schema reference indocs/run-spec.md; the README shows.dfandimplant_summary. -
pysrim2 run run.yaml [--set dotted.key=value ...] [--output DIR]runs TRIM from a run spec (values converted by the schema; outputs andrun.yamlcopied toDIR, default./srim-output-<UTC timestamp>), andpysrim2 import TRIM.IN [-o run.yaml]turns an existingTRIM.INinto a run spec. Exit codes indocs/cli.md. -
Example notebooks rewritten on the 0.8.0 API (default SRIM location,
.dftables,implant_summary,Collision.iter_events()/.df, Parquet export,run.yamlwithTRIM.from_specandpysrim2 run), with small ion counts and no committed outputs;Regular SRIM Calculation.ipynbis nowRegular_SRIM_Calculation.ipynb, andKTaO3.ipynbis merged intoSiC.ipynb. Asrim-marked test (tests/integration/test_run_notebooks.py, nbclient) executes them; a static test checks that they are valid and import existing names. -
examples/scripts/run_yaml_example/(arun.yamland README forpysrim2 run run.yaml --set ion.energy_keV=30); the agent skill andexamples/agents/README.mdteach.df,implant_summary, event tables, cascades withiter_events()and chunked export, andrun.yaml.
Changed
- A
Layerwithout a name is now named after its elements (Si+C, or the formula forLayer.from_formula("SiC", ...); the same default for a layer withoutname:inrun.yaml) instead of the textNone. This changes the layer name written toTRIM.IN(andrun.yaml) for unnamed layers compared with 0.7.0.
Fixed
-
The
.dfelement columns of Kinchin-Pease tables (vacancies_<element>_...,absorbed_<element>_...) are named after the element for single-element targets instead of1; the header of those tables lists no symbols, so they are read from the target section. Multi-element targets keep the numbers. -
A zero-byte
RANGE_3D.txtgives an emptyRange3Dframe (same columns) and a warning, like the event files, instead of raising.Range3Dalso warns when a line in the data section cannot be parsed (a truncated final line is still ignored silently). -
The reference example's "lateral straggle" (341.6 A for the boron case) was the root mean square of the radial distance, not what SRIM calls lateral straggling; the example and skill now report SRIM's definitions (lateral straggle 241.8 A, radial straggle 154.9 A).
-
Results.range3dalso findsRANGE_3D.txtin theSRIM Outputssubfolder. -
A table header whose element names cannot be read now warns before the element columns fall back to
1,2, ...; theVacancy.knock_onsdocs give the correct unit (knock-ons per Angstrom per ion). -
Collision(COLLISON.txt) now parses every ion: the file is decoded as cp437 and split on SRIM's box-drawing column separators, so numbers no longer fail with glued separator characters (508 of 1000 ions of the SiC-C fixture raisedValueError/IndexError). Cascades without a summary line and stray recoil lines are handled; the per-ion dict API is unchanged. -
pysrim2 installexits 130 with a[skip] ... cancelledline on Ctrl-C during a step instead of printing a traceback.