2 #pragma warning( disable : 4996 ) // -D_SCL_SECURE_NO_WARNINGS 3 #pragma warning( disable : 4244 ) // 'argument': conversion from 'std::streamsize' to 'int', possible loss of data - boost::copy 4 #define _HAS_AUTO_PTR_ETC 1 11 #include <boost/spirit/include/karma.hpp> 12 #include <boost/spirit/include/phoenix_core.hpp> 13 #include <boost/spirit/include/phoenix_operator.hpp> 14 #include <boost/spirit/include/phoenix_stl.hpp> 15 #include <boost/iostreams/copy.hpp> 16 #include <boost/iostreams/filtering_stream.hpp> 17 #include <boost/spirit/include/qi.hpp> 28 namespace qi = boost::spirit::qi;
29 namespace ascii = boost::spirit::ascii;
30 namespace phoenix = boost::phoenix;
34 template <
typename Iterator>
40 using qi::phrase_parse;
43 using phoenix::push_back;
45 bool r = phrase_parse(first, last,
63 template <
typename OutputIterator,
typename Container>
66 using boost::spirit::karma::long_;
67 using boost::spirit::karma::float_;
68 using boost::spirit::karma::repeat;
69 using boost::spirit::karma::generate;
71 using boost::spirit::ascii::space;
77 '\t' << long_ <<
'\t' <<
78 float_ <<
'\t' << float_ <<
'\t' << float_ <<
'\t' <<
79 long_ <<
'\t' << long_ <<
'\t' << long_ <<
'\n' 87 template <
typename OutputIterator,
typename Container>
90 using boost::spirit::karma::long_;
91 using boost::spirit::karma::float_;
92 using boost::spirit::karma::repeat;
93 using boost::spirit::karma::generate;
95 using boost::spirit::ascii::space;
101 float_ <<
'\t' << float_ <<
'\t' << float_ <<
'\n' 113 void readHeader(
const char* in, std::string &desc,
size_t &np,
121 const char* pend = in;
122 const char* pstart = in;
125 for (
size_t i = 0; i < 7; i++)
128 pend = strchr(pend,
'\n');
131 string lin(pstart, pend - pstart - 1);
132 if (*(lin.rbegin()) ==
'\r') lin.pop_back();
135 size_t posa = 0, posb = 0;
145 posa = lin.find_first_not_of(
" \t\n", posb);
147 posb = lin.find_first_of(
" \t\n", posa);
148 size_t len = posb - posa;
149 string s = lin.substr(posa, len);
150 np = boost::lexical_cast<
size_t>(s);
184 headerEnd = (pend - in) /
sizeof(
char);
192 const char* pa = &iin[headerEnd];
193 const char* pb = strchr(pa + 1,
'\0');
195 std::vector<float> parser_vals;
196 parser_vals.reserve(7 * numExpectedPoints);
198 assert(parser_vals.size() % 7 == 0);
200 numPoints = parser_vals.size() / 7;
201 assert(numPoints == numExpectedPoints);
204 std::set<uint8_t> constituents;
206 for (
size_t i = 0; i < numPoints; ++i)
208 size_t pIndex = 7 * i;
214 constituents.emplace(static_cast<uint8_t>(parser_vals[pIndex + 4]));
220 if (constituents.size() >= UINT8_MAX)
throw (std::invalid_argument(
"Shape has too many constituents."));
223 for (
size_t i = 0; i < numPoints; ++i)
225 size_t pIndex = 7 * i;
226 uint64_t substance_id =
static_cast<uint64_t
>(parser_vals[pIndex + 4]);
228 for (
auto it = constituents.cbegin(); it != constituents.cend(); ++it, ++offset) {
229 if ((*it) == substance_id)
break;
231 size_t idx = (i*constituents.size()) + offset;
245 size_t headerEnd = 0, numPoints = 0;
246 readHeader(str.c_str(), desc, numPoints, headerEnd);
258 std::ofstream out(filename.c_str());
263 out <<
"1.0\t1.0\t1.0\t= target vector a1 (in TF)" << endl;
264 out <<
"0.0\t1.0\t0.0\t= target vector a2 (in TF)" << endl;
265 out <<
"1.0\t1.0\t1.0\t= d_x/d d_y/d d_x/d (normally 1 1 1)" << endl;
268 out <<
"0.0\t0.0\t0.0\t= X0(1-3) = location in lattice of target origin" << endl;
269 out <<
"\tNo.\tix\tiy\tiz\tICOMP(x, y, z)" << endl;
273 std::vector<float> oi(numPoints * 7);
275 for (
size_t j = 0; j < numPoints; j++)
296 throw(std::invalid_argument(
"Cannot write a DDSCAT shape file with this type of dielectric!"));
299 oi[j * 7 + 4] = comp;
300 oi[j * 7 + 5] = comp;
301 oi[j * 7 + 6] = comp;
304 std::string generated;
305 std::back_insert_iterator<std::string> sink(generated);
308 throw(std::invalid_argument(
"Somehow unable to print the shape points properly."));
322 const char* pa = iin;
323 const char* pb = strchr(pa + 1,
'\0');
324 const char* pNumStart = pa;
327 while ((pNumStart[0] ==
'#' || pNumStart[0] ==
'N' || pNumStart[0] ==
'n') && pNumStart < pb) {
328 const char* lineEnd = strchr(pNumStart + 1,
'n');
329 pNumStart = lineEnd + 1;
331 if (pNumStart >= pb)
throw(std::invalid_argument(
"Cannot find any points in a shapefile."));
333 const char* firstLineEnd = strchr(pNumStart + 1,
'\n');
335 int guessNumPoints = std::count(pNumStart, pb,
'\n');
336 std::vector<float> firstLineVals;
338 std::vector<float> parser_vals;
339 parser_vals.reserve(guessNumPoints * 4);
341 const void* floatloc = memchr(pNumStart,
'.', pb - pNumStart);
346 size_t numCols = firstLineVals.size();
348 if (numCols == 3) good =
true;
349 if (numCols == 4) good =
true;
350 if (!good)
throw (std::invalid_argument(
"Bad read"));
351 if (parser_vals.size() == 0)
throw (std::invalid_argument(
"Bad read"));
353 size_t actualNumPoints = parser_vals.size() / numCols;
354 assert(actualNumPoints == guessNumPoints);
361 else if (numCols == 4) {
363 uint8_t max_constituent = 1;
364 for (
size_t i = 0; i < actualNumPoints; ++i) {
365 auto constit = parser_vals[(4 * i) + 3];
366 assert(static_cast<uint8_t>(constit) < UINT8_MAX);
367 if (static_cast<uint8_t>(constit) > max_constituent)
368 max_constituent =
static_cast<uint8_t
>(constit);
372 for (
size_t i = 0; i < max_constituent; ++i)
377 for (
size_t i = 0; i < actualNumPoints; ++i) {
378 size_t crdindex = (3 * i);
379 size_t parserindex = (4 * i);
395 std::ofstream out(filename.c_str());
396 std::string generated;
397 std::back_insert_iterator<std::string> sink(generated);
400 throw(std::invalid_argument(
"Somehow unable to print the shape points properly."));
406 const std::string &filename) {
410 std::ifstream in(filename.c_str());
411 std::ostringstream so;
412 boost::iostreams::copy(in, so);
413 std::string s = so.str();
415 auto end = s.find_first_of(
"\n\0");
416 Expects(end != std::string::npos);
417 std::string ssub = s.substr(0,end);
418 auto spos = ssub.find_first_not_of(
"0123456789. \t\n");
420 if (std::string::npos == spos)
std::vector< uint8_t > Int8Data_t
void writeDDSCAT(const std::string &filename, const ShapeDataBasic &p)
uint64_t number_of_particle_scattering_elements
ShapeDataBasic readRawText(const char *iin)
uint8_t particle_scattering_element_coordinates_are_integral
bool print_shapefile_entries(OutputIterator &sink, Container const &v)
Used in quickly printing shapefile.
void readDDSCATtextContents(const char *iin, size_t numExpectedPoints, size_t headerEnd, ShapeDataBasic &p)
Read ddscat text contents.
ShapeDataBasic readDDSCAT(const char *in)
ShapeDataBasic readTextFile(const std::string &filename)
Int8Data_t particle_scattering_element_composition_whole
IntData_t particle_scattering_element_number
FloatData_t particle_scattering_element_coordinates
ShapeCommonOptionalData optional
bool parse_shapefile_entries(Iterator first, Iterator last, std::vector< float > &v)
Parses space-separated shapefile entries.
Int8Data_t particle_constituent_number
bool print_shapefile_pts(OutputIterator &sink, Container const &v)
FloatData_t particle_scattering_element_composition_fractional
void writeTextRaw(const std::string &filename, const ShapeDataBasic &p)
ShapeRequiredData required
void readHeader(const char *in, std::string &desc, size_t &np, size_t &headerEnd)
uint8_t number_of_particle_constituents