Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# The image is built from pom.xml and src/ only; keep everything else out of the build context
.git
.idea
target
docs
vectikz
evaluation
tools
data
*.log
*.md
.env
.env.*
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# UDAV Environment Configuration Example
# Copy this file to .env and modify values as needed
# Optional: docker-compose.yml has defaults for everything. Copy this file to .env only to
# override them; the values below are the ones used for large corpus imports.

# ============================================
# Database Configuration
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: CI

on:
push:
branches: [main, develop]
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: maven
# The browser tests are opt-in (profile browser-tests) and stay out of CI
- run: mvn -B test
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ RUN addgroup -g 1000 appuser && \

# Copy JAR from builder stage. --chown here instead of a later "chown -R /app": a chown after
# COPY rewrites the whole 1.2 GB jar into a second image layer.
COPY --from=builder --chown=appuser:appuser /build/target/UDAV-1.0.jar app.jar
COPY --from=builder --chown=appuser:appuser /build/target/UDAV-2.0.0.jar app.jar

# Bundled pipelines and JSON sources (the demos and the evaluation workload). The importers read
# them from disk, not from the classpath, so the container needs its own copy. Point
Expand Down Expand Up @@ -73,7 +73,7 @@ ENV DUUI_IMPORTER_CAS_POOL_SIZE="8"

# Application Configuration
ENV APP_INPUT_DIR="/app/data/input"
ENV SROUCE_BUILDER="false"
ENV SOURCE_BUILDER="false"
ENV PIPELINE_IMPORTER="true"
ENV PIPELINE_IMPORTER_FOLDER="/app/pipelines"
ENV JSON_IMPORTER_FOLDER="/app/sourcefilesJSON"
Expand Down
File renamed without changes.
54 changes: 40 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div align="center">
<a href="/LICENSE"> <img src="https://img.shields.io/github/license/Texttechnologylab/Unified-Dynamic-Annotation-Visualizer"></a>
<a href="/LICENSE.txt"> <img src="https://img.shields.io/github/license/Texttechnologylab/Unified-Dynamic-Annotation-Visualizer"></a>
<a href="https://github.com/texttechnologylab/Unified-Dynamic-Annotation-Visualizer/releases"> <img src="https://img.shields.io/github/v/release/Texttechnologylab/Unified-Dynamic-Annotation-Visualizer"></a>
<a href="https://lrec2026.info/"> <img src="https://img.shields.io/badge/conference-LREC--2026-4b44ce.svg"></a>
<a href="https://aclanthology.org/2026.lrec-1.533.pdf"> <img src="https://img.shields.io/badge/paper-LREC--2026-fb44ce.svg"></a>
Expand Down Expand Up @@ -79,7 +79,7 @@ pipeline are exported concurrently inside a single page. Both are tunable:
| `TOMCAT_MAX_THREADS` | `200` | Servlet worker pool that the budget in the note below is expressed against. |

> [!NOTE]
> The headless page calls back into this same application for `/api/data` and `/api/convertions/*`.
> The headless page calls back into this same application for `/api/data` and `/api/conversions/*`.
> Batch-attributable worker usage is bounded by roughly
> `(max-sessions + max-waiters) + 6 * max-sessions` (Chromium caps connections per origin at ~6),
> so keep that under `server.tomcat.threads.max` (pinned to `200` by default).
Expand All @@ -104,7 +104,7 @@ pipeline are exported concurrently inside a single page. Both are tunable:

#### TeX export: VecTikZ

The `tex` format of the toolbar and of the batch API is produced by `POST /api/convertions/tikz`.
The `tex` format of the toolbar and of the batch API is produced by `POST /api/conversions/tikz`.
Widgets with a native LaTeX representation (Table, Highlight Text) generate it directly; every
SVG-drawing widget is converted by **VecTikZ** (`org.texttechnologylab.udav.widgets.svgtolatex`),
an SVG-to-TikZ converter that turns shapes, paths, text, gradients, patterns, markers, clip paths
Expand All @@ -129,6 +129,10 @@ the view shows a pager, the data API reports the group as `meta.total` / `meta.i
"Export all" toolbar entry and the batch API's `bulk=true` export every page. Only JSON/XML
sources can be grouped.

The corpus filter of a view selects documents by file, by tag and by import date: tags are the
`collectionId` of the `DocumentMetaData` the DUUI importer stores with each document, the date is
the import time of the document's sofa.

`CategoryNumber` and `TextFormatting` evaluate the filter lists `filesWhitelist` / `filesBlacklist`
and `categoriesWhitelist` / `categoriesBlacklist`, set on the generator or on its source.

Expand Down Expand Up @@ -161,11 +165,17 @@ publishes the app on port 18080 with measurements switched on) and run
`mvn test -Dtest=BatchExportEvaluationIT -DUDAV_BASE_URL=http://localhost:18080`, adding
`-Dudav.eval.bugHunt=true` for the smoke variant.

