quickclusteringspectra.cpp
来自「MS-Clustering is designed to rapidly clu」· C++ 代码 · 共 2,339 行 · 第 1/4 页
CPP
2,339 行
sim_sums[i]+=sim;
sim_sums[j]+=sim;
}
}
float max_sim=-1;
int max_sim_idx=-1;
for (i=0; i<basic_spectra.size(); i++)
{
if (sim_sums[i]>max_sim)
{
max_sim=sim_sums[i];
max_sim_idx=i;
}
}
peaks.resize(basic_spectra[max_sim_idx].num_peaks);
for (i=0; i<basic_spectra[max_sim_idx].num_peaks; i++)
peaks[i]=basic_spectra[max_sim_idx].peaks[i];
set_top_ranked_idxs(top_idxs[max_sim_idx]);
set_cluster_m_over_z();
return max_sim_idx;
}
int ClusterSpectrum::select_max_sqs_spectrum_as_consensus()
{
int max_idx=0;
float max_sqs=0;
int i;
for (i=0; i<basic_spectra.size(); i++)
{
if (basic_spectra[i].ssf->sqs>max_sqs)
{
max_idx=i;
max_sqs = basic_spectra[i].ssf->sqs;
}
}
BasicSpectrum& spec = basic_spectra[max_idx];
float top_x_masses[NUM_TOP_CLUSTER_PEAKS];
vector<int> top_idxs;
set_adjusted_inten(spec.peaks,spec.num_peaks);
select_top_peak_idxs(spec.peaks,spec.num_peaks,spec.ssf->m_over_z,
tolerance, top_idxs, top_x_masses, 20);
peaks.resize(basic_spectra[max_idx].num_peaks);
for (i=0; i<basic_spectra[max_idx].num_peaks; i++)
peaks[i]=basic_spectra[max_idx].peaks[i];
set_top_ranked_idxs(top_idxs);
set_cluster_m_over_z();
return max_idx;
}
/************************************************************************
// sets the m_over_z as the average of the m_over_z of the basic_spectra
*************************************************************************/
void ClusterSpectrum::set_cluster_m_over_z()
{
int i;
m_over_z=0;
/* int c = basic_spectra[0].ssf->charge;
for (i=1; i<basic_spectra.size(); i++)
if (basic_spectra[i].ssf->charge != c)
break;
// not all charges are the same, use the first m_over_z
if (i<basic_spectra.size())
{
m_over_z = basic_spectra[0].ssf->m_over_z;
return;
} */
for (i=0; i<basic_spectra.size(); i++)
m_over_z += basic_spectra[i].ssf->m_over_z;
if (basic_spectra.size() == 0)
{
cout << "Error: cluster has no basic spectra!" << endl;
exit(1);
}
m_over_z /= basic_spectra.size();
}
/************************************************************************
Choose Majority charge
*************************************************************************/
void ClusterSpectrum::set_charge()
{
vector<int> charge_counts;
charge_counts.resize(8,0);
if (basic_spectra.size() == 1)
{
charge = basic_spectra[0].ssf->charge;
return;
}
int i;
for (i=0; i<basic_spectra.size(); i++)
charge_counts[basic_spectra[i].ssf->charge]++;
int max_charge=0;
for (i=0; i<8; i++)
if (charge_counts[i]>=charge_counts[max_charge])
max_charge=i;
charge = max_charge;
if (charge ==0)
return;
const float ratio_max = (float)charge_counts[max_charge]/(float)basic_spectra.size();
if (charge>1 && ratio_max<=0.5)
charge=0;
if (charge == 2 || charge == 3)
{
float ratio2 = (float)charge_counts[2]/(float)basic_spectra.size();
float ratio3 = (float)charge_counts[3]/(float)basic_spectra.size();
if (ratio2>=0.33 && ratio3>=0.33)
charge=0;
}
}
// creates the title (file name) for the cluster
void ClusterSpectrum::make_title(string& name, int batch_idx, int cluster_idx)
{
ostringstream os1;
ostringstream os2;
os1 << batch_idx;
os2 << cluster_idx;
title = name + "." + os1.str() + "." + os2.str();
}
// finds how many spectra have a peptide sequence that
// doesn't match the majority assignment
// adds spectra to the mismatch category only if they contain
// masses that are not within tolerance of each other (modulo -3,-2,-1,+1,+2,+3)
int ClusterSpectrum::get_num_misassigned_spectra(mass_t pm_tolerance, int* mismatched_with_pep) const
{
vector<string> peptide_strings;
vector<int> counts;
int i;
if (mismatched_with_pep)
*mismatched_with_pep=0;
for (i=0; i<basic_spectra.size(); i++)
{
if (basic_spectra[i].ssf->peptide.get_num_aas()<2)
continue;
const string& pep_str = basic_spectra[i].ssf->peptide.as_string(config);
int j;
for (j=0; j<peptide_strings.size(); j++)
{
if (! strcmp(peptide_strings[j].c_str(),pep_str.c_str()))
{
counts[j]++;
break;
}
}
if (j<peptide_strings.size())
continue;
peptide_strings.push_back(pep_str);
counts.push_back(1);
}
if (counts.size()<=1)
return 0;
int max_idx=0;
int max_count=counts[0];
for (i=1; i<peptide_strings.size(); i++)
{
if (counts[i]>max_count)
{
max_idx=i;
max_count=counts[i];
}
}
Peptide max_pep;
string max_pep_str = peptide_strings[max_idx];
max_pep.parse_from_string(config,max_pep_str);
mass_t max_pep_mass_with_19 = max_pep.get_mass() + MASS_OHHH;
int num_missmatched=0;
int num_missmatched_with_peptide=0;
for (i=0; i<basic_spectra.size(); i++)
{
string pep_str = basic_spectra[i].ssf->peptide.as_string(config);
if (pep_str.length()>0 && ! strcmp(pep_str.c_str(),max_pep_str.c_str()) )
continue;
// check that if parent mass is wrong
mass_t pep_m_over_z = basic_spectra[i].ssf->m_over_z;
mass_t best_off = 9999;
mass_t best_pep_mass = -1;
int c;
for (c=1; c<=4; c++) // assume the spectrum's charge is between 1-4
{
mass_t pep_mass = pep_m_over_z * c - (c-1)* MASS_PROTON;
mass_t pm_offset;
for (pm_offset=-4.0; pm_offset<=4.0; pm_offset+=1.0)
{
mass_t offset = fabs(max_pep_mass_with_19 - pep_mass - pm_offset);
if (offset<best_off)
{
best_off = offset;
best_pep_mass = pep_mass;
}
}
}
if (best_off>pm_tolerance)
{
// cout << setprecision(8) << max_pep_mass_with_19 << " " << best_pep_mass << " " <<
// max_pep_mass_with_19 - best_pep_mass << endl;
num_missmatched++;
if (pep_str.length()>0)
{
// cout << pep_str << " " << num_missmatched_with_peptide << endl;
num_missmatched_with_peptide++;
}
}
}
if (mismatched_with_pep)
*mismatched_with_pep=num_missmatched_with_peptide;
return num_missmatched;
}
// returns true if there is a mjority annotation (with 75% of the annotated spectra)
// if so, returns its string and mass in the variables
bool ClusterSpectrum::has_majority_annotation(string& consensus_pep_str, mass_t& consensus_pep_mass) const
{
vector<string> peptide_strings;
vector<int> counts;
int num_annoatated_spectra=0;
int i;
peptide_strings.clear();
counts.clear();
for (i=0; i<basic_spectra.size(); i++)
{
if (basic_spectra[i].ssf->peptide.get_num_aas()<2)
continue;
const string& pep_str = basic_spectra[i].ssf->peptide.as_string(config);
num_annoatated_spectra++;
int j;
for (j=0; j<peptide_strings.size(); j++)
{
if (! strcmp(peptide_strings[j].c_str(),pep_str.c_str()))
{
counts[j]++;
break;
}
}
if (j<peptide_strings.size())
continue;
peptide_strings.push_back(pep_str);
counts.push_back(1);
}
if (counts.size()==0)
return false;
// cout << ">>> " << basic_spectra.size() << " <" << counts.size() << "> " <<
// num_annoatated_spectra << endl;
int max_idx=0;
int max_count=counts[0];
for (i=1; i<counts.size(); i++)
{
if (counts[i]>max_count)
{
max_idx=i;
max_count=counts[i];
}
}
// cout << max_count << " " << num_annoatated_spectra << endl;
if ( ((double)max_count/(double)num_annoatated_spectra) <0.75)
return false;
Peptide max_pep;
consensus_pep_str = peptide_strings[max_idx];
max_pep.parse_from_string(config,consensus_pep_str);
consensus_pep_mass = max_pep.get_mass() + MASS_OHHH;
return true;
}
int ClusterSpectrum::get_num_basic_spectra_with_peptide() const
{
int num_peps=0;
int i;
for (i=0; i<basic_spectra.size(); i++)
if (basic_spectra[i].ssf->peptide.get_num_aas()>1)
num_peps++;
return num_peps;
}
void ClusterSpectrum::print_cluster_peptides() const
{
vector<string> peptide_strings;
vector<int> counts;
int i;
for (i=0; i<basic_spectra.size(); i++)
{
if (basic_spectra[i].ssf->peptide.get_num_aas()<3)
continue;
const string& pep_str = basic_spectra[i].ssf->peptide.as_string(config);
int j;
for (j=0; j<peptide_strings.size(); j++)
{
if (! strcmp(peptide_strings[j].c_str(),pep_str.c_str()))
{
counts[j]++;
break;
}
}
if (j<peptide_strings.size())
continue;
peptide_strings.push_back(pep_str);
counts.push_back(1);
}
int num_with_peptide=0;
for (i=0; i<counts.size(); i++)
num_with_peptide+=counts[i];
cout << "Cluster: " << this->tmp_cluster_idx << " " << basic_spectra.size() << " (";
cout << num_with_peptide << ")" << endl;
for (i=0; i<counts.size(); i++)
cout << setw(4) << left << counts[i] << peptide_strings[i].c_str() << endl;
}
void ClusterSpectrum::print_cluster_similarities()
{
int i;
mass_t tolerance = config->get_tolerance();
for (i=0; i<basic_spectra.size(); i++)
{
BasicSpectrum& spec = basic_spectra[i];
float top_x_masses[NUM_TOP_CLUSTER_PEAKS];
vector<int> spec_top_idxs;
set_adjusted_inten(spec.peaks,spec.num_peaks);
select_top_peak_idxs(spec.peaks,spec.num_peaks,spec.ssf->m_over_z,
tolerance,spec_top_idxs, top_x_masses, num_top_peaks_per_1000_da);
float sim = calc_selected_dot_prod(tolerance,
&peaks[0], peaks.size(), top_ranked_peak_idxs,
spec.peaks,spec.num_peaks, spec_top_idxs);
cout << i << " " << sim << " " << spec.ssf->single_name;
}
}
void BasicSpectrum::output_to_mgf(ostream& mgf, Config *config, const char *seq) const
{
mgf << "BEGIN IONS" << endl;
mgf << "TITLE=" << ssf->single_name << endl;
if (ssf->peptide.get_num_aas()>0)
{
mgf << "SEQ=" << ssf->peptide.as_string(config) << endl;
}
else if (seq && strlen(seq)>2)
mgf << "SEQ=" << seq << endl;
if (ssf->type == MZXML)
{
// MZXML_single *mzxml_single = (MZXML_single *)ssf;
// if (mzxml_single->scan_number>=0)
// mgf << "SCAN=" <<mzxml_single->scan_number << endl;
// if (mzxml_single->retention_time>=0)
// mgf << "RT=" << mzxml_single->retention_time << endl;
}
mgf << "CHARGE=+" << ssf->charge << endl;
mgf << "PEPMASS=" << ssf->m_over_z << endl;
int i;
for (i=0; i<this->num_peaks; i++)
mgf << fixed << setprecision(3) << peaks[i].mass << " " << peaks[i].intensity << endl;
mgf << "END IONS" << endl << endl;
}
void BasicSpectrum::output_to_mgf(FILE* mgf_stream, Config *config, const char *seq) const
{
fprintf(mgf_stream,"BEGIN IONS\n");
fprintf(mgf_stream,"TITLE=%s\n",ssf->single_name.c_str());
if (ssf->peptide.get_num_aas()>0)
{
fprintf(mgf_stream,"SEQ=%s\n",ssf->peptide.as_string(config).c_str());
}
else if (seq && strlen(seq)>2)
fprintf(mgf_stream,"SEQ=%s\n", seq);
if (ssf->type == MZXML)
{
MZXML_single *mzxml_single = (MZXML_single *)ssf;
if (mzxml_single->scan_number>=0)
fprintf(mgf_stream,"SCAN=%d\n",mzxml_single->scan_number);
}
fprintf(mgf_stream,"CHARGE=+%d\n",ssf->charge);
fprintf(mgf_stream,"PEPMASS=%.3f\n",ssf->m_over_z);
int i;
for (i=0; i<this->num_peaks; i++)
fprintf(mgf_stream,"%.3f %.3f\n",peaks[i].mass, peaks[i].intensity);
fprintf(mgf_stream,"END IONS\n\n");
}
void ClusterSpectrum::write_cluster_basic_spectra_to_mgf(char *mgf_file) const
{
ofstream mgf(mgf_file);
int i;
for (i=0; i<basic_spectra.size(); i++)
basic_spectra[i].output_to_mgf(mgf,config);
mgf.close();
}
// writes the spectrum to the output file in the mgf format
void ClusterSpectrum::write_spectrum_to_mgf(ostream& mgf,bool write_peak_count) const
{
mgf << "BEGIN IONS" << endl;
mgf << "TITLE=" << title << endl;
if (peptide_str.length()>0)
mgf << "SEQ=" << peptide_str << endl;
// if (retention_time>=0)
// mgf << "RT=" << retention_time << endl;
// mgf << "CLUSTER_SIZE=" << basic_spectra.size() << endl;
if (this->charge>0 && config->get_use_spectrum_charge())
mgf << "CHARGE=" << this->charge << "+" << endl;
mgf << "PEPMASS=" << this->m_over_z << endl;
// filter peaks if there are too many
if (this->basic_spectra.size()>1)
{
if (peaks.size() <= maximum_good_peaks_to_output)
{
int i;
for (i=0; i<peaks.size(); i++)
{
mgf << fixed << setprecision(3) << peaks[i].mass << " " << setprecision(2) <<
(peaks[i].scaled_intensity>0 ? peaks[i].scaled_intensity : peaks[i].intensity);
if (write_peak_count)
mgf << " " << peaks[i].num_occurences << "/" << peaks[i].max_num_occurences;
mgf << endl;
}
}
else
{
vector<bool> good_peak_indicators;
mark_top_peaks_with_sliding_window(&peaks[0], peaks.size(),
config->get_local_window_size(),
config->get_max_number_peaks_per_local_window(),
good_peak_indicators);
int i;
for (i=0; i<peaks.size(); i++)
{
if (! good_peak_indicators[i])
continue;
mgf << fixed << setprecision(3) << peaks[i].mass << " " << setprecision(2) <<
(peaks[i].scaled_intensity>0 ? peaks[i].scaled_intensity : peaks[i].intensity);
if (write_peak_count)
mgf << " " << peaks[i].num_occurences << "/" << peaks[i].max_num_occurences;
mgf << endl;
}
}
}
else // output all peaks in the single basic spectrum - no filtering
{
const QCPeak *peaks = basic_spectra[0].peaks;
const int num_peaks = basic_spectra[0].num_peaks;
int i;
for (i=0; i<num_peaks; i++)
mgf << fixed << setprecision(3) << peaks[i].mass << " " << setprecision(3) <<
peaks[i].intensity << endl;
}
mgf << "END IONS" << endl << endl;
}
// writes the spectrum to the output file in the mgf format
void ClusterSpectrum::write_spectrum_to_pkl_single(string& file_name) const
{
ofstream pkl(file_name.c_str());
if (! pkl.is_open())
{
cout << "Error: couldn't open pkl for writing " << file_name << endl;
exit(1);
}
double total_ion_current =0;
int i;
for (i=0; i<basic_spectra.size(); i++)
total_ion_current += basic_spectra[i].ssf->precursor_intensity;
// cout << "TIC: " << total_ion_current << endl;
pkl << setprecision(4) << fixed << m_over_z << "\t";
pkl << setprecision(0) << total_ion_current << "\t";
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?