libatomprobe
Library for Atom Probe Tomography (APT) computation
plot-overlaps.cpp
Go to the documentation of this file.
1 #include "atomprobe/atomprobe.h"
2 
3 using namespace std;
4 using namespace AtomProbe;
5 
6 #include <fstream>
7 #include <set>
8 #include <iomanip>
9 #include <algorithm>
10 
11 //This code demonstrates creating a "DOT" [1] graph, consisting of a plot of all the
12 // overlaps present in a rangefile.
13 //
14 // The graph's edges and its output show which species and masses overlap
15 // Note that there are lots and lots of output edges at the moment,
16 // so you may need to use the strict keyword in the output dot file (text file)
17 // These plots were initially developed by London, 2016.
18 //
19 // [1] https://en.wikipedia.org/wiki/DOT_language
20 
21 int main(int argc, char *argv[])
22 {
23 
24  //Check input arguments
25  if(argc < 2)
26  {
27  cerr << "USAGE : " << argv[0] << " (Rangefile| Ion list)" << endl;
28  return 1;
29  }
30 
31  RangeFile rng;
32  if(argc == 2)
33  {
34  //Load the rangefile
35  //---
36  if(!rng.open(argv[1]))
37  {
38  cerr << "Failed to open rangefile :" << argv[1] << rng.getErrString() << endl;
39  return 2;
40  }
41  cerr << "Rangefile has :" << rng.getNumIons() << " ranges, and " << rng.getNumIons() << " ions." << endl;
42  //---
43  }
44  else
45  {
46  set<string> ionNames;
47  //Fake a rangefile using the specified ions
48  RGBf rgbf;
49  for(unsigned int ui=1;ui<argc;ui++)
50  ionNames.insert(string(argv[ui]));
51 
52  for(const auto & ionName : ionNames)
53  {
54  string s;
55  s = ionName;
56 
57  rng.addIon(s.c_str(),s.c_str(),rgbf);
58  }
59  }
60 
61  //Open the table of masses of elements
62  //---
63  AbundanceData natTable;
64  if(natTable.open("naturalAbundance.xml"))
65  {
66  cerr << "failed to open natural abundance file" << endl;
67  return 3;
68  }
69  //---
70 
71 
72  //Find the overlaps
73  //---
74  //Separation between overlap items
75  const float MASS_DELTA=0.05;
76  //Maximum charge to consider when evaluating overlaps
77  const unsigned int MAX_CHARGE=3;
78  vector<pair<size_t,size_t> > overlapIdx;
79  vector<pair<float,float> > overlapMass;
80  findOverlaps(natTable,rng,MASS_DELTA,MAX_CHARGE,overlapIdx,overlapMass);
81 
82  cerr << "Found :" << overlapIdx.size() << " overlaps, using max charge=" << MAX_CHARGE << " and mass delta=" << MASS_DELTA << endl;
83  //---
84 
85  //Save the result into a DOT formatted file
86  //---
87  ofstream f("dotFile.txt");
88  if(!f)
89  {
90  cerr << "Unable to open output file." <<endl;
91  return 4;
92  }
93 
94  // Get a list of all the nodes in the graph
95  vector<pair<string, unsigned int> > nodeList;
96  vector<string> nodeNames;
97  for(unsigned int ui=0; ui<overlapIdx.size(); ui++)
98  {
99  // first entry of overlapIdx
100  unsigned int rawId,id,charge;
101  rawId =overlapIdx[ui].first;
102  id = rawId/MAX_CHARGE;
103  charge=rawId%MAX_CHARGE +1;
104  nodeList.push_back( make_pair(rng.getName(id), charge) );
105 
106  // make a node label string for it
107  // TODO: Add <SUB></SUB> around numbers for subscripts
108  // TODO: replace only "1+" with "+", or replace "2+" with "++" etc.
109  std::stringstream buffer;
110  buffer << "\"" << rng.getName(id) << "|" << charge << "+\" ";
111  buffer << " [ label = <" << rng.getName(id) << "<SUP>" << charge << "+</SUP>> ];" << endl;
112  nodeNames.push_back(buffer.str());
113 
114  //second entry of overlapIdx
115  rawId =overlapIdx[ui].second;
116  id = rawId/MAX_CHARGE;
117  charge=rawId%MAX_CHARGE+1;
118  nodeList.push_back( make_pair(rng.getName(id), charge) );
119 
120  // make a node label string for 2nd node
121  buffer.str(""); // clear buffer
122  buffer << "\"" << rng.getName(id) << "|" << charge << "+\" ";
123  buffer << " [ label = <" << rng.getName(id) << "<SUP>" << charge << "+</SUP>> ];" << endl;
124  nodeNames.push_back(buffer.str());
125  }
126 
127  // TODO: When two nodes share multiple edges (peaks), display them
128  // as one edge with "peak1 \n peak2 \n peak3 etc." rather than
129  // multiple edges.
130 
131  // start graph
132  f << "strict graph overlap_map {" << endl;
133 
134  // Only print unique labels to cut down file size
135  // Find unique strings using a set
136  set <std::string> uniqueStrings;
137  for (auto & nodeName : nodeNames)
138  {
139  uniqueStrings.insert(nodeName);
140  }
141  // Print the unique labels
142  for (const auto & uniqueString : uniqueStrings)
143  {
144  f << uniqueString;
145  }
146 
147  for(unsigned int ui=0; ui<overlapIdx.size(); ui++)
148  {
149  //Create graph edge
150  f << "\"" << nodeList[ui*2].first << "|" << nodeList[ui*2].second << "+\" -- ";
151 
152  f << "\"" << nodeList[ui*2+1].first << "|" << nodeList[ui*2+1].second << "+\"";
153 
154  // average mass to label the edge with
155  float avgMass = (overlapMass[ui].first + overlapMass[ui].second)/2.0;
156  f << " [ label = \"" << std::fixed << std::setprecision( 1 ) << avgMass << "\" ];" << endl;
157  }
158  f << "}" << endl;
159  //---
160 
161  cerr << "Wrote overlaps to dotFile.txt" << endl;
162  return 0;
163 }
std::string getName(unsigned int ionID, bool shortName=true) const
Get the short name or long name of a specified ionID.
Definition: ranges.cpp:2975
unsigned int addIon(const std::string &shortName, const std::string &longName, const RGBf &ionCol)
Add the ion to the database returns ion ID if successful, -1 otherwise.
Definition: ranges.cpp:3274
Data holder for colour as float.
Definition: misc.h:26
STL namespace.
void findOverlaps(const AbundanceData &natData, const RangeFile &rng, float massDelta, unsigned int maxCharge, std::vector< std::pair< size_t, size_t > > &overlapIdx, std::vector< std::pair< float, float > > &overlapMasses)
Find the overlaps stemming from a given rangefile.
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. ...
Definition: abundance.cpp:79
Class to load abundance information for natural isotopes.
Definition: abundance.h:54
bool open(const char *rangeFile)
Open a specified range file - returns true on success.
Definition: ranges.cpp:678
Data storage and retrieval class for various range files.
Definition: ranges.h:95
unsigned int getNumIons() const
Get the number of unique ions.
Definition: ranges.cpp:2863
std::string getErrString() const
Retrieve the translated error associated with the current range file state.
Definition: ranges.cpp:3355