d2a7668073c78b3ed86ee6e23beebd6dac702640
mspeir
  Thu Oct 1 15:30:45 2026 -0700
Fix expMatrixToBarchartBed, which has aborted on every run since the python3 port, refs #37619

The port in 9ec8ecc35be left three things behind:

- median() and the tpmCutoffs block use / where they index a list. Under
python2 those were integer divisions; under python3 they are floats, so
both the default median path and --useMean abort with a TypeError.
- Every NamedTemporaryFile lost its bufsize=1, but two of them are read by
name through os.system while python still holds the buffer. Small inputs
came out as a header line with no data rows. Restored the original
line-buffered behaviour with an explicit flush before each read.

The six tests in tests/ would have caught this on the first run, but nothing
reaches them: testAll in src/utils/makefile iterates ALL_APPS, and
USER_APP_SCRIPTS is not part of it. They also invoked the bare program name,
which PATH resolves to the installed copy rather than the one in the tree, so
they were testing the shipped binary. They now run ../expMatrixToBarchartBed.
The makefile wiring that makes them run at all comes with barChartReorder.

Two columns of the expected output needed regenerating, neither of them
because of this fix:

- _lineLength is one smaller throughout. bedJoinTabOffset was rewritten in C
in 46dc535d3f5 and measures the line without its trailing newline. This is
harmless, since hgc reads _dataLen bytes and then chopByWhite's, and the
comment in getSampleValsFromFile says so. Confirmed that every offset and
length still lands on its own matrix row.
- score moves by one 111-wide bucket on rows whose value sits exactly on one
of the nine cutoffs. The value reaches an intermediate file through str()
and comes back through float(). python2's str() kept 12 significant digits,
so such a row compared as strictly less than its own cutoff and fell a
bucket; python3 round trips exactly. It affects about six rows whatever the
size of the dataset, since there are only nine cutoffs, and never by more
than one bucket.

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

diff --git src/utils/expMatrixToBarchartBed/tests/extraFields.output src/utils/expMatrixToBarchartBed/tests/extraFields.output
index acf2934e4cf..1c89a1d785a 100644
--- src/utils/expMatrixToBarchartBed/tests/extraFields.output
+++ src/utils/expMatrixToBarchartBed/tests/extraFields.output
@@ -1,11 +1,11 @@
 #chr	chromStart	chromEnd	name	score	strand	name2	expCount	expScores;A B C D	_offset	_lineLength	extra1	extra2
-chr1	100	175	t1	444	+	gene1	4	5.5,0,0,0	36	19	exp1	exp2
-chr1	80	95	t10	999	-	gene7	4	0,0,0,10	211	22	exp5	exp6
-chr2	100	325	t2	666	-	gene1	4	0,7.5,0,0	55	19	exp1	exp2
-chr2	900	1000	t3	222	+	gene2	4	0,0,2,0	74	19	exp3	exp4
-chr3	820	900	t4	999	+	gene2	4	0,0,0,10	93	21	exp3	exp4
-chr1	175	400	t5	444	-	gene3	4	5.5,0,0,0	114	19	exp5	exp6
-chr2	800	980	t6	666	+	gene4	4	0,7.5,0,0	133	19	exp1	exp2
-chr3	10	180	t7	222	-	gene5	4	0,0,2,0	152	19	exp3	exp4
-chr1	80	90	t8	999	+	gene6	4	0,0,0,10	171	21	exp3	exp4
-chr2	9	19	t9	222	+	gene6	4	0,0,2,0	192	19	exp2	exp5
+chr1	100	175	t1	444	+	gene1	4	5.5,0,0,0	36	18	exp1	exp2
+chr1	80	95	t10	999	-	gene7	4	0,0,0,10	211	21	exp5	exp6
+chr2	100	325	t2	666	-	gene1	4	0,7.5,0,0	55	18	exp1	exp2
+chr2	900	1000	t3	222	+	gene2	4	0,0,2,0	74	18	exp3	exp4
+chr3	820	900	t4	999	+	gene2	4	0,0,0,10	93	20	exp3	exp4
+chr1	175	400	t5	444	-	gene3	4	5.5,0,0,0	114	18	exp5	exp6
+chr2	800	980	t6	666	+	gene4	4	0,7.5,0,0	133	18	exp1	exp2
+chr3	10	180	t7	222	-	gene5	4	0,0,2,0	152	18	exp3	exp4
+chr1	80	90	t8	999	+	gene6	4	0,0,0,10	171	20	exp3	exp4
+chr2	9	19	t9	222	+	gene6	4	0,0,2,0	192	18	exp2	exp5