libatomprobe
Library for Atom Probe Tomography (APT) computation
zechBackground.cpp
Go to the documentation of this file.
1 /* zechBackground.cpp : Sample program to perform a max-likelihood estimation on mass spectra
2  * Copyright (C) 2019 D Haley
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include <iostream>
18 
19 #include "atomprobe/atomprobe.h"
20 
21 using namespace std;
22 using namespace AtomProbe;
23 
24 #ifndef ASSERT
25  #include <cassert>
26  #define ASSERT(f) assert(f)
27 #endif
28 
29 template<class T>
30 bool dumpHistogramToFile(std::vector<std::vector<T> > &hist, const char *filename)
31 {
32  ofstream f(filename);
33 
34  if(!f)
35  return false;
36 
37  for(auto ui=0u;ui<hist.size();ui++)
38  {
39  for(auto uj=0u;uj<hist[ui].size();uj++)
40  f << hist[ui][uj] << "\t";
41 
42  f << endl;
43  }
44 
45  return true;
46 }
47 
48 
49 void zechCorrect(vector<float> &background, vector<float> &observation, float alpha,
50  vector<float> &corrected)
51 
52 {
53  //Peform subtraction
54  ASSERT(background.size() == observation.size());
55 
56  corrected=observation;
57  const float THRESHOLD=550; // Counts
58  for(auto i=0u;i<background.size();i++)
59  {
60  if(observation[i] > THRESHOLD || background[i] > THRESHOLD)
61  corrected[i]=observation[i]-background[i];
62  else if(!observation[i])
63  {
64  //pass : estimator doesn't work with obs=0
65  }
66  else
67  {
68 
69 
70  float estimate;
71  if(AtomProbe::zechConfidenceLimits(background[i],observation[i],alpha,estimate))
72  corrected[i]=estimate;
73  else
74  corrected[i]=observation[i]-background[i];
75 
76  }
77  }
78 }
79 
80 int main(int argc, char *argv[])
81 {
82  //Check for correct program usage
83  if(argc < 3)
84  {
85  //print error message, and exit
86  cerr << "USAGE : " << argv[0] << " SPECTRUM_FILE [alpha1 alpha2 ....] OUTFILE" << endl;
87 
88  cerr << "In the spectrum file, the columns should be ordered as mass, count, background" << endl;
89  return 1;
90  }
91 
92 
93  //Load CSV Data
94  vector<string> headings;
95  vector<vector<float > > intensityData;
96 
97  //M/c, Uncorrected, Corrected, Background Estimate
98  auto errCode=loadTextData(argv[1],intensityData,headings,",\t");
99 
100  if(errCode)
101  {
102  cerr << "Error loading text file :" << errCode <<endl;
103  return 1;
104  }
105 
106  if(!intensityData.size())
107  {
108  cerr << "input data appears to be empty" << endl;
109  return 1;
110 
111  }
112  vector<float> alpha;
113  alpha.resize(argc-3,-1);
114 
115  if(!alpha.size())
116  {
117  cerr << "Alpha not specified, using 0.5 (most probable corretion) " << endl;
118  alpha.push_back(0.5);
119  }
120  else
121  {
122  unsigned int OFFSET=2;
123  for(auto ui=0u;ui<alpha.size();ui++)
124  {
125  float tmp;
126  if(stream_cast(tmp,argv[ui+OFFSET]))
127  {
128  cerr << "Unable to understand specified alpha :" << argv[ui+OFFSET] << endl;
129  return 1;
130  }
131 
132  alpha[ui]=tmp;
133  }
134  }
135 
136 
137 
138 
139  transposeVector(intensityData);
140  cerr << "Loaded :" << intensityData.size() << "Rows" << endl;
141 
142 
143  vector<float> mass,observed,background;
144  mass.resize(intensityData.size());
145  observed.resize(intensityData.size());
146  background.resize(intensityData.size());
147 
148  for(auto ui=0;ui<intensityData.size();ui++)
149  {
150  ASSERT(intensityData[ui].size() > 3);
151 
152  //mass[ui] = intensityData[ui][0];
153  observed[ui] = intensityData[ui][1];
154  background[ui] = intensityData[ui][3];
155 
156  }
157 
158  vector<vector<float> > corrected;
159  corrected.resize(alpha.size());
160  for(unsigned int ui=0;ui<alpha.size();ui++)
161  {
162  ASSERT(alpha[ui] > 0 && alpha[ui] < 1.0f);
163  zechCorrect(background,observed,alpha[ui],corrected[ui]);
164  }
165 
166  transposeVector(corrected);
167 
168 
169  const char *outFile=argv[argc-1];
170  if(!dumpHistogramToFile(corrected,outFile))
171  {
172  cerr << "Unable to write output to file" << endl;
173  return 1;
174  }
175 
176  cerr << "Complete. output written to :" << outFile << endl;
177 }
178 
void zechCorrect(vector< float > &background, vector< float > &observation, float alpha, vector< float > &corrected)
int main(int argc, char *argv[])
STL namespace.
bool zechConfidenceLimits(float lambdaBack, unsigned int observation, float alpha, float &estimate)
Provides a best estimate for true signal when true signal, background.
Definition: confidence.cpp:406
void transposeVector(std::vector< std::vector< T > > &v)
Perform an out-of-place tranposition of a given vector.
Definition: misc.h:81
unsigned int loadTextData(const char *cpFilename, std::vector< std::vector< float > > &dataVec, std::vector< std::string > &headerVec, const char *delim="\", bool allowNan=true, bool allowConvFails=false, unsigned int headerCount=-1)
Load a CSV, TSV or similar text file. Assumes "C" Locale for input (ie "." as decimal separator)...
Definition: dataFiles.cpp:1504
bool dumpHistogramToFile(std::vector< std::vector< T > > &hist, const char *filename)
#define ASSERT(f)
bool stream_cast(T1 &result, const T2 &obj)
Template function to cast and object to another by the stringstream.
Definition: stringFuncs.h:32