Skip to content

Commit

Permalink
throw exception when file not existing
Browse files Browse the repository at this point in the history
  • Loading branch information
Zilong-Li committed Aug 7, 2024
1 parent ae06697 commit 14d98ef
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 14 deletions.
23 changes: 13 additions & 10 deletions readme.org
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@
[[https://github.com/Zilong-Li/vcfpp/releases/latest][https://img.shields.io/github/v/release/Zilong-Li/vcfpp.svg]]
[[https://img.shields.io/github/license/Zilong-Li/vcfpp?style=plastic.svg]]

This project introduces vcfpp (vcf plus plus), a single C++ file as interface to the basic =htslib=, which can be easily included in a C++ program
for scripting high-performance genomic analyses.
This project introduces vcfpp (vcf plus plus), a single C++ file as interface to
the basic =htslib=, which can be easily included in a C++ program for scripting
high-performance genomic analyses. Check out [[https://github.com/Zilong-Li/vcfppR][vcfppR]] as an example of how vcfpp.h
can facilitate rapidly writing high-performance R package.

Features:
- single file to be easily included and compiled
- easy and safe [[https://zilongli.org/proj/vcfpp/index.html][API]] to use.
- objects are RAII. no worry about allocate and free memory.
- has the full functionalities of the =htslib=, eg. supports of compressed VCF/BCF and URL link as filename.
- the full functionalities of =htslib=, e.g. supports of compressed VCF/BCF and URL link as filename.
- compatible with C++11 and later


* Table of Contents :TOC:QUOTE:
#+BEGIN_QUOTE
- [[#installation][Installation]]
Expand Down Expand Up @@ -93,7 +96,7 @@ value =-9= into account for downstream analysis.

** Writing VCF

There are many ways in vcfpp for writing the VCF/BCF file.
There are many ways for writing the VCF/BCF file.

*** Use an empty template

Expand All @@ -110,13 +113,13 @@ for (auto& s : {"id01", "id02", "id03"}) bw.header.addSample(s); // add 3 sample
bw.writeLine("chr20\t2006060\trs146931526\tG\tC\t100\tPASS\tAF=0.000998403\tGT\t1|0\t1|1\t0|0");
#+end_src

*** Use another VCF as template
*** Use an existing VCF as template

In this example, we first read VCF file
=test/test-vcf-read.vcf.gz=. Secondly, we construct an empty variant record
and update the record with the input VCF. Thirdly, we construct a
BcfWriter object using the meta data in the header of the input VCF,
writing out the header and the modified variant record.
In this example, we first read VCF file =test/test-vcf-read.vcf.gz=. Second,
we construct an empty variant record and update the record with the input
VCF. Third, we construct a BcfWriter object using the meta data in the
header of the input VCF, writing out the header and the modified variant
record.

#+begin_src C++
BcfReader br("test/test-vcf-read.vcf.gz");
Expand Down
3 changes: 1 addition & 2 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ HTSINC = /usr/local/include
HTSLIB = /usr/local/lib
# detect OS architecture and add flags
CXX = g++
CXXFLAGS = -std=c++11 -Wall -fsanitize=address
# CXXFLAGS = -std=c++11 -Wall -g
CXXFLAGS = -std=c++11 -Wall -g -O2 -fsanitize=address
LDFLAGS = -L$(HTSLIB) -Wl,-rpath,$(HTSLIB)
LIBS = -lhts -lz -lm -lbz2 -llzma -lcurl -lpthread
INC = -I. -I.. -I${HTSINC}
Expand Down
8 changes: 8 additions & 0 deletions test/bcf-reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,11 @@ TEST_CASE("parse EV in vcf - vector<string>", "[bcf-reader]")
REQUIRE(ev[0]=="RD");
REQUIRE(ev[1]=="SR,PE");
}

TEST_CASE("throw error when file is not valid", "[bcf-reader]")
{
BcfReader br;
CHECK_THROWS(br.open("no-test-GL.vcf.gz"));
BcfReader bw;
CHECK_THROWS(bw.open("ff://no-access.vcf.gz"));
}
2 changes: 1 addition & 1 deletion tools/vcf2beagle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int main(int argc, char * argv[])
vector<double> out;
while(vcf.getNextVariant(var))
{
if(!var.isSNP()) continue;
// if(!var.isSNP()) continue;
if(tag == "PL")
{
var.getFORMAT("PL", pl); // try get PL values
Expand Down
6 changes: 5 additions & 1 deletion vcfpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file https://github.com/Zilong-Li/vcfpp/vcfpp.h
* @author Zilong Li
* @email [email protected]
* @version v0.4.0
* @version v0.4.1
* @breif a single C++ file for manipulating VCF
* Copyright (C) 2022-2023.The use of this code is governed by the LICENSE file.
******************************************************************************/
Expand Down Expand Up @@ -1519,6 +1519,7 @@ class BcfReader
{
fname = file;
fp = std::shared_ptr<htsFile>(hts_open(file.c_str(), "r"), htsFile_close());
if(!fp) throw std::invalid_argument("I/O error: input file is invalid");
header.hdr = bcf_hdr_read(fp.get());
nsamples = bcf_hdr_nsamples(header.hdr);
SamplesName = header.getSamples();
Expand Down Expand Up @@ -1710,6 +1711,7 @@ class BcfWriter
{
auto mode = getMode(fname, "w");
fp = std::shared_ptr<htsFile>(hts_open(fname.c_str(), mode.c_str()), htsFile_close());
if(!fp) throw std::invalid_argument("I/O error: input file is invalid");
}

/**
Expand All @@ -1724,6 +1726,7 @@ class BcfWriter
void open(const std::string & fname, const std::string & mode)
{
fp = std::shared_ptr<htsFile>(hts_open(fname.c_str(), mode.c_str()), htsFile_close());
if(!fp) throw std::invalid_argument("I/O error: input file is invalid");
}

/// close the BcfWriter object.
Expand Down Expand Up @@ -1751,6 +1754,7 @@ class BcfWriter
void copyHeader(const std::string & vcffile)
{
htsFile * fp2 = hts_open(vcffile.c_str(), "r");
if(!fp2) throw std::invalid_argument("I/O error: input file is invalid");
header.hdr = bcf_hdr_read(fp2);
hts_close(fp2);
initalHeader(header);
Expand Down

0 comments on commit 14d98ef

Please sign in to comment.