double
get_hapscore(hap_set_t& hap_set) {

    std::sort(hap_set.begin(),hap_set.end());

    std::vector<hinfo> haps;

    typedef hap_set_t::const_iterator hiter;
    {
        hiter i(hap_set.begin()), i_end(hap_set.end());
        for (; i!=i_end; ++i) {
            // 1: check if we match any types; add new type if not
            bool is_match(false);
            const unsigned hs(haps.size());
            for (unsigned j(0); j<hs; ++j) {
                if (is_hap_match(*i,haps[j])) {
                    is_match=true;
                    break;
                }
            }
            if (! is_match) haps.push_back(hinfo(*i));
        }
    }

    const bool is_2hap(haps.size()>1);

    // 2: get two most likely haplotypes:
    if (is_2hap) {
        std::partial_sort(haps.begin(),haps.begin()+2,haps.end());
    }

    // 3: calculate average read alignment score restricted to two best haplotypes:
    //static const double neginf(std::log(0));
    double ln2hapratio(0);
    {
        hiter i(hap_set.begin()), i_end(hap_set.end());
        for (; i!=i_end; ++i) {
            double als(get_align_score(*i,haps[0]));
            if (is_2hap) {
                als=std::max(als,get_align_score(*i,haps[1]));
            }
            //ln2hapratio = log_sum(ln2hapratio,als);
            ln2hapratio += als;
        }

        // target is log(avg(read_prob_ratio)), not avg(log(read_prob_ratio)):
        //
        //ln2hapratio -= std::log(static_cast<double>(hap_set.size()));
        ln2hapratio /= static_cast<double>(hap_set.size());
    }

    return ln2hapratio;
}
void PluginGeneratorGUI::save( const QString& filepath,const bool generatecpp)
{
	MLXMLTree tree;
	collectInfo(tree);
	if (generatecpp)
	{
		QDir dir(finfo.absolutePath());
		QString cppcode = MLXMLUtilityFunctions::generateCPP(finfo.baseName(),tree);
		QFileInfo cppinfo(finfo.absolutePath() + "/" +finfo.baseName() + ".cpp");	
		QString cppoldfilename = UsefulGUIFunctions::generateBackupName(cppinfo);
		dir.rename(cppinfo.fileName(),cppoldfilename);

		QFile cppfile(cppinfo.absoluteFilePath());
		if (!cppfile.open(QIODevice::WriteOnly | QIODevice::Text))
			return;
		QTextStream outcpp(&cppfile);
		outcpp << cppcode;
		cppfile.close();

		QString hcode = MLXMLUtilityFunctions::generateH(finfo.baseName(),tree);	
		QFileInfo hinfo(finfo.absolutePath() + "/" +finfo.baseName() + ".h");
		QString holdfilename = UsefulGUIFunctions::generateBackupName(hinfo);
		dir.rename(hinfo.fileName(),holdfilename);
		QFile hfile(hinfo.absoluteFilePath());
		if (!hfile.open(QIODevice::WriteOnly | QIODevice::Text))
			return;
		QTextStream outh(&hfile);
		outh << hcode;
		hfile.close();
	}
	QString xml = generateXML(tree);
	//QDomDocument has been introduced only in order to indent the xml code
	QDomDocument doc;
	doc.setContent(xml,false);
	xml = doc.toString();
	QFile file(filepath);
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
		return;
	QTextStream out(&file);
	out << xml;
	file.close();
	finfo.setFile(filepath);
}