Repository navigation
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·283 lines (258 loc) · 11.1 KB
/
Copy pathsetup.sh
File metadata and controls
executable file
·283 lines (258 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#!/bin/bash
#
set -e
export EXPDIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $EXPDIR
# Keep a full log of this run (and a state report at the end, see
# scripts/setup_report.sh) under logs/
mkdir -p logs
SETUP_LOG=$EXPDIR/logs/setup_$(date +%Y%m%d_%H%M%S).log
exec > >(tee -a "$SETUP_LOG") 2>&1
trap 'echo "### setup.sh FAILED at line $LINENO (exit $?): $BASH_COMMAND"; echo "### log: $SETUP_LOG"' ERR
step() { echo; echo "### $(date '+%F %T') $*"; }
step "setup.sh started in $EXPDIR (env: ${CONDA_DEFAULT_ENV:-none}, commit $(git -C "$EXPDIR" rev-parse --short HEAD 2>/dev/null))"
# Parallel build jobs: one per core, but at most one per 4 GB of available RAM,
# since metagraph's compile jobs need 2-4 GB each. Override with JOBS=<n>.
if [ -z "${JOBS:-}" ]; then
JOBS=$(awk '/^MemAvailable:/ {print int($2 / 1024 / 1024 / 4)}' /proc/meminfo)
if [ "$JOBS" -gt "$(nproc)" ]; then JOBS=$(nproc); fi
if [ "$JOBS" -lt 1 ]; then JOBS=1; fi
fi
# also used by the pip/scikit-build-core builds (pymetagraph)
export CMAKE_BUILD_PARALLEL_LEVEL=$JOBS
echo "Building with $JOBS parallel jobs"
# Create directory structure
mkdir -p code log logs out results tmp
step "minimap2"
# setup minimap2
cd $EXPDIR/code
if [ ! -f minimap2/minimap2 ]; then
[ -d minimap2 ] || git clone https://github.com/lh3/minimap2.git
cd minimap2 && make -j $JOBS
else
echo "minimap2 binary found, skipping."
fi
step "TurboPFor"
# setup TurboPFor (required by collinearity)
cd $EXPDIR/code
if [ ! -f TurboPFor-Integer-Compression/libic.a ]; then
[ -d TurboPFor-Integer-Compression ] || git clone https://github.com/powturbo/TurboPFor-Integer-Compression.git
cd TurboPFor-Integer-Compression && make -j $JOBS
else
echo "TurboPFor already built, skipping."
fi
TURBOPFOR_DIR=$EXPDIR/code/TurboPFor-Integer-Compression
step "collinearity"
# setup collinearity
cd $EXPDIR/code
if ! pip show pycollinearity &>/dev/null || [ ! -f collinearity/build/Collinearity ]; then
[ -d collinearity ] || git clone --recursive https://github.com/ratschlab/collinearity.git
cd collinearity
# patch hardcoded TurboPFor path in CMakeLists.txt
sed -i "s|/home/sayan/Downloads/TurboPFor-Integer-Compression|${TURBOPFOR_DIR}|g" CMakeLists.txt
# for python bindings
pip show pycollinearity &>/dev/null || pip install .
# to build from source
if [ ! -f build/Collinearity ]; then
mkdir -p build && cd build
cmake ..
make -j $JOBS
fi
else
echo "collinearity already installed, skipping."
fi
step "metagraphRF"
# setup metagraphRF: readfish plugin with a server backend (a `metagraph server_query`
# from conda metagraph 0.5.1) and a local backend (in-process pymetagraph, built below)
cd $EXPDIR/code
[ -x "$CONDA_PREFIX/bin/metagraph" ] \
|| conda install -y -c bioconda -c conda-forge metagraph=0.5.1
[ -d metagraphRF ] || git clone -b ak/local-backend https://github.com/ratschlab/metagraphRF
cd metagraphRF
if [ "$(git branch --show-current)" != "ak/local-backend" ]; then
echo "WARNING: code/metagraphRF is on '$(git branch --show-current)', not ak/local-backend;" >&2
echo " backend = \"local\" needs that branch." >&2
fi
if ! python -c "from metagraphRF.aligner import Aligner; Aligner._init_local" &>/dev/null; then
pip install .
else
echo "metagraphRF with local backend found, skipping."
fi
step "metagraph CLI"
# build metagraph (CLI for index building + pymetagraph bindings) from the
# ak/pymetagraph-query branch (master + query-only pymetagraph)
# From https://metagraph.ethz.ch/static/docs/installation.html#install-from-source
cd $EXPDIR/code
[ -d metagraph ] || git clone -b ak/pymetagraph-query --recursive https://github.com/ratschlab/metagraph.git
cd metagraph
if [ "$(git branch --show-current)" != "ak/pymetagraph-query" ]; then
echo "WARNING: code/metagraph is on '$(git branch --show-current)', not ak/pymetagraph-query;" >&2
echo " pymetagraph needs that branch (git -C code/metagraph checkout ak/pymetagraph-query)." >&2
fi
git submodule update --init --recursive
# (sdsl-lite is built by metagraph's own CMake project on master, position-independent
# when building the python bindings; no separate install step needed)
mkdir -p metagraph/build
cd metagraph/build
# metagraph's CLI/server build (BUILD_PYTHON_BINDINGS=OFF) requires Boost with
# static libs. A conda env's boost-cpp package only ships shared libs and its
# CMake config gets found before the system one, so point cmake at the system
# (apt libboost-all-dev) Boost explicitly, installing it first if it's missing.
# (The pymetagraph python bindings below use shared Boost and don't need this.)
BOOST_DIR=$(find /usr/lib/*/cmake -maxdepth 1 -type d -iname 'Boost-*' -print -quit 2>/dev/null || true)
BOOST_IOSTREAMS_DIR=$(find /usr/lib/*/cmake -maxdepth 1 -type d -iname 'boost_iostreams-*' -print -quit 2>/dev/null || true)
if [ -z "$BOOST_DIR" ] || [ -z "$BOOST_IOSTREAMS_DIR" ]; then
echo "metagraph: system Boost (static libs) not found, trying to install libboost-all-dev..."
# NO_SUDO=1 skips the install attempt; the timeout guards against sudo hanging
if [ "${NO_SUDO:-0}" != 1 ] && timeout 5 sudo -n true 2>/dev/null; then
sudo apt-get update && sudo apt-get install -y libboost-all-dev
elif [ "$(id -u)" = "0" ]; then
apt-get update && apt-get install -y libboost-all-dev
fi
BOOST_DIR=$(find /usr/lib/*/cmake -maxdepth 1 -type d -iname 'Boost-*' -print -quit 2>/dev/null || true)
BOOST_IOSTREAMS_DIR=$(find /usr/lib/*/cmake -maxdepth 1 -type d -iname 'boost_iostreams-*' -print -quit 2>/dev/null || true)
fi
if [ -f metagraph_DNA ]; then
echo "metagraph binary found, skipping."
elif [ -n "$BOOST_DIR" ] && [ -n "$BOOST_IOSTREAMS_DIR" ]; then
cmake -DBoost_DIR="$BOOST_DIR" -Dboost_iostreams_DIR="$BOOST_IOSTREAMS_DIR" ..
make -j $JOBS metagraph
else
echo "WARNING: skipping the metagraph CLI/server build -- could not find or" >&2
echo " install a system Boost with static libs (libboost-all-dev)." >&2
echo " Ask your admin to run: sudo apt-get install -y libboost-all-dev" >&2
echo " then re-run setup.sh to build the metagraph CLI binary." >&2
echo " (pymetagraph python bindings will still be installed below.)" >&2
fi
step "pymetagraph"
# pymetagraph python bindings (in-process label queries, used by metagraphRF's
# local backend). Separate cmake invocation via scikit-build-core with
# -DBUILD_PYTHON_BINDINGS=ON, which switches metagraph's CMakeLists.txt to shared
# Boost libs. Reinstalled if an older pymetagraph (no AnnotatedGraph) is present.
if ! python -c "import pymetagraph; pymetagraph.AnnotatedGraph" &>/dev/null; then
cd $EXPDIR/code/metagraph/metagraph/api/python/pymetagraph
# a failed earlier attempt leaves a CMake cache pointing at pip's deleted build env
rm -rf build
# point it at the system Boost, not the conda env's
if [ -n "$BOOST_DIR" ] && [ -n "$BOOST_IOSTREAMS_DIR" ]; then
CMAKE_ARGS="-DBoost_DIR=$BOOST_DIR -Dboost_iostreams_DIR=$BOOST_IOSTREAMS_DIR" pip install .
else
pip install .
fi
else
echo "pymetagraph already installed, skipping."
fi
step "spumoni"
# setup spumoni
cd $EXPDIR/code
if [ ! -f spumoni/build/spumoni ]; then
[ -d spumoni ] || git clone --recursive https://github.com/ratschlab/spumoni.git
cd spumoni
mkdir -p build && cd build
cmake ..
# Fix GCC 13: add missing <cstdint> to bwt2lcp (reverted by cmake git fetch)
grep -q "cstdint" _deps/bwt2lcp-src/internal/include.hpp || \
sed -i 's/#include <algorithm>/#include <algorithm>\n#include <cstdint>/' \
_deps/bwt2lcp-src/internal/include.hpp
# Fix GCC 13: add missing <utility> to shaped_slp/sux Vector.hpp
grep -q "<utility>" _deps/shaped_slp-src/external/sux/sux/util/Vector.hpp || \
sed -i 's/#include <sys\/mman.h>/#include <sys\/mman.h>\n#include <utility>/' \
_deps/shaped_slp-src/external/sux/sux/util/Vector.hpp
make -j $JOBS
make install
cd ..
fi
# python bindings
if ! pip show pyspumoni &>/dev/null; then
cd $EXPDIR/code/spumoni
pip install .
else
echo "spumoni already installed, skipping."
fi
step "rawhash"
# setup rawhash
cd $EXPDIR/code
if [ ! -f rawhash2/rawhash2 ]; then
[ -d rawhash2 ] || git clone -b cmake --recursive https://github.com/ratschlab/RawHash.git rawhash2
cd rawhash2
git submodule update --init --recursive
mkdir -p build && cd build
cmake NOHDF5=1 NOPOD5=1 ..
make -j $JOBS
# for python bindings
cd ..
pip show pyrawhash &>/dev/null || pip install .
else
echo "rawhash2 binary found, skipping."
fi
step "ReadBouncer"
# setup ReadBouncer
cd $EXPDIR/code
[ -d ReadBouncer ] || git clone --recursive https://github.com/ratschlab/ReadBouncer.git
cd ReadBouncer
git submodule update --init --recursive
mkdir -p build && cd build
cmake ../src
make -j $JOBS
# pyreadbouncer python bindings
cd $EXPDIR/code/ReadBouncer
pip install .
step "sigmoni"
# setup sigmoni
# requires SPUMONI (built above) and Uncalled4
cd $EXPDIR/code
[ -d sigmoni ] || git clone https://github.com/ratschlab/sigmoni.git
cd sigmoni
pip install "setuptools<81" uncalled4 # ont_fast5_api needs pkg_resources
# editable: sigmoni loads its pore models from <source>/poremodel/
pip install -e .
step "cumin"
# setup cumin (open-syncmer-based)
cd $EXPDIR/code
[ -d cumin ] || git clone --recursive https://github.com/sayangoswami/cumin.git
cd cumin
git submodule update --init --recursive
mkdir -p build && cd build
cmake ..
make -j $JOBS
# for python bindings
cd $EXPDIR/code/cumin
pip show pycumin &>/dev/null || pip install .
step "seq2squiggle"
# setup seq2squiggle (signal simulation only, not needed for live runs on a GridION;
# pulls in torch with CUDA wheels, ~5 GB, and pins numpy ^1.26;
# opt-in with WITH_SIMULATION=1)
cd $EXPDIR/code
if [ "${WITH_SIMULATION:-0}" != 1 ]; then
echo "skipping (simulation tools are opt-in: WITH_SIMULATION=1)"
else
[ -d seq2squiggle ] || git clone https://github.com/ZKI-PH-ImageAnalysis/seq2squiggle.git
cd seq2squiggle
pip install .
fi
step "MinKNOW API simulator"
# Setup Minknow API Simulator (only for simulated runs, not needed for live runs
# on a GridION; opt-in with WITH_SIMULATION=1)
cd $EXPDIR/code
if [ "${WITH_SIMULATION:-0}" != 1 ]; then
echo "skipping (simulation tools are opt-in: WITH_SIMULATION=1)"
elif ! pip show mksim &>/dev/null; then
[ -d MinknoApiSimulator ] || git clone https://github.com/ratschlab/MinknoApiSimulator.git
cd MinknoApiSimulator/certs
./generate.sh
cd ..
pip install .
else
echo "MinknoApiSimulator already installed, skipping."
fi
# NOTE: ont-dorado-server is NOT set up by this script. It is ONT's vendored
# Dorado/Guppy basecall server binary distribution, gated behind an ONT
# community login (https://community.nanoporetech.com/). Download the Linux
# server package matching your basecaller version and extract it to
# $EXPDIR/code/ont-dorado-server/ -- see README.md step 5 for checking
# client/server version compatibility.
cd $EXPDIR
step "setup.sh finished"
"$EXPDIR/scripts/setup_report.sh" || echo "### (setup_report.sh failed; the install itself finished)"
echo
echo "### log: $SETUP_LOG"