fragmentation.cpp
来自「MS-Clustering is designed to rapidly clu」· C++ 代码 · 共 682 行 · 第 1/2 页
CPP
682 行
#include "Fragmentation.h"
#include "Config.h"
const char *neutral_loss_labels[]={"","-H2O","-NH3","-H2OH2O","-H2ONH3","-NH3NH3"};
const mass_t neutral_loss_offsets[]={0,-MASS_H2O,-MASS_NH3,-MASS_H2OH2O,-MASS_H2ONH3,-MASS_NH3NH3};
const int num_neutral_losses = sizeof(neutral_loss_labels)/sizeof(char *);
const char *prefix_base_labels[]={"a","b","c"};
const mass_t prefix_base_offsets[]={-26.9871,MASS_PROTON,18.0343};
const int num_prefix_bases = sizeof(prefix_base_labels)/sizeof(char *);
const char *suffix_base_labels[]={"x","y","z"};
const mass_t suffix_base_offsets[]={45.9976,MASS_OHHH,2.99};
const int num_suffix_bases = sizeof(suffix_base_labels)/sizeof(char *);
void FragmentType::read_fragment(istream& is)
{
char line[128];
is.getline(line,128);
istringstream iss(line);
char direction;
iss >> direction;
if (direction == 'p')
{
orientation = PREFIX;
}
else if (direction == 's')
{
orientation = SUFFIX;
}
else
{
cout << "Error reading fragment: " << line << endl;
exit(1);
}
iss >> charge >> offset >> label;
}
void FragmentType::write_fragment(ostream& os) const
{
if (orientation == PREFIX)
{
os << "p ";
}
else
os << "s ";
os << charge << " ";
os << fixed << setprecision(5) << offset << " ";
os << label << endl;
}
/********************************************************
Creates a string label from the fragment information.
*********************************************************/
void FragmentType::make_frag_label(mass_t tolerance)
{
label = (orientation == PREFIX ? "p" : "s");
if (charge>1)
{
ostringstream os;
os << charge;
label+= os.str();
}
if (offset != 0)
{
ostringstream os;
os << fixed << setprecision(1) << offset;
if (offset>0)
label += "+";
label += os.str();
}
// use standard labels for known fragments
char **base_labels;
mass_t *base_offsets;
int num_bases;
if (orientation == PREFIX)
{
base_labels = (char **)prefix_base_labels;
base_offsets = (mass_t *)prefix_base_offsets;
num_bases = num_prefix_bases;
}
else
{
base_labels = (char **)suffix_base_labels;
base_offsets = (mass_t *)suffix_base_offsets;
num_bases = num_suffix_bases;
}
// check all possible fragments
mass_t tol = tolerance;
if (tolerance>=0.5)
{
tol = (0.8 * tolerance)/charge;
}
else if (tolerance>0.1)
tol = tolerance / charge;
int b;
for (b=0; b<num_bases; b++)
{
int n;
for (n=0; n<num_neutral_losses; n++)
{
mass_t calc_offset = (base_offsets[b] + (charge - 1)*MASS_PROTON + neutral_loss_offsets[n])/(mass_t)charge;
if (fabs(calc_offset-offset)<tol)
{
label = base_labels[b];
if (charge>1)
label+=char('0'+charge);
if (n>0)
label+=neutral_loss_labels[n];
offset = (base_offsets[b] + neutral_loss_offsets[n] + (charge - 1)*MASS_PROTON) / charge;
break;
}
}
if (n<num_neutral_losses)
break;
}
}
// removes fragments that appear to be isotopic peaks of previously
// selected fragments such as b+1, y+2 etc.
void FragmentTypeSet::remove_isotopic_fragments(mass_t tolerance)
{
sort_fragments_according_to_probs();
int f;
for (f=0; f<this->fragments.size(); f++)
{
FragmentType& frag = fragments[f];
if (frag.label.length()<1)
frag.make_frag_label(tolerance);
// don't check known labels
if (frag.label[0] != 's' && frag.label[0] != 'p')
continue;
int j;
for (j=0; j<f; j++)
{
FragmentType& previous = fragments[j];
if (previous.orientation == frag.orientation &&
previous.charge == frag.charge)
{
mass_t offset_diff = frag.offset - previous.offset;
offset_diff *= frag.charge;
if (offset_diff<3.3) // we do not want unrecognized fragments with such
// a small distance from selected fragments
{
cout << " --- removing isotopic frag " << frag.label << endl;
frag.prob = -1;
frag.spec_count = 0;
break;
}
}
}
}
sort_fragments_according_to_probs();
while (fragments.size()>0 && fragments[fragments.size()-1].prob<0)
fragments.pop_back();
}
void FragmentTypeSet::sort_fragments_according_to_probs()
{
sort(fragments.begin(),fragments.end());
}
/*************************************************
Outputs labels in single line
**************************************************/
void FragmentTypeSet::output_fragment_labels(ostream& os) const
{
int i;
for (i=0; i<fragments.size()-1; i++)
os << fragments[i].label << " ";
os << fragments[i].label << endl;
}
void FragmentTypeSet::print() const
{
int i;
cout << setw(4) << left << " "
<< setw(10) << left << "Label "
// << setw(5) << "Pidx"
// << "offset"
<< endl;
for (i=0; i<fragments.size(); i++)
cout << setw(4) << left <<i
<< setw(10) << left << fragments[i].label
// << setw(5) << fragments[i].parent_frag_idx
// << fragments[i].offset_from_parent_frag
<< endl;
}
/***************************************************************
For each fragment idx its parent fragment is defined as the
fragment with the highest probability that has the same charge
and oreientation as the fragment in question.
****************************************************************/
void FragmentTypeSet::set_parent_frag_idxs()
{
int i;
for (i=0; i<fragments.size(); i++)
{
int j;
for (j=0; j<i; j++)
{
if (fragments[j].charge == fragments[i].charge &&
fragments[j].orientation == fragments[i].orientation)
break;
}
// found parent_frag_idx
if (j<i)
{
fragments[i].parent_frag_idx = j;
fragments[i].offset_from_parent_frag = fragments[i].offset - fragments[j].offset;
}
else
{
fragments[i].parent_frag_idx=-1;
fragments[i].offset_from_parent_frag =0;
}
}
}
void RegionalFragments::select_fragments_with_minimum_prob(score_t min_prob, int max_num_frags)
{
while (frag_type_idxs.size()>0 && frag_probs[frag_type_idxs.size()-1]<min_prob)
{
frag_type_idxs.pop_back();
frag_probs.pop_back();
}
if (max_num_frags>0)
{
while (frag_type_idxs.size()>max_num_frags)
{
frag_type_idxs.pop_back();
frag_probs.pop_back();
}
}
}
void FragmentCombo::print_combo(const Config *config, ostream & os) const
{
int i;
for (i=0; i<this->frag_inten_idxs.size(); i++)
os << config->get_fragment(frag_inten_idxs[i]).label << " ";
os << "|";
for (i=0; i<this->frag_no_inten_idxs.size(); i++)
os << " " << config->get_fragment(frag_no_inten_idxs[i]).label;
os << endl;
}
void FragmentCombo::read_combo(Config *config, istream& is)
{
frag_inten_idxs.clear();
frag_no_inten_idxs.clear();
vector<string> tokens;
char buff[128];
is.getline(buff,128);
istringstream iss(buff);
string s;
while (iss >> s)
tokens.push_back(s);
// find pos of separator
int i;
for (i=0; i<tokens.size(); i++)
if (! strcmp(tokens[i].c_str(),"|"))
break;
if (i== tokens.size())
{
cout << "Error: couldn't find '|' for FragmentCombo : " << buff << endl;
exit(1);
}
const int sep_pos = i;
// get inten idxs
for (i=0; i<sep_pos; i++)
{
int f_idx=config->get_frag_idx_from_label(tokens[i]);
if (f_idx>=0)
{
frag_inten_idxs.push_back(f_idx);
}
else
break;
}
// get no inten idxs
for (i=sep_pos+1; i<tokens.size(); i++)
{
int f_idx=config->get_frag_idx_from_label(tokens[i]);
if (f_idx>=0)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?