d87ef2fb8472135b899fd1a89434033d5895217a
mspeir
  Thu Oct 1 15:31:26 2026 -0700
Add barChartReorder, a utility for changing the order of the bars in a barChart track, refs #37619

The bars of a barChart are drawn in the order their values appear in the
expScores field, and nothing re-sorts them when the track is drawn, so the
order is a property of the data file. Putting the bars in a different order
means rewriting that field in every row, which is awkward enough by hand that
we have twice done it for a data author instead of explaining it. This has
come up on #36998 and #37001.

barChartReorder takes the current bar order and the wanted order as two lists
of names, rewrites expScores in every row, optionally puts a .categories file
into the same order, and prints the barChartBars line for the track. It works
on any barChart BED whatever produced it, so unlike the --groupOrderFile
option of expMatrixToBarchartBed it does not assume the file was built here
from an expression matrix. A bigBarChart is handled by converting it with
bigBedToBed and rebuilding it afterwards, which the usage message spells out.

It refuses to write a half-correct file: the two orders must name the same
bars, every row must hold as many values as there are names, and a .categories
file must have a row for each bar.

Listed in USER_APP_SCRIPTS so it reaches hgdownload, and in the no-argument
branch of mkREADME.sh so the README picks up its usage message rather than the
argparse error that -verbose=2 would produce.

Its tests are also wired into the test target directly. testAll iterates
ALL_APPS, which does not include USER_APP_SCRIPTS, so none of these programs'
tests have ever been reachable from "make test" - that is why the suite sitting
next to expMatrixToBarchartBed never reported it was broken. The makefile
already keeps a short list of directories testAll cannot reach, and this adds
two more to it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

diff --git src/utils/barChartReorder/tests/makefile src/utils/barChartReorder/tests/makefile
new file mode 100644
index 00000000000..63eb3758ab6
--- /dev/null
+++ src/utils/barChartReorder/tests/makefile
@@ -0,0 +1,35 @@
+kentSrc = ../../..
+include ../../../inc/common.mk
+
+# Run the copy in the tree rather than an installed one, so that a plain
+# "make test" works without a preceding install and always exercises the
+# code that is about to be committed.
+reorder = ../barChartReorder
+
+all:
+	mkdir -p out
+	@printf "\ntest1: reorder a bed6+5 file, rewriting the header\n"
+	${reorder} in/test.oldOrder in/test.newOrder in/test.bed out/test.bed > out/bars.txt
+	diff out/test.bed expected/test.bed
+	diff out/bars.txt expected/bars.txt
+	@printf "\ntest2: bed6+3 with a trailing comma in expScores\n"
+	${reorder} in/test.oldOrder in/test.newOrder in/simple.bed out/simple.bed > /dev/null
+	diff out/simple.bed expected/simple.bed
+	@printf "\ntest3: reorder a .categories file to match\n"
+	${reorder} in/test.oldOrder in/test.newOrder in/test.bed out/test.bed \
+	    --categories in/test.categories --outCategories out/test.categories > /dev/null
+	diff out/test.categories expected/test.categories
+	@printf "\ntest4: reordering twice returns the original file\n"
+	${reorder} in/test.oldOrder in/test.newOrder in/test.bed out/once.bed > /dev/null
+	${reorder} in/test.newOrder in/test.oldOrder out/once.bed out/twice.bed > /dev/null
+	diff out/twice.bed in/test.bed
+	@printf "\ntest5: order files naming different bars is an error\n"
+	! ${reorder} in/test.oldOrder in/bad.newOrder in/test.bed out/bad.bed 2> /dev/null
+	@printf "\ntest6: a row with the wrong number of values is an error\n"
+	! ${reorder} in/test.oldOrder in/test.newOrder in/short.bed out/bad.bed 2> /dev/null
+	@printf "\nall barChartReorder tests passed\n"
+
+test: all
+
+clean:
+	rm -rf out