Skip to content

Commit

Permalink
merge offline to master
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-ji committed Sep 11, 2023
2 parents ea49c30 + 4f62a4b commit 8d5023e
Show file tree
Hide file tree
Showing 20 changed files with 7,812 additions and 39 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## ViralWasm-Consensus

A client-side WebAssembly pipeline for viral consensus sequence calling. For an offline version of this site, please see the offline-mode branch: https://github.com/Niema-Lab/ViralWasm-Consensus/tree/offline-mode
A client-side WebAssembly pipeline for viral consensus sequence calling. To run the pipeline locally without internet, download the **offline** version of ViralWasm-Consensus. To do so, download the latest release / repository (https://github.com/Niema-Lab/ViralWasm-Consensus/releases/latest/master.zip) and run the following command:

```python3 run_website.py```
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

<body>
<div id="root"></div>
<script src="https://biowasm.com/cdn/v3/aioli.js"></script>
<script type="module" src="/src/main.jsx"></script>
</body>

Expand Down
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@biowasm/aioli": "^3.1.0",
"bootstrap": "^5.3.1",
"bootstrap-icons": "^1.10.5",
"pako": "^2.1.0",
Expand Down
Binary file added public/tools/fastp/fastp.data
Binary file not shown.
6,261 changes: 6,261 additions & 0 deletions public/tools/fastp/fastp.js

Large diffs are not rendered by default.

Binary file added public/tools/fastp/fastp.wasm
Binary file not shown.
689 changes: 689 additions & 0 deletions public/tools/minimap2/minimap2-simd.data

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions public/tools/minimap2/minimap2-simd.js

Large diffs are not rendered by default.

Binary file added public/tools/minimap2/minimap2-simd.wasm
Binary file not shown.
689 changes: 689 additions & 0 deletions public/tools/minimap2/minimap2.data

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions public/tools/minimap2/minimap2.js

Large diffs are not rendered by default.

Binary file added public/tools/minimap2/minimap2.wasm
Binary file not shown.
22 changes: 22 additions & 0 deletions public/tools/viral_consensus/viral_consensus.js

Large diffs are not rendered by default.

Binary file not shown.
49 changes: 49 additions & 0 deletions run_website.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import http.server
import socketserver
import subprocess
import socket

PORT = 5000
DIRECTORY = "dist"

def kill_port_unix(port):
command = f"lsof -i :{port} -t"
try:
result = subprocess.check_output(command, shell=True).decode("utf-8")
pids = result.strip().split("\n")
for pid in pids:
subprocess.run(f"kill -9 {pid}", shell=True)
except subprocess.CalledProcessError as e:
return

def kill_port_windows(port):
command = f"netstat -ano | findstr :{port}"
try:
result = subprocess.check_output(command, shell=True).decode("utf-8").strip().split("\n")
for line in result:
pid = line.split()[-1]
subprocess.run(f"taskkill /F /PID {pid}", shell=True)
except subprocess.CalledProcessError as e:
return

# Check if port is already in use
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port_in_use = sock.connect_ex(('127.0.0.1', PORT)) == 0
sock.close()

# If port is in use, suggest using --force option
if port_in_use:
force_port = input(f"Port {PORT} is already in use. Try to close the port and continue [Y/n]? ")
if force_port.lower() == "y":
kill_port_unix(PORT)
kill_port_windows(PORT)
else:
exit(1)

class Handler(http.server.SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=DIRECTORY, **kwargs)

with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f'Serving at port {PORT}. Visit http://localhost:{PORT}/index.html')
httpd.serve_forever()
45 changes: 19 additions & 26 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// TODO: automatically create dist/
// TODO: don't manually download aioli, tools
// TODO: PWA?
import React, { Component } from 'react'
import Pako from 'pako';

import 'bootstrap/dist/css/bootstrap.min.css';
import "bootstrap-icons/font/bootstrap-icons.css";

import Aioli from "@biowasm/aioli/dist/aioli";

