Showing preview only (1,318K chars total). Download the full file or copy to clipboard to get everything.
Repository: BioOmics/iSeq
Branch: main
Commit: fb3f19bdbedc
Files: 24
Total size: 1.2 MB
Directory structure:
gitextract_o5hgf_3g/
├── INSTALL.md
├── LICENSE
├── README.md
├── bin/
│ └── iseq
├── docs/
│ ├── ChineseTutorial.md
│ ├── Examples.md
│ └── benchmark/
│ ├── README.md
│ ├── TestFasterqDump/
│ │ ├── testFasterqDump.log
│ │ └── timefasterqDump.sh
│ ├── TestiSeq-2GB/
│ │ ├── TestiSeq-2GB.bash
│ │ ├── timeENA.log
│ │ ├── timeFQ.log
│ │ ├── timeGSAFTP.log
│ │ ├── timeGSAHW.log
│ │ └── timeSRA.log
│ ├── TestiSeq-540MB/
│ │ ├── TestiSeq-540MB.bash
│ │ ├── timeENA.log
│ │ ├── timeFQ.log
│ │ ├── timeGSAFTP.log
│ │ ├── timeGSAHW.log
│ │ └── timeSRA.log
│ ├── benchmark.ipynb
│ └── iSeq-Table S1.xlsx
└── iSeq.yml
================================================
FILE CONTENTS
================================================
================================================
FILE: INSTALL.md
================================================
## Install the latest version of iSeq
```bash
version="1.9.8"
wget "https://github.com/BioOmics/iSeq/releases/download/v${version}/iSeq-v${version}.tar.gz"
tar -zvxf "iSeq-v${version}.tar.gz"
cd iSeq-v${version}/bin/
chmod +x iseq
echo 'export PATH=$PATH:'$(pwd) >> ~/.bashrc
source ~/.bashrc
```
Anyway, as long as you install the following dependencies and **add them to the environment variables**, **iSeq** can be used.
- [pigz](https://github.com/madler/pigz) (>=2.8), compressing FASTQ files into gzip format by multiple threads
- [wget](https://www.gnu.org/software/wget/) (>=1.16), downloading files by ftp or http
- [axel](https://github.com/axel-download-accelerator/axel) (>=2.17), downloading files by multiple threads
- [aspera](https://github.com/IBM/aspera-cli) (=4.4.0), downloading files by Aspera
- [sra-tools](https://github.com/ncbi/sra-tools) (>=2.11.0), fetching SRA download links
```{bash}
# all softwares can be installed by conda
conda create -n iseq -c conda-forge -c bioconda pigz wget axel aspera-cli sra-tools
# Check sotfware version
pigz --version | awk 'NR==1{print $2}'
wget --version | awk 'NR==1{print $3}'
axel --version | awk 'NR==1{print $2}'
ascp --version | awk 'NR==2{print $3}'
srapath --version | awk 'NR==2{print $3}'
# Use the following command to check whether dependent software is installed
iseq --version
```
> [!IMPORTANT]
> Using **Ubuntu on Windows**, installing `Wget` through `conda` may lead to "unable to resolve host address", which in turn may prevent `iSeq` from fetching data. You can don't install `wget` by `conda`. Or, this issue also can be resolved by following command:
> ```bash
> conda activate iseq
> # Map the system's built-in wget to the conda environment, ensuring that wget is properly installed.
> ln -sf /usr/bin/wget $(which wget)
> # Including the 'srapath'. you can install SRA Toolkit and then change the path below to your own.
> ln -sf ~/YourPathway/sratoolkit/bin/srapath $(which srapath)
## How to install dependencies from source on Linux/macOS
### 1. pigz
- Source install (non-Root)
```bash
wget https://zlib.net/pigz/pigz.tar.gz
tar -zvxf pigz.tar.gz
cd pigz
make
echo 'export PATH=$PATH:'$(pwd) >> ~/.bashrc
source ~/.bashrc
# Check sotfware version
pigz --version | awk 'NR==1{print $2}'
```
- apt install for Ubuntu (Root permission required)
```bash
sudo apt install pigz
```
- yum install for Centos (Root permission required)
```bash
sudo yum install pigz
```
- brew install for macOS (non-Root)
```bash
brew install pigz
```
### 2. wget
**`wget` is generally included in most Linux distributions and does not need to be installed by ourselves**
- Source install (non-Root)
```bash
wget https://ftp.gnu.org/gnu/wget/wget-latest.tar.gz
tar -zvxf wget-latest.tar.gz
cd wget-1.24.5 # change software version
./configure --prefix=$(pwd)
make
cd src
echo 'export PATH=$PATH:'$(pwd) >> ~/.bashrc
source ~/.bashrc
# Check sotfware version
wget --version | awk 'NR==1{print $3}'
```
- apt install for Ubuntu (Root permission required)
```bash
sudo apt install wget
```
- yum install for Centos (Root permission required)
```bash
sudo yum install wget
```
- brew install for macOS (non-Root)
```bash
brew install wget
```
### 3. axel
- Source install (non-Root)
```bash
# see "https://github.com/axel-download-accelerator/axel/releases" to fetch the latest version of axel
wget https://github.com/axel-download-accelerator/axel/releases/download/v2.17.14/axel-2.17.14.tar.gz
tar -zvxf axel-2.17.14.tar.gz # change software version
cd axel-2.17.14 # change software version
./configure --prefix=$(pwd)
make && make install
echo 'export PATH=$PATH:'$(pwd) >> ~/.bashrc
source ~/.bashrc
# Check sotfware version
axel --version | awk 'NR==1{print $2}'
```
- apt install for Ubuntu (Root permission required)
```bash
sudo apt install axel
```
- yum install for Centos (Root permission required)
```bash
sudo yum install axel
```
- brew install for macOS (non-Root)
```bash
brew install axel
```
### 4. aspera
- Source install (only support non-Root)
```bash
# see "https://www.ibm.com/aspera/connect" to fetch the latest version of aspera
wget https://d3gcli72yxqn2z.cloudfront.net/downloads/connect/latest/bin/ibm-aspera-connect_4.2.8.540_linux_x86_64.tar.gz
tar -zvxf ibm-aspera-connect_4.2.8.540_linux_x86_64.tar.gz # change software version
bash ibm-aspera-connect_4.2.8.540_linux_x86_64.sh # change software version
echo 'export PATH=$PATH:~/.aspera/connect/bin' >> ~/.bashrc
source ~/.bashrc
# Check sotfware version
ascp --version | awk 'NR==2{print $3}'
```
- brew & ruby install for macOS (non-Root)
```bash
brew install ruby
export PATH="$HOMEBREW_PREFIX/opt/ruby/bin:$PATH"
gem install aspera-cli
export PATH="$HOMEBREW_PREFIX/lib/ruby/gems/3.4.0/bin:$PATH"
ascli config ascp install
mkdir -p $HOME/.local/bin
cp $HOME/.aspera/sdk/ascp $HOME/.local/bin
```
### 5. sra-tools
- Source install (non-Root)
```bash
# see "https://ftp-trace.ncbi.nlm.nih.gov/sra/sdk/current" to choose the appropriate platform
# e.g. for Ubuntu
wget https://ftp-trace.ncbi.nlm.nih.gov/sra/sdk/current/sratoolkit.current-ubuntu64.tar.gz
tar -zvxf sratoolkit.current-ubuntu64.tar.gz
cd sratoolkit.3.1.0-ubuntu64/bin/ # change software version
echo 'export PATH=$PATH:'$(pwd) >> ~/.bashrc
source ~/.bashrc
# Check sotfware version
srapath --version | awk 'NR==2{print $3}'
```
- brew install for macOS (non-Root)
```bash
brew install sratoolkit
```
## Check iSeq version finally
```bash
iseq --version
```
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2024 BioOmics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](https://anaconda.org/bioconda/iseq)
[](https://anaconda.org/bioconda/iseq)
[](https://anaconda.org/bioconda/iseq)
[](https://anaconda.org/bioconda/iseq)
[](https://anaconda.org/bioconda/iseq)
[](https://github.com/BioOmics/iSeq/releases)
# [iSeq](https://github.com/BioOmics/iSeq): An [i](https://github.com/BioOmics/iSeq)ntegrated tool to fetch public [Seq](https://github.com/BioOmics/iSeq)uencing data
**Cite us**: Haoyu Chao, Zhuojin Li, Dijun Chen, Ming Chen, iSeq: An integrated tool to fetch public sequencing data, ***Bioinformatics***, 2024, btae641, https://doi.org/10.1093/bioinformatics/btae641
## Description
**iSeq** is a Bash script that allows you to download sequencing data and metadata from **[GSA](https://ngdc.cncb.ac.cn/gsa/)**, **[SRA](https://www.ncbi.nlm.nih.gov/sra/)**, **[ENA](https://www.ebi.ac.uk/ena/)**, and **[DDBJ](https://www.ddbj.nig.ac.jp/)** databases. See [Detail Pipeline](https://github.com/BioOmics/iSeq/blob/main/docs/img/iSeq-Pipeline-Detail.png) for iSeq. Here is the basic pipeline of iSeq:

> [!IMPORTANT]
> To use iSeq, Your system must be **connected to the network** and **support FTP, HTTP, and HTTPS protocols**.
## Update Notes:
### 2025.11.20
- **⚠️Update Notice**: Due to recent changes in the **GSA API**, we have updated the way iseq retrieves metadata. The metadata fetching process has been modified accordingly to ensure compatibility with the latest GSA API. **Everyone please update iSeq version (≥ 1.9.8)**
<details>
<summary>More Updates</summary>
### 2025.10.21
- **New `-Q`, `--quiet` option**: Added this option to suppress download progress bars. Useful when logging clean outputs.
- Fixed a bug where `--database` option failed to switch when ENA was inaccessible.
- If the MD5 check ultimately fails, delete the partially downloaded files.
### 2025.10.09
- Fixed a bug when checking md5 of SRA files.
### 2025.09.04
- **⚠️Update Notice**: Due to recent changes in the **ENA API**, we have updated the way iseq retrieves metadata. The metadata fetching process has been modified accordingly to ensure compatibility with the latest ENA API. **Everyone please update iSeq version (≥ 1.9.5)**
### 2025.07.22
- **New `-r`, `--protocol` option** to specify the protocol only when downloading files from ENA.
### 2025.06.16
- When using `-e`, `--merge`, create symbolic links or retain the original Run files to avoid re-downloading them after merging.
- Fixed the issue mentioned in [#40](https://github.com/BioOmics/iSeq/issues/40): modified the behavior so that batch downloads do not terminate upon encountering an error, and instead continue until all items are processed.
- Added an error message when download failures occur, such as `Download failures detected, please check fail.log for details.`
- Fixed a bug where incomplete downloads from GSA were incorrectly reported as successful.
### 2025.05.23
- Fixed the issue mentioned in [#39](https://github.com/BioOmics/iSeq/issues/39). The problem was that using both `-d sra` and `-g` together would skip the MD5 check in `vdb-validate`.
- **New `-k`, `--skip-md5` option**: Added this option to disable MD5 checks.
### 2025.04.25
- Fixed a bug that occurred when re-downloading with empty metadata.
- Fixed a bug where the while loop exited abnormally with a non-zero exit code.
### 2025.04.22
- Fixed the issue mentioned in [#33](https://github.com/BioOmics/iSeq/issues/33). `-s`, `--speed` re-enable use.
- Fix the exception when the metadata file is empty, mentioned in [#34](https://github.com/BioOmics/iSeq/issues/34)
- Bug fix to resolve the issue of MD5 checksum failure when downloading ONT or HiFi third-generation sequencing gzip data.
### 2025.04.02
- Fixed the issue mentioned in [#27](https://github.com/BioOmics/iSeq/issues/27) and [Rednote](http://xhslink.com/a/A0TnUnKlvVg9): In `sra-tools` > 3.0.0, running `vdb-validate` without specifying the SRA file path causes it to re-download the file, leading to a stuck process. Specifying the path (e.g., `vdb-validate ./SRR931847`) resolves the issue.
### 2025.03.14
- Fixed the issue mentioned in [#26](https://github.com/BioOmics/iSeq/issues/26#issuecomment-2721427208). The cause was that the data was `paired-end` but had only `one link`, such as `SRR23680070`.
### 2025.03.11
- Input file can contain accessions from different databases.
- `-p` and `-a` can be used simultaneously , with `-a` taking priority.
- Fixed some bugs when retrying download data from GSA.
### 2024.12.26
- Fixed the bugs mentioned in [#16](https://github.com/BioOmics/iSeq/issues/16), [#17](https://github.com/BioOmics/iSeq/issues/17) (2024.12.16) and https://github.com/BioOmics/iSeq/issues/19 (2024.12.26).
### 2024.11.21
- **Dependency update for aspera-cli**:
The version requirement for aspera-cli has been updated from `aspera-cli` to `aspera-cli=4.14.0`.
### 2024.10.23
- **New `-s`, `--speed` option** to set the download speed limit (MB/s) (default: 1000 MB/s). Such as `iseq -i SRR7706354 -s 10`
- **Dependency update for sra-tools**:
The version requirement for sra-tools has been updated from `sra-tools=2.11` to `sra-tools>=2.11.0`.
### 2024.09.14
- **New `-e` option for merging FASTQ files**:
Added a `-e` option to merge multiple FASTQ files into a single file for each `Experiment (-e ex)`, `Sample (-e sa)`, or `Study (-e st)`.
- **New `-i` option for input**:
`iSeq` can now accept a `file` containing multiple accession numbers as input by `-i fileName`.
- **API change for GSA metadata download**:
The API endpoint has been updated from `getRunInfo` to `getRunInfoByCra` for downloading GSA metadata.
- **Save result to personal directory**:
The output results will now be saved in the user's personal directory by `-o` option.
- **Updated regex for SAMC matching**:
The matching pattern for SAMC has been changed from `SAMC[A-Z]?[0-9]+` to `SAMC[0-9]+`.
- **Fix some bugs**
</details>
## Features
- **Multiple Database Support**: Supports multiple bioinformatics databases (GSA/SRA/ENA/DDBJ/GEO).
- **Multiple Input Formats**: Supports multiple accessions (Project, Study, Sample, Experiment, or Run accession).
- **Metadata Download**: Supports download sample metadata for each accession.
<details>
<summary>More features</summary>
- **File Format Selection**: Users can choose to directly download gzip-formatted FASTQ files or download SRA files and convert them to FASTQ format.
- **Multi-threading Support**: Supports the use of multi-threading to accelerate the conversion of SRA to FASTQ files or the compression of FASTQ files.
- **File Merging**: For experiment-level accession, the script can merge multiple FASTQ files into one.
- **Parallel Download**: Supports parallel download connections, allowing the specification of the number of connections to speed up download speeds.
- **Support for Aspera High-speed Download**: For GSA/ENA databases, the script supports high-speed data transfer using Aspera.
- **Automatic Retry Mechanism**: If a download or verification fails, the script will automatically retry until a set number of attempts have been reached.
- **Automated File Verification**: After the download is complete, the script will automatically verify the integrity of the files, including checking file sizes and MD5 checksums.
- **Error Handling**: The script provides error messages and suggestions for solutions when encountering errors.
</details>
## Installation
### 1. **iSeq** can be installed by conda easily
```{bash}
conda install bioconda::iseq
```
- If conda Found conflicts! You can try `conda install -c conda-forge -c bioconda iseq`
### 2. The latest version of iSeq can also be installed from source, see [INSTALL](https://github.com/BioOmics/iSeq/blob/main/INSTALL.md)
```{bash}
# Use the following command to check whether dependent software is installed
iseq --version
```
## Example ([See more](https://github.com/BioOmics/iSeq/blob/main/docs/Examples.md))
1. Download all Run sequencing data and metadata associated with an accession.
```
iseq -i PRJNA211801
```

2. Batch download by Aspera with `-a` to directly download gzip-formatted FASTQ files with `-g`.
```bash
iseq -i SRR_Acc_List.txt -a -g
```

## Usage ([中文教程](https://github.com/BioOmics/iSeq/blob/main/docs/ChineseTutorial.md)✨)
```{bash}
$ iseq --help
Usage:
iseq -i accession [options]
Required option:
-i, --input [text|file] Single accession or a file containing multiple accessions.
Note: Only one accession per line in the file
Optional options:
-m, --metadata Skip the sequencing data downloads and only fetch the metadata for the accession.
-g, --gzip Download FASTQ files in gzip format directly (*.fastq.gz).
Note: if *.fastq.gz files are not available, SRA files will be downloaded and converted to *.fastq.gz files.
-q, --fastq Convert SRA files to FASTQ format.
-t, --threads int The number of threads to use for converting SRA to FASTQ files or compressing FASTQ files (default: 8).
-e, --merge [ex|sa|st] Merge multiple fastq files into one fastq file for each Experiment, Sample or Study.
-d, --database [ena|sra] Specify the database to download SRA sequencing data (default: ena).
Note: new SRA files may not be available in the ENA database, even if you specify "ena".
-p, --parallel int Download sequencing data in parallel, the number of connections needs to be specified, such as -p 10.
Note: breakpoint continuation cannot be shared between different numbers of connections.
-a, --aspera Use Aspera to download sequencing data, only support GSA/ENA database.
-s, --speed int Download speed limit (MB/s) (default: 1000 MB/s).
-k, --skip-md5 Skip the md5 check for the downloaded files.
-r, --protocol [ftp|https] Specify the protocol only when downloading files from ENA (default: ftp).
-Q, --quiet Suppress download progress bars.
-o, --output text The output directory. If not exists, it will be created (default: current directory).
-h, --help Show the help information.
-v, --version Show the script version.
```
### 1. `-i`, `--input`
Input the accession you want to download, You also can input a file containing multiple accessions (Only one accession per line in the file).
```bash
iseq -i PRJNA211801
```
Firstly, **iSeq** will retrieve the metadata of the accession, then proceed to download each Run contained within.
Currently **supports 6 accession formats** from the following **5 databases**, with supported accession prefixes as follows:
| Databases | BioProject | Study | BioSample | Sample | Experiment | Run |
| --------- | ---------- | ----- | --------- | ------ | ---------- | ---- |
| **GSA** | PRJC | CRA | SAMC | \ | CRX | CRR |
| **SRA** | PRJNA | SRP | SAMN | SRS | SRX | SRR |
| **ENA** | PRJEB | ERP | SAME | ERS | ERX | ERR |
| **DDBJ** | PRJDB | DRP | SAMD | DRS | DRX | DRR |
| **GEO** | GSE | \ | GSM | \ | \ | \ |
Additionally, for the two data formats (`GSE/GSM`) from the GEO database, it will directly retrieve the associated `PRJNA/SAMN`, then proceed to obtain the contained Runs and download the sequencing data. Therefore, essentially, it still downloads sequencing data from the SRA database.
Here are some examples:
| Accession Type | Prefixes | Example |
| -------------- | ------------------------------ | ----------------------------------------------------------- |
| BioProject | PRJEB, PRJNA, PRJDB, PRJC, GSE | PRJEB42779, PRJNA480016, PRJDB14838, PRJCA000613, GSE122139 |
| Study | ERP, DRP, SRP, CRA | ERP126685, DRP009283, SRP158268, CRA000553 |
| BioSample | SAMD, SAME, SAMN, SAMC | SAMD00258402, SAMEA7997453, SAMN06479985, SAMC017083 |
| Sample | ERS, DRS, SRS, GSM | ERS5684710, DRS259711, SRS2024210, GSM7417667 |
| Experiment | ERX, DRX, SRX, CRX | ERX5050800, DRX406443, SRX4563689, CRX020217 |
| Run | ERR, DRR, SRR, CRR | ERR5260405, DRR421224, SRR7706354, CRR311377 |
In summary, regardless of the data format of your accession among the six options, it will eventually download and **check the MD5 value** of each contained Run. If the MD5 value does not match that in the public database, it will attempt a maximum of **three rounds** of re-downloading. If successful after three attempts of downloading and verification, the file name will be stored in `success.log`; otherwise, if the download fails, the file name will be stored in `fail.log`.
### 2. `-m`, `--metadata `
Download only the sample information of the accession and skip the download of sequencing data.
```bash
iseq -i PRJNA211801 -m
iseq -i CRR343031 -m
```
Therefore, regardless of whether the `-m` parameter is used or not, the sample information of the accession will be obtained. If metadata cannot be retrieved, the **iSeq** program will exit without proceeding to the subsequent download.
> [!NOTE]
> **Note 1**: If the retrieved accession is in the **SRA/ENA/DDBJ/GEO** databases, **iSeq** will first search in the ENA database. If sample information can be retrieved, it will download metadata in **`TSV` format** via the [ENA API](https://www.ebi.ac.uk/ena/portal/api/swagger-ui/index.html), typically containing 191 columns. However, some recently released data in the SRA database may not be promptly synchronized to the ENA database. Therefore, if metadata cannot be obtained from the ENA database, **iSeq** will directly download metadata in **`CSV` format** via the [SRA Database Backend](https://trace.ncbi.nlm.nih.gov/Traces/sra-db-be/), typically containing 30 columns. To maintain consistency with the TSV format, it will be converted to TSV format using `sed -i 's/,/\t/g'`. However, if a single field contains a comma, it may cause column disorder. Ultimately, you will obtain sample information named **`${accession}.metadata.tsv`**.
> [!NOTE]
> **Note 2**: If the retrieved accession is in the **GSA** database, **iSeq** will obtain sample information via GSA's [getRunInfo](https://ngdc.cncb.ac.cn/gsa/search/getRunInfo) interface, downloading metadata in **`CSV` format**, typically containing 25 columns. The metadata obtained above will be saved as `${accession}.metadata.csv`. To supplement more detailed metadata information, iSeq will automatically obtain metadata information for the Project to which the accession belongs via GSA's [exportExcelFile](https://ngdc.cncb.ac.cn/gsa/file/exportExcelFile) interface, downloading metadata in **`XLSX`** format, typically with 3 sheets: `Sample`, `Experiment`, `Run`. The final metadata information will be saved as `${accession}.metadata.xlsx`. In summary, you will ultimately obtain sample information named **`${accession}.metadata.csv`** and **`CRA*.metadata.xlsx`**.
### 3. `-g`, `--gzip`
Directly download FASTQ files in **gzip format**. If direct download is not possible, SRA files will be downloaded and converted to gzip format using multi-threading for decomposition and compression.
```bash
iseq -i SRR1178105 -g
```
Since the majority of data formats stored directly in the **GSA** database are in gzip format, if the accession being searched for is from the GSA database, whether the `-g` parameter is used or not, you can directly download FASTQ files in gzip format.
If the accession is from the **SRA/ENA/DDBJ/GEO** databases, **iSeq** will first attempt to access the ENA database. If it can directly download FASTQ files in gzip format, it will do so; otherwise, it will download SRA files and convert them to FASTQ format using the `fasterq-dump` tool, then compress the FASTQ files using the `pigz` tool, ultimately obtaining FASTQ files in gzip format.
> [!TIP]
> [parallel-fastq-dump](https://github.com/rvalieris/parallel-fastq-dump) can also convert SRA to gzip-compressed FASTQ files, typically **2-3 times** faster than `fasterq-dump + pigz`. However, considering **IO limitations**, `iSeq` currently does not support `parallel-fastq-dump`.
### 4. `-q`, `--fastq`
After downloading the SRA files, they will be decomposed into multiple **uncompressed FASTQ** files.
```bash
iseq -i SRR1178105 -q
```
This parameter is only effective when the accession is from the **SRA/ENA/DDBJ/GEO** databases and the downloaded files are **SRA files**. After downloading the SRA files, **iSeq** will use the `fasterq-dump` tool to convert them into FASTQ files. Additionally, you can specify the number of threads for conversion using the `-t` parameter.
> [!NOTE]
> **Note1**: `-q` is particularly useful for downloading **single-cell data**, especially for scATAC-Seq data, as it can effectively decompose the files into four parts: `I1`, `R1`, `R2`, `R3`. However, if FASTQ files are directly downloaded via the `-g` parameter, only `R1` and `R3` files will be obtained (e.g., [SRR13450125](https://www.ebi.ac.uk/ena/browser/view/SRR13450125)), which may cause issues during subsequent data analysis.
> [!NOTE]
> **Note 2**: When `-q` and `-g` are used together, the SRA file will first be downloaded, then converted to `FASTQ` files using the `fasterq-dump` tool, and finally compressed into gzip format using `pigz`. It does not directly download `FASTQ` files in gzip format, which is very useful for obtaining comprehensive single-cell data.
### 5. `-t`, `--threads`
Specifies the number of threads to use for decompressing SRA files into FASTQ files or compressing FASTQ files. The default value is `8`.
```bash
iseq -i SRR1178105 -q -t 10
```
Considering that sequencing data files are generally large, you can specify the number of threads for decomposition using the `-t` parameter. However, more threads does not necessarily mean better performance because excessive threads can lead to **high CPU or IO loads**, especially since `fasterq-dump` consumes a considerable amount of IO, potentially impacting the execution of other tasks. Based on the [benchmark evaluation](https://github.com/BioOmics/iSeq/blob/main/docs/img/benchmark.png), we recommend a maximum thread count of 15.
### 6. `-e`, `--merge`
Merge **multiple FASTQ** files into **one FASTQ** file for each Experiment (`ex`), Sample (`sa`) or Study (`st`) .
```bash
iseq -i SRX003906 -g -e ex
```
Although in most cases, an Experiment contains only one Run, some sequencing data may have multiple Runs within an Experiment (e.g., [SRX003906](https://www.ebi.ac.uk/ena/browser/view/SRX003906), [CRX020217](https://ngdc.cncb.ac.cn/gsa/search?searchTerm=CRX020217)). Hence, you can use the `-e` parameter to merge multiple FASTQ files from an Experiment into one. Considering paired-end sequencing, where `fastq_1` and `fastq_2` files need to be merged simultaneously and the sequence names in corresponding lines need to remain consistent, **iSeq** will merge multiple FASTQ files in the **same order**. Ultimately, for **single-end** sequencing data, a single file **`SRX*.fastq.gz`** will be generated, and for **paired-end** sequencing data, two files **`SRX*_1.fastq.gz`** and **`SRX*_2.fastq.gz`** will be generated.
> [!NOTE]
> **Note 1**: If the accession is a **Run ID**, the `-e` parameter cannot be used (see below). Currently, **iSeq** supports merging **both gzip-compressed and uncompressed FASTQ** files, but does not support merging files such as **BAM files and tar.gz** files.
- `-e ex`: merge all fastq files of the same **Experiment** into one fastq file. Accepted accession format: `ERX, DRX, SRX, CRX`.
- `-e sa`: merge all fastq files of the same **Sample** into one fastq file. Accepted accession format: `ERS, DRS, SRS, SAMC, GSM`.
- `-e st`: merge all fastq files of the same **Study** into one fastq file. Accepted accession format: `ERP, DRP, SRP, CRA`.
> [!NOTE]
> **Note 2**: Normally, when an Experiment contains only one Run, identical Runs should have the **same prefix**. For example, `SRR52991314_1.fq.gz` and `SRR52991314_2.fq.gz` have the same prefix `SRR52991314`. In this case, **iSeq** will directly **rename** them to **`SRX*_1.fastq.gz`** and **`SRX*_2.fastq.gz`**. However, there are exceptions, such as in [CRX006713](https://ngdc.cncb.ac.cn/gsa/search?searchTerm=CRX006713) where a Run `CRR007192` contains files with different prefixes. In such cases, **iSeq** will **rename** them as **`SRX*_original_filename`**, for example, they will be renamed as `CRX006713_CRD015671.gz` and `CRX006713_CRD015672.gz`.
### 7. `-d`, `--database`
Specifies the database for downloading SRA files, supporting **ENA** and **SRA** databases.
```bash
iseq -i SRR1178105 -d sra
```
By default, **iSeq** will automatically detect available databases, so specifying the `-d` parameter is **usually unnecessary**. However, some SRA files may download **slowly** from the ENA database. In such cases, you can force downloading from the SRA database by specifying `-d sra`.
> [!NOTE]
> **Note**: If the corresponding SRA file is not found in the **ENA** database, even if the `-d ena` parameter is specified, **iSeq** will still automatically switch to downloading from the **SRA** database.
### 8. `-p`, `--parallel`
Enables **multi-threaded downloading** and requires specifying the number of threads.
```bash
iseq -i PRJNA211801 -p 10
```
Considering that `wget` may be slow in some cases, you can use the `-p` parameter to let **iSeq** utilize the `axel` tool for multi-threaded downloading.
> [!NOTE]
> **Note 1**: The **resumable download** feature of multi-threaded downloading is only effective within the **same thread**. That is, if the `-p 10` parameter is used for the first download, it must also be used for the second download to enable resumable download.
> [!NOTE]
> **Note 2**: As mentioned, **iSeq** will maintain 10 connections throughout the download process. Therefore, you will see multiple occurrences of the same `Connection * finished` popping up during the download process. This is because some connections are released immediately after completing the download and then new connections are established for downloading.
### 9. `-a`, `--aspera`
Use Aspera for downloading.
```bash
iseq -i PRJNA211801 -a -g
```
As Aspera offers faster download speeds, you can use the `-a` parameter to instruct **iSeq** to use the `ascp` tool for downloading. Unfortunately, Aspera downloading is currently **only supported by the GSA and ENA databases**. The **NCBI SRA** database cannot utilize Aspera for downloading as it predominantly employs Google Cloud and AWS Cloud technologies and other reasons, see [Avoid-using-ascp](https://github.com/ncbi/sra-tools/wiki/Avoid-using-ascp-directly-for-downloads).
> [!NOTE]
> **Note 1**: When accessing the **GSA** database, if download links from **Huawei Cloud** are available, **iSeq** will prioritize downloading through Huawei Cloud, even if the `-a` parameter is used. This is because Huawei Cloud offers faster and more stable download speeds. Therefore, when downloading GSA data, it's **recommended to use the `-a` paramete**r. This way, if access to Huawei Cloud is unavailable, downloading through the Aspera channel is still relatively fast. Otherwise, you'll have to resort to downloading via `wget` or `axel`, which are slower methods.
> [!NOTE]
> **Note 2**: Since `Aspera` requires a key file, **iSeq** will **automatically search for the key** file in the `conda` environment or the `~/.aspera` directory. If the key file is not found, downloading will not be possible.
### 10. `-o`, `--output`
The output directory. If not exists, it will be created (default: current directory).
### 11. `-s`, `--speed`
Download speed limit (MB/s) (default: 1000 MB/s) for `Wget`, `AXEL` and `Aspera`.
### 12 `-k`, `--skip-md5`
Starting from v1.9.2, you can choose to skip the MD5 file integrity check. If you want to perform the MD5 check again after skipping it, simply remove the `-k` parameter and run the same command.
### 13 `-r`, `--protocol`
Starting from v1.9.4, you can specify the protocol only when downloading files from ENA. This is because, in some cases, HTTPS can be faster than FTP.
### 14 `-Q`, `--quiet`
Starting from v1.9.7, you can use the `-Q` or `--quiet` option to suppress download progress bars and non-essential messages from all download and conversion tools (wget, axel, ascp, fasterq-dump), making batch processing or logging cleaner.
## Output
- If the query accession in **SRA/ENA/DDBJ/GEO** database, the following files will be generated:
| Output | Description |
| ------------- | ------------------------------------------------------------ |
| SRA files | Can be converted to FASTQ files using `-q` option |
| .metadata.tsv | Metadata for query accession |
| success.log | Save the SRA file name that has been downloaded successfully |
| fail.log | Save the SRA file name that has been downloaded failed |
- If the query accession in **GSA** database, the following files will be generated:
| Output | Description |
| -------------- | ------------------------------------------------------------ |
| GSA files | Mostly in *.gz format, and a few are bam/tar/bz2 format |
| .metadata.csv | Metadata for query accession |
| .metadata.xlsx | Metadata for Project including query accession in xlsx format |
| success.log | Save the GSA file name that has been downloaded successfully |
| fail.log | Save the GSA file name that has been downloaded failed |
## Inspired
**iSeq** was inspired by **[fastq-dl](https://github.com/rpetit3/fastq-dl), [fetchngs](https://github.com/nf-core/fetchngs), [pysradb](https://github.com/saketkc/pysradb), [Kingfisher](https://github.com/wwood/kingfisher-download)**. These excellent tools may also be very helpful. Below are multiple comparisons of different software:
| Software name | Program languages | Supported databases | Supported accessions | Supported formats | Supported methods | Fetch metadata | MD5 check | Resumable download | Parallel download | Merge FASTQ | Skip downloaded | Conda installable | URL |
| ------------------------------------------------------------ | ----------------- | ------------------------ | ------------------------ | ------------------------ | ---------------------- | -------------- | --------- | ------------------ | ------------------ | ----------- | --------------- | ----------------- | --------------------------------------------------- |
| **iSeq** | Shell | GSA, SRA, ENA, DDBJ, GEO | All | fq, fq.gz, sra, bam | wget, axel, aspera | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | [🔗](https://github.com/BioOmics/iSeq) |
| [edgeturbo](https://ngdc.cncb.ac.cn/ettrans/download/) | C | GSA | All denied | fq, fq.gz, bam | edgeturbo download | ❌ | ❌ | ✔ | ❌ | ❌ | ❌ | ❌ | [🔗](https://ngdc.cncb.ac.cn/ettrans/download/) |
| [SRA Toolkit](https://github.com/ncbi/sra-tools) | C | SRA, ENA, DDBJ | All denied expect Run ID | fq, fq.gz, sra | prefetch | ❌ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | [🔗](https://github.com/ncbi/sra-tools) |
| [enaBrowserTools](https://github.com/enasequence/enaBrowserTools) | Python | SRA, ENA, DDBJ | All except GSA/GEO ID | fq, fq.gz, sra | urllib, aspera | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | [🔗](https://github.com/enasequence/enaBrowserTools) |
| [fastq-dl](https://github.com/rpetit3/fastq-dl) | Python | SRA, ENA, DDBJ | All except GSA/GEO ID | fq, fq.gz, sra, sra.lite | wget | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | [🔗](https://github.com/rpetit3/fastq-dl) |
| [fetchngs](https://github.com/nf-core/fetchngs) | Python | SRA, ENA, DDBJ, GEO | All except GSA ID | fq, fq.gz | wget, aspera, prefetch | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ❌ | [🔗](https://github.com/nf-core/fetchngs) |
| [pysradb](https://github.com/saketkc/pysradb) | Python | SRA, ENA, DDBJ, GEO | All except GSA ID | fq, fq.gz, sra, bam | requests, aspera | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | [🔗](https://github.com/saketkc/pysradb) |
| [Kingfisher](https://github.com/wwood/kingfisher-download) | Python | SRA, ENA, DDBJ | All except GSA/GEO ID | fq, fq.gz, sra | curl, aria2c, aspera | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | [🔗](https://github.com/wwood/kingfisher-download) |
| [ffq](https://github.com/pachterlab/ffq/tree/master) | Python | SRA, ENA, DDBJ, GEO | All except GSA ID | fq, fq.gz, sra, bam | requests | ✔ | ✔ | ❌ | ❌ | ❌ | ❌ | ✔ | [🔗](https://github.com/pachterlab/ffq/tree/master) |
## Contributing
Contributions to **iSeq** are welcome! If you have any suggestions, bug reports, or feature requests, please open an issue on the project's GitHub repository. If you would like to contribute code, please fork the repository, make your changes, and submit a pull request.
**Cite us**: [https://doi.org/10.1101/2024.05.16.594538](https://doi.org/10.1093/bioinformatics/btae641)
## License
This project is licensed under the [MIT License](LICENSE).
================================================
FILE: bin/iseq
================================================
#!/bin/bash
# Author: BioOmics (https://github.com/BioOmics)
# Last modified: 2025-11-20
# =======================================
function CheckSoftware(){
local software1=$1
local software2=$2
if command -v $software1 >/dev/null 2>&1; then
# echo -e "\033[1;34m Software check OK: \033[1;32m${software1}\033[0m"
sleep 0.01
else
echo -e "\033[1;31mError\033[0m: \033[1;32m${software1}\033[0m can not be found in your PATH environment variable."
echo -e "\033[1;34mHow to solve?\033[0m Please install \033[1;32m${software2}\033[0m by conda (e.g. \033[1;32mconda install -c conda-forge -c bioconda ${software2} -y\033[0m) or other ways and add it to the PATH environment variable."
echo -e "All required software:\033[1;32m wget, sra-tools, axel, aspera, pigz \033[0m"
exit 1
fi
}
CheckSoftware wget wget
CheckSoftware axel axel
CheckSoftware pigz pigz
CheckSoftware ascp "aspera-cli=4.14.0"
CheckSoftware md5sum coreutils
CheckSoftware srapath "sra-tools>=2.11.0"
CheckSoftware vdb-validate sra-tools
# =======================================
function usage() {
cat << EOF
Description:
Download sequencing data and matadata for each Run from [GSA, SRA, ENA or DDBJ] databases.
Usage:
$(basename $0) -i accession [options]
Accepted accession formats:
1. Projects: PRJEB, PRJNA, PRJDB, PRJC, GSE
2. Studies: ERP, DRP, SRP, CRA
3. BioSamples: SAMD, SAME, SAMN, SAMC
4. Samples: ERS, DRS, SRS, GSM
5. Experiments: ERX, DRX, SRX, CRX
6. Runs: ERR, DRR, SRR, CRR
Required option:
-i, --input [text|file] Single accession or a file containing multiple accessions.
Note: Only one accession per line in the file.
Optional options:
-m, --metadata Skip the sequencing data downloads and only fetch the metadata for the accession.
-g, --gzip Download FASTQ files in gzip format directly (*.fastq.gz).
Note: if *.fastq.gz files are not available, SRA files will be downloaded and converted to *.fastq.gz files.
-q, --fastq Convert SRA files to FASTQ format.
-t, --threads int The number of threads to use for converting SRA to FASTQ files or compressing FASTQ files (default: 8).
-e, --merge [ex|sa|st] Merge multiple fastq files into one fastq file for each Experiment, Sample or Study.
ex: merge all fastq files of the same Experiment into one fastq file. Accession format: ERX, DRX, SRX, CRX.
sa: merge all fastq files of the same Sample into one fastq file. Accession format: ERS, DRS, SRS, SAMC, GSM.
st: merge all fastq files of the same Study into one fastq file. Accession format: ERP, DRP, SRP, CRA.
-d, --database [ena|sra] Specify the database to download SRA sequencing data (default: ena).
Note: new SRA files may not be available in the ENA database, even if you specify "ena".
-p, --parallel int Download sequencing data in parallel, the number of connections needs to be specified, such as -p 10.
Note: breakpoint continuation cannot be shared between different numbers of connections.
-a, --aspera Use Aspera to download sequencing data, only support GSA/ENA database.
-s, --speed int Download speed limit (MB/s) (default: 1000 MB/s).
-k, --skip-md5 Skip the md5 check for the downloaded files.
-r, --protocol [ftp|https] Specify the protocol only when downloading files from ENA (default: ftp).
-Q, --quiet Suppress download progress bars.
-o, --output text The output directory. If not exists, it will be created (default: current directory).
-h, --help Show the help information.
-v, --version Show the script version.
See example:
https://github.com/BioOmics/iSeq/blob/main/docs/Examples.md
More information:
https://github.com/BioOmics/iSeq
EOF
}
function checkParameter(){
local parameterName=$1
local value=$2
if [[ -z $value || $value == -* ]]; then
echo -e "\033[1;31mError\033[0m: No parameter provided for \"$1\""
echo -e "\033[1;32mHow to solve?\033[0m Please specify [ex|sa|st] by \"$1\" option"
exit 1
else
return 0
fi
}
while [[ $# -gt 0 ]]; do
case $1 in
-i|--input) checkParameter $1 $2; if [[ $? -eq 0 ]]; then input=$2;shift 2; fi ;;
-m|--metadata) metadata=1 ; shift 1 ;;
-d|--database) checkParameter $1 $2; if [[ $? -eq 0 ]]; then database=$2;shift 2; fi ;;
-q|--fastq) fastq=1 ; shift 1 ;;
-g|--gzip) gzip=1 ; shift 1 ;;
-e|--merge) checkParameter $1 $2; if [[ $? -eq 0 ]]; then merge=$2;shift 2; fi ;;
-t|--threads) checkParameter $1 $2; if [[ $? -eq 0 ]]; then threads=$2;shift 2; fi ;;
-p|--parallel) checkParameter $1 $2; if [[ $? -eq 0 ]]; then parallel=$2;shift 2; fi ;;
-a|--aspera) aspera=1 ; shift 1 ;;
-s|--speed) checkParameter $1 $2; if [[ $? -eq 0 ]]; then speed=$2;shift 2; fi ;;
-k|--skip-md5) skip_md5=1 ; shift 1 ;;
-r|--protocol) checkParameter $1 $2; if [[ $? -eq 0 ]]; then protocol=$2;shift 2; fi ;;
-Q|--quiet) quiet=1 ; shift 1 ;;
-o|--output) checkParameter $1 $2; if [[ $? -eq 0 ]]; then output=$2;shift 2; fi ;;
-h|--help) usage; exit 0 ;;
-v|--version) echo "Version 1.9.8"; exit 0 ;;
*) echo -e "\033[1;31mError\033[0m: Invalid option: $1"; echo -e "\033[1;32mHow to solve?\033[0m Please remove $1 option"; exit 1 ;;
esac
done
# ==================================================
# ================parameters========================
# ==================================================
# --------------------"-i"--------------------------
# Check if input is provided
if [[ -z "$input" ]]; then
echo -e "\033[1;31mError\033[0m: No input provided"
echo -e "\033[1;32mHow to solve?\033[0m Please provide the input by \"-i\" option"
exit 1
fi
# --------------------Check if input is a file or single accession--------------------------
accessions=()
if file "$input" | grep -q 'text'; then
sed -i 's/\r$//' "$input"
while IFS= read -r line; do
accessions+=("$line")
done < "$input"
else
accessions+=("$input")
fi
# --------------------"-m"--------------------------
# if not use -m, then use 0
if [[ -z "$metadata" ]]; then
metadata=0
fi
# --------------------"-d"--------------------------
# if not use -d, then use auto detect
if [[ -z "$database" ]]; then
database="auto"
else
if ! [[ "$database" =~ ^([eE][nN][aA]|[sS][rR][aA])$ ]]; then
echo -e "\033[1;31mError\033[0m: Invalid database: $database"
echo -e "\033[1;32mHow to solve?\033[0m Please use \"ena\" or \"sra\" for the \"-d\" option"
exit 1
fi
fi
# --------------------"-g"--------------------------
# if not use -g, then use 0
if [[ -z "$gzip" ]]; then
gzip=0
fi
# --------------------"-q"--------------------------
# if not use -q, then use 0
if [[ -z "$fastq" ]]; then
fastq=0
else
CheckSoftware fasterq-dump sra-tools
fi
# --------------------"-e"--------------------------
# if not use -e, then use 0
if [[ -z "$merge" ]]; then
merge=0
else
CheckSoftware fasterq-dump sra-tools
if [[ $merge =~ ^[eE][xX]$ ]]; then
for accession in ${accessions[@]}; do
if [[ $accession =~ ^[CEDS]RR[0-9]{6,}$ ]]; then
echo -e "\033[1;31mError\033[0m: $accession is a Run ID, can not use -e option"
echo -e "\033[1;32mHow to solve?\033[0m Please use a Project, Study, Sample, or Experiment accession for the \"-i\" option"
exit 1
fi
done
elif [[ $merge =~ ^[sS][aA]$ ]]; then
for accession in ${accessions[@]}; do
if [[ $accession =~ ^[CEDS]RR[0-9]{6,}$ || $accession =~ ^[CEDS]RX[0-9]{6,}$ ]]; then
echo -e "\033[1;31mError\033[0m: $accession is a Run ID or Experiment ID, can not use -e option"
echo -e "\033[1;32mHow to solve?\033[0m Please use a Project, Study, or Sample accession for the \"-i\" option"
exit 1
fi
done
elif [[ $merge =~ ^[sS][tT]$ ]]; then
for accession in ${accessions[@]}; do
if [[ $accession =~ ^[CEDS]RR[0-9]{6,}$ || $accession =~ ^[CEDS]RX[0-9]{6,}$ || $accession =~ ^[EDS]RS[0-9]{6,}$ || $accession =~ ^SAM[CEDN][A-Z]?[0-9]+$ ]]; then
echo -e "\033[1;31mError\033[0m: $accession is a Run ID, Experiment ID, or Sample ID, can not use -e option"
echo -e "\033[1;32mHow to solve?\033[0m Please use a Project or Study accession for the \"-i\" option"
exit 1
fi
done
else
echo -e "\033[1;31mError\033[0m: Invalid merge: $merge"
echo -e "\033[1;32mHow to solve?\033[0m Please use \"ex\", \"sa\", or \"st\" for the \"-e\" option"
exit 1
fi
fi
# --------------------"-t"--------------------------
# if not use -t, then use 8
if [[ -z "$threads" ]]; then
threads=8
fi
# --------------------"-p"--------------------------
# if not use -p, then use 0
if [[ -z "$parallel" ]]; then
parallel=0
elif [[ ! $parallel =~ ^[1-9][0-9]*$ ]]; then
echo -e "\033[1;31mError\033[0m: Invalid parallel: $parallel"
echo -e "\033[1;32mHow to solve?\033[0m Please use a positive integer for the \"-p\" option"
exit 1
else
CheckSoftware axel axel
fi
# --------------------"-a"--------------------------
# if not use -a, then use 0
if [[ -z "$aspera" ]]; then
aspera=0
elif [[ $aspera -eq 1 && $parallel -gt 0 ]]; then
echo -e "\033[1;33mNote\033[0m: -a and -p options were used at the same time, -a will be used first"
elif [[ $aspera -eq 1 && $database =~ ^[sS][rR][aA]$ ]]; then
echo -e "\033[1;31mError\033[0m: SRA database does not support Aspera download"
echo -e "\033[1;32mHow to solve?\033[0m Please remove -a option or switch to the ENA database by \"-d ena\""
exit 1
else
for accession in ${accessions[@]}; do
if [[ $accession =~ ^PRJC[A-Z][0-9]+$ || $accession =~ ^SAMC[0-9]+$ || $accession =~ ^CRA[0-9]+$ || $accession =~ ^CRX[0-9]+$ || $accession =~ ^CRR[0-9]+$ ]]; then
if [[ ! -f .asperaGSA.openssh ]]; then
wget --user-agent="Mozilla/5.0" https://ngdc.cncb.ac.cn/gsa/file/downFile?fileName=download/aspera01.openssh -O .asperaGSA.openssh --quiet
fi
if [[ ! -f ".asperaGSA.openssh" ]]; then
echo -e "\033[1;31mError\033[0m: .asperaGSA.openssh is not exist"
echo -e "\033[1;32mHow to solve?\033[0m Please download GSA Aspera key file from https://ngdc.cncb.ac.cn/gsa/file/downFile?fileName=download/aspera01.openssh and rename it to .asperaGSA.openssh"
exit 1
fi
ascpKeyFile=.asperaGSA.openssh
else
CheckSoftware ascp aspera-cli
ascpPath=$(command -v ascp)
ascpKeyFile1=$(dirname $ascpPath)/../etc/aspera/aspera_bypass_rsa.pem
ascpKeyFile2=$(dirname $ascpPath)/../etc/aspera_tokenauth_id_rsa
if [[ -f $ascpKeyFile1 ]]; then
ascpKeyFile=$ascpKeyFile1
elif [[ -f $ascpKeyFile2 ]]; then
ascpKeyFile=$ascpKeyFile2
else
echo -e "\033[1;31mError\033[0m: Aspera key file not found in the path: \033[1;31m$ascpKeyFile1\033[0m OR \033[1;31m$ascpKeyFile2\033[0m"
echo -e "\033[1;32mHow to solve?\033[0m Please copy the Aspera key file in the above path and rename it"
exit 1
fi
fi
done
fi
# --------------------"-s"--------------------------
# if not use -s, then use 1000
if [[ -z "$speed" ]]; then
speed=1000
else
if [[ ! $speed =~ ^[1-9][0-9]*$ ]]; then
echo -e "\033[1;31mError\033[0m: Invalid speed: $speed"
echo -e "\033[1;32mHow to solve?\033[0m Please use a positive integer for the \"-s\" option, such as \"-s 1000\" means 1000 MB/s"
exit 1
fi
fi
# --------------------"-k"--------------------------
# if not use -k, then use 0
if [[ -z "$skip_md5" ]]; then
skip_md5=0
fi
# --------------------"-r"--------------------------
# if not use -r, then use ftp
if [[ -z "$protocol" ]]; then
protocol="ftp"
else
if ! [[ "$protocol" =~ ^(ftp|https)$ ]]; then
echo -e "\033[1;31mError\033[0m: Invalid protocol: $protocol"
echo -e "\033[1;32mHow to solve?\033[0m Please use \"ftp\" or \"https\" for the \"-r\" option"
exit 1
fi
fi
# --------------------"-Q"--------------------------
# if not use -Q, then use 0
if [[ -z "$quiet" ]]; then
quiet=0
fi
# --------------------"-o"--------------------------
# if use -o, cd to output directory
if [[ -z "$output" ]]; then
output=$(pwd)
else
if [[ ! -d $output ]]; then
mkdir -p $output
fi
if [[ ! -w $output ]]; then
echo -e "\033[1;31mError\033[0m: The output directory is not writable"
echo -e "\033[1;32mHow to solve?\033[0m Please check the write permission of the output directory"
exit 1
fi
cd $output
fi
# ==================================================
# ==================function========================
# ==================================================
function CheckFile(){
if [[ ! -f $1 ]]; then
echo -e "\033[1;31mError\033[0m: $1 is not exist"
echo -e "\033[1;32mHow to solve?\033[0m Please check the accession in $1"
exit 1
fi
if [[ ! -s $1 ]]; then
echo -e "\033[1;31mError\033[0m: $1 is empty"
echo -e "\033[1;32mHow to solve?\033[0m Please check the content in $1"
exit 1
fi
}
function executeDownload(){
local link=$1
local SaveName=$2
local wget_version=$(wget --version| head -1| awk 'NR==1{print $3}')
if [[ $(echo "$wget_version" | awk '{print ($1 < 1.16)}') -eq 1 ]]; then
local wget_params="--progress=bar"
else
local wget_params="--quiet --show-progress"
fi
if [[ $quiet -eq 1 ]]; then
wget_params="--quiet"
fi
if [[ $parallel -gt 0 ]]; then
maxSpeed=$(awk -v speed=$speed 'BEGIN{print speed*1024*1024}')
if [[ $quiet -eq 1 ]]; then
axel -n $parallel -o "$SaveName" -a -c "$link" -s ${maxSpeed} >/dev/null 2>&1
else
axel -n $parallel -o "$SaveName" -a -c "$link" -s ${maxSpeed}
fi
else
wget -c "$link" -O "$SaveName" $wget_params --limit-rate=${speed}M
fi
}
function executeAspera(){
local link=$1
local DB=$2
if [[ $DB == "ENA" ]]; then
ascpPath=$(command -v ascp)
ascpKeyFile1=$(dirname $ascpPath)/../etc/aspera/aspera_bypass_rsa.pem
ascpKeyFile2=$(dirname $ascpPath)/../etc/aspera_tokenauth_id_rsa
if [[ -f $ascpKeyFile1 ]]; then
ascpKeyFile=$ascpKeyFile1
elif [[ -f $ascpKeyFile2 ]]; then
ascpKeyFile=$ascpKeyFile2
else
echo -e "\033[1;31mError\033[0m: Aspera key file not found in the path: \033[1;31m$ascpKeyFile1\033[0m OR \033[1;31m$ascpKeyFile2\033[0m"
echo -e "\033[1;32mHow to solve?\033[0m Please copy the Aspera key file in the above path and rename it"
exit 1
fi
local asperaLink=$(echo $link | sed 's/ftp.sra.ebi.ac.uk\//era-fasp@fasp.sra.ebi.ac.uk:/g')
elif [[ $DB == "GSA" ]]; then
if [[ ! -f .asperaGSA.openssh ]]; then
wget --user-agent="Mozilla/5.0" https://ngdc.cncb.ac.cn/gsa/file/downFile?fileName=download/aspera01.openssh -O .asperaGSA.openssh --quiet
fi
if [[ ! -f ".asperaGSA.openssh" ]]; then
echo -e "\033[1;31mError\033[0m: .asperaGSA.openssh is not exist"
echo -e "\033[1;32mHow to solve?\033[0m Please download GSA Aspera key file from https://ngdc.cncb.ac.cn/gsa/file/downFile?fileName=download/aspera01.openssh and rename it to .asperaGSA.openssh"
exit 1
fi
ascpKeyFile=.asperaGSA.openssh
local asperaLink=$(echo $link | sed 's/ftp:\/\/download.big.ac.cn\//aspera01@download.cncb.ac.cn:/g')
fi
if [[ $quiet -eq 1 ]]; then
ascp -q -P 33001 -i "$ascpKeyFile" -QT -l "${speed}M" -k1 -d "$asperaLink" .
else
ascp -P 33001 -i "$ascpKeyFile" -QT -l "${speed}M" -k1 -d "$asperaLink" .
fi
}
function validateQuery() {
local accession="$1"
if [[ $accession =~ ^PRJ[EDN][A-Z][0-9]+$ || $accession =~ ^[EDS]RP[0-9]{6,}$ ]]; then
echo "$accession"
elif [[ $accession =~ ^SAM[EDN][A-Z]?[0-9]+$ || $accession =~ ^[EDS]RS[0-9]{6,}$ ]]; then
echo "$accession"
elif [[ $accession =~ ^[EDS]RX[0-9]{6,}$ ]]; then # {6,} means at least 6 digits
echo "$accession"
elif [[ $accession =~ ^[EDS]RR[0-9]{6,}$ ]]; then
echo "$accession"
elif [[ $accession =~ ^GSE[0-9]+$ ]]; then
local bioproject=$(wget -qO- "https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=$accession" | grep -oe "PRJ[EDN][A-Z][0-9]\+" | uniq)
if [[ -z $bioproject ]]; then
echo -e "\033[1;31mError\033[0m: $accession is not valid GEO Series accession." >&2
exit 1
fi
echo -e "\033[32mNote\033[0m: $accession belongs to $bioproject" >&2
echo "$bioproject"
elif [[ $accession =~ ^GSM[0-9]+$ ]]; then
local biosample=$(wget -qO- "https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=$accession" | grep -oe "SAM[EDN][A-Z]\?[0-9]\+" | uniq)
if [[ -z $biosample ]]; then
echo -e "\033[1;31mError\033[0m: $accession is not a valid GEO Sample accession." >&2
exit 1
fi
echo -e "\033[32mNote\033[0m: $accession belongs to $biosample" >&2
echo "$biosample"
else
echo -e "\033[1;31mError\033[0m: $accession is not a valid Study, Sample, Experiment, or Run accession." >&2
exit 1
fi
}
function getSRAMetadata() {
local accession="$1"
local query=$(validateQuery "$accession")
if [[ -z $query ]]; then
exit 1
fi
wget -c "https://www.ebi.ac.uk/ena/portal/api/filereport?accession=$query&result=read_run&fields=study_accession,secondary_study_accession,sample_accession,secondary_sample_accession,experiment_accession,run_accession,submission_accession,tax_id,scientific_name,instrument_platform,instrument_model,library_name,nominal_length,library_layout,library_strategy,library_source,library_selection,read_count,base_count,center_name,first_public,last_updated,experiment_title,study_title,study_alias,experiment_alias,run_alias,fastq_bytes,fastq_md5,fastq_ftp,fastq_aspera,fastq_galaxy,submitted_bytes,submitted_md5,submitted_ftp,submitted_aspera,submitted_galaxy,submitted_format,sra_bytes,sra_md5,sra_ftp,sra_aspera,sra_galaxy,sample_alias,broker_name,sample_title,nominal_sdev,first_created,bam_ftp,bam_bytes,bam_md5&format=tsv&download=true&limit=0" -O $accession.metadata.tsv --quiet
#wget -c "https://www.ebi.ac.uk/ena/portal/api/search?result=read_run&format=tsv&query=\"$query\"&fields=all" -O $accession.metadata.tsv --quiet
if [[ -z $(awk -vFS="\t" 'NR==2 {print $1}' $accession.metadata.tsv) ]]; then
echo -e "\033[93mNote\033[0m: No metadata information found for $accession in the ENA database, try to download from the SRA database"
database="sra"
wget --quiet --output-document="$accession.xml" "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=sra&term=${accession}&usehistory=y"
WebEnv=$(grep -oP '<WebEnv>\K[^<]+' $accession.xml)
QueryKey=$(grep -oP '<QueryKey>\K[^<]+' $accession.xml)
rm -f $accession.xml
wget --quiet --output-document="$accession.metadata.tsv" "https://trace.ncbi.nlm.nih.gov/Traces/sra-db-be/sra-db-be.cgi?rettype=runinfo&WebEnv=${WebEnv}&query_key=${QueryKey}"
sed -i "s/,/\t/g" $accession.metadata.tsv
if [[ -z $(awk -vFS="\t" 'NR==2 {print $1}' $accession.metadata.tsv) ]]; then
echo -e "\033[1;31mError\033[0m: No metadata information found for $accession in the all databases"
echo -e "\033[1;32mHow to solve?\033[0m 1. Check your accession format: $accession; 2. $accession is not available in the SRA database; 3. Network is not available on your server"
rm -f $accession.metadata.tsv
exit 1
fi
fi
}
function downloadSRA() {
local SRR=$1 # only SRR_ID
local SRALink=$(grep "$SRR" $accession.metadata.tsv | tr "\t" "\n" | grep -e "ftp.sra.ebi.ac.uk/vol[0-9]/[sde]rr" | grep -v "lite" | uniq)
local FASTQLink=$(grep "$SRR" $accession.metadata.tsv | tr "\t" "\n" | grep -e "ftp.sra.ebi.ac.uk/vol[0-9]/fastq" | uniq)
if [[ $gzip -eq 1 && ! -z $FASTQLink && ! $database =~ ^[sS][rR][aA]$ && $fastq -eq 0 ]]; then
echo -e "\033[32mNote\033[0m: -g used, download FASTQ files in gzip format directly"
local layout=$(grep "$SRR" $accession.metadata.tsv | awk '{if($0~"PAIRED"){print "paired"}else{print "single"}}' | uniq)
local linkNum=$(echo $FASTQLink | tr ";" "\n" | wc -l) # even single-end data may have multiple links, such as SRR18030918
if [[ $layout == "single" && $linkNum -eq 1 ]]; then
local link=$(echo $FASTQLink | tr ";" "\n" | grep "fastq.gz")
if [[ $aspera -eq 1 ]]; then
echo -e "File size: $(wget --spider "ftp://$link" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: Aspera"
executeAspera "$link" "ENA"
else
if [[ $protocol == "https" ]]; then
echo -e "File size: $(wget --spider "https://$link" 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: ENA\tMode: https"
executeDownload "https://$link" $(basename $link)
else
echo -e "File size: $(wget --spider "ftp://$link" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: ftp"
executeDownload "ftp://$link" $(basename $link)
fi
fi
else
if [[ $layout == "single" ]]; then
echo -e "\033[93mNote\033[0m: $SRR is single-end data, but has multiple links"
fi
if [[ $linkNum -eq 2 ]]; then
local link1=$(echo $FASTQLink | tr ";" "\n" | grep "_1.fastq.gz")
local link2=$(echo $FASTQLink | tr ";" "\n" | grep "_2.fastq.gz")
if [[ $aspera -eq 1 ]]; then
echo -e "File size: $(wget --spider "ftp://$link1" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: Aspera"
executeAspera "$link1" "ENA"
echo -e "File size: $(wget --spider "ftp://$link2" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: Aspera"
executeAspera "$link2" "ENA"
else
if [[ $protocol == "https" ]]; then
echo -e "File size: $(wget --spider "https://$link1" 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: ENA\tMode: https"
executeDownload "https://$link1" $(basename $link1)
echo -e "File size: $(wget --spider "https://$link2" 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: ENA\tMode: https"
executeDownload "https://$link2" $(basename $link2)
else
echo -e "File size: $(wget --spider "ftp://$link1" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: ftp"
executeDownload "ftp://$link1" $(basename $link1)
echo -e "File size: $(wget --spider "ftp://$link2" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: ftp"
executeDownload "ftp://$link2" $(basename $link2)
fi
fi
else
echo -e "\033[93mNote\033[0m: $SRR is paired-end data, but has only one link" # such as SRR23680070
local link=$(echo $FASTQLink | tr ";" "\n" | grep ".fastq.gz")
if [[ $aspera -eq 1 ]]; then
echo -e "File size: $(wget --spider "ftp://$link" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: Aspera"
executeAspera "$link" "ENA"
else
if [[ $protocol == "https" ]]; then
echo -e "File size: $(wget --spider "https://$link" 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: ENA\tMode: https"
executeDownload "https://$link" $(basename $link)
else
echo -e "File size: $(wget --spider "ftp://$link" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: ftp"
executeDownload "ftp://$link" $(basename $link)
fi
fi
fi
fi
else
if [[ $database =~ ^[sS][rR][aA]$ || -z $SRALink ]]; then
if [[ $database =~ ^[eE][nN][aA]$ ]]; then
echo -e "\033[93mNote\033[0m: The SRA file of $SRR is not available in the ENA database, switch to the SRA database"
fi
if [[ $gzip -eq 1 && $fastq -eq 0 && ! $database =~ ^[sS][rR][aA]$ ]]; then
echo -e "\033[93mNote\033[0m: $SRR FASTQ file is also not available in the ENA database, switch to download SRA file"
fi
if [[ $gzip -eq 1 && $database =~ ^[sS][rR][aA]$ ]]; then
echo -e "\033[92mNote\033[0m: SRA database used, will download SRA file and convert to FASTQ file in gzip format"
fi
if [[ $aspera -eq 1 ]]; then
echo -e "\033[93mNote\033[0m: SRA database does not support Aspera download, switch to download SRA file by https"
fi
local link=$(srapath $SRR) # srapath may can't find the SRR file, e.g ERR1143237
if [[ -z $link ]]; then
echo -e "\033[1;31mError\033[0m: The sequencing file of $SRR is not available in all databases"
exit 1
fi
echo -e "File size: $(wget --spider $link 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: SRA\tMode: https"
executeDownload $link $SRR
else
if [[ $gzip -eq 1 && $fastq -eq 0 ]]; then
echo -e "\033[93mNote\033[0m: $SRR FASTQ file is not available in the ENA database, switch to download SRA file"
fi
if [[ $aspera -eq 1 ]]; then
echo -e "File size: $(wget --spider "ftp://$SRALink" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: Aspera"
executeAspera "$SRALink" "ENA"
else
if [[ $protocol == "https" ]]; then
echo -e "File size: $(wget --spider "https://$SRALink" 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: ENA\tMode: https"
executeDownload "https://$SRALink" $SRR
else
echo -e "File size: $(wget --spider "ftp://$SRALink" 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: ENA\tMode: ftp"
executeDownload "ftp://$SRALink" $SRR
fi
fi
fi
fi
}
count=1
function checkSRA() {
local SRR=$1 # only SRR_ID
if [[ $gzip -eq 1 && $fastq -eq 0 && ! $database =~ ^[sS][rR][aA]$ ]]; then
mapfile -t fastq_files < <(grep "$SRR" "${accession}.metadata.tsv" | grep -o "${SRR}\(_[^;/[:space:]]*\)\?\.fastq\.gz")
if [[ ${#fastq_files[@]} -gt 0 ]]; then
all_pass=true
for file in "${fastq_files[@]}"; do
if [[ ! -f $file ]]; then
all_pass=false
break
fi
md5=$(md5sum "$file" | awk '{print $1}')
if ! grep -q "$md5" "${accession}.metadata.tsv"; then
echo -e "\033[91mMD5 mismatch for:\033[0m $file"
all_pass=false
break
fi
done
if [[ "$all_pass" == true ]]; then
echo -e "\033[92m${SRR} download and md5 check successful, save ${SRR} in success.log\033[0m"
echo -e "$(date)\t$SRR" >> success.log
sed -i "/$SRR/d" fail.log 2>/dev/null
elif [[ $count -le 1 ]]; then
echo -e "\033[93mNote\033[0m: ${SRR} validate failed, retry ${count} times"
downloadSRA "$SRR"
count=$((count+1))
checkSRA "$SRR"
elif [[ $count -le 2 ]]; then
echo -e "\033[93mNote\033[0m: ${SRR} validate failed, remove the files and retry ${count} times"
rm -f "${fastq_files[@]}"
downloadSRA "$SRR"
count=$((count+1))
checkSRA "$SRR"
else
for f in "${fastq_files[@]}"; do
[[ -f "$f" ]] && rm -f "$f"
done
echo -e "\033[91m${SRR} md5 check failed after trying ${count} times, save Run ID in fail.log\033[0m"
echo -e "$(date)\t$SRR" >> fail.log
#exit 1
touch "$tmp_fail_flag"
fi
else
echo -e "\033[93mNote\033[0m: No FASTQ files found for ${SRR}"
if [[ $count -le 2 ]]; then
count=$((count+1))
downloadSRA "$SRR"
checkSRA "$SRR"
else
for f in "${fastq_files[@]}"; do
[[ -f "$f" ]] && rm -f "$f"
done
echo -e "\033[91m${SRR} failed: no FASTQ files after retry, saving to fail.log\033[0m"
echo -e "$(date)\t$SRR" >> fail.log
touch "$tmp_fail_flag"
fi
fi
else
vdb-validate ./$SRR > $SRR.log 2>&1
if [[ $? -eq 0 ]]; then
echo -e "\033[92m${SRR} download and md5 check successful, save ${SRR} in success.log\033[0m"
echo -e "$(date)\t$SRR" >> success.log
sed -i "/$SRR/d" fail.log 2>/dev/null
rm -f $SRR.log
elif [[ $count -le 1 ]]; then # retry times
echo -e "\033[93mNote\033[0m: ${SRR} validate failed, retry ${count} times"
downloadSRA $SRR
count=$((count+1))
checkSRA $SRR
elif [[ $count -le 2 ]]; then # retry times
echo -e "\033[93mNote\033[0m: ${SRR} validate failed, remove the file and retry ${count} times"
if [[ -f "$SRR" ]]; then rm -f "$SRR"; fi
downloadSRA $SRR
count=$((count+1))
checkSRA $SRR
else
if [[ -f "$SRR" ]]; then rm -f "$SRR"; fi
echo -e "\033[91m${SRR} md5 check failed after trying ${count} times, save Run ID in fail.log\033[0m"
echo -e "$(date)\t$SRR" >> fail.log
touch "$tmp_fail_flag"
fi
fi
}
function getGSAxlsx(){
local cra=$1
wget --quiet --post-data="type=3&dlAcession=${cra}" \
--user-agent="Mozilla/5.0" \
--output-document="${cra}.metadata.xlsx" "https://ngdc.cncb.ac.cn/gsa/file/exportExcelFile"
}
function getGSAMetadata() {
local accession=$1
if [[ $accession =~ ^CRR[0-9]+$ || $accession =~ ^CRX[0-9]+$ ]]; then
CRA=$(wget --user-agent="Mozilla/5.0" -qO- https://ngdc.cncb.ac.cn/gsa/search?searchTerm=${accession} | grep -v "example" | grep -oe "CRA[0-9]\+" | uniq)
if [[ -z $CRA ]]; then
echo -e "\033[1;31mError\033[0m: Cannot infer the Project ID (CRA*) for $accession." >&2
echo -e "\033[1;32mHow to solve?\033[0m 1. Check your internet connection (You can try \"wget https://ngdc.cncb.ac.cn/gsa/search?searchTerm=${accession}\" for a test). 2. Check the format of $accession."
exit 1
fi
wget --quiet --post-data="searchTerm=${CRA}&totalDatas=9999&downLoadCount=9999" \
--user-agent="Mozilla/5.0" \
--output-document="${accession}.tmp" "https://ngdc.cncb.ac.cn/gsa/search/getRunInfoByCra"
awk -vaccession=${accession} 'NR==1{print $0}NR>1{if($0~accession)print $0}' ${accession}.tmp > ${accession}.metadata.csv
rm ${accession}.tmp
if [[ ! -f ${CRA}.metadata.xlsx ]]; then
echo -e "\033[32mNote\033[0m: ${accession} belongs to ${CRA}, ${CRA}.metadata.xlsx will also be downloaded"
getGSAxlsx $CRA
fi
elif [[ $accession =~ ^PRJC[A-Z][0-9]+$ || $accession =~ ^SAMC[0-9]+$ || $accession =~ ^CRA[0-9]+$ ]]; then
if [[ $accession =~ ^PRJC[A-Z][0-9]+$ || $accession =~ ^SAMC[0-9]+$ ]]; then
wget --quiet --post-data="searchTerm=%26quot%3B${accession}%26quot%3BtotalDatas=9999%3BdownLoadCount=9999" \
--user-agent="Mozilla/5.0" \
--output-document="${accession}.metadata.csv" "https://ngdc.cncb.ac.cn/gsa/search/getRunInfo"
elif [[ $accession =~ ^CRA[0-9]+$ ]]; then
wget --quiet --post-data="searchTerm=${accession}&totalDatas=9999&downLoadCount=9999" \
--user-agent="Mozilla/5.0" \
--output-document="${accession}.metadata.csv" "https://ngdc.cncb.ac.cn/gsa/search/getRunInfoByCra"
fi
if [[ $(awk -F, 'NR==2{print $1}' ${accession}.metadata.csv) == "" ]]; then
echo -e "\033[1;31mError\033[0m: $accession is not a valid Study, Sample, or Experiment accession." >&2
rm ${accession}.metadata.csv
exit 1
fi
CRA=$(grep -oe "CRA[0-9]\+" ${accession}.metadata.csv | uniq) # when accession is PRJ, CRA may be more than one
while IFS= read -r cra; do
if [[ ! -f ${cra}.metadata.xlsx ]]; then
if [[ $accession =~ ^CRA[0-9]+$ ]]; then
echo -e "\033[32mNote\033[0m: ${cra}.metadata.xlsx will also be downloaded"
else
echo -e "\033[32mNote\033[0m: ${accession} belongs to ${cra}, ${cra}.metadata.xlsx will also be downloaded"
fi
getGSAxlsx "$cra"
fi
done <<< "$CRA"
else
echo -e "\033[1;31mError\033[0m: $accession is not a valid Study, Sample, Experiment, or Run accession." >&2
exit 1
fi
}
function downloadGSA() {
local CRR=$1 # only CRR_ID
local CRA=$(grep "$CRR" ${accession}.metadata.csv | grep -o "CRA[0-9]\+" | uniq)
local allLinks=$(wget -qO- --user-agent="Mozilla/5.0" https://ngdc.cncb.ac.cn/gsa/browse/${CRA}/${CRR} | grep -oE '(https|ftp)://[^"]*\.(gz|bam|tar|bz2)' | sort | uniq)
local httpsLink=$(echo $allLinks | tr " " "\n" | grep "https://download.cncb.ac.cn")
local ftpLink=$(echo $allLinks | tr " " "\n" | grep "ftp://download.big.ac.cn")
local HuaWeiLink=$(echo $allLinks | tr " " "\n" | grep "huaweicloud")
if [[ ! -z $HuaWeiLink ]]; then # use HuaWei Cloud to download firstly, even if aspera is available
if [[ $aspera -eq 1 ]]; then
echo -e "\033[92mNote\033[0m: HUAWEI Cloud is available, which is faster than Aspera, so HUAWEI Cloud will be used first, even if -a option is used"
fi
for link in $HuaWeiLink; do
local SaveName=$(basename $link)
if [[ $(grep -c $SaveName success.log) -ge "1" ]]; then
echo -e "\033[32mNote\033[0m: ${SaveName} has been downloaded successfully, please check success.log for details. If you want to download it again, please remove it from success.log (sed -i '/$$SaveName/d' success.log)"
else
echo -e "File size: $(wget --user-agent="Mozilla/5.0" --spider $link 2>&1 | grep Length | awk '{printf "%.2fG", ($2/1024/1024/1024)}')\tDatabase: GSA\tMode: HUAWEI Cloud"
executeDownload $link $SaveName
if [[ $skip_md5 -eq 0 ]]; then
checkGSA $SaveName $CRR
else
echo -e "\033[32mNote\033[0m: Skip md5 check for $SaveName, as -k option is used"
fi
fi
done
elif [[ $aspera -eq 1 ]]; then
for link in $ftpLink; do
local SaveName=$(basename $link)
if [[ $(grep -c $SaveName success.log) -ge "1" ]]; then
echo -e "\033[32mNote\033[0m: ${SaveName} has been downloaded successfully, please check success.log for details. If you want to download it again, please remove it from success.log (sed -i '/$$SaveName/d' success.log)"
else
echo -e "File size: $(wget --user-agent="Mozilla/5.0" --spider $link 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: GSA\tMode: Aspera"
executeAspera $link "GSA"
if [[ $skip_md5 -eq 0 ]]; then
checkGSA $SaveName $CRR
else
echo -e "\033[32mNote\033[0m: Skip md5 check for $SaveName, as -k option is used"
fi
fi
done
else
for link in $ftpLink; do
local SaveName=$(basename $link)
if [[ $(grep -c $SaveName success.log) -ge "1" ]]; then
echo -e "\033[32mNote\033[0m: ${SaveName} has been downloaded successfully, please check success.log for details. If you want to download it again, please remove it from success.log (sed -i '/$$SaveName/d' success.log)"
else
echo -e "File size: $(wget --user-agent="Mozilla/5.0" --spider $link 2>&1 | grep SIZE | awk '{printf "%.2fG", ($5/1024/1024/1024)}')\tDatabase: GSA\tMode: ftp"
executeDownload $link $SaveName
if [[ $skip_md5 -eq 0 ]]; then
checkGSA $SaveName $CRR
else
echo -e "\033[32mNote\033[0m: Skip md5 check for $SaveName, as -k option is used"
fi
fi
done
fi
}
count=1
function checkGSA() {
local filename=$1 # CRR file name
local CRR=$2
if [[ ! -f $CRA.md5sum.txt ]]; then
md5URL=$(echo "https://download.cncb.ac.cn/"$(grep -oe "gsa[0-9]\+/$CRA\|gsa/$CRA" ${accession}.metadata.csv | uniq)"/md5sum.txt")
wget --user-agent="Mozilla/5.0" "$md5URL" -O $CRA.md5sum.txt --quiet
fi
if ! command -v md5sum >/dev/null 2>&1 || [[ ! -s $CRA.md5sum.txt ]]; then
echo -e "\033[32mNote\033[0m: Skip md5 check for $filename, as md5sum command is not available or $CRA.md5sum.txt is empty"
CheckFile $filename
echo -e "\033[92m${filename} download successful, save ${filename} in success.log\033[0m"
echo -e "$(date)\t$filename" >> success.log
sed -i "/$filename/d" fail.log 2>/dev/null
else
local md5sum=$(grep "$filename" $CRA.md5sum.txt | awk '{print tolower($1)}')
if [[ -f $filename && $(md5sum $filename | awk '{print $1}') == $md5sum ]]; then
echo -e "\033[92m${filename} download and md5 check successful, save ${filename} in success.log\033[0m"
echo -e "$(date)\t$filename" >> success.log
sed -i "/$filename/d" fail.log 2>/dev/null
elif [[ $count -le 1 ]]; then # retry times
echo -e "\033[93mNote\033[0m: ${filename} validate failed, retry ${count} times"
count=$((count+1))
downloadGSA $CRR
elif [[ $count -le 2 ]]; then # retry times
echo -e "\033[93mNote\033[0m: ${filename} validate failed, remove the file and retry ${count} times"
rm -f $filename
count=$((count+1))
downloadGSA $CRR
else
echo -e "\033[91m${filename} md5 check failed after trying ${count} times, save ${filename} in fail.log\033[0m"
echo -e "$(date)\t$filename" >> fail.log
#exit 1
touch "$tmp_fail_flag"
fi
fi
}
function mergeSRArun(){
local metadata=$1
if [[ $merge == "ex" ]]; then
local experimentList=$(grep -oe "[EDS]RX[0-9]\+" $metadata | sort | uniq)
elif [[ $merge == "sa" ]]; then
local experimentList=$(grep -oe "SAM[EDN][A-Z]*[0-9]\+" $metadata | sort | uniq)
elif [[ $merge == "st" ]]; then
local experimentList=$(grep -oe "PRJ[EDN][A-Z][0-9]\+" $metadata | sort | uniq)
fi
for experiment in $experimentList; do
local runList=$(awk -vFS="\t" -v experiment=$experiment 'NR>1 && $0~experiment {print $1}' $metadata)
local layout=$(grep $experiment $metadata | awk '{if($0~"PAIRED"){print "paired"}else{print "single"}}' | uniq)
local SRR=$(echo $runList | awk '{print $1}') # get the first run ID
if [[ $gzip -eq 1 && ( -f ${SRR}_1.fastq.gz || -f ${SRR}_2.fastq.gz || -f ${SRR}.fastq.gz ) ]]; then
if [[ -f ${experiment}.fastq.gz || -f ${experiment}_1.fastq.gz ]]; then
echo -e "\033[32mNote\033[0m: ${experiment} has been merged, skip"
else
if [[ $(echo $runList | wc -w) -eq 1 ]]; then # if only one run in the experiment, just rename it
if [[ $layout == "single" ]]; then
echo -e "\033[32mNote\033[0m: $experiment only has one run, rename $runList to $experiment.fastq.gz"
ln -s ${runList}.fastq.gz ${experiment}.fastq.gz
else
echo -e "\033[32mNote\033[0m: $experiment only has one run, rename $runList to ${experiment}_1.fastq.gz and ${experiment}_2.fastq.gz"
ln -s ${runList}_1.fastq.gz ${experiment}_1.fastq.gz
ln -s ${runList}_2.fastq.gz ${experiment}_2.fastq.gz
fi
else
if [[ $layout == "single" ]]; then
echo -e "\033[32mNote\033[0m: Those runs: \n$(for run in $runList; do echo $run.fastq.gz; done) \nwill be merged into $experiment.fastq.gz, may take a while"
cat $(for run in $runList; do echo $run.fastq.gz; done) > ${experiment}.fastq.gz
# for run in $runList; do rm -f $run.fastq.gz; done
else
echo -e "\033[32mNote\033[0m: Those runs: \n$(for run in $runList; do echo ${run}_1.fastq.gz; done) \nwill be merged into ${experiment}_1.fastq.gz, may take a while"
cat $(for run in $runList; do echo ${run}_1.fastq.gz; done) > ${experiment}_1.fastq.gz
# for run in $runList; do rm -f ${run}_1.fastq.gz; done
echo -e "\033[32mNote\033[0m: Those runs: \n$(for run in $runList; do echo ${run}_2.fastq.gz; done) \nwill be merged into ${experiment}_2.fastq.gz, may take a while"
cat $(for run in $runList; do echo ${run}_2.fastq.gz; done) > ${experiment}_2.fastq.gz
# for run in $runList; do rm -f ${run}_2.fastq.gz; done
fi
fi
fi
elif [[ -f ${SRR}.fastq || -f ${SRR}_1.fastq || -f ${SRR}_2.fastq ]]; then
if [[ -f ${experiment}.fastq || -f ${experiment}_1.fastq ]]; then
echo -e "\033[32mNote\033[0m: ${experiment} has been merged, skip"
else
if [[ $(echo $runList | wc -w) -eq 1 ]]; then # if only one run in the experiment, just rename it
if [[ $layout == "single" ]]; then
if [[ $runList =~ _1.fastq ]]; then # maybe is a single cell data
echo -e "\033[32mNote\033[0m: $experiment only has one run, rename $runList to ${experiment}_1.fastq"
ln -s ${runList}_1.fastq ${experiment}_1.fastq
else
echo -e "\033[32mNote\033[0m: $experiment only has one run, rename $runList to $experiment.fastq"
ln -s ${runList}.fastq ${experiment}.fastq
fi
else
echo -e "\033[32mNote\033[0m: $experiment only has one run, rename $runList to ${experiment}_1.fastq and ${experiment}_2.fastq"
ln -s ${runList}_1.fastq ${experiment}_1.fastq
ln -s ${runList}_2.fastq ${experiment}_2.fastq
fi
else
if [[ $layout == "single" ]]; then
echo -e "\033[32mNote\033[0m: Those runs: \n$(for run in $runList; do echo $run.fastq; done) \nwill be merged into $experiment.fastq, may take a while"
cat $(for run in $runList; do echo $run.fastq; done) > ${experiment}.fastq
# for run in $runList; do rm -f $run.fastq; done
else
echo -e "\033[32mNote\033[0m: Those runs: \n$(for run in $runList; do echo ${run}_1.fastq; done) \nwill be merged into ${experiment}_1.fastq, may take a while"
cat $(for run in $runList; do echo ${run}_1.fastq; done) > ${experiment}_1.fastq
# for run in $runList; do rm -f ${run}_1.fastq; done
echo -e "\033[32mNote\033[0m: Those runs: \n$(for run in $runList; do echo ${run}_2.fastq; done) \nwill be merged into ${experiment}_2.fastq, may take a while"
cat $(for run in $runList; do echo ${run}_2.fastq; done) > ${experiment}_2.fastq
# for run in $runList; do rm -f ${run}_2.fastq; done
fi
fi
fi
else
echo -e "\033[1;31mError\033[0m: $SRR can't be found when merge $experiment" >&2
exit 1
fi
done
}
function mergeGSArun(){
local metadata=$1
if [[ $merge == "ex" ]]; then
local experimentList=$(grep -oe "CRX[0-9]\+" $metadata | sort | uniq)
elif [[ $merge == "sa" ]]; then
local experimentList=$(grep -oe "SAMC[0-9]\+" $metadata | sort | uniq)
elif [[ $merge == "st" ]]; then
local experimentList=$(grep -oe "PRJC[A-Z][0-9]\+" $metadata | sort | uniq)
fi
for experiment in $experimentList; do
local colNum=$(grep $experiment $metadata | cut -d "," -f7 | awk -vFS="|" '{print NF}' | uniq)
local rowNum=$(grep $experiment $metadata | wc -l)
if [[ $rowNum -eq 1 ]]; then # if only one run in the experiment, just rename it
local CRR=$(grep $experiment $metadata | cut -d "," -f1)
local prefixes=$(grep $experiment $metadata | cut -d "," -f7 |
awk -vFS="|" '{for(i=1;i<=NF;i++) print $i}' |
awk -F"/" '{print $NF}' |
awk -F '[._]' '{print $1}' | uniq)
if [[ $CRR == $prefixes ]]; then # Due to one CRR may have multiple files, so need to check if the CRR is the same as the prefixe of those files
grep $experiment $metadata | cut -d "," -f7 | awk -vFS="|" '{for(i=1;i<=NF;i++) print $i}' | awk -F"/" '{print $NF}' | while read filename; do
if [[ -f ${filename/$CRR/$experiment} && ! -f $filename ]]; then
echo -e "\033[32mNote\033[0m: ${filename/$CRR/$experiment} has been merged (here renamed), skip"
else
echo -e "\033[32mNote\033[0m: $experiment only has one run $CRR, rename $filename to ${filename/$CRR/$experiment}"
ln -s $filename ${filename/$CRR/$experiment}
fi
done
else
echo -e "\033[32mNote\033[0m: $experiment only has one run ($CRR), however, the prefix ($(echo $prefixes)) of the files are different, rename them:"
grep $experiment $metadata | cut -d "," -f7 | awk -vFS="|" '{for(i=1;i<=NF;i++) print $i}' | awk -F"/" '{print $NF}' | while read filename; do
if [[ -f ${experiment}_${filename} && ! -f $filename ]]; then
echo -e "\033[32mNote\033[0m: ${experiment}_${filename} has been merged (here renamed), skip"
else
echo -e "\033[32mNote\033[0m: Rename $filename to ${experiment}_${filename}"
ln -s $filename ${experiment}_${filename}
fi
done
fi
else
for ((i=1; i<=$colNum; i++)); do
local files=$(grep $experiment $metadata | cut -d "," -f7 | awk -vFS="|" -v i=$i '{print $i}' | awk -F"/" '{print $NF}')
local prefix=$(echo $files | awk -F"[._]" '{print $1}' | uniq)
local CRR=$(grep $prefix $metadata | cut -d "," -f1 | uniq)
local example_file=$(echo $files | cut -d " " -f1)
if [[ $example_file =~ [fastq|fq].gz ]]; then # only can merge [fastq|fq].gz files
if [[ $CRR == $prefix ]]; then
if [[ -f ${example_file/$prefix/$experiment} ]]; then
echo -e "\033[32mNote\033[0m: ${example_file/$prefix/$experiment} has been merged, skip"
else
echo -e "\033[32mNote\033[0m: Those files: \n$(for file in $files; do echo $file; done) \nwill be merged into ${example_file/$prefix/$experiment}, may take a while"
cat $(for file in $files; do echo $file; done) > ${example_file/$prefix/$experiment}
# for file in $files; do rm -f $file; done
fi
else
if [[ -f ${experiment}_${example_file} ]]; then
echo -e "\033[32mNote\033[0m: ${experiment}_${example_file} has been merged, skip"
else
echo -e "\033[32mNote\033[0m: Those files: \n$(for file in $files; do echo $file; done) \nwill be merged into ${experiment}_${example_file}, may take a while"
cat $(for file in $files; do echo $file; done) > ${experiment}_${example_file}
# for file in $files; do rm -f $file; done
fi
fi
else
echo -e "\033[93mNote\033[0m: Those files: \n$(for file in $files; do echo $file; done) \nwill not be merged, as they are not end with [fastq|fq].gz"
fi
done
fi
done
}
# ==================================================
# ==================process=========================
# ==================================================
tmp_fail_flag=".has_failed.flag"
rm -f $tmp_fail_flag
printf "%s\n" "${accessions[@]}" | while read -r accession; do
(
if [[ $accession =~ ^PRJC[A-Z][0-9]+$ || $accession =~ ^SAMC[0-9]+$ || $accession =~ ^CRA[0-9]+$ || $accession =~ ^CRX[0-9]+$ || $accession =~ ^CRR[0-9]+$ ]]; then
if [[ -s ${accession}.metadata.csv ]]; then
echo -e "\033[32mNote\033[0m: ${accession}.metadata.csv exists, skip downloading metadata for $accession"
else
getGSAMetadata $accession
CheckFile $accession.metadata.csv
fi
if [[ $metadata -eq 0 ]]; then
awk -F, 'NR>1{split($5, filenames, "|");split($6, fileSizes, "|")
for (i=1; i<=length(filenames); i++) {fileSize = fileSizes[i] / (1024 * 1024 * 1024);printf " %s %.2fG \t ", filenames[i], fileSize}
printf "\n"}' ${accession}.metadata.csv
echo -e "\033[32mNote\033[0m: Above Run will be downloaded. You can see the details in ${accession}.metadata.csv"
CRA=$(grep -oe "CRA[0-9]\+" ${accession}.metadata.csv | uniq)
for CRR in $(awk -F, 'NR>1{print $1}' ${accession}.metadata.csv | sort -u); do
if [[ ! -f success.log ]]; then
touch success.log
fi
# check all CRR files
filenames=$(awk -F, -v cr=$CRR 'NR>1 && $1==cr {
split($5, arr, "|");
for (i in arr) print arr[i];
}' ${accession}.metadata.csv)
all_present=true
for fname in $filenames; do
if ! grep -q "$fname" success.log; then
all_present=false
break
fi
done
if $all_present; then
echo -e "\033[32mNote\033[0m: ${CRR} has been downloaded successfully, please check success.log for details. If you want to download it again, please remove it from success.log (sed -i '/${CRR}/d' success.log)"
else
downloadGSA $CRR
fi
done
rm -f $CRA.md5sum.txt
if [[ "$merge" != 0 && $? -eq 0 ]]; then
echo -e "\033[32mNote\033[0m: All Runs have been downloaded, start to merge them"
mergeGSArun ${accession}.metadata.csv
fi
else
echo -e "\033[32mNote\033[0m: You choose to skip downloading GSA files (-m used), only retrieve the metadata for each accession, see ${accession}.metadata.csv"
fi
else
if [[ -s $accession.metadata.tsv ]]; then
echo -e "\033[32mNote\033[0m: $accession.metadata.tsv exists, skip downloading metadata for $accession"
else
getSRAMetadata $accession
CheckFile $accession.metadata.tsv
fi
if [[ $metadata -eq 0 ]]; then
FASTQLinktmp=$(grep -o 'ftp\.sra\.ebi\.ac\.uk/vol[0-9]/fastq/[^ ]*\.fastq\.gz' $accession.metadata.tsv)
if [[ $gzip -eq 1 && ! -z $FASTQLinktmp && $fastq -eq 0 ]]; then
awk -v FS="\t" 'NR>1{split($30, filenames, ";"); split($28, fileSizes, ";");
for (i=1; i<=length(filenames); i++) { split(filenames[i], parts, "/");file_extension = parts[length(parts)];
fileSize = fileSizes[i] / (1024 * 1024 * 1024);printf " %s %.2fG \t ", file_extension, fileSize;}printf "\n"}' ${accession}.metadata.tsv
else
awk -v FS="\t" 'NR>1{size7 = $7/1024;size8 = $8/1024;size39 = $39/1024/1024/1024;
if (size7 == 0 && size8 != 0) {if ($0~"lite"){printf " %s\t>%.2fG\n", $1, size39} else {printf " %s\t%.2fG\n", $1, size39}}
else {printf " %s\t%.2fG\n", $1, size8}}' $accession.metadata.tsv
fi
echo -e "\033[32mNote\033[0m: Above Run will be downloaded. You can see the details in $accession.metadata.tsv"
for SRR in $(awk -vFS="\t" 'NR>1 {print $1}' $accession.metadata.tsv); do
if [[ ! -f success.log ]]; then
touch success.log
fi
if [[ $(grep -c $SRR success.log) -ge "1" ]]; then
echo -e "\033[32mNote\033[0m: ${SRR} has been downloaded successfully, please check success.log for details. If you want to download it again, please remove it from success.log (sed -i '/$SRR/d' success.log)"
elif [[ -f $SRR ]]; then
if [[ $skip_md5 -eq 0 ]]; then
checkSRA $SRR
else
echo -e "\033[32mNote\033[0m: Skip md5 check for $SRR, as -k option is used"
fi
else
downloadSRA $SRR
if [[ $skip_md5 -eq 0 ]]; then
checkSRA $SRR
else
echo -e "\033[32mNote\033[0m: Skip md5 check for $SRR, as -k option is used"
fi
fi
SRX=$(grep $SRR $accession.metadata.tsv | grep -oe "[EDS]RX[0-9]\+" | sort | uniq)
if [[ ($fastq -eq 1 || "$merge" != 0 || $gzip -eq 1) && -f $SRR
&& ! -f ${SRR}_1.fastq.gz && ! -f ${SRR}_2.fastq.gz && ! -f ${SRR}.fastq.gz
&& ! -f ${SRX}_1.fastq.gz && ! -f ${SRX}_2.fastq.gz && ! -f ${SRX}.fastq.gz ]]; then # if SRA file is not exist, means fastq files have been downloaded
echo -e "\033[32mNote\033[0m: Converting $SRR to fastq files using $threads threads"
SrrPath=$(dirname $(realpath $SRR))
if [[ $quiet -eq 1 ]]; then
fasterq-dump -p -S --include-technical -e $threads -O "$SrrPath" "$SrrPath/$SRR" > /dev/null 2>&1
else
fasterq-dump -p -S --include-technical -e $threads -O "$SrrPath" "$SrrPath/$SRR"
fi
rm -rf fasterq.tmp*
if [[ $gzip -eq 1 && -f $SRR ]]; then
ls ${SRR}*fastq | while read fastq; do
echo -e "\033[32mNote\033[0m: Compressing $fastq to $fastq.gz using $threads threads, may take a while"
pigz -p $threads $fastq
done
fi
fi
done
if [[ "$merge" != 0 && $? -eq 0 ]]; then
echo -e "\033[32mNote\033[0m: All Runs have been downloaded, start to merge them"
mergeSRArun $accession.metadata.tsv
fi
else
echo -e "\033[32mNote\033[0m: You choose to skip downloading SRA files (-m used), only retrieve the metadata for each accession, see $accession.metadata.tsv"
fi
fi
if [[ $? -eq 0 ]]; then
total_equals=$(( ($(tput cols) - ${#accession} - 22) / 2 ))
equals=$(printf "%-${total_equals}s" "=")
echo "${equals// /=}${accession} download finished${equals// /=}"
fi
)
done
if [[ -f $tmp_fail_flag ]]; then
echo -e "\033[1;31mError\033[0m: Download failures detected. Please check \033[4mfail.log\033[0m for details."
echo -e "\033[93mNote:\033[0m You can re-run the script to retry failed items."
exit 1
fi
================================================
FILE: docs/ChineseTutorial.md
================================================
## iSeq使用方法
- 中文纯手打,英文是由ChatGPT翻译的😀
```{bash}
$ iseq --help
Usage:
iseq -i accession [options]
Required option:
-i, --input [text|file] Single accession or a file containing multiple accessions.
Note: Only one accession per line in the file.
Optional options:
-m, --metadata Skip the sequencing data downloads and only fetch the metadata for the accession.
-g, --gzip Download FASTQ files in gzip format directly (*.fastq.gz).
Note: if *.fastq.gz files are not available, SRA files will be downloaded and converted to *.fastq.gz files.
-q, --fastq Convert SRA files to FASTQ format.
-t, --threads int The number of threads to use for converting SRA to FASTQ files or compressing FASTQ files (default: 8).
-e, --merge [ex|sa|st] Merge multiple fastq files into one fastq file for each Experiment, Sample or Study.
ex: merge all fastq files of the same Experiment into one fastq file. Accession format: ERX, DRX, SRX, CRX.
sa: merge all fastq files of the same Sample into one fastq file. Accession format: ERS, DRS, SRS, SAMC, GSM.
st: merge all fastq files of the same Study into one fastq file. Accession format: ERP, DRP, SRP, CRA.
-d, --database [ena|sra] Specify the database to download SRA sequencing data (default: ena).
Note: new SRA files may not be available in the ENA database, even if you specify "ena".
-p, --parallel int Download sequencing data in parallel, the number of connections needs to be specified, such as -p 10.
Note: breakpoint continuation cannot be shared between different numbers of connections.
-a, --aspera Use Aspera to download sequencing data, only support GSA/ENA database.
-s, --speed int Download speed limit (MB/s) (default: 1000 MB/s).
-k, --skip-md5 Skip the md5 check for the downloaded files.
-r, --protocol [ftp|https] Specify the protocol only when downloading files from ENA (default: ftp).
-Q, --quiet Suppress download progress bars.
-o, --output text The output directory. If not exists, it will be created (default: current directory).
-h, --help Show the help information.
-v, --version Show the script version.
```
### 1. `-i`, `--input`
输入你想下载的accession,首先获取accession的metadata,然后逐一对包含在内的Run ID进行下载。v1.1.0版本之后可以接收文件输入,每行一个accession。这个文件最好在linux下通过vim编辑,要不然从windows上传的话可能文字编码有问题影响下载(如win通常是`CR LF`, 而Linux能识别的是`LF`格式的)。
```bash
iseq -i PRJNA211801
```
目前支持以下5个数据库的6种数据格式,支持的accession前缀如下:
| Databases | BioProject | Study | BioSample | Sample | Experiment | Run |
| --------- | ---------- | ----- | --------- | ------ | ---------- | ---- |
| **GSA** | PRJC | CRA | SAMC | \ | CRX | CRR |
| **SRA** | PRJNA | SRP | SAMN | SRS | SRX | SRR |
| **ENA** | PRJEB | ERP | SAME | ERS | ERX | ERR |
| **DDBJ** | PRJDB | DRP | SAMD | DRS | DRX | DRR |
| **GEO** | GSE | \ | GSM | \ | \ | \ |
其中对于来自于GEO数据库的两种数据格式`GSE/GSM`,会直接获取到与之关联的`PRJNA/SAMN`,然后获取到包含在内的Run ID并进行测序数据的下载。因此,本质上还是从SRA数据库中下载测序数据。
以下是一些例子:
| Accession Type | Prefixes | Example |
| -------------- | ------------------------------ | ----------------------------------------------------------- |
| BioProject | PRJEB, PRJNA, PRJDB, PRJC, GSE | PRJEB42779, PRJNA480016, PRJDB14838, PRJCA000613, GSE122139 |
| Study | ERP, DRP, SRP, CRA | ERP126685, DRP009283, SRP158268, CRA000553 |
| BioSample | SAMD, SAME, SAMN, SAMC | SAMD00258402, SAMEA7997453, SAMN06479985, SAMC017083 |
| Sample | ERS, DRS, SRS, GSM | ERS5684710, DRS259711, SRS2024210, GSM7417667 |
| Experiment | ERX, DRX, SRX, CRX | ERX5050800, DRX406443, SRX4563689, CRX020217 |
| Run | ERR, DRR, SRR, CRR | ERR5260405, DRR421224, SRR7706354, CRR311377 |
总之,无论你的accession是6种数据格式的哪一种,最终都会对其中包含的Run ID逐一下载并检查文件的md5值,如果md5值和公共数据库中的不一致,则会进行至多3轮的重新下载。如果在3次尝试内下载并校验成功,则会将文件名存入`success.log`中,否则,下载失败,文件名将会存入`fail.log`中。
### 2. `-m`, `--metadata `
只下载accession的样本信息,跳过测序数据的下载。
```bash
iseq -i PRJNA211801 -m
iseq -i CRR343031 -m
```
因此,无论使用不使用`-m`参数,accession的样本信息都会被获取到,如果metadata获取不到的话,iSeq程序会退出,不会执行后续下载。
> [!NOTE]
> **注意1**:如果检索的accession在SRA/ENA/DDBJ/GEO数据库中,iSeq会首先在ENA数据库中进行检索,如果可以检索到样本信息,则会通过[ENA API](https://www.ebi.ac.uk/ena/portal/api/swagger-ui/index.html)下载`TSV`格式的metadata,通常有191列。但是,有些最新在SRA数据库中公开的数据可能不会及时同步到ENA数据库中。因此,如果一旦无法在ENA数据库中获取到metadata的信息,则直接通过[SRA Database Backend](https://trace.ncbi.nlm.nih.gov/Traces/sra-db-be/)下载`CSV`格式的metadata,通常有30列。为了和TSV格式保持一致,会通过`sed -i 's/,/\t/g'`的方式改为TSV格式,如何单个字段含有逗号,可能会造成列的混乱。最终,你将得到名字为`${accession}.metadata.tsv`的样本信息。
> [!NOTE]
>**注意2**:如果检索的accession在GSA数据库中,iSeq会通过GSA的[getRunInfo](https://ngdc.cncb.ac.cn/gsa/search/getRunInfo)接口获取样本信息,下载`CSV`格式的metadata,通常有25列,上述得到的metadata信息会被保存为`${accession}.metadata.csv`文件。为了补充更加详细的metadata信息,iSeq会自动通过GSA的[exportExcelFile](https://ngdc.cncb.ac.cn/gsa/file/exportExcelFile)接口获取accession所属的Project的metadata信息,下载`XLSX`格式的metadata,通常有3个sheet,分别是`Sample`, `Experiment`, `Run`。最终得到的metadata信息会被保存为`${accession}.metadata.xlsx`文件。总而言之,你最终将得到名字为`${accession}.metadata.csv`和`CRA*.metadata.xlsx`的样本信息。
### 3. `-g`, `--gzip`
直接下载gzip格式的FASTQ文件,如果不能直接下载,则会下载SRA文件并通过多线程分解和压缩转换为gzip格式。
```bash
iseq -i SRR1178105 -g
```
由于`GSA`数据库直接存储的格式大多数为`gzip`格式,因此,如果检索的accession来自于`GSA`数据库,无论是否使用`-g` 参数都可以直接下载`gzip`格式的FASTQ文件。如果accession来自于`SRA/ENA/DDBJ/GEO`数据库,那么iSeq会首先访问`ENA`数据库,如果可以直接下载`gzip`格式的FASTQ文件,则会直接下载,否则,会下载`SRA`文件并通过`fasterq-dump`工具转换为`FASTQ`, 然后通过`pigz`工具对`FASTQ`文件进行压缩,最终得到`gzip`格式的FASTQ文件。
### 4. `-q`, `--fastq`
将下载完成的SRA文件分解为多个未压缩的FASTQ格式。
```bash
iseq -i SRR1178105 -q
```
该参数只有在accession来自于`SRA/ENA/DDBJ/GEO`数据库,并且下载的文件为SRA文件时才有效。总之,SRA文件下载完成后,iSeq会通过`fasterq-dump`工具转换为`FASTQ`文件,除此之外,可以通过`-t`参数指定转换的线程数。
> [!NOTE]
> **注意1**:`-q`在下载单细胞数据,尤其对于scATAC-Seq数据,可以很好的分解出`I1`, `R1`, `R2`, `R3`四个文件。而如果通过`-g`参数直接下载FASTQ文件,只会得到`R1`, `R3`两个文件(如:[SRR13450125](https://www.ebi.ac.uk/ena/browser/view/SRR13450125)),这可能会导致后续数据分析时出现问题。
> [!NOTE]
> **`注意2`**:`-q`和`-g`同时使用的时候,会先下载SRA文件,然后通过`fasterq-dump`工具转换为`FASTQ`文件,最后通过`pigz`压缩为gzip格式。并不是直接下载gzip格式的FASTQ文件,这对获取全面的单细胞数据非常有用。
### 5. `-t`, `--threads`
指定分解SRA文件为FASTQ文件或者压缩FASTQ文件的线程数,默认为8。
```bash
iseq -i SRR1178105 -q -t 10
```
考虑到测序数据一般都是大文件,因此,可以通过`-t`参数指定分解的线程数,但是,线程数不是越多越好,因为线程数过多会导致CPU或者IO负载过高,尤其是`fasterq-dump`会占用大量IO,从而影响其他任务的执行。
### 6. `-e`, `--merge`
将Experiment中的多个FASTQ文件合并为一个FASTQ文件。 v1.1.0版本之后,不仅可以对同一个Experiment中的多个FASTQ文件合并,还可以选择不用的参数对Sample (-e sa)或者Study (-e st)进行合并。
```bash
iseq -i SRX003906 -g -e ex
```
虽然大多数情况下,一个Experiment仅包含一个Run,但是有些测序数据中的Experiment中可能包含多个Run(如[SRX003906](https://www.ebi.ac.uk/ena/browser/view/SRX003906), [CRX020217](https://ngdc.cncb.ac.cn/gsa/search?searchTerm=CRX020217)),因此,可以通过`-e`参数将Experiment中的多个FASTQ文件合并为一个FASTQ文件。考虑到双端测序时,`fastq_1`和`fastq_2`文件需要同时合并且对应行号的序列名需要保持一致,因此,iSeq会按照相同的顺序合并多个FASTQ文件。最终,对于单端测序数据会生成一个文件:`SRX*.fastq.gz`,对于双端测序数据会生成两个文件:`SRX*_1.fastq.gz`和`SRX*_2.fastq.gz`。对于Sample (-e sa)或者Study (-e st)同理。
> [!NOTE]
> **注意1**:如果accession是Run ID,则不能使用`-e`参数,反正就是你想合并的时候,输入的accession必须大于等于要合并的那一级所需要的accession。目前,iSeq支持合并gzip压缩和未压缩的FASTQ文件,对于bam文件和tar.gz文件等暂不支持合并。
> [!NOTE]
> **注意2**:正常情况下,一个Experiment仅包含一个Run时,相同的Run应该有相同的前缀。如`SRR52991314_1.fq.gz`和`SRR52991314_2.fq.gz`都有相同的前缀名`SRR52991314`,此时,iSeq会直接重命名为`SRX*_1.fastq.gz`和`SRX*_2.fastq.gz`。但是有例外的情况,如[CRX006713](https://ngdc.cncb.ac.cn/gsa/search?searchTerm=CRX006713)中包含有一个Run为`CRR007192`,但是该Run包含多个前缀名不同的文件,此时,iSeq会直接重命名为`SRX*_原本的文件名`,如这里将直接重命名为:`CRX006713_CRD015671.gz`和`CRX006713_CRD015672.gz`。
### 7. `-d`, `--database`
指定下载SRA文件的数据库,支持`ena`和`sra`两种数据库。
```bash
iseq -i SRR1178105 -d sra
```
通常情况下,iSeq默认会自动检测可用的数据库,所以不需要指定`-d`参数。但是,有些SRA文件可能在ENA数据库中下载速度较慢,此时可以通过`-d sra`强制指定从SRA数据库下载数据。
> [!NOTE]
> **注意**:如果在ENA数据库中没有找到对应的SRA文件,即使指定了`-d ena`参数,iSeq依旧会自动切换到SRA数据库进行下载。
### 8. `-p`, `--parallel`
开启多线程下载,需要指定下载的线程数。
```bash
iseq -i PRJNA211801 -p 10
```
考虑到`wget`在部分情况下下载速度较慢,因此,可以通过`-p`参数让`iSeq`调用`axel`工具进行多线程下载。
> [!NOTE]
> **注意1**:多线程下载的断点续传功能只能在同一个线程内有效,即如果在第一次下载时使用了`-p 10`参数,那么在第二次下载时也需要使用`-p 10`参数,否则无法实现断点续传。
> [!NOTE]
> **注意2**:如上,iSeq将全程保持10个连接进行下载,因此在下载的过程中你将多次看到相同的`Connection * finished`弹出,这是因为有些连接下载完成后会立即释放,然后重新建立新的连接进行下载。
### 9. `-a`, `--aspera`
使用Aspera进行下载。
```bash
iseq -i PRJNA211801 -a -g
```
由于`Aspera`下载速度较快,因此,可以通过`-a`参数让`iSeq`调用`ascp`工具进行下载。可惜的是,目前仅有`GSA`和`ENA`数据库支持`Aspera`下载,`NCBI SRA`数据库由于广泛采用了`Google Cloud` 和 `AWS Cloud`技术以及其他原因(请看[Avoid-using-ascp](https://github.com/ncbi/sra-tools/wiki/Avoid-using-ascp-directly-for-downloads)),暂无法使用`Aspera`进行下载。
> [!NOTE]
> **注意1**:在访问`GSA`数据库时,如果存在`HUAWEI Cloud`的下载链接,`iSeq`会优先通过`HUAWEI Cloud`通道下载,即使使用了`-a`参数,`iSeq`也会自动切换到`HUAWEI Cloud`下载。这么做的原因是`HUAWEI Cloud`下载速度更快和稳定。因此,在下载`GSA`数据时,推荐使用`-a`参数,这样如果访问不到`HUAWEI Cloud`通道,通过`Aspera`通道下载速度也不慢,否则,只能通过`wget`或者`axel`进行下载,而这两种方式下载速度较慢。
> [!NOTE]
> **注意2**:由于`Aspera`需要key文件,因此,`iSeq`会自动在`conda`环境或者`~/.aspera`目录下查找key文件,如果没有找到,则无法下载。
### 10. `-o`, `--output`
v1.1.0之后可以选择输出文件的位置,如果不存在相应的文件夹,则创建
```bash
iseq -i SRR931847 -o PRJNA211801
```
### 11. `-s`, `--speed`
v1.2.0之后可以选择限速下载,单位是MB/s
```bash
iseq -i SRR931847 -s 10
```
### 12 `-k`, `--skip-md5`
v1.9.2之后可以选择跳过md5文件完整性检验。当你初次跳过后, 想再次进行md5检验,只需要删除-k参数,执行相同的代码就可以了。
### 13 `-r`, `--protocol`
从 v1.9.4 开始,当在 ENA 下载文件时可以指定协议。这样做是因为有时候通过 HTTPS 下载的速度会比 FTP 更快。
### 14 `-Q `,`--quiet`
从v1.9.7开始,可以使用-Q或--quiet选项来不显示进度条,避免log文件反复写入进度信息。
================================================
FILE: docs/Examples.md
================================================
# Examples of using iSeq
## Basic examples
1. Download all Run sequencing data and metadata associated with a Project
```
iseq -i PRJNA211801
```

if you run the same code again, iSeq will **skip** downloaded data

```bash
iseq -i CRA000553
```
iSeq will prioritize access to the **HUAWEI Cloud** when accessing the **GSA** database.

```bash
iseq -i GSE122139
```
If the **MD5 check fails** after the sequencing data is downloaded, iSeq will attempt to re-download up to 3 times. If it still fails, the ID will be stored in the **fail.log file**.

```bash
iseq -i SRR931847 -o PRJNA211801
```
iSeq will save result in `PRJNA211801` directory.

3. Download all sequencing data and metadata associated with an Experiment or a BioSample
```bash
iseq -i SRX477044
iseq -i CRX020217
iseq -i GSM7417667
```
4. Download a single sequencing data and metadata associated with a Run
```bash
iseq -i SRR1178105
iseq -i CRR311377
```
5. Only download metadata information
```bash
iseq -i PRJNA211801 -m
```

6. Download SRA files and convert them to FASTQ files
```bash
iseq -i SRR1178105 -q
```

7. Download sequencing data in parallel with 10 connections
```bash
iseq -i SRR1178105 -p 10
```

8. Download sequencing data by Aspera
```bash
iseq -i SRR1178105 -a
```

```bash
iseq -i CRR311377 -a
```
When accessing the GSA database using Aspera, it will still prioritize access to the HUAWEI Cloud. If it is not available, it will proceed with the normal download using Aspera

9. Download gzip-formatted FASTQ files directly
```bash
iseq -i SRR1178105 -g
```

9. Merge multiple FASTQ files into one FASTQ file
- Merge multiple FASTQ files into one FASTQ file for `each Experiment`.
```bash
iseq -i CRX020217 -e ex
```

- Merge multiple FASTQ files into one FASTQ file for `each Sample`.
```bash
rm success.log
iseq -i SAMC017083 -e sa
```

- Merge multiple FASTQ files into one FASTQ file for `each Study`.
```bash
rm success.log
iseq -i PRJCA000613 -e st
```

9. Download sequencing data from SRA database
```bash
iseq -i SRR1178105 -d sra
```

## Advanced examples
1. Use 10 connections to download SRA files in parallel with `-p 10`, then demultiplex into FASTQ files with the default 8 threads using `-q` and quickly compress with `-g`. Finally, merge Runs from the same Experiment with `-e`.
```bash
iseq -i SRX2993509 -q -g -p 10 -e ex
```

2. Use Aspera with `-a` to directly download gzip-formatted FASTQ files with `-g`, and then merge Runs from the same Experiment. If there is only one Run, rename it with `-e`.
```bash
iseq -i PRJNA211801 -a -g -e ex
```

3. Batch download by giving a file and using Aspera with `-a` to directly download gzip-formatted FASTQ files with `-g`.
```bash
iseq -i SRR_Acc_List.txt -a -g
```

================================================
FILE: docs/benchmark/README.md
================================================
## Stability
iSeq demonstrated high stability, successfully downloading and passing integrity checks for a large number of NGS files from GSA and INSDC-related databases.
## Efficiency
- FTP Channel: Prioritizing ENA's FTP channel, iSeq showed fastest and stable download speeds with Aspera, while supporting parallel downloads with AXEL.
- Cloud Storage: AXEL was faster for AWS Cloud channel from SRA, while Wget was faster for HUAWEI Cloud channel from GSA.
- Gzip-formatted FASTQ Files Download: Directly fetching gzip-formatted FASTQ files proved to be the fastest method, with the option to use "--fastq" and "--gzip" parameters for specific data types. Increasing threads notably improved compression speed.
## Overview

================================================
FILE: docs/benchmark/TestFasterqDump/testFasterqDump.log
================================================
2 Convert SRA to FASTQ 74
2 Compress FASTQ 803
3 Convert SRA to FASTQ 66
3 Compress FASTQ 528
4 Convert SRA to FASTQ 64
4 Compress FASTQ 404
5 Convert SRA to FASTQ 53
5 Compress FASTQ 333
6 Convert SRA to FASTQ 53
6 Compress FASTQ 289
7 Convert SRA to FASTQ 50
7 Compress FASTQ 251
8 Convert SRA to FASTQ 67
8 Compress FASTQ 228
9 Convert SRA to FASTQ 75
9 Compress FASTQ 206
10 Convert SRA to FASTQ 77
10 Compress FASTQ 190
11 Convert SRA to FASTQ 76
11 Compress FASTQ 171
12 Convert SRA to FASTQ 62
12 Compress FASTQ 153
13 Convert SRA to FASTQ 72
13 Compress FASTQ 163
14 Convert SRA to FASTQ 82
14 Compress FASTQ 129
15 Convert SRA to FASTQ 70
15 Compress FASTQ 124
16 Convert SRA to FASTQ 71
16 Compress FASTQ 119
17 Convert SRA to FASTQ 59
17 Compress FASTQ 114
18 Convert SRA to FASTQ 62
18 Compress FASTQ 103
19 Convert SRA to FASTQ 66
19 Compress FASTQ 99
20 Convert SRA to FASTQ 68
20 Compress FASTQ 94
21 Convert SRA to FASTQ 81
21 Compress FASTQ 88
22 Convert SRA to FASTQ 67
22 Compress FASTQ 86
23 Convert SRA to FASTQ 72
23 Compress FASTQ 82
24 Convert SRA to FASTQ 80
24 Compress FASTQ 80
25 Convert SRA to FASTQ 66
25 Compress FASTQ 78
26 Convert SRA to FASTQ 64
26 Compress FASTQ 70
27 Convert SRA to FASTQ 65
27 Compress FASTQ 71
28 Convert SRA to FASTQ 66
28 Compress FASTQ 70
29 Convert SRA to FASTQ 70
29 Compress FASTQ 72
30 Convert SRA to FASTQ 85
30 Compress FASTQ 71
31 Convert SRA to FASTQ 67
31 Compress FASTQ 71
32 Convert SRA to FASTQ 77
32 Compress FASTQ 71
33 Convert SRA to FASTQ 74
33 Compress FASTQ 67
34 Convert SRA to FASTQ 78
34 Compress FASTQ 65
35 Convert SRA to FASTQ 84
35 Compress FASTQ 60
36 Convert SRA to FASTQ 95
36 Compress FASTQ 66
37 Convert SRA to FASTQ 86
37 Compress FASTQ 61
38 Convert SRA to FASTQ 81
38 Compress FASTQ 67
39 Convert SRA to FASTQ 80
39 Compress FASTQ 68
40 Convert SRA to FASTQ 88
40 Compress FASTQ 64
================================================
FILE: docs/benchmark/TestFasterqDump/timefasterqDump.sh
================================================
================================================
FILE: docs/benchmark/TestiSeq-2GB/TestiSeq-2GB.bash
================================================
#!/bin/bash
if command -v iseq >/dev/null 2>&1; then
sleep 0
else
echo "iseq is not installed"
echo "Please install iseq first"
echo "conda create -n iseq -c conda-forge -c bioconda iseq"
exit 1
fi
calculate_time_difference() {
start_time=$1
end_time=$2
method=$3
diff=$((end_time - start_time))
echo -e "${method}\t${diff}"
}
# Create a directory to store the downloaded files
if [ ! -d "iseq" ]; then
mkdir iseq
fi
cd ./iseq
# =======================================ENA=============================================
for ((i=1; i<=20; i++)); do
# SRX3662754 (SE, 540 MB)
SRX=SRX3662754
# CRX917377 (SE, 540 MB)
CRX=CRX917377
# Perform tests for ENA FTP download by Wget
start=$(date +%s)
iseq -i $SRX
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeENA.log
rm -rf *
# Perform tests for ENA FTP download by Aspera
start=$(date +%s)
iseq -i $SRX -a
end=$(date +%s)
calculate_time_difference $start $end "Aspera" >> ../timeENA.log
rm -rf *
# Perform tests for ENA FTP download by 10 parallel by AXEL
start=$(date +%s)
iseq -i $SRX -p 10
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeENA.log
rm -rf *
# =======================================ENA=============================================
# =======================================SRA=============================================
# Perform tests for SRA HTTPS download by Wget
start=$(date +%s)
iseq -i $SRX -d sra
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeSRA.log
rm -rf *
# Perform tests for SRA HTTPS download by AXEL
start=$(date +%s)
iseq -i $SRX -d sra -p 10
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeSRA.log
rm -rf *
# =======================================SRA=============================================
# =======================================ENA FQ/FQ.GZ====================================
# Perform tests to compare the time taken for directly downloading fq.gz files versus downloading fq files and then compressing them into fq.gz.
start=$(date +%s)
iseq -i $SRX -a -q
end=$(date +%s)
calculate_time_difference $start $end "--fastq" >> ../timeFQ.log
rm -rf *
start=$(date +%s)
iseq -i $SRX -a -q -g
end=$(date +%s)
calculate_time_difference $start $end "--fastq+gzip" >> ../timeFQ.log
rm -rf *
start=$(date +%s)
iseq -i $SRX -a -g
end=$(date +%s)
calculate_time_difference $start $end "--gzip" >> ../timeFQ.log
rm -rf *
# =======================================ENA FQ/FQ.GZ====================================
# =======================================GSA FTP=============================================
# Perform tests for GSA FTP download by Wget
start=$(date +%s)
iseq -i $CRX -m
wget ftp://download.big.ac.cn/gsa2/CRA014342/CRR1007729/CRR1007729.fq.gz
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeGSAFTP.log
rm -rf *
# Perform tests for GSA FTP download by AXEL
start=$(date +%s)
iseq -i $CRX -m
axel -n 10 -a -c ftp://download.big.ac.cn/gsa2/CRA014342/CRR1007729/CRR1007729.fq.gz
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeGSAFTP.log
rm -rf *
# Perform tests for GSA FTP download by Aspera
start=$(date +%s)
iseq -i $CRX -m
wget https://ngdc.cncb.ac.cn/gsa/file/downFile?fileName=download/aspera01.openssh -O .asperaGSA.openssh --quiet
ascp -P 33001 -i .asperaGSA.openssh -QT -l 1000m -k1 -d aspera01@download.cncb.ac.cn:gsa2/CRA014342/CRR1007729/CRR1007729.fq.gz .
end=$(date +%s)
calculate_time_difference $start $end "Aspera" >> ../timeGSAFTP.log
rm -rf *
# =======================================GSA HUAWEI_CLOUD=============================================
# Perform tests for GSA HUAWEI_CLOUD download by AXEL
start=$(date +%s)
iseq -i $CRX -m
axel -n 10 -a -c https://cncb-gsa.obs.cn-north-4.myhuaweicloud.com/data/gsapub/CRA014342/CRR1007729/CRR1007729.fq.gz
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeGSAHW.log
rm -rf *
# Perform tests for GSA HUAWEI_CLOUD download by Wget
start=$(date +%s)
iseq -i $CRX -m
wget https://cncb-gsa.obs.cn-north-4.myhuaweicloud.com/data/gsapub/CRA014342/CRR1007729/CRR1007729.fq.gz
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeGSAHW.log
rm -rf *
done
cd ..
================================================
FILE: docs/benchmark/TestiSeq-2GB/timeENA.log
================================================
Wget 583
Aspera 215
AXEL 59
Wget 976
Aspera 87
AXEL 73
Wget 607
Aspera 208
AXEL 69
Wget 187
Aspera 312
AXEL 54
Wget 150
Aspera 196
AXEL 129
Wget 522
Aspera 275
AXEL 113
Wget 671
Aspera 147
AXEL 70
Wget 151
Aspera 154
AXEL 46
Wget 142
Aspera 36
AXEL 50
Wget 1330
Aspera 51
AXEL 96
Wget 155
Aspera 57
AXEL 76
Wget 113
Aspera 246
AXEL 55
Wget 860
Aspera 732
AXEL 126
Wget 750
Aspera 53
AXEL 49
Wget 1137
Aspera 57
AXEL 104
Wget 909
Aspera 275
AXEL 74
Wget 804
Aspera 83
AXEL 67
Wget 94
Aspera 314
AXEL 53
Wget 814
Aspera 52
AXEL 93
Wget 1444
Aspera 48
AXEL 75
Wget 781
Aspera 23
AXEL 65
Wget 992
Aspera 440
AXEL 103
Wget 812
Aspera 26
AXEL 95
Wget 268
Aspera 30
AXEL 130
Wget 314
Aspera 35
AXEL 147
Wget 1206
Aspera 32
AXEL 100
Wget 600
Aspera 36
AXEL 157
Wget 354
Aspera 33
AXEL 130
Wget 118
Aspera 32
AXEL 253
Wget 98
Aspera 16
AXEL 128
Wget 990
Aspera 59
AXEL 121
Wget 520
Aspera 33
AXEL 177
Wget 216
Aspera 43
AXEL 140
Wget 887
Aspera 53
AXEL 103
Wget 1022
Aspera 55
AXEL 64
Wget 57
Aspera 50
AXEL 211
Wget 354
Aspera 315
AXEL 156
Wget 669
Aspera 53
AXEL 135
Wget 1339
Aspera 47
AXEL 92
Wget 431
Aspera 95
AXEL 56
================================================
FILE: docs/benchmark/TestiSeq-2GB/timeFQ.log
================================================
--fastq 537
--fastq+gzip 316
--gzip 42
--fastq 116
--fastq+gzip 211
--gzip 149
--fastq 293
--fastq+gzip 315
--gzip 144
--fastq 109
--fastq+gzip 240
--gzip 176
--fastq 154
--fastq+gzip 487
--gzip 43
--fastq 79
--fastq+gzip 245
--gzip 43
--fastq 78
--fastq+gzip 242
--gzip 56
--fastq 79
--fastq+gzip 236
--gzip 49
--fastq 69
--fastq+gzip 389
--gzip 43
--fastq 74
--fastq+gzip 282
--gzip 1196
--fastq 354
--fastq+gzip 160
--gzip 43
--fastq 166
--fastq+gzip 243
--gzip 62
--fastq 373
--fastq+gzip 218
--gzip 89
--fastq 326
--fastq+gzip 378
--gzip 253
--fastq 190
--fastq+gzip 400
--gzip 98
--fastq 879
--fastq+gzip 176
--gzip 69
--fastq 185
--fastq+gzip 352
--gzip 62
--fastq 142
--fastq+gzip 282
--gzip 54
--fastq 223
--fastq+gzip 253
--gzip 811
--fastq 78
--fastq+gzip 312
--gzip 1534
--fastq 291
--fastq+gzip 419
--gzip 32
--fastq 46
--fastq+gzip 250
--gzip 250
--fastq 341
--fastq+gzip 323
--gzip 35
--fastq 50
--fastq+gzip 389
--gzip 298
--fastq 55
--fastq+gzip 367
--gzip 39
--fastq 54
--fastq+gzip 259
--gzip 40
--fastq 62
--fastq+gzip 450
--gzip 70
--fastq 176
--fastq+gzip 185
--gzip 50
--fastq 52
--fastq+gzip 284
--gzip 61
--fastq 56
--fastq+gzip 297
--gzip 46
--fastq 58
--fastq+gzip 264
--gzip 129
--fastq 134
--fastq+gzip 247
--gzip 44
--fastq 366
--fastq+gzip 221
--gzip 262
--fastq 449
--fastq+gzip 379
--gzip 59
--fastq 86
--fastq+gzip 273
--gzip 66
--fastq 75
--fastq+gzip 281
--gzip 69
--fastq 91
--fastq+gzip 286
--gzip 66
--fastq 118
--fastq+gzip 498
--gzip 60
--fastq 280
--fastq+gzip 228
--gzip 75
--fastq 228
--fastq+gzip 200
--gzip 72
================================================
FILE: docs/benchmark/TestiSeq-2GB/timeGSAFTP.log
================================================
Wget 1085
AXEL 148
Aspera 89
Wget 1244
AXEL 134
Aspera 87
Wget 956
AXEL 137
Aspera 92
Wget 1083
AXEL 171
Aspera 87
Wget 1113
AXEL 172
Aspera 98
Wget 983
AXEL 125
Aspera 100
Wget 1214
AXEL 111
Aspera 94
Wget 1080
AXEL 119
Aspera 96
Wget 1433
AXEL 186
Aspera 98
Wget 1281
AXEL 155
Aspera 84
Wget 1171
AXEL 117
Aspera 18
Wget 1124
AXEL 174
Aspera 88
Wget 1839
AXEL 164
Aspera 16
Wget 1340
AXEL 165
Aspera 87
Wget 1262
AXEL 147
Aspera 85
Wget 1256
AXEL 170
Aspera 83
Wget 1245
AXEL 141
Aspera 96
Wget 819
AXEL 127
Aspera 93
Wget 1257
AXEL 140
Aspera 95
Wget 1101
AXEL 133
Aspera 85
Wget 1180
AXEL 113
Aspera 76
Wget 1237
AXEL 139
Aspera 76
Wget 787
AXEL 131
Aspera 88
Wget 929
AXEL 151
Aspera 89
Wget 861
AXEL 138
Aspera 102
Wget 878
AXEL 104
Aspera 99
Wget 1095
AXEL 143
Aspera 121
Wget 807
AXEL 118
Aspera 87
Wget 971
AXEL 115
Aspera 83
Wget 1322
AXEL 166
Aspera 97
Wget 1226
AXEL 158
Aspera 13
Wget 1088
AXEL 139
Aspera 13
Wget 1099
AXEL 142
Aspera 87
Wget 1274
AXEL 177
Aspera 87
Wget 1819
AXEL 180
Aspera 91
Wget 1201
AXEL 136
Aspera 13
Wget 1131
AXEL 151
Aspera 81
Wget 1289
AXEL 123
Aspera 82
Wget 1200
AXEL 154
Aspera 82
Wget 944
AXEL 105
Aspera 80
================================================
FILE: docs/benchmark/TestiSeq-2GB/timeGSAHW.log
================================================
AXEL 21
Wget 10
AXEL 20
Wget 14
AXEL 16
Wget 16
AXEL 17
Wget 10
AXEL 13
Wget 11
AXEL 9
Wget 15
AXEL 22
Wget 15
AXEL 21
Wget 11
AXEL 21
Wget 13
AXEL 17
Wget 17
AXEL 15
Wget 11
AXEL 10
Wget 11
AXEL 15
Wget 16
AXEL 21
Wget 11
AXEL 21
Wget 10
AXEL 15
Wget 11
AXEL 29
Wget 13
AXEL 14
Wget 11
AXEL 29
Wget 10
AXEL 13
Wget 10
AXEL 18
Wget 9
AXEL 20
Wget 8
AXEL 19
Wget 13
AXEL 26
Wget 9
AXEL 20
Wget 8
AXEL 23
Wget 9
AXEL 20
Wget 9
AXEL 20
Wget 10
AXEL 20
Wget 10
AXEL 19
Wget 8
AXEL 21
Wget 8
AXEL 21
Wget 16
AXEL 21
Wget 10
AXEL 21
Wget 10
AXEL 21
Wget 11
AXEL 21
Wget 9
AXEL 21
Wget 8
AXEL 21
Wget 10
AXEL 23
Wget 8
AXEL 19
Wget 8
================================================
FILE: docs/benchmark/TestiSeq-2GB/timeSRA.log
================================================
Wget 125
AXEL 75
Wget 261
AXEL 79
Wget 87
AXEL 85
Wget 95
AXEL 64
Wget 120
AXEL 86
Wget 108
AXEL 59
Wget 76
AXEL 63
Wget 80
AXEL 77
Wget 111
AXEL 84
Wget 67
AXEL 66
Wget 109
AXEL 67
Wget 195
AXEL 62
Wget 218
AXEL 50
Wget 167
AXEL 103
Wget 74
AXEL 152
Wget 106
AXEL 181
Wget 94
AXEL 102
Wget 159
AXEL 141
Wget 75
AXEL 78
Wget 129
AXEL 77
Wget 102
AXEL 51
Wget 117
AXEL 68
Wget 82
AXEL 53
Wget 91
AXEL 54
Wget 100
AXEL 45
Wget 84
AXEL 44
Wget 98
AXEL 36
Wget 94
AXEL 41
Wget 84
AXEL 48
Wget 104
AXEL 46
Wget 85
AXEL 43
Wget 122
AXEL 39
Wget 84
AXEL 49
Wget 88
AXEL 63
Wget 120
AXEL 57
Wget 101
AXEL 62
Wget 80
AXEL 46
Wget 98
AXEL 49
Wget 98
AXEL 58
Wget 98
AXEL 43
================================================
FILE: docs/benchmark/TestiSeq-540MB/TestiSeq-540MB.bash
================================================
#!/bin/bash
if command -v iseq >/dev/null 2>&1; then
sleep 0
else
echo "iseq is not installed"
echo "Please install iseq first"
exit 1
fi
calculate_time_difference() {
start_time=$1
end_time=$2
method=$3
diff=$((end_time - start_time))
echo -e "${method}\t${diff}"
}
# Create a directory to store the downloaded files
if [ ! -d "iseq" ]; then
mkdir iseq
fi
cd ./iseq
# =======================================ENA=============================================
for ((i=1; i<=20; i++)); do
# SRX1663467 (PE, 2 GB)
SRX=SRX1663467
# CRX095512 (SE, 2 GB)
CRX=CRX095512
# Perform tests for ENA FTP download by Wget
start=$(date +%s)
iseq -i $SRX
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeENA.log
rm -rf *
# Perform tests for ENA FTP download by Aspera
start=$(date +%s)
iseq -i $SRX -a
end=$(date +%s)
calculate_time_difference $start $end "Aspera" >> ../timeENA.log
rm -rf *
# Perform tests for ENA FTP download by 10 parallel by AXEL
start=$(date +%s)
iseq -i $SRX -p 10
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeENA.log
rm -rf *
# =======================================ENA=============================================
# =======================================SRA=============================================
# Perform tests for SRA HTTPS download by Wget
start=$(date +%s)
iseq -i $SRX -d sra
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeSRA.log
rm -rf *
# Perform tests for SRA HTTPS download by AXEL
start=$(date +%s)
iseq -i $SRX -d sra -p 10
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeSRA.log
rm -rf *
# =======================================SRA=============================================
# =======================================ENA FQ/FQ.GZ====================================
# Perform tests to compare the time taken for directly downloading fq.gz files versus downloading fq files and then compressing them into fq.gz.
start=$(date +%s)
iseq -i $SRX -a -q
end=$(date +%s)
calculate_time_difference $start $end "--fastq" >> ../timeFQ.log
rm -rf *
start=$(date +%s)
iseq -i $SRX -a -q -g
end=$(date +%s)
calculate_time_difference $start $end "--fastq+gzip" >> ../timeFQ.log
rm -rf *
start=$(date +%s)
iseq -i $SRX -a -g
end=$(date +%s)
calculate_time_difference $start $end "--gzip" >> ../timeFQ.log
rm -rf *
# =======================================ENA FQ/FQ.GZ====================================
# =======================================GSA FTP=============================================
# Perform tests for GSA FTP download by Wget
start=$(date +%s)
iseq -i $CRX -m
wget ftp://download.big.ac.cn/gsa3/CRA002399/CRR120307/CRR120307.fastq.gz
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeGSAFTP.log
rm -rf *
# Perform tests for GSA FTP download by AXEL
start=$(date +%s)
iseq -i $CRX -m
axel -n 10 -a -c ftp://download.big.ac.cn/gsa3/CRA002399/CRR120307/CRR120307.fastq.gz
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeGSAFTP.log
rm -rf *
# Perform tests for GSA FTP download by Aspera
start=$(date +%s)
iseq -i $CRX -m
wget https://ngdc.cncb.ac.cn/gsa/file/downFile?fileName=download/aspera01.openssh -O .asperaGSA.openssh --quiet
ascp -P 33001 -i .asperaGSA.openssh -QT -l 1000m -k1 -d aspera01@download.cncb.ac.cn:gsa3/CRA002399/CRR120307/CRR120307.fastq.gz .
end=$(date +%s)
calculate_time_difference $start $end "Aspera" >> ../timeGSAFTP.log
rm -rf *
# =======================================GSA HUAWEI_CLOUD=============================================
# Perform tests for GSA HUAWEI_CLOUD download by AXEL
start=$(date +%s)
iseq -i ${CRX} -p 10
end=$(date +%s)
calculate_time_difference $start $end "AXEL" >> ../timeGSAHW.log
rm -rf *
# Perform tests for GSA HUAWEI_CLOUD download by Wget
start=$(date +%s)
iseq -i ${CRX}
end=$(date +%s)
calculate_time_difference $start $end "Wget" >> ../timeGSAHW.log
rm -rf *
done
cd ..
================================================
FILE: docs/benchmark/TestiSeq-540MB/timeENA.log
================================================
Wget 781
Aspera 23
AXEL 65
Wget 992
Aspera 440
AXEL 103
Wget 812
Aspera 26
AXEL 95
Wget 268
Aspera 30
AXEL 130
Wget 314
Aspera 35
AXEL 147
Wget 1206
Aspera 32
AXEL 100
Wget 600
Aspera 36
AXEL 157
Wget 354
Aspera 33
AXEL 130
Wget 118
Aspera 32
AXEL 253
Wget 98
Aspera 16
AXEL 128
Wget 990
Aspera 59
AXEL 121
Wget 520
Aspera 33
AXEL 177
Wget 216
Aspera 43
AXEL 140
Wget 887
Aspera 53
AXEL 103
Wget 1022
Aspera 55
AXEL 64
Wget 57
Aspera 50
AXEL 211
Wget 354
Aspera 315
AXEL 156
Wget 669
Aspera 53
AXEL 135
Wget 1339
Aspera 47
AXEL 92
Wget 431
Aspera 95
AXEL 56
================================================
FILE: docs/benchmark/TestiSeq-540MB/timeFQ.log
================================================
--fastq 291
--fastq+gzip 419
--gzip 32
--fastq 46
--fastq+gzip 250
--gzip 250
--fastq 341
--fastq+gzip 323
--gzip 35
--fastq 50
--fastq+gzip 389
--gzip 298
--fastq 55
--fastq+gzip 367
--gzip 39
--fastq 54
--fastq+gzip 259
--gzip 40
--fastq 62
--fastq+gzip 450
--gzip 70
--fastq 176
--fastq+gzip 185
--gzip 50
--fastq 52
--fastq+gzip 284
--gzip 61
--fastq 56
--fastq+gzip 297
--gzip 46
--fastq 58
--fastq+gzip 264
--gzip 129
--fastq 134
--fastq+gzip 247
--gzip 44
--fastq 366
--fastq+gzip 221
--gzip 262
--fastq 449
--fastq+gzip 379
--gzip 59
--fastq 86
--fastq+gzip 273
--gzip 66
--fastq 75
--fastq+gzip 281
--gzip 69
--fastq 91
--fastq+gzip 286
--gzip 66
--fastq 118
--fastq+gzip 498
--gzip 60
--fastq 280
--fastq+gzip 228
--gzip 75
--fastq 228
--fastq+gzip 200
--gzip 72
================================================
FILE: docs/benchmark/TestiSeq-540MB/timeGSAFTP.log
================================================
Wget 1180
AXEL 113
Aspera 76
Wget 1237
AXEL 139
Aspera 76
Wget 787
AXEL 131
Aspera 88
Wget 929
AXEL 151
Aspera 89
Wget 861
AXEL 138
Aspera 102
Wget 878
AXEL 104
Aspera 99
Wget 1095
AXEL 143
Aspera 121
Wget 807
AXEL 118
Aspera 87
Wget 971
AXEL 115
Aspera 83
Wget 1322
AXEL 166
Aspera 97
Wget 1226
AXEL 158
Aspera 13
Wget 1088
AXEL 139
Aspera 13
Wget 1099
AXEL 142
Aspera 87
Wget 1274
AXEL 177
Aspera 87
Wget 1819
AXEL 180
Aspera 91
Wget 1201
AXEL 136
Aspera 13
Wget 1131
AXEL 151
Aspera 81
Wget 1289
AXEL 123
Aspera 82
Wget 1200
AXEL 154
Aspera 82
Wget 944
AXEL 105
Aspera 80
================================================
FILE: docs/benchmark/TestiSeq-540MB/timeGSAHW.log
================================================
AXEL 18
Wget 9
AXEL 20
Wget 8
AXEL 19
Wget 13
AXEL 26
Wget 9
AXEL 20
Wget 8
AXEL 23
Wget 9
AXEL 20
Wget 9
AXEL 20
Wget 10
AXEL 20
Wget 10
AXEL 19
Wget 8
AXEL 21
Wget 8
AXEL 21
Wget 16
AXEL 21
Wget 10
AXEL 21
Wget 10
AXEL 21
Wget 11
AXEL 21
Wget 9
AXEL 21
Wget 8
AXEL 21
Wget 10
AXEL 23
Wget 8
AXEL 19
Wget 8
================================================
FILE: docs/benchmark/TestiSeq-540MB/timeSRA.log
================================================
Wget 102
AXEL 51
Wget 117
AXEL 68
Wget 82
AXEL 53
Wget 91
AXEL 54
Wget 100
AXEL 45
Wget 84
AXEL 44
Wget 98
AXEL 36
Wget 94
AXEL 41
Wget 84
AXEL 48
Wget 104
AXEL 46
Wget 85
AXEL 43
Wget 122
AXEL 39
Wget 84
AXEL 49
Wget 88
AXEL 63
Wget 120
AXEL 57
Wget 101
AXEL 62
Wget 80
AXEL 46
Wget 98
AXEL 49
Wget 98
AXEL 58
Wget 98
AXEL 43
================================================
FILE: docs/benchmark/benchmark.ipynb
================================================
{
"cells": [
{
"cell_type": "code",
"execution_count": 187,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"library(ggplot2)\n",
"library(patchwork)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"theme_chy <- function() {theme(\n",
" axis.text = element_text(size = 12, colour = \"black\"),\n",
" axis.line = element_line(colour = \"black\"),\n",
" title = element_text(size = 15, colour = \"black\"),\n",
" legend.text = element_text(size = 12, colour = \"black\"),\n",
" legend.title = element_text(size = 15, colour = \"black\"),\n",
" panel.background = element_blank()\n",
" )\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 188,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [
{
"data": {
"image/png": "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fz6AW2+9lZlvu+027N76mEqlvG/Q63LSiffxZqu/9v9i4X5R/aXXqO+T5s2b5434ZeZuq4lc133++ef/8z//0/vTMIwHH3zwpptuev75519++eX3339/1apVq1atuv/++6+88spHH300N950KrhkN5qmCSCVSgGIRqMATjjhBO+m2a1UKhUKhbx/ewEpV2tr62c/+1mvXae8vPzEE08cN27cuHHjJk6cmFt86dMO9GvK2rx5s1eLctVVV82aNauhoeGBBx644447zj///IkTJ/ZAzvu9s88++/777//kk09isZhX9zV9+vTcX/7MmTNfeumlv//97z/72c+8sfS5RQ2vPX9PB+/UefJAL5Y+r5eDmnZQvLEOn/nMZ7p91SuAn3322XvaPZlMvvbaaxdeeKF3FT3yyCPedq+kcv7553fdJdse47Vtet1j5syZs8+seiWVIUOGdNp+/fXXA6ioqHjttddyt2cnqOgHJZWD+5qUUl49TEVFRWNjIzNHo1Gvo8TkyZO79irWJZWD0Nzc7D1IzZ8/33uIefTRR3MTeLVbRFRbWxsOhwHMnj07N0F5eTmAf/zjH52O7NUtI6eksv8XC/eLkopuU+l7YrHYSy+9BOBLX/pStwkuuugiAG+88UZtbS2AeDx+77333nvvvdmfu9/vnzlz5pw5cy699FIAXoVy1ltvveWN88rlVcrbtj106FAAXmeYDz74oOvZ33vvvXvvvfcvf/nL3t/FvHnzANxxxx1ee0+W91jXDxzo15T14IMPegPxfvOb33gtMeFw+KGHHgKwePHiu++++3DnfCAoKio67rjjALzyyiveUPnp06fnJhg9evSwYcOY+b777vMuh9wGFXRcAl3nEMvOO9kp5aFcLH1Mb0c17YA9+eSTAIQQ27dv7zbB+vXrvS/3gQceYGallNfw3mn0IjN7XZJuvvlm789sl+I777wzN1lLS4vXp/6qq67ytnjdloqLi3MHiDFzIpEYN25c9tS855LKiBEjADz++OOdtn/3u9/18tDXSyoH+jV51q1b51WDXHDBBZ3Sf/WrXwVgmuaHH36Yu12XVA6OV8HolUJGjx7dNYFXLeklGD9+fKdXveGQVVVVuaNMlFLZIffZksr+XyzcUVJ59dVX8/Y+e5wOKn2PNzfR6aefvpc0kyZNAnDqqad6f3p9twYNGvT44483NDQw8/bt22+//Xav+uv111/3kuUOfvzBD36watWq1tbWefPmjRkzBoDP59u0aVP2FN7EfCUlJU888cS2bdtc133//fe9Tk3V1dVevQ3vOah4VUNjx45dtWoVMyulVq5cmftQv2LFijx9YL3jIL4mKaX3OByJRHLHmXrq6+vLysoATJgwITfiekHloosuatiraDSa3cULKr/85S/3lDj3Rtlfvfjii9kf23XXXdc1wezZs/eSwHVdb/DjlClTvOkpV6xYcfHFF9u27U3OljtXxX5eLNwRVO67777D9K57gA4qfUxDQ4NlWfv82d1xxx3exeA1gWzdutW7H3m8JnfP7bffnt3LCyqXX375kCFDOpVoDcN47LHHck+xfv36kSNH5ibw/lFSUrJ48eJssj0FlXXr1mU7+FdUVHiP54WFhX/84x+9nmChUOi222479E+sVxzc1+QNwQPw8MMPd5vemwrMC/nZjfsz+BE5pUzuCCp70W0PwH6mpaUl2z/l+eef75qgubk5+6vudk6dTz755KijjvISeIcioj/84Q9epaU3K49nPy8WZs5OpzR48OD7778/7++6B+ig0sd4desAcgsNXWXnZLznnnu8LY2NjbfeeusJJ5xQVlYWCoUmTJhw+eWXdxri6wUVr7vRDTfcMGzYMNu2KyoqLrnkko8++qjrWaLR6D333PO5z32uurq6sLBwypQpt912W3Nzc26aPQUVZt6wYcMVV1wxcuTIUCh04oknXnfddVu2bGHmp59+urKysqCgIPfW2bccxNe0atUqr4/ctGnTcvu2duLNCWYYxjvvvONt0UHloHnDRIQQnX60WdmOiLW1td0maGhouO6668aPHx8MBk855ZSXX37ZcRyvAiB3pD3v38XCzMuWLTv11FP9fn9paemeni2OcMR77hinDTRf//rXH3vssVmzZnW7YoemaVmpVEpKadu2VyTN2rhx4/Dhw30+n9f5fgDSvb80TdMO2E9+8pNwOPz1r3+903avg4a3as7ApIOKpmnaAfM6vzz33HO5E7j99a9//cUvfgHgW9/6Vq/lrLfpoKJpmnbApk6d+uMf/9hxnAsvvHDIkCGTJk0qLCy8+OKL29rarr76am8E2MCkg4q2ixDCNM3cKVs0TduTO+64Y/78+eedd55pmmvWrBk+fPjll18+Z86c3DULBiDdUK9pmqbljX4m1TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb3RQ0TRN0/JGBxVN0zQtb/4/EIJqvsO0WEEAAAAASUVORK5CYII=",
"text/plain": [
"plot without title"
]
},
"metadata": {
"image/png": {
"height": 300,
"width": 270
}
},
"output_type": "display_data"
}
],
"source": [
"timeENA1 <- read.table(\"./TestiSeq-540MB/timeENA.log\", header = F, sep = \"\\t\")\n",
"options(repr.plot.width = 4.5, repr.plot.height = 5)\n",
"ggplot(timeENA1, aes(x = V1, y = V2, color = V1)) +\n",
" geom_boxplot(alpha = 0.8) +\n",
" geom_jitter(position = position_jitter(width = 0.2), alpha = 0.7, size = 3) +\n",
" scale_color_manual(values = c(\"Wget\" = \"#fc4e07\", \"Aspera\" = \"#00afbb\", \"AXEL\" = \"#e7b800\")) +\n",
" theme_chy() + theme(legend.position = \"\") +\n",
" theme(axis.text = element_text(size = 15, colour = \"black\"))+\n",
" labs(title = \"FTP from ENA\", x = \"\", y = \"Time (s)\")-> p1\n",
"p1"
]
},
{
"cell_type": "code",
"execution_count": 189,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [
{
"data": {
"image/png": "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
gitextract_o5hgf_3g/ ├── INSTALL.md ├── LICENSE ├── README.md ├── bin/ │ └── iseq ├── docs/ │ ├── ChineseTutorial.md │ ├── Examples.md │ └── benchmark/ │ ├── README.md │ ├── TestFasterqDump/ │ │ ├── testFasterqDump.log │ │ └── timefasterqDump.sh │ ├── TestiSeq-2GB/ │ │ ├── TestiSeq-2GB.bash │ │ ├── timeENA.log │ │ ├── timeFQ.log │ │ ├── timeGSAFTP.log │ │ ├── timeGSAHW.log │ │ └── timeSRA.log │ ├── TestiSeq-540MB/ │ │ ├── TestiSeq-540MB.bash │ │ ├── timeENA.log │ │ ├── timeFQ.log │ │ ├── timeGSAFTP.log │ │ ├── timeGSAHW.log │ │ └── timeSRA.log │ ├── benchmark.ipynb │ └── iSeq-Table S1.xlsx └── iSeq.yml
Condensed preview — 24 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,324K chars).
[
{
"path": "INSTALL.md",
"chars": 5729,
"preview": "## Install the latest version of iSeq\r\n\r\n```bash\r\nversion=\"1.9.8\"\r\nwget \"https://github.com/BioOmics/iSeq/releases/downl"
},
{
"path": "LICENSE",
"chars": 1064,
"preview": "MIT License\n\nCopyright (c) 2024 BioOmics\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\no"
},
{
"path": "README.md",
"chars": 32193,
"preview": "[](https://anaconda.org/bioconda/iseq)\r\n["
},
{
"path": "bin/iseq",
"chars": 58365,
"preview": "#!/bin/bash\n# Author: BioOmics (https://github.com/BioOmics)\n# Last modified: 2025-11-20\n# ============================="
},
{
"path": "docs/ChineseTutorial.md",
"chars": 10139,
"preview": "## iSeq使用方法 \r\n- 中文纯手打,英文是由ChatGPT翻译的😀\r\n```{bash}\r\n$ iseq --help\r\n\r\nUsage:\r\n iseq -i accession [options]\r\n\r\nRequired opt"
},
{
"path": "docs/Examples.md",
"chars": 3814,
"preview": "# Examples of using iSeq\r\n\r\n## Basic examples\r\n1. Download all Run sequencing data and metadata associated with a Projec"
},
{
"path": "docs/benchmark/README.md",
"chars": 817,
"preview": "## Stability\niSeq demonstrated high stability, successfully downloading and passing integrity checks for a large number "
},
{
"path": "docs/benchmark/TestFasterqDump/testFasterqDump.log",
"chars": 1873,
"preview": "2\tConvert SRA to FASTQ\t74\n2\tCompress FASTQ\t803\n3\tConvert SRA to FASTQ\t66\n3\tCompress FASTQ\t528\n4\tConvert SRA to FASTQ\t64\n"
},
{
"path": "docs/benchmark/TestFasterqDump/timefasterqDump.sh",
"chars": 1,
"preview": "\n"
},
{
"path": "docs/benchmark/TestiSeq-2GB/TestiSeq-2GB.bash",
"chars": 4591,
"preview": "#!/bin/bash\n\nif command -v iseq >/dev/null 2>&1; then\n sleep 0\nelse\n echo \"iseq is not installed\"\n echo \"Please"
},
{
"path": "docs/benchmark/TestiSeq-2GB/timeENA.log",
"chars": 1115,
"preview": "Wget\t583\nAspera\t215\nAXEL\t59\nWget\t976\nAspera\t87\nAXEL\t73\nWget\t607\nAspera\t208\nAXEL\t69\nWget\t187\nAspera\t312\nAXEL\t54\nWget\t150\n"
},
{
"path": "docs/benchmark/TestiSeq-2GB/timeFQ.log",
"chars": 1556,
"preview": "--fastq\t537\n--fastq+gzip\t316\n--gzip\t42\n--fastq\t116\n--fastq+gzip\t211\n--gzip\t149\n--fastq\t293\n--fastq+gzip\t315\n--gzip\t144\n-"
},
{
"path": "docs/benchmark/TestiSeq-2GB/timeGSAFTP.log",
"chars": 1153,
"preview": "Wget\t1085\nAXEL\t148\nAspera\t89\nWget\t1244\nAXEL\t134\nAspera\t87\nWget\t956\nAXEL\t137\nAspera\t92\nWget\t1083\nAXEL\t171\nAspera\t87\nWget\t"
},
{
"path": "docs/benchmark/TestiSeq-2GB/timeGSAHW.log",
"chars": 627,
"preview": "AXEL\t21\nWget\t10\nAXEL\t20\nWget\t14\nAXEL\t16\nWget\t16\nAXEL\t17\nWget\t10\nAXEL\t13\nWget\t11\nAXEL\t9\nWget\t15\nAXEL\t22\nWget\t15\nAXEL\t21\nW"
},
{
"path": "docs/benchmark/TestiSeq-2GB/timeSRA.log",
"chars": 664,
"preview": "Wget\t125\nAXEL\t75\nWget\t261\nAXEL\t79\nWget\t87\nAXEL\t85\nWget\t95\nAXEL\t64\nWget\t120\nAXEL\t86\nWget\t108\nAXEL\t59\nWget\t76\nAXEL\t63\nWget"
},
{
"path": "docs/benchmark/TestiSeq-540MB/TestiSeq-540MB.bash",
"chars": 4298,
"preview": "#!/bin/bash\n\nif command -v iseq >/dev/null 2>&1; then\n sleep 0\nelse\n echo \"iseq is not installed\"\n echo \"Please"
},
{
"path": "docs/benchmark/TestiSeq-540MB/timeENA.log",
"chars": 558,
"preview": "Wget\t781\nAspera\t23\nAXEL\t65\nWget\t992\nAspera\t440\nAXEL\t103\nWget\t812\nAspera\t26\nAXEL\t95\nWget\t268\nAspera\t30\nAXEL\t130\nWget\t314\n"
},
{
"path": "docs/benchmark/TestiSeq-540MB/timeFQ.log",
"chars": 773,
"preview": "--fastq\t291\n--fastq+gzip\t419\n--gzip\t32\n--fastq\t46\n--fastq+gzip\t250\n--gzip\t250\n--fastq\t341\n--fastq+gzip\t323\n--gzip\t35\n--f"
},
{
"path": "docs/benchmark/TestiSeq-540MB/timeGSAFTP.log",
"chars": 575,
"preview": "Wget\t1180\nAXEL\t113\nAspera\t76\nWget\t1237\nAXEL\t139\nAspera\t76\nWget\t787\nAXEL\t131\nAspera\t88\nWget\t929\nAXEL\t151\nAspera\t89\nWget\t8"
},
{
"path": "docs/benchmark/TestiSeq-540MB/timeGSAHW.log",
"chars": 308,
"preview": "AXEL\t18\nWget\t9\nAXEL\t20\nWget\t8\nAXEL\t19\nWget\t13\nAXEL\t26\nWget\t9\nAXEL\t20\nWget\t8\nAXEL\t23\nWget\t9\nAXEL\t20\nWget\t9\nAXEL\t20\nWget\t1"
},
{
"path": "docs/benchmark/TestiSeq-540MB/timeSRA.log",
"chars": 327,
"preview": "Wget\t102\nAXEL\t51\nWget\t117\nAXEL\t68\nWget\t82\nAXEL\t53\nWget\t91\nAXEL\t54\nWget\t100\nAXEL\t45\nWget\t84\nAXEL\t44\nWget\t98\nAXEL\t36\nWget\t"
},
{
"path": "docs/benchmark/benchmark.ipynb",
"chars": 1177449,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 187,\n \"metadata\": {\n \"vscode\": {\n \"languageId\":"
},
{
"path": "iSeq.yml",
"chars": 127,
"preview": "channels:\n - conda-forge\n - bioconda\ndependencies:\n - pigz\n - wget\n - axel\n - aspera-cli ==4.14.0\n - sra-tools >="
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the BioOmics/iSeq GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 24 files (1.2 MB), approximately 818.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.