Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
ce129e9
Replace hardcoded math answers with dynamic hash-based verification
babaknaderi Jun 12, 2026
9d28ef4
Normalize gold source level and rework loudness degradation
babaknaderi Jun 29, 2026
47d7b23
Add Silero VAD silence pre-screen for rating clips
babaknaderi Jun 29, 2026
b0c6eab
Ignore internal general assets CSV
babaknaderi Jun 29, 2026
616d5e3
Add silent / no-speech option for P.804 ratings
babaknaderi Jun 29, 2026
8c7f1a9
Remove obsolete 'New Instruction (April, 2023)' banner
babaknaderi Jun 29, 2026
eb57865
Decouple qualification into a separate, toggleable section
babaknaderi Jun 29, 2026
04e4ce7
Disable front-end gold/trapping QC and stop embedding answers
babaknaderi Jun 30, 2026
63fa94f
Improve standalone qualification page and answers export
babaknaderi Jun 30, 2026
9e6e35b
Disable front-end gold/trapping QC across remaining HIT templates
babaknaderi Jun 30, 2026
3842361
Highlight the headset rule in red across all HIT templates
babaknaderi Jun 30, 2026
4d763e3
Add bandwidth-check clip generator and docs
babaknaderi Jul 1, 2026
566f9a3
Add --no_anonymize option to bandwidth-check generator
babaknaderi Jul 2, 2026
d550a7a
Have study agents write a re-runnable .bat
babaknaderi Jul 3, 2026
d94c626
Add --payment_per_session to result_parser and wire it into the agent
babaknaderi Jul 3, 2026
efb5f86
Add target platform to result-parser config; skip bonus report on Pro…
babaknaderi Jul 3, 2026
2549d2a
Keep Prolific submissions that match a completed HIT App assignment
babaknaderi Jul 3, 2026
dd38736
Write result parser log fresh each run (mode='w')
babaknaderi Jul 3, 2026
3579e5f
Do not write empty result CSVs
babaknaderi Jul 3, 2026
85caf96
Add detailed rejection-reason breakdown (matrix + combinations)
babaknaderi Jul 3, 2026
2ee56e8
Fix two bugs in rater performance evaluation
babaknaderi Jul 3, 2026
d5914ef
Gate rater reject pass on content-QC (accept), use pass on accept_and…
babaknaderi Jul 6, 2026
008a332
Review by submission status: pay used work, don't re-action
babaknaderi Jul 6, 2026
50bfd2c
Emit one row per gold question in detailed_gold_question_performance.csv
babaknaderi Jul 6, 2026
01b7ead
Add gold_summary.csv: per-gold-clip wrong-rate per scale
babaknaderi Jul 6, 2026
1831710
Add per-scale expected answer to gold_summary.csv
babaknaderi Jul 6, 2026
38e6462
gold_summary: add max_wrong_pct and per-scale mean rating
babaknaderi Jul 6, 2026
0be1991
Write gold detail/summary next to the answers file
babaknaderi Jul 6, 2026
f10d149
Add --gold_overrides: correct gold-clip answers/variance per item
babaknaderi Jul 6, 2026
e15a773
gold_overrides: a listed clip is authoritative; blank scale is skipped
babaknaderi Jul 6, 2026
4c7f81b
Order votes_per_cond_all-scales columns per scale
babaknaderi Jul 6, 2026
4d682ed
Carry Prolific status through result_parser into the review file; use it
babaknaderi Jul 6, 2026
98aa53f
Guard RDP group assignment against missing remote_desktop_failed column
babaknaderi Jul 6, 2026
23915d5
Improve gold-clip generation: decouple loudness from OVRL, delay loud…
babaknaderi Jul 6, 2026
b467c52
Fix Prolific bulk approver leaving submissions unapproved
babaknaderi Jul 6, 2026
89014e5
Make individual approval resilient to transient rate limiting
babaknaderi Jul 7, 2026
91e548e
Stop result parser on duplicate URLs in gold overrides file
babaknaderi Jul 7, 2026
8f33280
Do not set expected SIG for gold clips in high-noise/low-loudness cases
babaknaderi Jul 7, 2026
c881d26
Split gold loudness into too-loud and too-quiet variants
babaknaderi Jul 7, 2026
22a99be
Make gold post-processing bumps subtle so degradations stay perceptible
babaknaderi Jul 7, 2026
9b5a432
Make gold coloration more extreme and sample-rate consistent
babaknaderi Jul 7, 2026
dc2721c
Apply coloration before adding noise for realistic colored+noise gold
babaknaderi Jul 7, 2026
dc2be4b
Reduce gold clean-reference prefix from 3s to 2s
babaknaderi Jul 7, 2026
c74bb27
Rename 'Wrong Verification Code' to a clearer category
babaknaderi Jul 9, 2026
b433589
Strip @author lines from generated study HTML
babaknaderi Jul 9, 2026
a6f34c1
bw-check qualification: variable pool + role-based checking (Part 1 b…
babaknaderi Jul 9, 2026
d2b7849
bw-check qualification Part 2: wire P808_multi.html to batch + hash c…
babaknaderi Jul 9, 2026
9817d18
bw-check qualification UX: shuffle on load, manual check button, retr…
babaknaderi Jul 9, 2026
5bcdd41
bw-check qualification: tell participant they have one more try on fi…
babaknaderi Jul 9, 2026
bfb4509
Wire optional screenout_code through master_script config
babaknaderi Jul 9, 2026
5f1f417
bw-check screen-out: show return-task message when no completion code…
babaknaderi Jul 9, 2026
d4f6189
Port bw-check qualification flow to P835_personalized_template3
babaknaderi Jul 9, 2026
91ecbe7
Port bw-check qualification locking flow to ACR_template
babaknaderi Jul 9, 2026
4f891f1
Port bw-check qualification locking flow to DCR_template and CCR_temp…
babaknaderi Jul 9, 2026
62c72d9
Port bw-check qualification locking flow to P835_template
babaknaderi Jul 9, 2026
2566935
result_parser: treat Prolific SCREENED OUT as a separate, non-rejecte…
babaknaderi Jul 9, 2026
d0e9991
result_parser: fix log typos, relative paths, and payment-stat format…
babaknaderi Jul 10, 2026
2d7c8f0
Split screen-out code into qualification + setup, add setup screen-out
babaknaderi Jul 10, 2026
230a5ee
Add a 'Check answers' button to the setup section (button-driven eval…
babaknaderi Jul 10, 2026
7caa1ee
Show confirmation when the setup check passes
babaknaderi Jul 10, 2026
85283fb
Hash-protect the setup CMP correct answers (no plaintext in the page)
babaknaderi Jul 10, 2026
77a5cb1
Setup section: allow up to two attempts and say so in the message
babaknaderi Jul 10, 2026
36cdbb4
docs: document the screen-out completion codes for study creation
babaknaderi Jul 10, 2026
6877dd6
Add JND setup-clip generator utility + docs
babaknaderi Jul 10, 2026
a2a584b
Add merge_jnd_sources.py: build JND source clips with silence gaps
babaknaderi Jul 10, 2026
95d10a1
master_script: support explicit JND pair answer (pair_ans) for anonym…
babaknaderi Jul 10, 2026
6b3316b
Fix offline setup (CMP) grading for anonymized clips
babaknaderi Jul 10, 2026
801fcce
Add run_online_eval_qualification / run_online_eval_setup toggles
babaknaderi Jul 10, 2026
4d90a88
docs: document run_online_eval_qualification / run_online_eval_setup
babaknaderi Jul 10, 2026
a6ba454
Move scale_*.py and *_utils.py under src/utils
babaknaderi Jul 10, 2026
396c2bf
Replace listening-device keyword check with objective acoustic echo t…
babaknaderi Jul 10, 2026
e02f136
Device check: qualification self-report vs required device, move chec…
babaknaderi Jul 10, 2026
7b5e94a
Device check: make the probe tone quiet and safe (hearing safety)
babaknaderi Jul 13, 2026
c653791
Device check: add console diagnostics + control-frequency metric for …
babaknaderi Jul 13, 2026
48cf319
Device check: use net_db as the decision metric (default threshold 20)
babaknaderi Jul 13, 2026
8adcb9e
Device check: add beep-count audibility check to catch a muted / sile…
babaknaderi Jul 13, 2026
d7f597f
Device check: TEMPORARY test flag to unlock the check on load (easier…
babaknaderi Jul 13, 2026
04d8362
Device check: combine the probe tone and the audibility beeps into on…
babaknaderi Jul 13, 2026
7013b9a
Device check: reframe audibility as "one longer beep + count the shor…
babaknaderi Jul 13, 2026
a700ffb
Device check: remove "Play beeps again"; retry re-runs the whole chec…
babaknaderi Jul 13, 2026
f3a783c
Device check: fix hidden beep-count input (remove leftover display:none)
babaknaderi Jul 13, 2026
b696054
Device check: log net_db + device names, and support required_playbac…
babaknaderi Jul 13, 2026
b0f86dd
Device check: adapt instruction rule to required device; skip check w…
babaknaderi Jul 13, 2026
3bc0ba9
Device check: document settings (docs + master.cfg + agent) and remov…
babaknaderi Jul 13, 2026
351b7b6
Device check: replicate the objective listening-device check to the 5…
babaknaderi Jul 13, 2026
1fdf2df
result_parser: parse and report the objective listening-device check
babaknaderi Jul 13, 2026
7cbfbe4
Qualification: mother-tongue checkboxes (like Qualification.html) + d…
babaknaderi Jul 13, 2026
f1f3421
Qualification: replicate mother-tongue checkboxes + drop working-area…
babaknaderi Jul 13, 2026
e845453
P.804: add config-gated per-scale "Cannot rate it" option (col/disc/r…
babaknaderi Jul 13, 2026
fc68bc0
P.804: rename "Cannot rate it" -> "Cannot tell" and add a (?) explana…
babaknaderi Jul 13, 2026
036169c
create_gold_clips: add coloration review note + reminder for the rese…
babaknaderi Jul 13, 2026
e39fce4
create_gold_clips: default coloration sig_ans/ovrl_ans to 2 (was 1)
babaknaderi Jul 13, 2026
40dc3dc
Require per-study screen-out codes in create-study agent
babaknaderi Jul 13, 2026
a62e6f0
Fix HIT app server jinja2 crash on literal ${...} in template comment
babaknaderi Jul 13, 2026
72d5e64
Write result_parser CSV reports as UTF-8
babaknaderi Jul 14, 2026
2a919d9
Report screened-out count in the not-found-in-HITAPP log line
babaknaderi Jul 14, 2026
bbb47e2
Call screened-out counts submissions, not participants
babaknaderi Jul 14, 2026
b5afaf9
Default p804 acceptance_criteria min acceptance rate to 0
babaknaderi Jul 14, 2026
1685004
Gate post-setup sections on passing the setup, not answering it
babaknaderi Jul 14, 2026
ae16ebe
Remove dead is_test flag from P808_multi
babaknaderi Jul 14, 2026
be81ad8
Surface cannot-rate counts in the per-clip report
babaknaderi Jul 14, 2026
43998d3
Report only silent/cannot-rate percentages and add cannot-rate to all…
babaknaderi Jul 14, 2026
fcdc1a0
Ask for internal-vs-general master-script assets in create-study agent
babaknaderi Jul 14, 2026
0b5da8c
Fix screen-out message: enter code and close window, not submit form
babaknaderi Jul 15, 2026
9e7ec80
Add loud-sample warning to P.804 instruction
babaknaderi Jul 15, 2026
ad7ba7a
Fix typo in control-clip instruction (that -> the)
babaknaderi Jul 15, 2026
c73de67
Ask no-completed-task submissions to return, not skip them
babaknaderi Jul 20, 2026
451e114
docs: fix inaccuracies for the PR's feature changes
babaknaderi Jul 20, 2026
f0a9b2e
Device check: gray-zone dispute policy
babaknaderi Jul 20, 2026
cbfee65
fix: address Copilot reviewer comments on wave mode, typo, and JS var…
Copilot Jul 21, 2026
6a68ea4
Require full qualification answers before grading; merge screen-out c…
babaknaderi Jul 22, 2026
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
101 changes: 89 additions & 12 deletions .github/agents/analyze-results.agent.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: analyze-results
description: Analyzes crowdsourced subjective test results — runs result_parser.py for data cleaning, quality checks, and per-clip/per-worker MOS aggregation.
description: Analyzes crowdsourced subjective test results — runs result_parser.py for data cleaning, quality checks, and per-clip/per-worker MOS aggregation, and writes a re-runnable rerun_result_parser.bat that re-runs result_parser.py.
---

# Analyze subjective test results
Expand Down Expand Up @@ -45,6 +45,12 @@ Do not guess these values if they are missing:
(AMT) or HIT App server. Contains worker responses.
4. **Prolific demographic CSV** (optional): `prolific_demographic_export_*.csv`
— only needed if the study was run on Prolific via HIT App server.
5. **Payment per session** (Prolific only): the reward paid to a participant per
session/HIT (e.g. `2.10`). Prolific does not include the reward in its export,
so the parser cannot compute payment-per-hour statistics without it. Ask the
user for this value whenever the study was run on Prolific; pass it to the
parser as `--payment_per_session`. Not needed for AMT (the reward is already a
column in the AMT batch).

## Execution workflow

Expand All @@ -54,6 +60,8 @@ Do not guess these values if they are missing:
- The path to the project directory (where the `*_result_parser.cfg` is).
- The test method used.
- Whether they used Prolific or AMT.
- **If Prolific**: the payment per session (reward per HIT, e.g. `2.10`) — this is
not in the Prolific export and is required for payment-per-hour statistics.

Then instruct: "Please download the answers file (`Batch_XXX.csv`) and, if using
Prolific, the demographic export (`prolific_demographic_export_*.csv`) and place
Expand Down Expand Up @@ -94,13 +102,17 @@ python REPO_ROOT\src\result_parser.py `

**With Prolific demographic data:**

Also pass `--payment_per_session` (the reward per HIT, e.g. `2.10`) so payment-per-hour
statistics are computed — Prolific does not include the reward in its export.

```powershell
Set-Location PROJECT_DIR
python REPO_ROOT\src\result_parser.py `
--cfg RESULT_PARSER_CFG `
--method METHOD `
--answers Batch_XXX.csv `
--prolific_answers prolific_demographic_export_XXX.csv
--prolific_answers prolific_demographic_export_XXX.csv `
--payment_per_session 2.10
```

**Notes:**
Expand All @@ -109,6 +121,39 @@ python REPO_ROOT\src\result_parser.py `
- The working directory should be the project directory so output files are
written there.

### 3b. Write a re-run batch file (rerun_result_parser.bat)

Always write a `rerun_result_parser.bat` in the results directory so the requester can
re-run the analysis later (e.g. after a config change or with an updated answers export)
without re-deriving the command. It must reproduce the exact `result_parser.py` invocation
from step 3, using `%BASE%` (the folder the `.bat` lives in) for the input files and the
absolute repo path for the script. Include the `--prolific_answers` and
`--payment_per_session` lines only if Prolific was used.

```bat
@echo off
REM Re-run the result parser for PROJECT (METHOD).
REM Rebuilds the data-cleaning report and per-clip / per-worker MOS outputs from the
REM batch answers CSV using the existing result-parser config.

setlocal
set "BASE=%~dp0"
set "REPO=REPO_ROOT"

cd /d "%BASE%"

python "%REPO%\src\result_parser.py" ^
--cfg "%BASE%RESULT_PARSER_CFG" ^
--method METHOD ^
--answers "%BASE%Batch_XXX.csv" ^
--prolific_answers "%BASE%prolific_demographic_export_XXX.csv" ^
--payment_per_session 2.10

endlocal
```

Save as `rerun_result_parser.bat` in the results directory.

### 4. Analyze the output and summarize

After the parser completes, provide a summary covering:
Expand All @@ -124,22 +169,51 @@ Calculate: `rejection_percentage = XXXX / YYYY * 100`
**⚠️ If rejection rate > 35%**: flag as alarming. Ask the user to investigate
the rejection reasons in the data cleaning report.

**Rejection reason breakdown**: because a submission can fail several checks at
once, a flat per-reason count over-counts. Use the parser's "Rejection breakdown"
log and the two files it writes to report the marginal count per reason, how many
were rejected by a single reason ("only-this-reason", e.g. removed *only* because
of performance), and the most common reason combinations:
- `Batch_XXX_rejection_reason_matrix.csv` — reason co-occurrence matrix (diagonal /
`total` = submissions failing that reason; `only_this_reason` = failed that reason
alone; off-diagonal = failed both).
- `Batch_XXX_rejection_reason_combinations.csv` — each distinct reason combination
with its count and percentage.

#### 4b. Gold question performance

Read `detailed_gold_question_performance.csv` from the working directory.
Read `Batch_XXX_detailed_gold_question_performance.csv` (next to the answers file).

The report has **one row per gold question** (so a P.804 submission with two gold
clips contributes two rows). Key columns:
- `gold_url` — the gold clip evaluated on that row (exactly one per row).
- `wrong` / `correct` — number of dimensions answered wrong / correct for that gold
on that submission; per-dimension detail is in `<dim>_wrong` (e.g. `sig_wrong`).
- `worker_id`, `HITID` — the submission the row belongs to.

- Look for columns matching `wrong*` — these indicate how many times each gold
clip received a wrong answer.
- Look for columns matching `url*` — these identify the gold clip URLs.
- **Any row where the sum of `wrong*` columns > 0** means that gold clip received
at least one wrong answer.
- Calculate the rejection rate per gold clip:
`gold_rejection_rate = wrong_count / total_times_shown * 100`
To assess gold clips, **group by `gold_url`**:
- A row counts as a failed presentation when `wrong > 0`.
- `gold_rejection_rate = (rows with wrong > 0 for that gold_url) / (total rows for that gold_url) * 100`.

**⚠️ If any gold clip is rejected > 20% of the time**: flag as alarming. Ask the
user to check that clip and verify the expected answer is correct. It may
indicate a bad gold clip rather than bad workers.

For P.804, `Batch_XXX_gold_summary.csv` gives this directly: one row per gold clip with
`url`, `n_submission`, `max_wrong_pct` (worst scale wrong rate for that clip), and
per scale `<scale>_expected` (correct answer, blank if not targeted),
`<scale>_mean` (mean rating participants gave), and `<scale>_wrong_pct`. Sort by
`max_wrong_pct`; when the mean rating is far from the expected answer with a high
wrong rate, the gold clip is likely mis-keyed or too hard on that scale.

**Correcting gold answers**: to override mis-keyed gold clips, build a CSV with a
`url` column plus, per scale, `<scale>` (correct answer) and optional `<scale>_var`
(variance), and pass it as `--gold_overrides`. A listed clip is authoritative: the
scales you fill are checked with those values and blank scales are skipped (not
checked); clips not listed keep the encoded answers. A good starting point per
scale is the rounded `<scale>_mean` for scales with a high `<scale>_wrong_pct`;
review before re-running.

#### 4c. Summary to present

Provide the user with a structured summary:
Expand All @@ -166,8 +240,11 @@ After analysis, direct the user to the key output files:
| `Batch_XXX_votes_per_worker_[SCALE].csv` | Per-worker rating statistics |
| `Batch_XXX_all_votes_per_clip.csv` | All individual votes per clip (key: `all_votes` in name) |
| `Batch_XXX_data_cleaning_report.csv` | Detailed per-submission data cleaning report |
| `detailed_gold_question_performance.csv` | Per-gold-clip acceptance/rejection statistics |
| `Batch_XXX_quantity_bonus_report.csv` | Quantity bonus calculations |
| `Batch_XXX_rejection_reason_matrix.csv` | Reason co-occurrence matrix (total, only-this-reason, and pairwise counts) |
| `Batch_XXX_rejection_reason_combinations.csv` | Count/percentage of each distinct reason combination |
| `Batch_XXX_detailed_gold_question_performance.csv` | One row per gold question per submission (single `gold_url` per row) |
| `Batch_XXX_gold_summary.csv` | Per-gold-clip summary (P.804): `url`, `n_submission`, `max_wrong_pct`, and per scale `<scale>_expected` + `<scale>_mean` + `<scale>_wrong_pct` |
| `Batch_XXX_quantity_bonus_report.csv` | Quantity bonus calculations (MTurk only; not generated when the platform is Prolific) |

**Scale suffixes by method:**

Expand Down
Loading