import {
VIRAL_CONSENSUS_VERSION,
MINIMAP2_VERSION,
Expand All @@ -21,9 +26,6 @@ import {
EXAMPLE_REF_FILE,
DEFAULT_REF_FILE_NAME,
DEFAULT_PRIMER_FILE_NAME,
DEFAULT_VALS_FILE,
DEFAULT_VALS_FALLBACK_FILE,
DEFAULT_VALS_MAPPING,
ARE_FASTQ,
IS_GZIP,
INPUT_IS_NONNEG_INTEGER,
Expand Down Expand Up @@ -75,7 +77,20 @@ export class App extends Component {

async componentDidMount() {
this.setState({
CLI: await new Aioli(["ViralConsensus/viral_consensus/" + VIRAL_CONSENSUS_VERSION, "minimap2/" + MINIMAP2_VERSION, "fastp/" + FASTP_VERSION], {
CLI: await new Aioli([{
tool: "ViralConsensus",
program: "viral_consensus",
version: VIRAL_CONSENSUS_VERSION,
urlPrefix: `${window.location.origin}${import.meta.env.BASE_URL || ''}tools/viral_consensus`,
}, {
tool: "minimap2",
version: MINIMAP2_VERSION,
urlPrefix: `${window.location.origin}${import.meta.env.BASE_URL || ''}tools/minimap2`,
}, {
tool: "fastp",
version: FASTP_VERSION,
urlPrefix: `${window.location.origin}${import.meta.env.BASE_URL || ''}tools/fastp`,
}], {
printInterleaved: false,
})
}, () => {
Expand All @@ -85,7 +100,6 @@ export class App extends Component {

this.preventNumberInputScrolling();
this.fetchExampleFiles();
this.loadDefaults();
}

preventNumberInputScrolling = () => {
Expand All @@ -105,27 +119,6 @@ export class App extends Component {
this.setState({ exampleRefFile, exampleAlignmentFile: exampleAlignmentFile })
}

// Fetch and load ViralConsensus default values
loadDefaults = async () => {
let defaultTextFile;
try {
defaultTextFile = await (await fetch(DEFAULT_VALS_FILE)).text();
} catch (e) {
defaultTextFile = await (await fetch(`${import.meta.env.BASE_URL || ''}${DEFAULT_VALS_FALLBACK_FILE}`)).text();
}
const defaultText = [...defaultTextFile.matchAll(/#define DEFAULT.*$/gm)].map((line) => line[0].split(' '));
for (const defaultValue of defaultText) {
if (DEFAULT_VALS_MAPPING[defaultValue[1]]) {
if (isNaN(defaultValue[2])) {
defaultValue[2] = defaultValue[2].replace(/"|'/g, '');
} else {
defaultValue[2] = Number(defaultValue[2]);
}
this.setState({ [DEFAULT_VALS_MAPPING[defaultValue[1]] + "Default"]: defaultValue[2], [DEFAULT_VALS_MAPPING[defaultValue[1]]]: defaultValue[2] })
}
}
}

uploadRefFile = (e) => {
this.setState({ refFile: e.target.files[0], refFileValid: true, inputChanged: true })
}
Expand Down
23 changes: 14 additions & 9 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ export const TEMP_FASTP_OUTPUT = BIOWASM_WORKING_DIR + 'temp-trimmed.fastq.gz';
export const COMBINED_SEQUENCES_FILE_NAME = BIOWASM_WORKING_DIR + 'sequences.fastq.gz';
export const FASTP_OUTPUT_FILE_NAME = BIOWASM_WORKING_DIR + 'trimmed-sequences.fastq.gz';
export const MINIMAP_OUTPUT_FILE_NAME = BIOWASM_WORKING_DIR + 'reads.sam';
export const DEFAULT_VALS_FILE = "https://raw.githubusercontent.com/niemasd/ViralConsensus/main/common.h";
export const DEFAULT_VALS_FALLBACK_FILE = "data/common.h";
export const DEFAULT_VALS_MAPPING = {
"DEFAULT_MIN_QUAL": "minBaseQuality",
"DEFAULT_MIN_DEPTH": "minDepth",
"DEFAULT_MIN_FREQ": "minFreq",
"DEFAULT_AMBIG": "ambigSymbol",
"DEFAULT_PRIMER_OFFSET": "primerOffset",
export const DEFAULT_VALS = {
minBaseQuality: 20,
minBaseQualityDefault: 20,
minDepth: 10,
minDepthDefault: 10,
minFreq: 0.5,
minFreqDefault: 0.5,
ambigSymbol: "N",
ambigSymbolDefault: "N",
primerOffset: 0,
primerOffsetDefault: 0,
}
export const CONSENSUS_FILE_NAME = BIOWASM_WORKING_DIR + 'consensus.fa';
export const POSITION_COUNTS_FILE_NAME = BIOWASM_WORKING_DIR + 'positionCounts.tsv';
Expand Down Expand Up @@ -72,7 +75,9 @@ export const DEFAULT_INPUT_STATE = {
ambigSymbolValid: true,

genPosCounts: false,
genInsCounts: false
genInsCounts: false,

...DEFAULT_VALS,
}

export const ARE_FASTQ = (files) => {
Expand Down
2 changes: 1 addition & 1 deletion vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
base: '/ViralWasm-Consensus/',
base: '/',
plugins: [react()],
build: {
sourcemap: true,
Expand Down

0 comments on commit 8d5023e

Please sign in to comment.