The report of the campaign the paper is based on is `evaluation/evaluation-report-2026-08-26.txt`.
The paper is based on the three JVM runs of 2026-10-31, `evaluation/evaluation-report-2026-10-31-run1.txt`
to `-run3.txt`; `evaluation/evaluation-report-2026-08-26.txt` is the earlier single-run campaign.
The script writes `evaluation-report.txt`, whose first section states whether the numbers are usable;
section 5 holds the LaTeX rows of the paper's tables and section 7 the raw per-run data. Harness
knobs (`-Dudav.eval.analysisRuns=15`, `-Dudav.eval.pipelines=P1,P5`, ...) are passed through.
`tools/make_eval_pipelines.py` regenerates the pipelines and their JSON sources.
`tools/make_eval_pipelines.py` regenerates the pipelines and their JSON sources, and
`tools/cost_model.py evaluation/evaluation-report-2026-10-31-run*.txt` recomputes the workload and
cost-model tables of the paper, the bootstrap intervals, the marginal resource costs and the other
numbers of the evaluation section from section 7 of the reports. `tools/run-evaluation.sh --docker --jvm-runs 3` runs the campaign three
times with a restart of UDAV in between and writes one report per run; `tools/cost_model.py` pools
any number of reports.

`mvn test` runs the unit tests. The tests tagged `browser` launch Playwright's own Chromium (downloaded
on the first run, about 1 GB together with Firefox and WebKit) and are opt-in: `mvn test -Pbrowser-tests`.
Expand Down Expand Up @@ -201,26 +211,42 @@ startup, so the pipeline list is populated right away.

### Quick Start (Docker Compose)

1. **Clone the repository:**
Nothing to configure: `docker-compose.yml` carries defaults for everything.

1. **Clone and start:**

```bash
git clone https://github.com/texttechnologylab/Unified-Dynamic-Annotation-Visualizer.git
cd Unified-Dynamic-Annotation-Visualizer
docker compose up -d
```

2. **Create your `.env` file** by copying the provided example:
The first start builds the image (a Maven build inside Docker, several minutes depending on the
connection); later starts take seconds. The web UI is available at
[http://localhost:8080](http://localhost:8080) once the container is healthy. The bundled demo
and evaluation pipelines with their JSON sources are imported and built in the first minute
after that; pipelines whose sources are UIMA annotation types stay empty until a corpus is
imported (see below).

2. **Check it:**

```bash
cp .env.example .env
tools/smoke-test.sh
```

3. **Start the application:**
Needs only bash and curl: it waits for the application and its pipelines, reads widget data
through the data API, exports a whole pipeline through the batch API and converts an SVG to
TikZ. On Windows run it from Git Bash or WSL, or open the UI and use the export menu of a
widget instead.

```bash
docker compose up -d
```
3. **Stop it** with `docker compose down`, or `docker compose down -v` to drop the database as well.

This starts PostgreSQL and the UDAV application. The web UI is available at [http://localhost:8080](http://localhost:8080) once the container is healthy (usually within 30-60 seconds). The image ships the demo and evaluation pipelines with their JSON sources and imports them at startup; set `PIPELINE_IMPORTER=false` or point `PIPELINE_IMPORTER_FOLDER` / `JSON_IMPORTER_FOLDER` at mounted folders to import your own instead. The default memory settings suit a laptop; `.env.example` lists the values for large corpus imports.
The defaults cap the Java heap at 4 GB and give PostgreSQL 1 GB of shared buffers; with the bundled
pipelines built, the two containers use about 1.5 GB of memory together, which suits a laptop. To change anything, create a `.env` next to `docker-compose.yml` with the variables to
override; `.env.example` documents them with the values used for large corpus imports. Set
`PIPELINE_IMPORTER=false`, or point `PIPELINE_IMPORTER_FOLDER` / `JSON_IMPORTER_FOLDER` at mounted
folders, to import your own pipelines instead of the bundled ones. After a code change,
`docker compose up -d --build` rebuilds the image.

> [!NOTE]
> If you're looking for a small demo without any setup, check our [open demo](https://demo.udav.texttechnologylab.org/).
Expand Down Expand Up @@ -343,7 +369,7 @@ JAVA_OPTS=-Xmx10G -Xms1024m

## License

This project is published under the AGPL-3.0 [license](/LICENSE).
This project is published under the AGPL-3.0 [license](/LICENSE.txt).

# Cite
If you want to use the project please quote this as follows:
Expand Down
4 changes: 1 addition & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ services:
interval: 10s
timeout: 5s
retries: 10
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data

Expand Down Expand Up @@ -61,7 +59,7 @@ services:
PIPELINE_IMPORTER_FOLDER: ${PIPELINE_IMPORTER_FOLDER:-/app/pipelines}
JSON_IMPORTER_FOLDER: ${JSON_IMPORTER_FOLDER:-/app/sourcefilesJSON}
PIPELINE_IMPORTER_REPLACE_IF_DIFFERENT: ${PIPELINE_IMPORTER_REPLACE_IF_DIFFERENT:-false}
SROUCE_BUILDER: ${SROUCE_BUILDER:-false}
SOURCE_BUILDER: ${SOURCE_BUILDER:-false}
LLM_BASE_URL: ${LLM_BASE_URL:-}
LLM_API_TOKEN: ${LLM_API_TOKEN:-}
# Batch export API (headless Chromium is shipped in the image; see README)
Expand Down
Loading
Loading