<commit_before>/*
 *   PairedInputFilter.h
 *
 *   Authors: mat and jtr
 */

#ifndef FLEXBAR_PAIREDINPUTFILTER_H
#define FLEXBAR_PAIREDINPUTFILTER_H

#include "SeqInputFilter.h"


template <typename TSeqStr, typename TString>
class PairedInputFilter : public tbb::filter {

private:
	
	const bool m_isPaired, m_useBarcodeRead, m_useNumberTag;
	const unsigned int m_bundleSize;
	
	tbb::atomic<unsigned long> m_uncalled, m_uncalledPairs, m_tagCounter;
	
	SeqInputFilter<TSeqStr, TString> *m_f1, *m_f2, *m_b;
	
public:
	
	PairedInputFilter(const Options &o) :
		
		filter(serial_in_order),
		m_useNumberTag(o.useNumberTag),
		m_isPaired(o.isPaired),
		m_useBarcodeRead(o.barDetect == flexbar::BARCODE_READ),
		m_bundleSize(o.bundleSize){
		
		m_tagCounter    = 0;
		m_uncalled      = 0;
		m_uncalledPairs = 0;
		
		m_f1 = new SeqInputFilter<TSeqStr, TString>(o, o.readsFile, false, true, o.useStdin);
		
		m_f2 = NULL;
		m_b  = NULL;
		
		if(m_isPaired){
			m_f2 = new SeqInputFilter<TSeqStr, TString>(o, o.readsFile2, false, true, false);
		}
		
		if(m_useBarcodeRead){
			m_b = new SeqInputFilter<TSeqStr, TString>(o, o.barReadsFile, false, false, false);
		}
	}
	
	
	virtual ~PairedInputFilter(){
		delete m_f1;
		delete m_f2;
		delete m_b;
	}
	
	
	void* getPairedRead(){
		
		using namespace std;
		
		SeqRead<TSeqStr, TString> *read1 = NULL, *read2 = NULL, *barRead = NULL;
		
		bool uncalled = true, uncalled2 = true, uBR = true;
		
		if(! m_isPaired){
			
			while(uncalled){
				read1 = static_cast< SeqRead<TSeqStr, TString>* >(m_f1->getRead(uncalled));
				
				if(m_useBarcodeRead) barRead = static_cast< SeqRead<TSeqStr, TString>* >(m_b->getRead(uBR));
				
				if(read1 == NULL && m_useBarcodeRead && barRead != NULL){
					cerr << "Error: barcode read without read, or file reading error.\n" << endl;
					exit(1);
				}
				else if(read1 == NULL){
					return NULL;
				}
				else if(m_useBarcodeRead && barRead == NULL){
					cerr << "Error: read without barcode read, or file reading error.\n" << endl;
					exit(1);
				}
				
				if(uncalled){
					++m_uncalled;
					delete read1;
					delete barRead;
				}
			}
		}
		
		// paired read input
		else{
			
			while(uncalled || uncalled2){
				
				read1 = static_cast< SeqRead<TSeqStr, TString>* >(m_f1->getRead(uncalled));
				read2 = static_cast< SeqRead<TSeqStr, TString>* >(m_f2->getRead(uncalled2));
				
				if(m_useBarcodeRead) barRead = static_cast< SeqRead<TSeqStr, TString>* >(m_b->getRead(uBR));
				
				
				if((read1 == NULL || read2 == NULL) && m_useBarcodeRead && barRead != NULL){
					cerr << "Error: barcode read without read-pair or file reading error.\n" << endl;
					exit(1);
				}
				else if(read1 == NULL && read2 == NULL){
					return NULL;
				}
				else if(read1 == NULL || read2 == NULL){
					cerr << "Error: single read in paired mode, or file reading error.\n" << endl;
					exit(1);
				}
				else if(m_useBarcodeRead && barRead == NULL){
					cerr << "Error: reads without barcode read or file reading error.\n" << endl;
					exit(1);
				}
				
				if(uncalled || uncalled2){
					++m_uncalledPairs;
					if(uncalled)  ++m_uncalled;
					if(uncalled2) ++m_uncalled;
					
					delete read1;
					delete read2;
					delete barRead;
				}
			}
		}
		
		if(m_useNumberTag){
			stringstream converter;
			converter << ++m_tagCounter;
			TString tagCount = converter.str();
			
			read1->setSequenceTag(tagCount);
			if(m_isPaired) read2->setSequenceTag(tagCount);
			if(m_useBarcodeRead) barRead->setSequenceTag(tagCount);
		}
		
		return new PairedRead<TSeqStr, TString>(read1, read2, barRead);
	}
	
	
	// tbb filter operator
	void* operator()(void*){
		
		using namespace std;
		
		vector<PairedRead<TSeqStr, TString>* > *bundle = new vector<PairedRead<TSeqStr, TString>* >();
		
		for(unsigned int i = 0; i < m_bundleSize; ++i){
			
			PairedRead<TSeqStr, TString> *pRead = NULL;
			
			pRead = static_cast< PairedRead<TSeqStr, TString>* >(getPairedRead());
			
			     if(pRead == NULL && i == 0) return NULL;
			else if(pRead == NULL)           break;
			else                             bundle->push_back(pRead);
		}
		return new PairedReadBundle<TSeqStr, TString>(bundle);
	}
	
	
	unsigned long getNrUncalledReads() const{
		return m_uncalled;
	}
	
	
	unsigned long getNrUncalledPairedReads() const{
		return m_uncalledPairs;<commit_msg>Reserve bundle capacity<commit_after>/*
 *   PairedInputFilter.h
 *
 *   Authors: mat and jtr
 */

#ifndef FLEXBAR_PAIREDINPUTFILTER_H
#define FLEXBAR_PAIREDINPUTFILTER_H

#include "SeqInputFilter.h"


template <typename TSeqStr, typename TString>
class PairedInputFilter : public tbb::filter {

private:
	
	const bool m_isPaired, m_useBarcodeRead, m_useNumberTag;
	const unsigned int m_bundleSize;
	
	tbb::atomic<unsigned long> m_uncalled, m_uncalledPairs, m_tagCounter;
	
	SeqInputFilter<TSeqStr, TString> *m_f1, *m_f2, *m_b;
	
public:
	
	PairedInputFilter(const Options &o) :
		
		filter(serial_in_order),
		m_useNumberTag(o.useNumberTag),
		m_isPaired(o.isPaired),
		m_useBarcodeRead(o.barDetect == flexbar::BARCODE_READ),
		m_bundleSize(o.bundleSize){
		
		m_tagCounter    = 0;
		m_uncalled      = 0;
		m_uncalledPairs = 0;
		
		m_f1 = new SeqInputFilter<TSeqStr, TString>(o, o.readsFile, false, true, o.useStdin);
		
		m_f2 = NULL;
		m_b  = NULL;
		
		if(m_isPaired){
			m_f2 = new SeqInputFilter<TSeqStr, TString>(o, o.readsFile2, false, true, false);
		}
		
		if(m_useBarcodeRead){
			m_b = new SeqInputFilter<TSeqStr, TString>(o, o.barReadsFile, false, false, false);
		}
	}
	
	
	virtual ~PairedInputFilter(){
		delete m_f1;
		delete m_f2;
		delete m_b;
	}
	
	
	void* getPairedRead(){
		
		using namespace std;
		
		SeqRead<TSeqStr, TString> *read1 = NULL, *read2 = NULL, *barRead = NULL;
		
		bool uncalled = true, uncalled2 = true, uBR = true;
		
		if(! m_isPaired){
			
			while(uncalled){
				read1 = static_cast< SeqRead<TSeqStr, TString>* >(m_f1->getRead(uncalled));
				
				if(m_useBarcodeRead) barRead = static_cast< SeqRead<TSeqStr, TString>* >(m_b->getRead(uBR));
				
				if(read1 == NULL && m_useBarcodeRead && barRead != NULL){
					cerr << "Error: barcode read without read, or file reading error.\n" << endl;
					exit(1);
				}
				else if(read1 == NULL){
					return NULL;
				}
				else if(m_useBarcodeRead && barRead == NULL){
					cerr << "Error: read without barcode read, or file reading error.\n" << endl;
					exit(1);
				}
				
				if(uncalled){
					++m_uncalled;
					delete read1;
					delete barRead;
				}
			}
		}
		
		// paired read input
		else{
			
			while(uncalled || uncalled2){
				
				read1 = static_cast< SeqRead<TSeqStr, TString>* >(m_f1->getRead(uncalled));
				read2 = static_cast< SeqRead<TSeqStr, TString>* >(m_f2->getRead(uncalled2));
				
				if(m_useBarcodeRead) barRead = static_cast< SeqRead<TSeqStr, TString>* >(m_b->getRead(uBR));
				
				
				if((read1 == NULL || read2 == NULL) && m_useBarcodeRead && barRead != NULL){
					cerr << "Error: barcode read without read-pair or file reading error.\n" << endl;
					exit(1);
				}
				else if(read1 == NULL && read2 == NULL){
					return NULL;
				}
				else if(read1 == NULL || read2 == NULL){
					cerr << "Error: single read in paired mode, or file reading error.\n" << endl;
					exit(1);
				}
				else if(m_useBarcodeRead && barRead == NULL){
					cerr << "Error: reads without barcode read or file reading error.\n" << endl;
					exit(1);
				}
				
				if(uncalled || uncalled2){
					++m_uncalledPairs;
					if(uncalled)  ++m_uncalled;
					if(uncalled2) ++m_uncalled;
					
					delete read1;
					delete read2;
					delete barRead;
				}
			}
		}
		
		if(m_useNumberTag){
			stringstream converter;
			converter << ++m_tagCounter;
			TString tagCount = converter.str();
			
			read1->setSequenceTag(tagCount);
			if(m_isPaired) read2->setSequenceTag(tagCount);
			if(m_useBarcodeRead) barRead->setSequenceTag(tagCount);
		}
		
		return new PairedRead<TSeqStr, TString>(read1, read2, barRead);
	}
	
	
	// tbb filter operator
	void* operator()(void*){
		
		using namespace std;
		
		vector<PairedRead<TSeqStr, TString>* > *bundle = new vector<PairedRead<TSeqStr, TString>* >();
		
		bundle->reserve(m_bundleSize);
		
		for(unsigned int i = 0; i < m_bundleSize; ++i){
			
			PairedRead<TSeqStr, TString> *pRead = NULL;
			
			pRead = static_cast< PairedRead<TSeqStr, TString>* >(getPairedRead());
			
			     if(pRead == NULL && i == 0) return NULL;
			else if(pRead == NULL)           break;
			else                             bundle->push_back(pRead);
			
			// cout << "Bundle slot: " << i << endl;
			// cout << "Capacity:    " << bundle->capacity() << endl;
		}
		return new PairedReadBundle<TSeqStr, TString>(bundle);
	}
	
	
	unsigned long getNrUncalledReads() const{
		return m_uncalled;
	}
	
	
	unsigned long getNrUncalledPairedReads() const{
		return m_uncalledPairs;
{'fraction_non_alphanumeric': 0.13067089037221405, 'fraction_numerical': 0.01040841724176943, 'mean_word_length': 3.2035187826913933, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '886627', 'n_tokens_mistral': 3979, 'n_tokens_neox': 3242, 'n_words': 701}