Exemplo n.º 1
0
void TableRowElement::layout( const AttributeManager* am )
{
    Q_UNUSED( am )
    // Get the parent table to query width/ height values
    TableElement* parentTable = static_cast<TableElement*>( parentElement() );
    setHeight( parentTable->rowHeight( this ) );

    // Get alignment for every table data
    QList<Align> verticalAlign = alignments( Qt::Vertical );
    QList<Align> horizontalAlign = alignments( Qt::Horizontal );

    // align the row's entries
    QPointF origin;
    qreal hOffset = 0.0;
    for ( int i = 0; i < m_data.count(); i++ ) {
//         origin = QPointF();
        hOffset = 0.0;
        if( verticalAlign[ i ] == Bottom )
            origin.setY( height() - m_data[ i ]->height() );
        else if( verticalAlign[ i ] == Center || verticalAlign[ i ] == BaseLine )
            origin.setY( ( height() - m_data[ i ]->height() ) / 2 );
            // Baseline is treated like Center for the moment until someone also refines
            // TableElement::determineDimensions so that it pays attention to baseline.
            // Axis as alignment option is ignored as it is tought to be an option for
            // the table itsself.
//         kDebug() << horizontalAlign[ i ]<<","<<Axis;
        if( horizontalAlign[ i ] == Center ) {
            hOffset = ( parentTable->columnWidth( i ) - m_data[ i ]->width() ) / 2;
        }
        else if( horizontalAlign[ i ] == Right ) {
            hOffset = parentTable->columnWidth( i ) - m_data[ i ]->width();
        }

        m_data[ i ]->setOrigin( origin + QPointF( hOffset, 0.0 ) );
        origin += QPointF( parentTable->columnWidth( i ), 0.0 );
    }

    setWidth( origin.x() );
    // setting of the baseline should not be needed as the table row will only occur
    // inside a table where it does not matter if a table row has a baseline or not
}
Exemplo n.º 2
0
//**********************************************************************************************************************
int ChimeraPerseusCommand::driver(string chimeraFileName, vector<seqData>& sequences, string accnosFileName, int& numChimeras){
	try {
		
		vector<vector<double> > correctModel(4);	//could be an option in the future to input own model matrix
		for(int i=0;i<4;i++){	correctModel[i].resize(4);	}
		
		correctModel[0][0] = 0.000000;	//AA
		correctModel[1][0] = 11.619259;	//CA
		correctModel[2][0] = 11.694004;	//TA
		correctModel[3][0] = 7.748623;	//GA
		
		correctModel[1][1] = 0.000000;	//CC
		correctModel[2][1] = 7.619657;	//TC
		correctModel[3][1] = 12.852562;	//GC
		
		correctModel[2][2] = 0.000000;	//TT
		correctModel[3][2] = 10.964048;	//TG
		
		correctModel[3][3] = 0.000000;	//GG
		
		for(int i=0;i<4;i++){
			for(int j=0;j<i;j++){
				correctModel[j][i] = correctModel[i][j];
			}
		}
		
		int numSeqs = sequences.size();
		int alignLength = sequences[0].sequence.size();
		
		ofstream chimeraFile;
		ofstream accnosFile;
		m->openOutputFile(chimeraFileName, chimeraFile); 
		m->openOutputFile(accnosFileName, accnosFile); 
		
		Perseus myPerseus;
		vector<vector<double> > binMatrix = myPerseus.binomial(alignLength);
		
		chimeraFile << "SequenceIndex\tName\tDiffsToBestMatch\tBestMatchIndex\tBestMatchName\tDiffstToChimera\tIndexofLeftParent\tIndexOfRightParent\tNameOfLeftParent\tNameOfRightParent\tDistanceToBestMatch\tcIndex\t(cIndex - singleDist)\tloonIndex\tMismatchesToChimera\tMismatchToTrimera\tChimeraBreakPoint\tLogisticProbability\tTypeOfSequence\n";
		
		vector<bool> chimeras(numSeqs, 0);
		
		for(int i=0;i<numSeqs;i++){	
			if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }
			
			vector<bool> restricted = chimeras;
			
			vector<vector<int> > leftDiffs(numSeqs);
			vector<vector<int> > leftMaps(numSeqs);
			vector<vector<int> > rightDiffs(numSeqs);
			vector<vector<int> > rightMaps(numSeqs);
			
			vector<int> singleLeft, bestLeft;
			vector<int> singleRight, bestRight;
			
			int bestSingleIndex, bestSingleDiff;
			vector<pwAlign> alignments(numSeqs);
			
			int comparisons = myPerseus.getAlignments(i, sequences, alignments, leftDiffs, leftMaps, rightDiffs, rightMaps, bestSingleIndex, bestSingleDiff, restricted);
			if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }

			int minMismatchToChimera, leftParentBi, rightParentBi, breakPointBi;
			
			string dummyA, dummyB;
			
			if(comparisons >= 2){	
				minMismatchToChimera = myPerseus.getChimera(sequences, leftDiffs, rightDiffs, leftParentBi, rightParentBi, breakPointBi, singleLeft, bestLeft, singleRight, bestRight, restricted);
				if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }

				int minMismatchToTrimera = numeric_limits<int>::max();
				int leftParentTri, middleParentTri, rightParentTri, breakPointTriA, breakPointTriB;
				
				if(minMismatchToChimera >= 3 && comparisons >= 3){
					minMismatchToTrimera = myPerseus.getTrimera(sequences, leftDiffs, leftParentTri, middleParentTri, rightParentTri, breakPointTriA, breakPointTriB, singleLeft, bestLeft, singleRight, bestRight, restricted);
					if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }
				}
				
				double singleDist = myPerseus.modeledPairwiseAlignSeqs(sequences[i].sequence, sequences[bestSingleIndex].sequence, dummyA, dummyB, correctModel);
				
				if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }

				string type;
				string chimeraRefSeq;
				
				if(minMismatchToChimera - minMismatchToTrimera >= 3){
					type = "trimera";
					chimeraRefSeq = myPerseus.stitchTrimera(alignments, leftParentTri, middleParentTri, rightParentTri, breakPointTriA, breakPointTriB, leftMaps, rightMaps);
				}
				else{
					type = "chimera";
					chimeraRefSeq = myPerseus.stitchBimera(alignments, leftParentBi, rightParentBi, breakPointBi, leftMaps, rightMaps);
				}
				;
				if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }
				
				double chimeraDist = myPerseus.modeledPairwiseAlignSeqs(sequences[i].sequence, chimeraRefSeq, dummyA, dummyB, correctModel);
				
				if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }

				double cIndex = chimeraDist;//modeledPairwiseAlignSeqs(sequences[i].sequence, chimeraRefSeq);
				double loonIndex = myPerseus.calcLoonIndex(sequences[i].sequence, sequences[leftParentBi].sequence, sequences[rightParentBi].sequence, breakPointBi, binMatrix);		
				
				if (m->control_pressed) { chimeraFile.close(); m->mothurRemove(chimeraFileName); accnosFile.close(); m->mothurRemove(accnosFileName); return 0; }

				chimeraFile << i << '\t' << sequences[i].seqName << '\t' << bestSingleDiff << '\t' << bestSingleIndex << '\t' << sequences[bestSingleIndex].seqName << '\t';
				chimeraFile << minMismatchToChimera << '\t' << leftParentBi << '\t' << rightParentBi << '\t' << sequences[leftParentBi].seqName << '\t' << sequences[rightParentBi].seqName << '\t';
				chimeraFile << singleDist << '\t' << cIndex << '\t' << (cIndex - singleDist) << '\t' << loonIndex << '\t';
				chimeraFile << minMismatchToChimera << '\t' << minMismatchToTrimera << '\t' << breakPointBi << '\t';
				
				double probability = myPerseus.classifyChimera(singleDist, cIndex, loonIndex, alpha, beta);
				
				chimeraFile << probability << '\t';
				
				if(probability > cutoff){ 
					chimeraFile << type << endl;
					accnosFile << sequences[i].seqName << endl;
					chimeras[i] = 1;
					numChimeras++;
				}
				else{
					chimeraFile << "good" << endl;
				}
				
			}
			else{
				chimeraFile << i << '\t' << sequences[i].seqName << "\t0\t0\tNull\t0\t0\t0\tNull\tNull\t0.0\t0.0\t0.0\t0\t0\t0\t0.0\t0.0\tgood" << endl;
			}
	
			//report progress
			if((i+1) % 100 == 0){ 	m->mothurOut("Processing sequence: " + toString(i+1) + "\n");		}
		}
		
		if((numSeqs) % 100 != 0){ 	m->mothurOut("Processing sequence: " + toString(numSeqs) + "\n");		}
		
		chimeraFile.close();
		accnosFile.close();
		
		return numSeqs;
	}
	catch(exception& e) {
		m->errorOut(e, "ChimeraPerseusCommand", "driver");
		exit(1);
	}
}
Exemplo n.º 3
0
void Foam::cellShapeControlMesh::distribute
(
    const backgroundMeshDecomposition& decomposition
)
{
    DynamicList<Foam::point> points(number_of_vertices());
    DynamicList<scalar> sizes(number_of_vertices());
    DynamicList<tensor> alignments(number_of_vertices());

    DynamicList<Vb> farPts(8);

    for
    (
        Finite_vertices_iterator vit = finite_vertices_begin();
        vit != finite_vertices_end();
        ++vit
    )
    {
        if (vit->real())
        {
            points.append(topoint(vit->point()));
            sizes.append(vit->targetCellSize());
            alignments.append(vit->alignment());
        }
        else if (vit->farPoint())
        {
            farPts.append
            (
                Vb
                (
                    vit->point(),
                    -1,
                    Vb::vtFar,
                    Pstream::myProcNo()
                )
            );

            farPts.last().targetCellSize() = vit->targetCellSize();
            farPts.last().alignment() = vit->alignment();
        }
    }

    autoPtr<mapDistribute> mapDist =
        DistributedDelaunayMesh<CellSizeDelaunay>::distribute
        (
            decomposition,
            points
        );

    mapDist().distribute(sizes);
    mapDist().distribute(alignments);

    // Reset the entire tessellation
    DelaunayMesh<CellSizeDelaunay>::reset();


    // Internal points have to be inserted first
    DynamicList<Vb> verticesToInsert(points.size());


    forAll(farPts, ptI)
    {
        verticesToInsert.append(farPts[ptI]);
    }
Exemplo n.º 4
0
Foam::cellShapeControlMesh::cellShapeControlMesh(const Time& runTime)
:
    DistributedDelaunayMesh<CellSizeDelaunay>
    (
        runTime,
        meshSubDir
    ),
    runTime_(runTime),
    defaultCellSize_(0.0)
{
    if (this->vertexCount())
    {
        fvMesh mesh
        (
            IOobject
            (
                meshSubDir,
                runTime.timeName(),
                runTime,
                IOobject::READ_IF_PRESENT,
                IOobject::NO_WRITE
            )
        );

        if (mesh.nPoints() == this->vertexCount())
        {
            pointScalarField sizes
            (
                IOobject
                (
                    "sizes",
                    runTime.timeName(),
                    meshSubDir,
                    runTime,
                    IOobject::READ_IF_PRESENT,
                    IOobject::NO_WRITE,
                    false
                ),
                pointMesh::New(mesh)
            );

            triadIOField alignments
            (
                IOobject
                (
                    "alignments",
                    mesh.time().timeName(),
                    meshSubDir,
                    mesh.time(),
                    IOobject::READ_IF_PRESENT,
                    IOobject::AUTO_WRITE,
                    false
                )
            );

            if
            (
                sizes.size() == this->vertexCount()
             && alignments.size() == this->vertexCount()
            )
            {
                for
                (
                    Finite_vertices_iterator vit = finite_vertices_begin();
                    vit != finite_vertices_end();
                    ++vit
                )
                {
                    vit->targetCellSize() = sizes[vit->index()];
                    vit->alignment() = alignments[vit->index()];
                }
            }
            else
            {
                FatalErrorInFunction
                    << "Cell size point field is not the same size as the "
                    << "mesh."
                    << abort(FatalError);
            }
        }
    }
}
Exemplo n.º 5
0
void SNPBamProcessor::process_reads(std::vector< std::vector<BamTools::BamAlignment> >& paired_strs_by_rg,
				    std::vector< std::vector<BamTools::BamAlignment> >& mate_pairs_by_rg,
				    std::vector< std::vector<BamTools::BamAlignment> >& unpaired_strs_by_rg,
				    std::vector<std::string>& rg_names, Region& region, 
				    std::string& ref_allele, std::string& chrom_seq, std::ostream& out){
  // Only use specialized function for 10X genomics BAMs if flag has been set
  if(bams_from_10x_){
    process_10x_reads(paired_strs_by_rg, mate_pairs_by_rg, unpaired_strs_by_rg, rg_names, region, ref_allele, chrom_seq, out);
    return;
  }

  locus_snp_phase_info_time_ = clock();
  assert(paired_strs_by_rg.size() == mate_pairs_by_rg.size() && paired_strs_by_rg.size() == unpaired_strs_by_rg.size());
  if (paired_strs_by_rg.size() == 0 && unpaired_strs_by_rg.size() == 0)
    return;
  
  std::vector<  std::vector<BamTools::BamAlignment> > alignments(paired_strs_by_rg.size());
  std::vector< std::vector<double> > log_p1s, log_p2s;
  bool got_snp_info = false;
  if (have_snp_vcf_){
    std::vector<SNPTree*> snp_trees;
    std::map<std::string, unsigned int> sample_indices;      
    if(create_snp_trees(region.chrom(), (region.start() > MAX_MATE_DIST ? region.start()-MAX_MATE_DIST : 1), 
			region.stop()+MAX_MATE_DIST, phased_snp_vcf_, sample_indices, snp_trees, logger())){
      got_snp_info = true;
      std::set<std::string> bad_samples, good_samples;
      for (unsigned int i = 0; i < paired_strs_by_rg.size(); ++i){
	if (sample_indices.find(rg_names[i]) != sample_indices.end()){
	  good_samples.insert(rg_names[i]);
	  std::vector<double> log_p1, log_p2;
	  SNPTree* snp_tree = snp_trees[sample_indices[rg_names[i]]];
	  calc_het_snp_factors(paired_strs_by_rg[i], mate_pairs_by_rg[i], base_quality_, snp_tree, log_p1, log_p2, match_count_, mismatch_count_);
	  calc_het_snp_factors(unpaired_strs_by_rg[i], base_quality_, snp_tree, log_p1, log_p2, match_count_, mismatch_count_);
	  log_p1s.push_back(log_p1); log_p2s.push_back(log_p2);
	}
	else {
	  std::vector<double> log_p1, log_p2;
	  for (unsigned int j = 0; j < paired_strs_by_rg[i].size()+unpaired_strs_by_rg[i].size(); ++j){
	    log_p1.push_back(0); log_p2.push_back(0); // Assign equal phasing LLs as no SNP info is available
	  }
	  log_p1s.push_back(log_p1); log_p2s.push_back(log_p2);
	  bad_samples.insert(rg_names[i]);
	}
	
	// Copy alignments
	alignments[i].insert(alignments[i].end(), paired_strs_by_rg[i].begin(),   paired_strs_by_rg[i].end());
	alignments[i].insert(alignments[i].end(), unpaired_strs_by_rg[i].begin(), unpaired_strs_by_rg[i].end());
      }
      logger() << "Found VCF info for " << good_samples.size() << " out of " << good_samples.size()+bad_samples.size() << " samples with STR reads" << std::endl;
    }
    else 
      logger() << "Warning: Failed to construct SNP trees for " << region.chrom() << ":" << region.start() << "-" << region.stop() << std::endl;
    destroy_snp_trees(snp_trees);      
  }
  if (!got_snp_info){
    for (unsigned int i = 0; i < paired_strs_by_rg.size(); i++){
      // Copy alignments                                                                                                                                             
      alignments[i].insert(alignments[i].end(), paired_strs_by_rg[i].begin(),   paired_strs_by_rg[i].end());
      alignments[i].insert(alignments[i].end(), unpaired_strs_by_rg[i].begin(), unpaired_strs_by_rg[i].end());
      
      // Assign equal phasing LLs as no SNP info is available
      log_p1s.push_back(std::vector<double>(paired_strs_by_rg[i].size()+unpaired_strs_by_rg[i].size(), 0.0));
      log_p2s.push_back(std::vector<double>(paired_strs_by_rg[i].size()+unpaired_strs_by_rg[i].size(), 0.0));
    }
  }
  
  int phased_samples = 0, phased_reads = 0, total_reads = 0;
  for (unsigned int i = 0; i < alignments.size(); i++){
    bool sample_phased = false;
    for (unsigned int j = 0; j < alignments[i].size(); j++){
      sample_phased |= (log_p1s[i][j] != log_p2s[i][j]);
      phased_reads  += (log_p1s[i][j] != log_p2s[i][j]);
    }
    total_reads    += alignments[i].size();
    phased_samples += sample_phased;
  }

  logger() << "Phased SNPs add info for " << phased_reads << " out of " << total_reads << " reads"
	   << " and " << phased_samples << " out of " << rg_names.size() <<  " samples" << std::endl;

  locus_snp_phase_info_time_  = (clock() - locus_snp_phase_info_time_)/CLOCKS_PER_SEC;
  total_snp_phase_info_time_ += locus_snp_phase_info_time_;

  // Run any additional analyses using phasing probabilities
  analyze_reads_and_phasing(alignments, log_p1s, log_p2s, rg_names, region, ref_allele, chrom_seq, 0);
}
Exemplo n.º 6
0
/*
** Exploratory function for analyzing data from 10X Genomics BAMs
** These BAMs contain haplotype tags, which can be used in place of the physical-phasing + VCF approach
** used in the standard process_reads function
 */
void SNPBamProcessor::process_10x_reads(std::vector< std::vector<BamTools::BamAlignment> >& paired_strs_by_rg,
					std::vector< std::vector<BamTools::BamAlignment> >& mate_pairs_by_rg,
					std::vector< std::vector<BamTools::BamAlignment> >& unpaired_strs_by_rg,
					std::vector<std::string>& rg_names, Region& region,
					std::string& ref_allele, std::string& chrom_seq, std::ostream& out){
  locus_snp_phase_info_time_ = clock();
  assert(paired_strs_by_rg.size() == mate_pairs_by_rg.size() && paired_strs_by_rg.size() == unpaired_strs_by_rg.size());
  if (paired_strs_by_rg.size() == 0 && unpaired_strs_by_rg.size() == 0)
    return;

  std::vector<  std::vector<BamTools::BamAlignment> > alignments(paired_strs_by_rg.size());
  std::vector< std::vector<double> > log_p1s, log_p2s;
  int32_t phased_reads = 0, total_reads = 0;
  for (unsigned int i = 0; i < paired_strs_by_rg.size(); i++){
    // Copy alignments
    alignments[i].insert(alignments[i].end(), paired_strs_by_rg[i].begin(),   paired_strs_by_rg[i].end());
    alignments[i].insert(alignments[i].end(), unpaired_strs_by_rg[i].begin(), unpaired_strs_by_rg[i].end());

    log_p1s.push_back(std::vector<double>());
    log_p2s.push_back(std::vector<double>());
    for (unsigned int j = 0; j < paired_strs_by_rg[i].size(); j++){
      total_reads++;
      int haplotype_1 = get_haplotype(paired_strs_by_rg[i][j]);
      int haplotype_2 = get_haplotype(mate_pairs_by_rg[i][j]);

      // If the two mate pairs don't have the same haplotype index, it's possible that
      // i)  One of them is unmapped (and therefore has a -1)
      // ii) They map to two different phase sets. This is essentially a phasing breakpoint and we
      //     probably want to avoid using phase information for these reads
      int haplotype;
      if (haplotype_1 != haplotype_2)
	haplotype = -1;
      else
	haplotype = haplotype_1;
      if (haplotype != -1){
	phased_reads++;
	log_p1s[i].push_back(haplotype == 1 ? FROM_HAP_LL : OTHER_HAP_LL);
	log_p2s[i].push_back(haplotype == 2 ? FROM_HAP_LL : OTHER_HAP_LL);
      }
      else {
	log_p1s[i].push_back(0.0);
	log_p2s[i].push_back(0.0);
      }
    }
    for (unsigned int j = 0; j < unpaired_strs_by_rg[i].size(); j++){
      total_reads++;
      int haplotype = get_haplotype(unpaired_strs_by_rg[i][j]);
      if (haplotype != -1){
	phased_reads++;
	log_p1s[i].push_back(haplotype == 1 ? FROM_HAP_LL : OTHER_HAP_LL);
	log_p2s[i].push_back(haplotype == 2 ? FROM_HAP_LL : OTHER_HAP_LL);
      }
      else {
	log_p1s[i].push_back(0.0);
	log_p2s[i].push_back(0.0);
      }
    }
  }

  logger() << "Phased SNPs add info for " << phased_reads << " out of " << total_reads << " reads" << std::endl;
  locus_snp_phase_info_time_  = (clock() - locus_snp_phase_info_time_)/CLOCKS_PER_SEC;
  total_snp_phase_info_time_ += locus_snp_phase_info_time_;

  // Run any additional analyses using phasing probabilities
  analyze_reads_and_phasing(alignments, log_p1s, log_p2s, rg_names, region, ref_allele, chrom_seq, 0);
}
Exemplo n.º 7
0
    void summarizeLibraryTypeCounts(boost::filesystem::path& opath){
        LibraryFormat fmt1(ReadType::SINGLE_END, ReadOrientation::NONE, ReadStrandedness::U);
        LibraryFormat fmt2(ReadType::SINGLE_END, ReadOrientation::NONE, ReadStrandedness::U);

        std::ofstream ofile(opath.string());

        fmt::MemoryWriter errstr;

        auto log = spdlog::get("jointLog");

        uint64_t numFmt1{0};
        uint64_t numFmt2{0};
        uint64_t numAgree{0};
        uint64_t numDisagree{0};

        for (auto& rl : readLibraries_) {
            auto fmt = rl.format();
            auto& counts = rl.libTypeCounts();

            // If the format is un-stranded, check that
            // we have a similar number of mappings in both
            // directions and then aggregate the forward and
            // reverse counts.
            if (fmt.strandedness == ReadStrandedness::U) {
                std::vector<ReadStrandedness> strands;
                switch (fmt.orientation) {
                    case ReadOrientation::SAME:
                    case ReadOrientation::NONE:
                        strands.push_back(ReadStrandedness::S);
                        strands.push_back(ReadStrandedness::A);
                        break;
                    case ReadOrientation::AWAY:
                    case ReadOrientation::TOWARD:
                        strands.push_back(ReadStrandedness::AS);
                        strands.push_back(ReadStrandedness::SA);
                        break;
                }

                fmt1.type = fmt.type; fmt1.orientation = fmt.orientation;
                fmt1.strandedness = strands[0];
                fmt2.type = fmt.type; fmt2.orientation = fmt.orientation;
                fmt2.strandedness = strands[1];

                numFmt1 = 0;
                numFmt2 = 0;
                numAgree = 0;
                numDisagree = 0;

                for (size_t i = 0; i < counts.size(); ++i) {
                    if (i == fmt1.formatID()) {
                        numFmt1 = counts[i];
                    } else if (i == fmt2.formatID()) {
                        numFmt2 = counts[i];
                    } else {
                        numDisagree += counts[i];
                    }
                }
                numAgree = numFmt1 + numFmt2;
                double ratio = static_cast<double>(numFmt1) / (numFmt1 + numFmt2);

                if ( std::abs(ratio - 0.5) > 0.01) {
                    errstr << "NOTE: Read Lib [" << rl.readFilesAsString() << "] :\n";
                    errstr << "\nDetected a strand bias > 1\% in an unstranded protocol "
                           << "check the file: " << opath.string() << " for details\n";

                    log->warn() << errstr.str();
                    errstr.clear();
                }

                ofile << "========\n"
                      << "Read library consisting of files: "
                      << rl.readFilesAsString()
                      << "\n\n"
                      << "Expected format: " << rl.format()
                      << "\n\n"
                      << "# of consistent alignments: " << numAgree << "\n"
                      << "# of inconsistent alignments: " << numDisagree << "\n"
                      << "strand bias = " << ratio << " (0.5 is unbiased)\n"
                      << "# alignments with format " << fmt1 << ": " << numFmt1 << "\n"
                      << "# alignments with format " << fmt2 << ": " << numFmt2 << "\n"
                      << "\n========\n";
            } else {
                numAgree = 0;
                numDisagree = 0;

                for (size_t i = 0; i < counts.size(); ++i) {
                    if (i == fmt.formatID()) {
                        numAgree = counts[i];
                    } else {
                        numDisagree += counts[i];
                    }
                } // end for

                ofile << "========\n"
                      << "Read library consisting of files: "
                      << rl.readFilesAsString()
                      << "\n\n"
                      << "Expected format: " << rl.format()
                      << "\n\n"
                      << "# of consistent alignments: " << numAgree << "\n"
                      << "# of inconsistent alignments: " << numDisagree << "\n"
                      << "\n========\n";

            } //end else

            double disagreeRatio = static_cast<double>(numDisagree) / (numAgree + numDisagree);
            if (disagreeRatio > 0.05) {
                errstr << "NOTE: Read Lib [" << rl.readFilesAsString() << "] :\n";
                errstr << "\nGreater than 5\% of the alignments (but not, necessarily reads) "
                       << "disagreed with the provided library type; "
                       << "check the file: " << opath.string() << " for details\n";

                log->warn() << errstr.str();
                errstr.clear();
            }

            ofile << "---- counts for each format type ---\n";
            for (size_t i = 0; i < counts.size(); ++i) {
                ofile << LibraryFormat::formatFromID(i) << " : " << counts[i] << "\n";
            }
            ofile << "------------------------------------\n\n";
        }
        ofile.close();
    }