diff --git a/src/intersectFile/intersectFile.cpp b/src/intersectFile/intersectFile.cpp index e61f4d23165c587cee7c01453964ac56ff9fbfd9..32643ac9fc851a20c5ef92b625ae4e31067976e4 100644 --- a/src/intersectFile/intersectFile.cpp +++ b/src/intersectFile/intersectFile.cpp @@ -97,7 +97,6 @@ bool FileIntersect::processUnsortedFiles() } queryFRM->deleteRecord(queryRecord); } - queryFRM->close(); //clean up. delete binTree; diff --git a/src/mapFile/mapMain.cpp b/src/mapFile/mapMain.cpp index f08e56b3905727b3333e4743e53b9bb9e9aaa239..235c1fb72a31362ea755a56fa467492c58a608d1 100644 --- a/src/mapFile/mapMain.cpp +++ b/src/mapFile/mapMain.cpp @@ -48,18 +48,29 @@ void map_help(void) { cerr << "Options: " << endl; - cerr << "\t-c\t" << "Specify the column from the B file to map onto intervals in A." << endl; - cerr << "\t\t - Default = 5." << endl << endl; + cerr << "\t-c\t" << "Specify columns from the B file to map onto intervals in A." << endl; + cerr << "\t\tDefault: 5." << endl; + cerr << "\t\tMultiple columns can be specified in a comma-delimited list." << endl << endl; cerr << "\t-o\t" << "Specify the operation that should be applied to -c." << endl; - cerr << "\t\t Valid operations:" << endl; + cerr << "\t\tValid operations:" << endl; cerr << "\t\t sum, min, max, absmin, absmax," << endl; cerr << "\t\t mean, median," << endl; cerr << "\t\t collapse (i.e., print a comma separated list (duplicates allowed)), " << endl; cerr << "\t\t distinct (i.e., print a comma separated list (NO duplicates allowed)), " << endl; cerr << "\t\t count" << endl; cerr << "\t\t count_distinct (i.e., a count of the unique values in the column), " << endl; - cerr << "\t\t- Default: sum" << endl << endl; + cerr << "\t\tDefault: sum" << endl; + cerr << "\t\tMultiple operations can be specified in a comma-delimited list." << endl << endl; + + cerr << "\t\tIf there is only column, but multiple operations, all operations will be" << endl; + cerr << "\t\tapplied on that column. Likewise, if there is only one operation, but" << endl; + cerr << "multiple columns, that operation will be applied to all columns." << endl; + cerr << "\t\tOtherwise, the number of columns must match the the number of operations," << endl; + cerr << "and will be applied in respective order." << endl; + cerr << "\t\tE.g., \"-c 5,4,6 -o sum,mean,count\" will give the sum of column 5," << endl; + cerr << "the mean of column 4, and the count of column 6." << endl; + cerr << "\t\tThe order of output columns will match the ordering given in the command." << endl << endl<<endl; cerr << "\t-f\t" << "Minimum overlap required as a fraction of A." << endl; cerr << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl; diff --git a/src/utils/BinTree/BinTree.cpp b/src/utils/BinTree/BinTree.cpp index f5cddd83fa5feef95ac47780770ddb6751266040..253dea2798320bfd7886931213612b2c21931baf 100644 --- a/src/utils/BinTree/BinTree.cpp +++ b/src/utils/BinTree/BinTree.cpp @@ -86,13 +86,6 @@ void BinTree::loadDB() exit(1); } } - _databaseFile->close(); - - //TBD: give ERROR and return false if tree is empty. - if (_mainMap.empty()) { - fprintf(stderr, "ERROR: Tree is empty, no records added.\n"); - exit(1); - } } void BinTree::getHits(Record *record, RecordKeyList &hitSet) diff --git a/src/utils/Contexts/ContextBase.cpp b/src/utils/Contexts/ContextBase.cpp index c76d29b45978d8fdc3e3d506cb33eedade6a72cc..55d5b6ad3b25965e26b6872cedc6fc7b637fbe69 100644 --- a/src/utils/Contexts/ContextBase.cpp +++ b/src/utils/Contexts/ContextBase.cpp @@ -233,6 +233,13 @@ bool ContextBase::openFiles() { if (_allFilesOpened) { return true; } + + if (_fileNames.size() == 0) { + //No input was specified. Error and exit. + _errorMsg += "\n***** ERROR: No input file given. Exiting. *****"; + return false; + } + _files.resize(_fileNames.size()); for (int i = 0; i < (int)_fileNames.size(); i++) { diff --git a/src/utils/Contexts/ContextMerge.cpp b/src/utils/Contexts/ContextMerge.cpp index 5d6c58aac3cb051a8eb485c89be8bb91a033f96b..d17d3bdb6823041c497d5f596a758756e7463a1b 100644 --- a/src/utils/Contexts/ContextMerge.cpp +++ b/src/utils/Contexts/ContextMerge.cpp @@ -82,7 +82,30 @@ bool ContextMerge::isValidState() } if (_files.size() != 1) { _errorMsg = "\n***** ERROR: input file not specified. *****"; - // Allow one and only input file for now + // Allow only one input file for now + return false; + } + + // + // Tests for stranded merge + // + if (_desiredStrand != FileRecordMergeMgr::ANY_STRAND) { // requested stranded merge + // make sure file has strand. + if (!getFile(0)->recordsHaveStrand()) { + _errorMsg = "\n***** ERROR: stranded merge requested, but input file records do not have strand. *****"; + return false; + } + //make sure file is not VCF. + if (!getFile(0)->getFileType() == FileRecordTypeChecker::VCF_FILE_TYPE) { + _errorMsg = "\n***** ERROR: stranded merge not supported for VCF files. *****"; + return false; + } + } + + //column operations not allowed with BAM input + if ((!_keyListOps->getColumns().empty() || !_keyListOps->getOperations().empty()) && + getFile(0)->getFileType() == FileRecordTypeChecker::BAM_FILE_TYPE) { + _errorMsg = "\n***** ERROR: stranded merge not supported for VCF files. *****"; return false; } return true; @@ -108,36 +131,25 @@ bool ContextMerge::handle_d() { bool ContextMerge::handle_n() { - //This is the same as telling map "-c any -o count" - _keyListOps->addColumns("1"); //doesn't really matter which column, but the default column - //for keyListOps is score, which not every record necessarily has. - _keyListOps->addOperations("count"); markUsed(_i - _skipFirstArgs); - return true; + _errorMsg = "\n***** ERROR: -n option is deprecated. Please see the documentation for the -c and -o column operation options. *****"; + return false; } bool ContextMerge::handle_nms() { - //This is the same as telling map "-c 4 -o collapse" - _keyListOps->addColumns("4"); - _keyListOps->addOperations("collapse"); markUsed(_i - _skipFirstArgs); - return true; + _errorMsg = "\n***** ERROR: -nms option is deprecated. Please see the documentation for the -c and -o column operation options. *****"; + return false; + } bool ContextMerge::handle_scores() { - if ((_i+1) < _argc) { - _keyListOps->addColumns("5"); - _keyListOps->addOperations(_argv[_i+1]); - markUsed(_i - _skipFirstArgs); - _i++; - markUsed(_i - _skipFirstArgs); - return true; - } - _errorMsg = "\n***** ERROR: -scores option given, but no operation specified. *****"; - + // No longer supporting this deprecated option. + markUsed(_i - _skipFirstArgs); + _errorMsg = "\n***** ERROR: -scores option is deprecated. Please see the documentation for the -c and -o column operation options. *****"; return false; } @@ -149,15 +161,20 @@ bool ContextMerge::handle_s() { bool ContextMerge::handle_S() { if ((_i+1) < _argc) { + bool validChar = false; if (_argv[_i+1][0] == '+') { _desiredStrand = FileRecordMergeMgr::SAME_STRAND_FORWARD; + validChar = true; } else if (_argv[_i+1][0] == '-') { + validChar = true; _desiredStrand = FileRecordMergeMgr::SAME_STRAND_REVERSE; } - markUsed(_i - _skipFirstArgs); - _i++; - markUsed(_i - _skipFirstArgs); - return true; + if (validChar) { + markUsed(_i - _skipFirstArgs); + _i++; + markUsed(_i - _skipFirstArgs); + return true; + } } _errorMsg = "\n***** ERROR: -S option must be followed by + or -. *****"; return false; diff --git a/src/utils/FileRecordTools/FileReaders/BufferedStreamMgr.cpp b/src/utils/FileRecordTools/FileReaders/BufferedStreamMgr.cpp index 27f07894c347c2b871201f933287ed410c555bd0..373b8d15a040471a40cb8f42b26ff527c296151f 100644 --- a/src/utils/FileRecordTools/FileReaders/BufferedStreamMgr.cpp +++ b/src/utils/FileRecordTools/FileReaders/BufferedStreamMgr.cpp @@ -73,7 +73,18 @@ bool BufferedStreamMgr::getTypeData() if (!_typeChecker.scanBuffer(_currScanBuffer.c_str(), _currScanBuffer.size()) && !_typeChecker.needsMoreData()) { return false; } else if (_typeChecker.needsMoreData()) { - _inputStreamMgr->populateScanBuffer(); + if (!_inputStreamMgr->populateScanBuffer()) { + // We have found a file with just a header. If the file and record type are known, + //break here. Otherwise, assign those types to empty file and record type, then break. + if ((_typeChecker.getFileType() != FileRecordTypeChecker::UNKNOWN_FILE_TYPE) && + (_typeChecker.getRecordType() != FileRecordTypeChecker::UNKNOWN_RECORD_TYPE)) { + break; + } else { + _typeChecker.setFileType(FileRecordTypeChecker::EMPTY_FILE_TYPE); + _typeChecker.setRecordType(FileRecordTypeChecker::EMPTY_RECORD_TYPE); + break; + } + } _currScanBuffer.append(_inputStreamMgr->getSavedData()); } } while (_typeChecker.needsMoreData()); diff --git a/src/utils/FileRecordTools/FileReaders/InputStreamMgr.cpp b/src/utils/FileRecordTools/FileReaders/InputStreamMgr.cpp index 2035b9c6529e8ac97f53766b22c2fd98c8eba56b..5736a5189114df908fb944b9e7f3789c6e00c838 100644 --- a/src/utils/FileRecordTools/FileReaders/InputStreamMgr.cpp +++ b/src/utils/FileRecordTools/FileReaders/InputStreamMgr.cpp @@ -125,7 +125,7 @@ int InputStreamMgr::read(char *data, size_t dataSize) return origRead + _finalInputStream->gcount(); } -void InputStreamMgr::populateScanBuffer() +bool InputStreamMgr::populateScanBuffer() { _scanBuffer.clear(); _saveDataStr.clear(); @@ -133,8 +133,7 @@ void InputStreamMgr::populateScanBuffer() int currChar = 0; while (1) { if (_isGzipped && _bamRuledOut) { - readZipChunk(); - return; + return readZipChunk(); } currChar = _pushBackStreamBuf->sbumpc(); //Stop when EOF hit. @@ -145,7 +144,8 @@ void InputStreamMgr::populateScanBuffer() _scanBuffer.push_back(currChar); if (_isGzipped) { if (!_bamRuledOut && detectBamOrBgzip(numChars, currChar)) { - return; + //we now know the file is in bgzipped format + return true; } if (numChars == 0) { continue; //this will only happen when we've just discovered that this @@ -163,6 +163,9 @@ void InputStreamMgr::populateScanBuffer() //append it to the savedDataStr. _scanBuffer.toStr(_saveDataStr, true); + if (_numBytesInBuffer == 0) return false; + return true; + } bool InputStreamMgr::detectBamOrBgzip(int &numChars, int currChar) @@ -239,7 +242,7 @@ bool InputStreamMgr::detectBamOrBgzip(int &numChars, int currChar) return false; } -void InputStreamMgr::readZipChunk() +bool InputStreamMgr::readZipChunk() { if (_tmpZipBuf == NULL) { _tmpZipBuf = new char[SCAN_BUFFER_SIZE +1]; @@ -251,7 +254,8 @@ void InputStreamMgr::readZipChunk() if ((int)numCharsRead < SCAN_BUFFER_SIZE) { _streamFinished = true; } - return; + if (numCharsRead == 0) return false; + return true; } bool InputStreamMgr::resetStream() diff --git a/src/utils/FileRecordTools/FileReaders/InputStreamMgr.h b/src/utils/FileRecordTools/FileReaders/InputStreamMgr.h index 1c463d37ebf5769c5b4ddf90c3181579fcee1fc3..058a247769c8e6934a19c94e4cf21ab40df5e949 100644 --- a/src/utils/FileRecordTools/FileReaders/InputStreamMgr.h +++ b/src/utils/FileRecordTools/FileReaders/InputStreamMgr.h @@ -30,7 +30,7 @@ public: // istream *getFinalStream() { return _finalInputStream; } const BTlist<int> &getScanBuffer() const { return _scanBuffer; } int getBufferLength() const { return _numBytesInBuffer; } - void populateScanBuffer(); + bool populateScanBuffer(); const QuickString &getSavedData() const { return _saveDataStr; } bool isGzipped() const { return _isGzipped; } PushBackStreamBuf *getPushBackStreamBuf() const {return _pushBackStreamBuf; } @@ -65,7 +65,7 @@ private: BamTools::Internal::BgzfStream *_bgStream; static const char *FIFO_STRING_LITERAL; - void readZipChunk(); + bool readZipChunk(); bool detectBamOrBgzip(int &numChars, int currChar); // void decompressBuffer(); diff --git a/src/utils/FileRecordTools/FileRecordMgr.cpp b/src/utils/FileRecordTools/FileRecordMgr.cpp index 0edf73a687a0a8feb0b77ae150f552b94ce610f9..56417fbb4e016fa18cafb5e7c4a142731d86d4a9 100644 --- a/src/utils/FileRecordTools/FileRecordMgr.cpp +++ b/src/utils/FileRecordTools/FileRecordMgr.cpp @@ -208,6 +208,7 @@ void FileRecordMgr::deleteRecord(RecordKeyList *keyList) { void FileRecordMgr::allocateFileReader() { switch (_fileType) { + case FileRecordTypeChecker::EMPTY_FILE_TYPE: case FileRecordTypeChecker::SINGLE_LINE_DELIM_TEXT_FILE_TYPE: case FileRecordTypeChecker::VCF_FILE_TYPE: _fileReader = new SingleLineDelimTextFileReader(_bufStreamMgr->getTypeChecker().getNumFields(), _bufStreamMgr->getTypeChecker().getDelimChar()); diff --git a/src/utils/FileRecordTools/Records/EmptyRecord.cpp b/src/utils/FileRecordTools/Records/EmptyRecord.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81d16864b3ac6ce57ac2a901c32a8c21a76d730c --- /dev/null +++ b/src/utils/FileRecordTools/Records/EmptyRecord.cpp @@ -0,0 +1,34 @@ +/* + * EmptyRecord.cpp + * + * Created on: Apr 14, 2014 + * Author: nek3d + */ + + +#include "EmptyRecord.h" +#include "SingleLineDelimTextFileReader.h" + +//Technically, there is nothing to do here. Just adding the file +//to keep make happy. + +EmptyRecord::EmptyRecord() { + +} + +EmptyRecord::~EmptyRecord() { + +} + +bool EmptyRecord::initFromFile(FileReader *fileReader) +{ + SingleLineDelimTextFileReader *sldFileReader = static_cast<SingleLineDelimTextFileReader*>(fileReader); + return initFromFile(sldFileReader); +} + + +bool EmptyRecord::initFromFile(SingleLineDelimTextFileReader *fileReader) +{ + return true; +} + diff --git a/src/utils/FileRecordTools/Records/EmptyRecord.h b/src/utils/FileRecordTools/Records/EmptyRecord.h new file mode 100644 index 0000000000000000000000000000000000000000..29f6f4654a3fe5508d7605e5c92a7fc59c7baacc --- /dev/null +++ b/src/utils/FileRecordTools/Records/EmptyRecord.h @@ -0,0 +1,30 @@ +/* + * EmptyRecord.h + * + * Created on: Apr 14, 2014 + * Author: nek3d + */ + +#ifndef EMPTYRECORD_H_ +#define EMPTYRECORD_H_ + +#include "Record.h" + +class SingleLineDelimTextFileReader; + +class EmptyRecord : public Record { +public: + //This is really just a place holder that doesn't have to do much. + //But in order for the rest of the code to not have to contain special + //ugly if statements for empty records, it at least has to instantiable, + //so any purely virtual functions from the base class will have to be overriden. + EmptyRecord(); + ~EmptyRecord(); + + bool initFromFile(FileReader *); + virtual bool initFromFile(SingleLineDelimTextFileReader *); + int getNumFields() const { return 0; } +}; + + +#endif /* EMPTYRECORD_H_ */ diff --git a/src/utils/FileRecordTools/Records/Makefile b/src/utils/FileRecordTools/Records/Makefile index 556cc82df90188cbaf17e2e325a178abef9918a0..f471e666f110fa39f3cc4dde99b879ec580e07f1 100644 --- a/src/utils/FileRecordTools/Records/Makefile +++ b/src/utils/FileRecordTools/Records/Makefile @@ -17,12 +17,12 @@ INCLUDES = -I$(UTILITIES_DIR)/FileRecordTools/FileReaders/ \ # ---------------------------------- # define our source and object files # ---------------------------------- -SOURCES= RecordMgr.cpp RecordMgr.h Record.h Record.cpp Bed3Interval.h Bed3Interval.cpp \ +SOURCES= RecordMgr.cpp RecordMgr.h Record.h Record.cpp EmptyRecord.h EmptyRecord.cpp Bed3Interval.h Bed3Interval.cpp \ Bed4Interval.h Bed4Interval.cpp BedGraphInterval.h BedGraphInterval.cpp Bed5Interval.h Bed5Interval.cpp \ Bed6Interval.h Bed6Interval.cpp \ BedPlusInterval.h BedPlusInterval.cpp Bed12Interval.h Bed12Interval.cpp BamRecord.h BamRecord.cpp VcfRecord.h VcfRecord.cpp \ GffRecord.h GffRecord.cpp RecordKeyList.h RecordKeyList.cpp BlockMgr.h BlockMgr.cpp StrandQueue.h StrandQueue.cpp -OBJECTS= RecordMgr.o Record.o Bed3Interval.o Bed4Interval.o BedGraphInterval.o Bed5Interval.o Bed6Interval.o BedPlusInterval.o Bed12Interval.o BamRecord.o \ +OBJECTS= RecordMgr.o Record.o EmptyRecord.o Bed3Interval.o Bed4Interval.o BedGraphInterval.o Bed5Interval.o Bed6Interval.o BedPlusInterval.o Bed12Interval.o BamRecord.o \ VcfRecord.o GffRecord.o RecordKeyList.o BlockMgr.o StrandQueue.o _EXT_OBJECTS=ParseTools.o QuickString.o ChromIdLookup.o EXT_OBJECTS=$(patsubst %,$(OBJ_DIR)/%,$(_EXT_OBJECTS)) @@ -38,7 +38,7 @@ $(BUILT_OBJECTS): $(SOURCES) clean: @echo "Cleaning up." - @rm -f $(OBJ_DIR)/RecordMgr.o $(OBJ_DIR)/Record.o $(OBJ_DIR)/Bed3Interval.o $(OBJ_DIR)/Bed4Interval.o \ + @rm -f $(OBJ_DIR)/RecordMgr.o $(OBJ_DIR)/Record.o $(OBJ_DIR)/EmptyRecord.o $(OBJ_DIR)/Bed3Interval.o $(OBJ_DIR)/Bed4Interval.o \ $(OBJ_DIR)/BedGraphInterval.o $(OBJ_DIR)/Bed5Interval.o $(OBJ_DIR)/Bed6Interval.o \ $(OBJ_DIR)/BedPlusInterval.o $(OBJ_DIR)/Bed12Interval.o $(OBJ_DIR)/BamRecord.o $(OBJ_DIR)/VcfRecord.o $(OBJ_DIR)/GffRecord.o $(OBJ_DIR)/BlockMgr.o $(OBJ_DIR)/StrandQueue.o diff --git a/src/utils/FileRecordTools/Records/RecordMgr.cpp b/src/utils/FileRecordTools/Records/RecordMgr.cpp index 9799fedc325d208fa502cee814a1f29f6ca471e6..92d9dc54ad714a47fd65aa4edf929dda78635962 100644 --- a/src/utils/FileRecordTools/Records/RecordMgr.cpp +++ b/src/utils/FileRecordTools/Records/RecordMgr.cpp @@ -8,6 +8,13 @@ RecordMgr::RecordMgr(FileRecordTypeChecker::RECORD_TYPE recType, int blockSize) _freeListBlockSize(blockSize) { switch(_recordType) { + case FileRecordTypeChecker::EMPTY_RECORD_TYPE: + { + _freeList = new FreeList<EmptyRecord>(0); + break; + } + + case FileRecordTypeChecker::BED3_RECORD_TYPE: { _freeList = new FreeList<Bed3Interval>(_freeListBlockSize); @@ -72,6 +79,11 @@ RecordMgr::RecordMgr(FileRecordTypeChecker::RECORD_TYPE recType, int blockSize) RecordMgr::~RecordMgr() { switch(_recordType) { + case FileRecordTypeChecker::EMPTY_RECORD_TYPE: + { + delete (FreeList<EmptyRecord> *)_freeList; + break; + } case FileRecordTypeChecker::BED3_RECORD_TYPE: { delete (FreeList<Bed3Interval> *)_freeList; @@ -138,6 +150,12 @@ Record *RecordMgr::allocateRecord() { Record *record = NULL; switch(_recordType) { + case FileRecordTypeChecker::EMPTY_RECORD_TYPE: + { + EmptyRecord *er = ((FreeList<EmptyRecord> *)_freeList)->newObj(); + record = er; + break; + } case FileRecordTypeChecker::BED3_RECORD_TYPE: { Bed3Interval *b3i = ((FreeList<Bed3Interval> *)_freeList)->newObj(); @@ -215,6 +233,12 @@ Record *RecordMgr::allocateRecord() void RecordMgr::deleteRecord(const Record *record) { switch(_recordType) { + case FileRecordTypeChecker::EMPTY_RECORD_TYPE: + { + ((FreeList<EmptyRecord> *)_freeList)->deleteObj(static_cast<const EmptyRecord *>(record)); + break; + } + case FileRecordTypeChecker::BED3_RECORD_TYPE: { ((FreeList<Bed3Interval> *)_freeList)->deleteObj(static_cast<const Bed3Interval *>(record)); diff --git a/src/utils/FileRecordTools/Records/RecordMgr.h b/src/utils/FileRecordTools/Records/RecordMgr.h index 1d73f9055877fc42f76cc2cf0d10efd498101a51..37193b9c8137c72c64df2d48f3eac4d2e93d52ff 100644 --- a/src/utils/FileRecordTools/Records/RecordMgr.h +++ b/src/utils/FileRecordTools/Records/RecordMgr.h @@ -10,6 +10,7 @@ //include headers for all Records and derivative classes #include "Record.h" +#include "EmptyRecord.h" #include "Bed3Interval.h" #include "Bed4Interval.h" #include "Bed5Interval.h" diff --git a/src/utils/NewChromsweep/NewChromsweep.cpp b/src/utils/NewChromsweep/NewChromsweep.cpp index c04fefb19b1cdfcb99f3cf03486074d4dd21c1aa..34647d678c448ccdfefbe32adcd856a81476b58b 100644 --- a/src/utils/NewChromsweep/NewChromsweep.cpp +++ b/src/utils/NewChromsweep/NewChromsweep.cpp @@ -41,9 +41,9 @@ bool NewChromSweep::init() { _databaseFRM = _context->getFile(_context->getDatabaseFileIdx()); nextRecord(false); - if (_currDatabaseRec == NULL) { - return false; - } +// if (_currDatabaseRec == NULL) { +// return false; +// } //determine whether to stop when the database end is hit, or keep going until the //end of the query file is hit as well. diff --git a/src/utils/RecordOutputMgr/RecordOutputMgr.cpp b/src/utils/RecordOutputMgr/RecordOutputMgr.cpp index 9ab8b52b060163e1cc47753a4e2f446f1c36f531..9aaa511bc3d2e10c73c15706bbd42e29808f435a 100644 --- a/src/utils/RecordOutputMgr/RecordOutputMgr.cpp +++ b/src/utils/RecordOutputMgr/RecordOutputMgr.cpp @@ -37,6 +37,10 @@ RecordOutputMgr::RecordOutputMgr() RecordOutputMgr::~RecordOutputMgr() { + // In the rare case when a file had a header but was otherwise empty, + // we'll need to make a last check to see if the header still needs to be printed. + checkForHeader(); + if (_outBuf.size() > 0) { flush(); } @@ -122,7 +126,10 @@ void RecordOutputMgr::printRecord(const Record *record, const QuickString & valu { _afterVal = value; printRecord(record); - _outBuf.append(value); + if (!value.empty()) { + tab(); + _outBuf.append(value); + } newline(); if (needsFlush()) { @@ -152,9 +159,8 @@ void RecordOutputMgr::printRecord(RecordKeyList &keyList, RecordKeyList *blockLi } //The first time we print a record is when we print any header, because the header //hasn't been read from the query file until after the first record has also been read. - if (_context->getPrintHeader()) { - checkForHeader(); - } + checkForHeader(); + const_cast<Record *>(keyList.getKey())->undoZeroLength(); _currBamBlockList = blockList; @@ -208,9 +214,11 @@ void RecordOutputMgr::printRecord(RecordKeyList &keyList, RecordKeyList *blockLi _currBamBlockList = NULL; return; } else if (_context->getProgram() == ContextBase::MAP) { - if (!printKeyAndTerminate(keyList)) { - tab(); - } + printKeyAndTerminate(keyList); + _currBamBlockList = NULL; + return; + } else if (_context->getProgram() == ContextBase::MERGE) { + printKeyAndTerminate(keyList); _currBamBlockList = NULL; return; } else if (_context->getProgram() == ContextBase::MERGE) { @@ -228,6 +236,9 @@ void RecordOutputMgr::printRecord(RecordKeyList &keyList, RecordKeyList *blockLi } void RecordOutputMgr::checkForHeader() { + // Do we need to print a header? + if (!_context->getPrintHeader()) return; + //if the program is based on intersection, we want the header from the query file. if (_context->hasIntersectMethods()) { int queryIdx = (static_cast<ContextIntersect *>(_context))->getQueryFileIdx(); diff --git a/src/utils/fileType/FileRecordTypeChecker.cpp b/src/utils/fileType/FileRecordTypeChecker.cpp index 370cfffa7eb5d418618f29af1e928813e76a2049..fb81f09c53e489d62c83a88fb421527532fc41fd 100644 --- a/src/utils/fileType/FileRecordTypeChecker.cpp +++ b/src/utils/fileType/FileRecordTypeChecker.cpp @@ -12,7 +12,7 @@ FileRecordTypeChecker::FileRecordTypeChecker() _isText = false; _isBed = false; _isDelimited = false; - _delimChar = '\0'; + _delimChar = '\t'; //tab by default _lines.clear(); _firstValidDataLineIdx = -1; _isVCF = false; @@ -21,8 +21,10 @@ FileRecordTypeChecker::FileRecordTypeChecker() _isGzipped = false; _insufficientData = false; _fourthFieldNumeric = false; + _givenEmptyBuffer = false; _hasName[UNKNOWN_RECORD_TYPE] = false; + _hasName[EMPTY_RECORD_TYPE] = false; _hasName[BED3_RECORD_TYPE] = false; _hasName[BED6_RECORD_TYPE] = true; _hasName[BED12_RECORD_TYPE] = true; @@ -32,6 +34,7 @@ FileRecordTypeChecker::FileRecordTypeChecker() _hasName[GFF_RECORD_TYPE] = true; _hasScore[UNKNOWN_RECORD_TYPE] = false; + _hasScore[EMPTY_RECORD_TYPE] = false; _hasScore[BED3_RECORD_TYPE] = false; _hasScore[BED6_RECORD_TYPE] = true; _hasScore[BED12_RECORD_TYPE] = true; @@ -41,6 +44,7 @@ FileRecordTypeChecker::FileRecordTypeChecker() _hasScore[GFF_RECORD_TYPE] = true; _hasStrand[UNKNOWN_RECORD_TYPE] = false; + _hasStrand[EMPTY_RECORD_TYPE] = false; _hasStrand[BED3_RECORD_TYPE] = false; _hasStrand[BED6_RECORD_TYPE] = true; _hasStrand[BED12_RECORD_TYPE] = true; @@ -50,6 +54,7 @@ FileRecordTypeChecker::FileRecordTypeChecker() _hasStrand[GFF_RECORD_TYPE] = true; _recordTypeNames[UNKNOWN_RECORD_TYPE] = "Unknown record type"; + _recordTypeNames[EMPTY_RECORD_TYPE] = "Empty record type"; _recordTypeNames[BED3_RECORD_TYPE] = "Bed3 record type"; _recordTypeNames[BED6_RECORD_TYPE] = "Bed6 record type"; _recordTypeNames[BED12_RECORD_TYPE] = "Bed12 record type"; @@ -58,11 +63,8 @@ FileRecordTypeChecker::FileRecordTypeChecker() _recordTypeNames[VCF_RECORD_TYPE] = "VCF record type"; _recordTypeNames[GFF_RECORD_TYPE] = "GFF record type"; -// UNKNOWN_FILE_TYPE, SINGLE_LINE_DELIM_TEXT_FILE_TYPE, -// MULTI_LINE_ENTRY_TEXT_FILE_TYPE, -// GFF_FILE_TYPE, GZIP_FILE_TYPE, BAM_FILE_TYPE - _fileTypeNames[UNKNOWN_FILE_TYPE] = "Unknown file type"; + _fileTypeNames[EMPTY_FILE_TYPE] = "Empty file type"; _fileTypeNames[SINGLE_LINE_DELIM_TEXT_FILE_TYPE] = "Delimited text file type"; _fileTypeNames[GZIP_FILE_TYPE] = "Gzip file type"; _fileTypeNames[BAM_FILE_TYPE] = "BAM file type"; @@ -77,8 +79,9 @@ bool FileRecordTypeChecker::scanBuffer(const char *buffer, size_t len) } _numBytesInBuffer = len; if (_numBytesInBuffer == 0) { - cerr << "Error: " << _filename << " is an empty file."<< endl; - exit(1); + _fileType = EMPTY_FILE_TYPE; + _recordType = EMPTY_RECORD_TYPE; + return true; } //special: the first thing we do is look for a gzipped file. diff --git a/src/utils/fileType/FileRecordTypeChecker.h b/src/utils/fileType/FileRecordTypeChecker.h index 6d598acea456c8a2e5852a97ca8c3dacd0d72b4e..4af5a80206ff3d53582fb0526465b4a6dd44413c 100644 --- a/src/utils/fileType/FileRecordTypeChecker.h +++ b/src/utils/fileType/FileRecordTypeChecker.h @@ -25,11 +25,11 @@ public: FileRecordTypeChecker(); ~FileRecordTypeChecker() {} - typedef enum { UNKNOWN_FILE_TYPE, SINGLE_LINE_DELIM_TEXT_FILE_TYPE, + typedef enum { UNKNOWN_FILE_TYPE, EMPTY_FILE_TYPE, SINGLE_LINE_DELIM_TEXT_FILE_TYPE, MULTI_LINE_ENTRY_TEXT_FILE_TYPE, GFF_FILE_TYPE, GZIP_FILE_TYPE, BAM_FILE_TYPE, VCF_FILE_TYPE} FILE_TYPE; - typedef enum { UNKNOWN_RECORD_TYPE, BED3_RECORD_TYPE, BED4_RECORD_TYPE, BEDGRAPH_RECORD_TYPE, BED5_RECORD_TYPE, + typedef enum { UNKNOWN_RECORD_TYPE, EMPTY_RECORD_TYPE, BED3_RECORD_TYPE, BED4_RECORD_TYPE, BEDGRAPH_RECORD_TYPE, BED5_RECORD_TYPE, BED6_RECORD_TYPE, BED12_RECORD_TYPE, BED_PLUS_RECORD_TYPE, BAM_RECORD_TYPE, VCF_RECORD_TYPE, GFF_RECORD_TYPE} RECORD_TYPE; void setFilename(const QuickString & filename) { _filename = filename; } @@ -41,7 +41,12 @@ public: bool recordTypeHasStrand(RECORD_TYPE type) const { return _hasStrand.find(type) != _hasStrand.end(); } FILE_TYPE getFileType() const { return _fileType; } + void setFileType(FILE_TYPE type) { _fileType = type; } + + RECORD_TYPE getRecordType() const { return _recordType; } + void setRecordType(RECORD_TYPE type) { _recordType = type; } + const string &getFileTypeName() const { return _fileTypeNames.find(_fileType)->second; } @@ -99,6 +104,7 @@ private: bool _isGzipped; bool _insufficientData; //set to true if scan buffer had only header lines. bool _fourthFieldNumeric; //this is just to distinguish between Bed4 and BedGraph files. + bool _givenEmptyBuffer; map<RECORD_TYPE, string> _recordTypeNames; map<FILE_TYPE, string> _fileTypeNames; diff --git a/test/intersect/headerOnly.vcf b/test/intersect/headerOnly.vcf new file mode 100644 index 0000000000000000000000000000000000000000..9863ae581046b88e4a9f1b8d957480b03dafe165 --- /dev/null +++ b/test/intersect/headerOnly.vcf @@ -0,0 +1,121 @@ +##fileformat=VCFv4.1 +##FORMAT=<ID=AD,Number=.,Type=Integer,Description="Allelic depths for the ref and alt alleles in the order listed"> +##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Approximate read depth (reads with MQ=255 or with bad mates are filtered)"> +##FORMAT=<ID=GQ,Number=1,Type=Float,Description="Genotype Quality"> +##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype"> +##FORMAT=<ID=PL,Number=G,Type=Integer,Description="Normalized, Phred-scaled likelihoods for genotypes as defined in the VCF specification"> +##INFO=<ID=AC,Number=A,Type=Integer,Description="Allele count in genotypes, for each ALT allele, in the same order as listed"> +##INFO=<ID=AF,Number=A,Type=Float,Description="Allele Frequency, for each ALT allele, in the same order as listed"> +##INFO=<ID=AN,Number=1,Type=Integer,Description="Total number of alleles in called genotypes"> +##INFO=<ID=BaseQRankSum,Number=1,Type=Float,Description="Z-score from Wilcoxon rank sum test of Alt Vs. Ref base qualities"> +##INFO=<ID=DP,Number=1,Type=Integer,Description="Approximate read depth; some reads may have been filtered"> +##INFO=<ID=DS,Number=0,Type=Flag,Description="Were any of the samples downsampled?"> +##INFO=<ID=Dels,Number=1,Type=Float,Description="Fraction of Reads Containing Spanning Deletions"> +##INFO=<ID=FS,Number=1,Type=Float,Description="Phred-scaled p-value using Fisher's exact test to detect strand bias"> +##INFO=<ID=HRun,Number=1,Type=Integer,Description="Largest Contiguous Homopolymer Run of Variant Allele In Either Direction"> +##INFO=<ID=HaplotypeScore,Number=1,Type=Float,Description="Consistency of the site with at most two segregating haplotypes"> +##INFO=<ID=InbreedingCoeff,Number=1,Type=Float,Description="Inbreeding coefficient as estimated from the genotype likelihoods per-sample when compared against the Hardy-Weinberg expectation"> +##INFO=<ID=MQ,Number=1,Type=Float,Description="RMS Mapping Quality"> +##INFO=<ID=MQ0,Number=1,Type=Integer,Description="Total Mapping Quality Zero Reads"> +##INFO=<ID=MQRankSum,Number=1,Type=Float,Description="Z-score From Wilcoxon rank sum test of Alt vs. Ref read mapping qualities"> +##INFO=<ID=QD,Number=1,Type=Float,Description="Variant Confidence/Quality by Depth"> +##INFO=<ID=ReadPosRankSum,Number=1,Type=Float,Description="Z-score from Wilcoxon rank sum test of Alt vs. Ref read position bias"> +##UnifiedGenotyper="analysis_type=UnifiedGenotyper input_file=[bam/all.conc.on.pos.dedup.realigned.bam] read_buffer_size=null phone_home=STANDARD read_filter=[] intervals=null excludeIntervals=null interval_set_rule=UNION interval_merging=ALL reference_sequence=/home/arq5x/cphg-home/shared/genomes/hg19/bwa/gatk/hg19_gatk.fa rodBind=[] nonDeterministicRandomSeed=false downsampling_type=BY_SAMPLE downsample_to_fraction=null downsample_to_coverage=250 baq=OFF baqGapOpenPenalty=40.0 performanceLog=null useOriginalQualities=false defaultBaseQualities=-1 validation_strictness=SILENT unsafe=null num_threads=10 num_cpu_threads=null num_io_threads=null num_bam_file_handles=null read_group_black_list=null pedigree=[] pedigreeString=[] pedigreeValidationType=STRICT allow_intervals_with_unindexed_bam=false logging_level=INFO log_to_file=null help=false genotype_likelihoods_model=BOTH p_nonref_model=EXACT heterozygosity=0.0010 pcr_error_rate=1.0E-4 genotyping_mode=DISCOVERY output_mode=EMIT_VARIANTS_ONLY standard_min_confidence_threshold_for_calling=30.0 standard_min_confidence_threshold_for_emitting=30.0 computeSLOD=false alleles=(RodBinding name= source=UNBOUND) min_base_quality_score=17 max_deletion_fraction=0.05 multiallelic=false max_alternate_alleles=5 min_indel_count_for_genotyping=5 indel_heterozygosity=1.25E-4 indelGapContinuationPenalty=10.0 indelGapOpenPenalty=45.0 indelHaplotypeSize=80 bandedIndel=false indelDebug=false ignoreSNPAlleles=false dbsnp=(RodBinding name= source=UNBOUND) out=org.broadinstitute.sting.gatk.io.stubs.VCFWriterStub NO_HEADER=org.broadinstitute.sting.gatk.io.stubs.VCFWriterStub sites_only=org.broadinstitute.sting.gatk.io.stubs.VCFWriterStub debug_file=null metrics_file=null annotation=[] excludeAnnotation=[] filter_mismatching_base_and_quals=false" +##contig=<ID=chr1,length=249250621,assembly=hg19> +##contig=<ID=chr10,length=135534747,assembly=hg19> +##contig=<ID=chr11,length=135006516,assembly=hg19> +##contig=<ID=chr11_gl000202_random,length=40103,assembly=hg19> +##contig=<ID=chr12,length=133851895,assembly=hg19> +##contig=<ID=chr13,length=115169878,assembly=hg19> +##contig=<ID=chr14,length=107349540,assembly=hg19> +##contig=<ID=chr15,length=102531392,assembly=hg19> +##contig=<ID=chr16,length=90354753,assembly=hg19> +##contig=<ID=chr17,length=81195210,assembly=hg19> +##contig=<ID=chr17_ctg5_hap1,length=1680828,assembly=hg19> +##contig=<ID=chr17_gl000203_random,length=37498,assembly=hg19> +##contig=<ID=chr17_gl000204_random,length=81310,assembly=hg19> +##contig=<ID=chr17_gl000205_random,length=174588,assembly=hg19> +##contig=<ID=chr17_gl000206_random,length=41001,assembly=hg19> +##contig=<ID=chr18,length=78077248,assembly=hg19> +##contig=<ID=chr18_gl000207_random,length=4262,assembly=hg19> +##contig=<ID=chr19,length=59128983,assembly=hg19> +##contig=<ID=chr19_gl000208_random,length=92689,assembly=hg19> +##contig=<ID=chr19_gl000209_random,length=159169,assembly=hg19> +##contig=<ID=chr1_gl000191_random,length=106433,assembly=hg19> +##contig=<ID=chr1_gl000192_random,length=547496,assembly=hg19> +##contig=<ID=chr2,length=243199373,assembly=hg19> +##contig=<ID=chr20,length=63025520,assembly=hg19> +##contig=<ID=chr21,length=48129895,assembly=hg19> +##contig=<ID=chr21_gl000210_random,length=27682,assembly=hg19> +##contig=<ID=chr22,length=51304566,assembly=hg19> +##contig=<ID=chr3,length=198022430,assembly=hg19> +##contig=<ID=chr4,length=191154276,assembly=hg19> +##contig=<ID=chr4_ctg9_hap1,length=590426,assembly=hg19> +##contig=<ID=chr4_gl000193_random,length=189789,assembly=hg19> +##contig=<ID=chr4_gl000194_random,length=191469,assembly=hg19> +##contig=<ID=chr5,length=180915260,assembly=hg19> +##contig=<ID=chr6,length=171115067,assembly=hg19> +##contig=<ID=chr6_apd_hap1,length=4622290,assembly=hg19> +##contig=<ID=chr6_cox_hap2,length=4795371,assembly=hg19> +##contig=<ID=chr6_dbb_hap3,length=4610396,assembly=hg19> +##contig=<ID=chr6_mann_hap4,length=4683263,assembly=hg19> +##contig=<ID=chr6_mcf_hap5,length=4833398,assembly=hg19> +##contig=<ID=chr6_qbl_hap6,length=4611984,assembly=hg19> +##contig=<ID=chr6_ssto_hap7,length=4928567,assembly=hg19> +##contig=<ID=chr7,length=159138663,assembly=hg19> +##contig=<ID=chr7_gl000195_random,length=182896,assembly=hg19> +##contig=<ID=chr8,length=146364022,assembly=hg19> +##contig=<ID=chr8_gl000196_random,length=38914,assembly=hg19> +##contig=<ID=chr8_gl000197_random,length=37175,assembly=hg19> +##contig=<ID=chr9,length=141213431,assembly=hg19> +##contig=<ID=chr9_gl000198_random,length=90085,assembly=hg19> +##contig=<ID=chr9_gl000199_random,length=169874,assembly=hg19> +##contig=<ID=chr9_gl000200_random,length=187035,assembly=hg19> +##contig=<ID=chr9_gl000201_random,length=36148,assembly=hg19> +##contig=<ID=chrM,length=16571,assembly=hg19> +##contig=<ID=chrUn_gl000211,length=166566,assembly=hg19> +##contig=<ID=chrUn_gl000212,length=186858,assembly=hg19> +##contig=<ID=chrUn_gl000213,length=164239,assembly=hg19> +##contig=<ID=chrUn_gl000214,length=137718,assembly=hg19> +##contig=<ID=chrUn_gl000215,length=172545,assembly=hg19> +##contig=<ID=chrUn_gl000216,length=172294,assembly=hg19> +##contig=<ID=chrUn_gl000217,length=172149,assembly=hg19> +##contig=<ID=chrUn_gl000218,length=161147,assembly=hg19> +##contig=<ID=chrUn_gl000219,length=179198,assembly=hg19> +##contig=<ID=chrUn_gl000220,length=161802,assembly=hg19> +##contig=<ID=chrUn_gl000221,length=155397,assembly=hg19> +##contig=<ID=chrUn_gl000222,length=186861,assembly=hg19> +##contig=<ID=chrUn_gl000223,length=180455,assembly=hg19> +##contig=<ID=chrUn_gl000224,length=179693,assembly=hg19> +##contig=<ID=chrUn_gl000225,length=211173,assembly=hg19> +##contig=<ID=chrUn_gl000226,length=15008,assembly=hg19> +##contig=<ID=chrUn_gl000227,length=128374,assembly=hg19> +##contig=<ID=chrUn_gl000228,length=129120,assembly=hg19> +##contig=<ID=chrUn_gl000229,length=19913,assembly=hg19> +##contig=<ID=chrUn_gl000230,length=43691,assembly=hg19> +##contig=<ID=chrUn_gl000231,length=27386,assembly=hg19> +##contig=<ID=chrUn_gl000232,length=40652,assembly=hg19> +##contig=<ID=chrUn_gl000233,length=45941,assembly=hg19> +##contig=<ID=chrUn_gl000234,length=40531,assembly=hg19> +##contig=<ID=chrUn_gl000235,length=34474,assembly=hg19> +##contig=<ID=chrUn_gl000236,length=41934,assembly=hg19> +##contig=<ID=chrUn_gl000237,length=45867,assembly=hg19> +##contig=<ID=chrUn_gl000238,length=39939,assembly=hg19> +##contig=<ID=chrUn_gl000239,length=33824,assembly=hg19> +##contig=<ID=chrUn_gl000240,length=41933,assembly=hg19> +##contig=<ID=chrUn_gl000241,length=42152,assembly=hg19> +##contig=<ID=chrUn_gl000242,length=43523,assembly=hg19> +##contig=<ID=chrUn_gl000243,length=43341,assembly=hg19> +##contig=<ID=chrUn_gl000244,length=39929,assembly=hg19> +##contig=<ID=chrUn_gl000245,length=36651,assembly=hg19> +##contig=<ID=chrUn_gl000246,length=38154,assembly=hg19> +##contig=<ID=chrUn_gl000247,length=36422,assembly=hg19> +##contig=<ID=chrUn_gl000248,length=39786,assembly=hg19> +##contig=<ID=chrUn_gl000249,length=38502,assembly=hg19> +##contig=<ID=chrX,length=155270560,assembly=hg19> +##contig=<ID=chrY,length=59373566,assembly=hg19> +##reference=file:///home/arq5x/cphg-home/shared/genomes/hg19/bwa/gatk/hg19_gatk.fa +##SnpEffVersion="SnpEff 3.0g (build 2012-08-31), by Pablo Cingolani" +##SnpEffCmd="SnpEff -i vcf -o vcf GRCh37.66 /home/udp3f/cphg-home/projects/rs-exome/varCalling/2012-Feb-01/all.raw.nobaq.vcf " +##INFO=<ID=EFF,Number=.,Type=String,Description="Predicted effects for this variant.Format: 'Effect ( Effect_Impact | Functional_Class | Codon_Change | Amino_Acid_change| Amino_Acid_length | Gene_Name | Gene_BioType | Coding | Transcript | Exon [ | ERRORS | WARNINGS ] )' "> +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT 1094PC0005 1094PC0009 1094PC0012 1094PC0013 diff --git a/test/intersect/new_test-intersect.sh b/test/intersect/new_test-intersect.sh index 4bdcdf05a1b208d1339dd21c416ef924d59d089e..3b7722239ba0217ad98e55f35466845b25430d01 100755 --- a/test/intersect/new_test-intersect.sh +++ b/test/intersect/new_test-intersect.sh @@ -609,12 +609,12 @@ check obs exp rm obs exp ########################################################### -# Test that we throw an error for empty files +# Test that we allow empty query files ############################################################ echo " intersect.new.t51...\c" -echo "is an empty file." > exp +touch exp touch dummy.txt -$BT intersect -a dummy.txt -b b.bed 2>&1 > /dev/null | cut -f3-6 -d ' ' > obs +$BT intersect -a dummy.txt -b b.bed 2>&1 > /dev/null | cat - > obs check obs exp rm obs exp dummy.txt @@ -664,5 +664,86 @@ $BT intersect -a gdc.gff -b gdc_one.bed > obs check obs exp rm obs exp +########################################################### +# Test that we allow empty database files, unsorted +############################################################ +echo " intersect.new.t56...\c" +touch exp +touch dummy.txt +$BT intersect -a a.bed -b dummy.txt 2>&1 > /dev/null | cat - > obs +check obs exp +rm obs exp dummy.txt + +########################################################### +# Test that we allow empty database files, sorted +############################################################ +echo " intersect.new.t57...\c" +touch exp +touch dummy.txt +$BT intersect -a a.bed -b dummy.txt -sorted 2>&1 > /dev/null | cat - > obs +check obs exp +rm obs exp dummy.txt + + +########################################################### +# Test that we allow empty database files, unsorted, with +# -v (noHit) option +############################################################ +echo " intersect.new.t58...\c" +touch dummy.txt +$BT intersect -a a.bed -b dummy.txt -v > obs +check obs a.bed +rm obs dummy.txt + + +########################################################### +# Test that an empty query with header run with -header +# option will print header +############################################################ +echo " intersect.new.t59...\c" +echo "#Random Header" >dummy.txt +$BT intersect -a dummy.txt -b a.bed -header > obs +check obs dummy.txt +rm obs dummy.txt + + +########################################################### +# Test that an empty query with header, gzipped, that +# runs with -header option will print header +############################################################ +echo " intersect.new.t60...\c" +echo "#Random Header" >dummy.txt +gzip dummy.txt +echo "#Random Header" >exp +$BT intersect -a dummy.txt.gz -b a.bed -header > obs +check obs exp +rm obs dummy.txt.gz exp + +########################################################### +# Test that an empty query with header, bgzipped, that +# runs with -header option will print header +############################################################ +echo " intersect.new.t61...\c" +echo "#Random Header" >dummy.txt +bgzip dummy.txt +echo "#Random Header" >exp +$BT intersect -a dummy.txt.gz -b a.bed -header > obs +check obs exp +rm obs dummy.txt.gz exp + + +########################################################### +# Test that an empty VCF query with header that +# runs with -header option will print header +############################################################ +echo " intersect.new.t62...\c" +$BT intersect -a headerOnly.vcf -b a.bed -header > obs +check obs headerOnly.vcf +rm obs + + + + + diff --git a/test/sample/test-sample.sh b/test/sample/test-sample.sh index 5a65085cb5ea6a7ebf4f3581fa422069272336ed..0994994627de09915e29463f4c7c059173b18e86 100644 --- a/test/sample/test-sample.sh +++ b/test/sample/test-sample.sh @@ -40,21 +40,19 @@ rm obs ############################################################ echo " sample.new.t02...\c" echo "***** ERROR: Unrecognized parameter: -wrongArg *****" > exp -$BT sample -wrongArg 2>&1 > /dev/null | head -2 | tail -1 > obs +$BT sample -i mainFile.bed -wrongArg 2>&1 > /dev/null | head -2 | tail -1 > obs check obs exp rm obs exp - ########################################################### -# Test that we throw an error when no input file is given +# Test that we throw an error when no input file was given. ############################################################ echo " sample.new.t03...\c" -echo "***** ERROR: input file not specified. *****" > exp +echo "***** ERROR: No input file given. Exiting. *****" > exp; $BT sample -n 10 2>&1 > /dev/null | head -2 | tail -1 > obs check obs exp rm obs exp - ########################################################### # Test that we throw an error for -i without input file ############################################################ @@ -116,6 +114,9 @@ $BT sample -i mainFile.bed -n 10 -header | head -1 > obs check obs exp rm obs exp + + + rm mainFile.bed