Skip to content

Commit

Permalink
Merge branch 'main' of github.com:rat-pac/ratpac-two into whack-a-war…
Browse files Browse the repository at this point in the history
…ning
  • Loading branch information
James Shen committed Jan 9, 2025
2 parents 2c3fb7a + 5d7039e commit bb47da2
Show file tree
Hide file tree
Showing 84 changed files with 1,182 additions and 7,285 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/rattests-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
on:
workflow_call:
inputs:
rattest-name:
required: true
type: string

jobs:
rattest:
runs-on: ubuntu-latest
container:
image: ratpac/ratpac-two:latest-base
options: --user root
steps:
- name: Get build cache
id: cache
uses: actions/cache/restore@v4
with:
path: ratpac2
key: ${{ github.sha }}-install
- name: Run rattest
working-directory: ratpac2
shell: bash
run: |
source /ratpac-setup/env.sh
source ../ratpac2/ratpac.sh
rattest -t test/full/${{ inputs.rattest-name }}
id: test
continue-on-error: true
- name: upload-result
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.rattest-name }}-result
if-no-files-found: error
path: |
ratpac2/test/full/${{ inputs.rattest-name }}/*.png
ratpac2/test/full/${{ inputs.rattest-name }}/*.html
- name: check-test-result
if: steps.test.outcome != 'success'
run: exit 1

42 changes: 42 additions & 0 deletions .github/workflows/rattests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: rattests
on:
push:
branches: [ main ]
pull_request:
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
container:
image: ratpac/ratpac-two:latest-base
options: --user root
steps:
- name: Checkout Ratpac2
uses: actions/checkout@v4
with:
path: ratpac2
- name: Build Ratpac2
working-directory: ratpac2
shell: bash
run: |
source /ratpac-setup/env.sh
make -j$(nproc)
- name: Cache build output
id: cache
uses: actions/cache/save@v4
with:
key: ${{ github.sha }}-install
path: ratpac2

acrylic_attenuation:
needs: build
uses: ./.github/workflows/rattests-template.yml
with:
rattest-name: acrylic_attenuation

fitcentroid:
needs: build
uses: ./.github/workflows/rattests-template.yml
with:
rattest-name: fitcentroid
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ src/core/Config.hh

*.log
*.root
!test/full/*/standard.root
*.heprep
.DS_Store
*.gif
Expand All @@ -28,8 +29,14 @@ src/core/Config.hh

.idea/
.vscode/
.cache/
compile_commands.json
doc/_build/
doc/doxygen
.pytest_cache*
ratpac.*sh
RatpacConfig.cmake

