static void WriteHeader(MetabolizerPhenotypingEngine *eng, affx::TsvFile &tsv, int idx, std::ofstream &str)
{
	// Output the header
	str << "# For research use only. Not for diagnostic purposes." << std::endl;
	str << "#%report-guid=" << affxutil::Guid::GenerateNewGuid() << std::endl;
	str << "#%Program=" << MET_PROGRAM_NAME << std::endl;
	str << "#%Version=" << MET_PROGRAM_VERSION << std::endl;
	str << "#%Date=" << Util::getTimeStamp() << std::endl;
	str << "#%MetabolizerFile=" << eng->getOpt("metabolizer-file") << std::endl;
	str << "#%AlleleFile=" << eng->getOpt("allele-file") << std::endl;
	for (int i=0; i<(int)eng->PhenotypeCallDescs().size(); i++)
		str << "#%PhenotypeCallDesc=" << eng->PhenotypeCallDescs()[i] << std::endl;
	for (int i=0; i<(int)eng->UserInformation().size(); i++)
		str << "#%Info=" << eng->UserInformation()[i] << std::endl;
	str << "Index" << "\t"
		<< "CHP File" << "\t"
		<< "Gene" << "\t"
		<< "Phenotype Call" << "\t"
		<< "Gene Activity" << "\t"
		<< "Known Call" << "\t"
		<< "Unknown Call" << "\t"
		<< "Interpretation Code";
	int n = tsv.getColumnCount(0);
	for (int i=idx; i<n; i++)
	{
		std::string name = tsv.getColumnName(0, i);
		str << "\t" << name;
	}
	str << std::endl;
}
void 
affx::TsvFileDiff::open_residuals(const std::string& filename,
                                  affx::TsvFile& tsv1,
                                  affx::TsvFile& tsv2)
{
  // no file
  if (filename=="") {
    return;
  }
  //
  m_residuals_tsv=new affx::TsvFile();
  //
  for (int clvl=0;clvl<tsv1.getLevelCount();clvl++) {
    for (int cidx=0;cidx<tsv1.getColumnCount(clvl);cidx++) {
      std::string cname=tsv1.getColumnName(clvl,cidx); // +"_res";
      m_residuals_tsv->defineColumn(clvl,cidx,cname);
    }
  }
  //
  m_residuals_tsv->addHeader("apt-file-type","tsv-diff-residuals");
  m_residuals_tsv->addHeader("tsv-diff-input-file1",tsv1.getFileName());
  m_residuals_tsv->addHeader("tsv-diff-input-file2",tsv2.getFileName());
  m_residuals_tsv->addHeader("file-guid",affxutil::Guid::GenerateNewGuid());
  //
  if (m_residuals_tsv->getLevelCount()==1) {
    m_residuals_tsv->writeTsv_v1(filename);
  } else {
    m_residuals_tsv->writeTsv_v2(filename);
  }
}
static int FindStartingAttributeColumnIndex(affx::TsvFile &tsv)
{
	int n = tsv.getColumnCount(0);
	int idx = n;
	for (int i=0; i<n; i++)
	{
		std::string name = tsv.getColumnName(0, i);
		if (name == "Override Comment")
		{
			idx = i+1;
			break;
		}
	}
	return idx;
}