16 void getMassDistributions(
const vector<FRAGMENT> &fragmentVec, 
const vector<string> &parentSpecies,
    17     const AbundanceData &natTable, vector<vector<pair<float,float> > > &massDistVec);
    22     normTotal=std::accumulate(v.begin(),v.end(),0.0f);
    27 int main(
int argc, 
char *argv[])
    33     string sAbundance = 
"naturalAbundance.xml";
    39     if(natTable.
open(sAbundance.c_str()))
    41         cerr << 
"Failed to open abundance table : " << sAbundance << endl;
    48     std::vector<string> species;
    51     cerr << 
"Enter species names, space separated" << endl;
    59         cerr << 
"no species specified, aborting" << endl;
    65     cerr << 
"Enter species atomic compositions, space separated. This will be normalised" << endl;
    68     vector<float> compositions;
    69     vector<string> compStrVec;
    74     for(
auto &i : compStrVec)
    79             cerr << 
"Unable to understand composition : \"" << i << 
"\", aborting";
    85             cerr << 
"Composition cannot be negative" << endl;
    88         compositions.push_back(f);
    91     if(compositions.size() != species.size())
    93         cerr << 
"Number of compositions did not match number of species, aborting" << endl;
    97     for(
auto frac : compositions)
   101             cerr << 
"Negative compositions not allowed. Aborting" << endl;
   113     vector<vector<int> >  chargeStates;
   114     cout << 
"Enter charge states, as numbers, e.g. 1 3"<<  endl;
   115     for(
auto &sS: species)
   118         vector<string> chargesStrVec;
   121         getline(cin,chargeStr);
   130         for(
auto &s : chargesStrVec)
   135                 cerr << 
"Unable to understand charge value, aborting" << endl;
   140                 cerr << 
"Charge states must be positive" << endl;
   144             charges.push_back(i);
   148         chargeStates.push_back(charges);
   155     unsigned int nCharges=0;
   156     for(
auto &v : chargeStates)
   161         cerr << 
"No charges specified, aborting" << endl;
   170     vector<vector<float> > chargeIntensities;
   171     bool haveMultiCharge=
false;
   172     for( 
auto &v : chargeStates)
   176             haveMultiCharge=
true;
   184         cout << 
"Enter charge state intensities (0->1), will be normalised " << endl;
   185     for(
auto i=0;i<chargeStates.size();i++)
   190         if(chargeStates[i].size() > 1)
   192             for(
auto c : chargeStates[i])
   195                 cout << species[i] << 
"(" <<c << 
") ?";
   200                     cerr << 
"Charge state intensity must be greater than 0. Aborting" << endl;
   212         chargeIntensities.push_back(cR);
   217     vector<FRAGMENT> fragmentVec;
   220     for(
auto &s : species)
   222         vector<pair<string,size_t> > frags;
   223         if(!RangeFile::decomposeIonNames(s,frags))
   225             cerr << 
"WARN : Failed to decompose fragment : " << s << 
", skipping" << endl;
   228         fragmentVec.push_back(frags);
   233     vector<vector<pair<float,float> > > massDistVec;
   239     cerr << 
"Output is (mass, relative intensity, charge) " << endl;
   240     for(
auto ui=0;ui<massDistVec.size();ui++)
   242         cerr << 