# rattest outputs
test/full/*/*.png
test/full/*/*.html
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ install(DIRECTORY models/ DESTINATION ${RATSHARE}/models
install(DIRECTORY python/ DESTINATION ${RATSHARE}/python
PATTERN "python/*")

# Install rattest executable
install(PROGRAMS python/rattest.py DESTINATION bin RENAME rattest)

# Install the macro files
install(DIRECTORY macros/ DESTINATION ${RATSHARE}/macros
PATTERN "macros/*")
Expand Down
55 changes: 47 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Ratpac-two

[![Documentation Status](https://readthedocs.org/projects/ratpac/badge/?version=latest)](https://ratpac.readthedocs.io/en/latest/?badge=latest)

[![Build RatpacExperiment](https://github.com/rat-pac/ratpac-two/actions/workflows/build-experiment.yml/badge.svg)](https://github.com/rat-pac/ratpac-two/actions/workflows/build-experiment.yml)
Expand All @@ -7,23 +8,60 @@

[![Build Docker Image](https://github.com/rat-pac/ratpac-two/actions/workflows/latest-container.yml/badge.svg?branch=main&event=deployment)](https://github.com/rat-pac/ratpac-two/actions/workflows/latest-container.yml)

[ratpac.readthedocs.io](ratpac.readthedocs.io)
[ratpac.readthedocs.io](https://ratpac.readthedocs.io)

## Quick Start with containers

The easiest way to get started with ratpac-two is via containers. The latest
builds can be found on
[dockerhub](https://hub.docker.com/r/ratpac/ratpac-two/tags) or on
[ghcr.io](https://github.com/rat-pac/ratpac-two/pkgs/container/ratpac-two).

On HPC platforms, apptainer/singularity containers are a better option than
docker containers. To create these, run

```sh
apptainer pull ratpac2.sif docker://ratpac/ratpac-two:main
```

To enter the container:

```sh
apptainer run [-B /disks/to/mount] ratpac2.sif
```

## Installation
Installation requires [ROOT 6.25+](https://root.cern.ch),

Installation requires [ROOT 6.25+](https://root.cern.ch),
[Geant4 11.0+](https://geant4.web.cern.ch/), and [cmake 3.22+](https://cmake.org/)

Install using cmake
For development, the following are also required:

$ cmake . -Bbuild
$ cmake --build build -- -j$(nproc)
- clang-format: major version 14. _other major versions are known to produce
different outputs that will result in failed checks_

If you want to install the code, just add
The most well-supported way of installing ratpac-two is via the [ratpac-setup
script](https://github.com/rat-pac/ratpac-setup). Follow the instruction will
produce a standalone directory that includes all dependencies. You can also
check this repo for the best-tested minor versions of each dependency.

A convenience Makefile exists to automate the above process, simply type `make`.

Install using cmake:

$ cmake --build build . --target install -j$(nproc)
``` sh
cmake . -Bbuild
cmake --build build -- -j$(nproc)
```

A convenience Makefile exists to automate the above process.
If you want to install the code, just add

``` sh
cmake --build build . --target install -j$(nproc)
```

## Usage

Ratpac-two compiles as a library which can be extended for specific experiment
use cases. The library can be accessed through CMake using
`find_package(Ratpac)`.
Expand All @@ -34,6 +72,7 @@ against the ratpac library, and any specific additions to the C++ framework
should exist outside of the main repository.

## About

Ratpac-two is a refactor of ratpac which makes the necessary changes to compile
with modern versions of GCC and is compatible with the latest Geant4 and ROOT
versions. This version of Ratpac is not backwards compatible with the previous
Expand Down
2 changes: 1 addition & 1 deletion cformat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fi

echo "Checking formatting..."
changes=0
for file in $(find ./src \( -name "*.cc" -o -name "*.hh" -o -name "*.icc" -o -name "*.cpp" -o -name "*.hpp" \)); do
for file in $(find ./src ./test \( -name "*.cc" -o -name "*.hh" -o -name "*.icc" -o -name "*.cpp" -o -name "*.hpp" -o -name "*.C" \)); do
retval=$(clang-format -style=file -n -Werror $file)
if [ $? -eq 1 ]; then
echo "Formatting $file"
Expand Down
73 changes: 46 additions & 27 deletions doc/users_guide/rattest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@ Rattest is a framework for creating unit and functional tests for RAT. These tes

At minimum, a test consists of a RAT macro and a ROOT macro -- the Monte Carlo and the analysis. New (simplified) geometries, modified RATDB databases, etc. can also be included. When run, these tests are compared to a standard via a KS test, and a web page is created with histograms (standard and current) and KS test results. The standard RAT logs and output ROOT file is also available for analysis.

The existing rattests are included with the standard RAT distribution, in `$RATROOT/test/`, with the functional tests in `$RATROOT/test/full/<test-name>`. To run a single test, `cd` to the test directory and simply run `rattest <test-name>` where `<test-name>` corresponds to a folder in `$RATROOT/test/full`. Rattest will iterate through the directory structure to find the test, run the RAT macro, run the ROOT macro on the output, and generate a report page.
The existing rattests are included with the standard RAT distribution, in `$RATSHARE/test/`, with the functional tests in `$RATSHARE/test/full/<test-name>`. To run a single test, `cd` to the test directory and simply run `rattest <test-name>` where `<test-name>` corresponds to a folder in `$RATSHARE/test/full`. Rattest will iterate through the directory structure to find the test, run the RAT macro, run the ROOT macro on the output, and generate a report page.

The `rattest` utility takes the following options::
The `rattest.py` script takes the following options::

Usage: rattest [options]
Options:
-h, --help show this help message and exit
-u, --update Update "standard" histogram with current results
-m, --regen-mc Force Monte Carlo to be regenerated
-r, --regen-plots Force histograms to be regenerated
-t, --text-only Do not open web pages with plots
usage: rattest.py [-h] [-u] [-m] [-r] [-t] [--make-template TEMPLATE] input [input ...]

positional arguments:
input RAT test(s) to run. Must be a directory or directories.

options:
-h, --help show this help message and exit
-u, --update Update "standard" histogram with current results.
-m, --regen-mc Force Monte Carlo to be regenerated.
-r, --regen-plots Force histograms to be regenerated.
-t, --text-only Do not open web pages with plots.
--make-template TEMPLATE
Write a template rattest to current directory for you to edit. Supplied name is used for .mac and .C files.

Existing RAT Tests
``````````````````
Expand All @@ -29,10 +34,19 @@ Existing RAT Tests
acrylic_attenuation
Tests the attenuation length of acrylic by generating photons in an acrylic block and checking track lengths

Automated rattests
``````````````````

Every time a PR is submitted to ratpac-two, the rattests in $RATROOT/test/full (FIXME currently just acrylic_attentuation) are ran via GitHub actions using a Github hosted runner. PRs that do not pass all of the rattests will not be merged in, unless the reasons for the test failures are intended. If a test begins to fail because of an intended change, the `standard.root` file should be updated.

The workflow file that controls the running of the rattests can be found at $RATSHARE/.github/workflows/rattests.yml. To add a test, one must add another job to the workflow file using the same format used by the other rattests.

Downstream forks and experiment repositories are encouraged to create their own rattests using the same workflow setup and the `rattest.py` script.

Writing a RAT Test
``````````````````

1. Create a new folder in `$RATROOT/test/full` with useful but short name for your test
1. Create a new folder in `$RATSHARE/test/full` with useful but short name for your test
2. Create a `rattest.config` file, like this::

#!python
Expand All @@ -58,7 +72,7 @@ The RAT macro and ROOT macro do not need to have the same name as the test, they
material: "acrylic_polycast",
}

RAT will prefer a geometry or database in your test directory, and default to the ones in `$RATROOT/data`.
RAT will prefer a geometry or database in your test directory, and defaults to the ones in `$RATSHARE/ratdb`.

4. Create your RAT macro.

Expand Down Expand Up @@ -94,30 +108,36 @@ Keep things as simple as possible, and turn off as many options as possible. The
/run/beamOn 500

You can also create a custom rat "experiment" in the test directory. This experiment can include any custom ratdb tables you want.
You can tell rat to use this experiment by adding the line::

/rat/db/set DETECTOR experiment "cylinder"

5. Write a ROOT macro

The ROOT macro should create a histogram that captures the benchmark you are looking for. It should consist of a single `void` function `make_plots(TFile *event_file, TTree *T, TFile *out_file)`.
The ROOT macro should create a histogram that captures the benchmark you are looking for. It should consist of a single `void` function with the same name as the macro ie `acrylic_attentuation(std::string event_file, std::string outfile)`. `rattest` will automatically fill in the function arguments when it calls the root macro.

Basically, do your analysis, make a histogram, and output it with `[histogram name]->Write()`. Note that when using `Draw()` to make histograms, you'll probably want the `"goff"` option.

`rattest` will pull histogram names from this macro automatically for creation of the results page.

The ROOT macro from `acrylic_attenuation`::

void make_plots(TFile *event_file, TTree *T, TFile *out_file)
void acrylic_attenuation(std::string event_filename, std::string out_filename)
{
...
TH1F *acr_attn_300 = new TH1F("acr_attn_300", "Photon track length (300 nm)", 20, 0, 2500);
acr_attn_300->SetXTitle("Track length (mm)");
acr_attn_300->SetYTitle("Count");
T->Draw("mc.track.GetLastMCTrackStep()->length>>acr_attn_300","TMath::Abs(1.23997279736421566e-03/(mc.track.GetLastMCTrackStep()->ke)-300)<10","goff");
acr_attn_300->Fit("expo");
acr_attn_300->Draw("goff");
acr_attn_300->Write();
...
TFile *event_file = new TFile(event_filename.c_str(),"READ");
TTree *T = (TTree*)event_file->Get("T");
TFile *out_file = new TFile(out_filename.c_str(),"RECREATE");

TH1F *acr_attn_100 = new TH1F("acr_attn_100", "Photon track length (100 nm)", 50, 0, 50);
acr_attn_100->SetXTitle("Track length (mm)");
acr_attn_100->SetYTitle("Count");
T->Draw("mc.track.GetLastMCTrackStep()->length>>acr_attn_100","TMath::Abs(1.23997279736421566e-03/(mc.track.GetLastMCTrackStep()->ke)-100)<10","goff");
//acr_attn_100->Fit("expo");
//acr_attn_100->Draw("goff");
acr_attn_100->Write();

...
}

Expand All @@ -132,4 +152,3 @@ The ROOT macro from `acrylic_attenuation`::
This is pretty much it. If you run `rattest [your test name]` again, you should get a results page (which will open in your default browser unless you specified the `-t` option) with very similar results.

If you think the test is useful to others, commit it to the RAT repository with svn. Be sure to commit only the `rattest.config`, RAT and ROOT macro, any geometry or RATDB files, and `standard.root`.

68 changes: 68 additions & 0 deletions python/rattest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python3
#-*-python-*-

from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

import sys
import os.path
import argparse
import webbrowser
from rattest import RatTest, RatHtml, make_template

#### Parse command line options
parser = argparse.ArgumentParser()

parser.add_argument('input',
nargs='+', type=str,
help='RAT test(s) to run. Must be a directory or directories.')

parser.add_argument('-u', '--update',
action='store_true', dest='update', default=False,
help='Update "standard" histogram with current results.')

parser.add_argument('-m', '--regen-mc',
action='store_true', dest='regen_mc', default=False,
help='Force Monte Carlo to be regenerated.')

parser.add_argument('-r', '--regen-plots',
action='store_true', dest='regen_plots', default=False,
help='Force histograms to be regenerated.')

parser.add_argument('-t', '--text-only',
action='store_false', dest='web', default=True,
help='Do not open web pages with plots.')

parser.add_argument('--make-template', type=str, dest='template', default=None,
help='Write a template rattest to current directory for you to edit. '\
'Supplied name is used for .mac and .C files.')

args = parser.parse_args()

if args.template is not None:
make_template(args.template)
print('Writing test template to current directory...')
sys.exit(0)

#### Open runfile
configname = 'rattest.config'
htmlname = 'results.html'
success = True
for dirname in args.input:
for dirpath, _, filenames in os.walk(dirname):
if configname in filenames:
testcase = RatTest(os.path.join(dirpath, configname))
if args.update:
testcase.update(regen_mc=args.regen_mc, regen_plots=args.regen_plots)
else:
testcase_html = RatHtml(os.path.join(dirpath, htmlname))
result = testcase.run(regen_mc=args.regen_mc, regen_plots=args.regen_plots,
html=testcase_html)
testcase_html.write()
if args.web:
webbrowser.open('file://'+os.path.abspath(testcase_html.htmlname), new=1)
success = (success and result)

if not success:
sys.exit(1)
Loading

0 comments on commit bb47da2

Please sign in to comment.