/****************************************************************************
Returns the score of the variable element in the breakages:
the strong features that are aa dependant.
*****************************************************************************/
score_t RegionalScoreModel::score_a_single_breakage_combo(
							   PrmGraph *prm,  
							   Node& node,
							   const Breakage *breakage,
							   BreakageInfo& info,
							   bool verbose) const
{
	if (node.type == NODE_N_TERM || node.type == NODE_C_TERM)
	{
		const score_t terminal_score=config->get_terminal_score();
		info.score = terminal_score;
		return terminal_score;
	}
	
	Spectrum *spec = prm->get_source_spectrum();
	const mass_t pm_with_19 = prm->get_pm_with_19();

	if (node.const_strong_exps.size()==0)
		calc_constant_element(node,spec,pm_with_19,breakage);

	const bool print_all = false;

	score_t score=0;

	int f;
	for (f=0; f<this->strong_models.size(); f++)
	{
		const StrongFragModel& strong_model = strong_models[f];
		const int frag_idx = strong_model.model_frag_idx;

		if (! strong_model.ind_has_models)
			continue;

		if (! breakage->is_frag_type_visible(frag_idx))
			continue;

		ME_Regression_Sample sam;
		sam.f_vals.clear();
		strong_model.fill_aa_variable_vals(spec,pm_with_19,breakage,&info,sam.f_vals);
	
		score_t prev = score;
		const int pos = breakage->get_position_of_frag_idx(frag_idx);
		if (pos>=0)
		{
			const float var_exp = strong_model.inten_model.get_sum_exp(sam);
			const float e = exp(var_exp + node.const_strong_exps[f]);

			float prob = e/(1.0 + e);
			if (prob>0.99)
				prob=0.99;
			if (prob<0.001)
				prob=0.001;

			const float log_random_peak = spec->get_peak(breakage->fragments[pos].peak_idx).log_rand_prob;
			score += (strong_model.inten_log_scaling_factor + log(prob) - log_random_peak);

			if (print_all)
			{
				cout << "viz >> SCORE " << score << "\t(lrp= " << log_random_peak << " , ilsf=" << strong_model.inten_log_scaling_factor <<
					" , lp=" << log(prob) << " , lrandp=" << log_random_peak << endl;
			}
		}
		else
		{
			const float var_exp = strong_model.no_inten_model.get_sum_exp(sam);
			const float e = exp(var_exp + node.const_strong_exps[f]);

			float prob = e/(1.0 + e);
			if (prob>0.99)
				prob=0.99;
			if (prob<0.01)
				prob=0.01;

			score += (strong_model.no_inten_log_scaling_factor + log(prob) - log_one_minus_random);

			if (print_all)
			{
				cout << "no viz >> SCORE " << score << "\t(nilsf=" << strong_model.inten_log_scaling_factor <<
					" , lp=" << log(prob) << " , loneminusrandp=" << log_one_minus_random << endl;
			}
		}

		if (verbose)
		{
			cout << setprecision(4) << fixed << f << "\t" << score-prev << endl;
		}
	}

	for (f=0; f<regular_models.size(); f++)
	{
		const RegularFragModel& regular_model = regular_models[f];
		const int frag_idx = regular_model.model_frag_idx;

		if (! regular_model.ind_has_models)
			continue;

		if (! breakage->is_frag_type_visible(frag_idx))
			continue;

		ME_Regression_Sample sam;
		sam.f_vals.clear();
		regular_model.fill_aa_variable_vals(spec,pm_with_19,breakage,&info,sam.f_vals);
		
		score_t prev= score;

		const int pos = breakage->get_position_of_frag_idx(frag_idx);
		if (pos>=0)
		{
			const float var_exp = regular_model.inten_model.get_sum_exp(sam);
			const float e = exp(var_exp + node.const_regular_exps[f]);

			float prob = e/(1.0 + e);
			if (prob>0.99)
				prob=0.99;
			if (prob<0.01)
				prob=0.01;

			const float log_random_peak = spec->get_peak(breakage->fragments[pos].peak_idx).log_rand_prob;
			score += (regular_model.inten_log_scaling_factor + log(prob) - log_random_peak);
		}
		else
		{
			const float var_exp = regular_model.no_inten_model.get_sum_exp(sam);
			const float e = exp(var_exp + node.const_regular_exps[f]);

			float prob = e/(1.0 + e);
			if (prob>0.99)
				prob=0.99;
			if (prob<0.02)
				prob=0.02;

			score += (regular_model.no_inten_log_scaling_factor + log(prob) - log_one_minus_random);
		}

		if (verbose)
		{
			cout << f << "\t" << score-prev << endl;
		}
	}

	// correct for digest node scores
	if (node.type == NODE_DIGEST)
	{
		const score_t digest_score=config->get_digest_score();

		if ((info.connects_to_N_term && info.n_edge_idx<0) || 
			(info.connects_to_C_term && info.c_edge_idx<0) )
		{
			score -= digest_score; // penalty for ending here!
		}
			
		if (info.connects_to_N_term && info.preferred_digest_aa_N_term && score<0)
			score = 0;
		if (info.connects_to_C_term && info.preferred_digest_aa_C_term && score<0)
			score = 0;
	}

	return score;
}