"--- " <<  species[ui] << 
"---" << endl;
   243         vector<tuple<float,float,int> > speciesPeaks;
   244         for(
auto j=0;j<chargeStates[ui].size();j++)
   246             int charge = chargeStates[ui][j];
   248             for(
auto &m : massDistVec[ui])
   250                 float chargeIntensity = chargeIntensities[ui][j];
   251                 speciesPeaks.push_back(
   252                 std::make_tuple(m.first/charge,m.second*compositions[ui]*chargeIntensity, charge)); 
   262         vector<pair<int,int> > linked;
   263         for(
auto i=0;i<speciesPeaks.size();i++)
   281             for(
auto j=i+1;j<speciesPeaks.size();j++)
   284                 mass1=std::get<0>(speciesPeaks[j]); 
   285                 mass2=std::get<0>(speciesPeaks[i]);
   287                 charge1=std::get<2>(speciesPeaks[j]);
   288                 charge2=std::get<2>(speciesPeaks[i]);
   291                 if(fabs( mass1/charge1- mass2/charge2) < 
MASS_TOL)
   292                     linked.push_back(make_pair(i,j));
   299         vector<std::tuple<float,float,vector<int> > > mergedPeaks;
   302             tuple<float,float,int> t1,t2;
   303             t1 = speciesPeaks[i.first];
   304             t2 = speciesPeaks[i.second];
   306             std::vector<int> charges;
   307             charges.push_back(std::get<2>(t1));
   308             charges.push_back(std::get<2>(t2));
   311             mergedPeaks.push_back(
   312                 std::make_tuple((std::get<0>(t1) + std::get<0>(t2))*0.5,
   313                     std::get<1>(t1)+std::get<1>(t2),charges));
   317         vector<bool> unlinked;
   318         unlinked.resize(speciesPeaks.size(),
true);
   320             unlinked[i.first]=unlinked[i.second]=
false;
   322         for(
auto i=0;i<speciesPeaks.size();i++)
   326                 auto t = speciesPeaks[i];
   328                 v.push_back(std::get<2>(t));
   329                 mergedPeaks.push_back(
   330                     make_tuple(std::get<0>(t),std::get<1>(t),v));
   335         for(
auto &t : mergedPeaks)
   340             for(
auto charge : std::get<2>(t))
   347              cerr << std::get<0>(t) << 
"," << std::get<1>(t) << 
   348                 "," << sCharges << endl;
   351         cerr << 
"-------------------------------" << endl << endl;
   361     const AbundanceData &natTable, vector<vector<pair<float,float> > > &massDistVec)
   365     for(
auto ui=0;ui<fragmentVec.size();ui++)
   369         vector<pair<size_t,unsigned int> > outputVec;
   373         bool fragmentLookupOK;
   374         fragmentLookupOK=
true;
   375         vector<size_t> indexVec,freqVec;
   376         for( 
auto &p : outputVec)
   379             if(p.first == (
size_t)-1)
   381                 cerr << 
"Unable to lookup mass for component:" << ui<< endl;
   382                 fragmentLookupOK=
false;
   387             indexVec.push_back(p.first);
   389             freqVec.push_back(p.second);
   393         if(!fragmentLookupOK)
   395             cerr << 
"Component lookup for Fragment :" << parentSpecies[ui] << 
"failed" << endl;
   402         vector<pair<float,float> > massDist;
   405         massDistVec.emplace_back(massDist);
 void normaliseVec(vector< float > &v)
void getSymbolIndices(const std::vector< std::string > &symbols, std::vector< size_t > &indices) const
Return a vector of symbol indices. 
vector< pair< string, size_t > > FRAGMENT
void splitStrsRef(const char *cpStr, const char delim, std::vector< std::string > &v)
Split string references using a single delimiter. 
void generateGroupedIsotopeDist(const std::vector< size_t > &elementIdx, const std::vector< size_t > &frequency, std::vector< std::pair< float, float > > &massDist, float massTolerance) const
As per generateIsotopeDist, however, this convenience groups the distribution to limit the effect of ...
int main(int argc, char *argv[])
size_t open(const char *file, bool strict=false)
Attempt to open the abundance data file, return 0 on success, nonzero on failure. ...
Class to load abundance information for natural isotopes. 
void getMassDistributions(const vector< FRAGMENT > &fragmentVec, const vector< string > &parentSpecies, const AbundanceData &natTable, vector< vector< pair< float, float > > > &massDistVec)
bool stream_cast(T1 &result, const T2 &obj)
Template function to cast and object to another by the stringstream. 
void stripZeroEntries(std::vector< std::string > &s)