10 #include <boost/lexical_cast.hpp> 19 const char* in,
const size_t inlen,
float* out,
const size_t outlen,
float& max_element)
28 const char* end = in + inlen;
29 bool readnums =
false;
30 for (
const char* cur = in; (cur <= end) && (curout < outlen); ++cur) {
31 if ((*cur <=
'9') && (*cur >=
'0')) {
33 numerator += (*cur -
'0');
36 out[curout] = numerator;
37 if (numerator > max_element) max_element = numerator;
48 const char* in,
const size_t inlen,
float* out,
const size_t outlen)
52 bool isNegative =
false;
53 bool inExponent =
false;
54 bool expIsNeg =
false;
55 bool pastDecimal =
false;
57 uint64_t numerator, numeratorExp;
58 uint64_t digits_denom, digits_denom_Exp;
60 {numerator = 0; digits_denom = 0;
61 numeratorExp = 0; digits_denom_Exp = 0;
62 isNegative =
false; inExponent =
false;
63 expIsNeg =
false; pastDecimal =
false; };
67 const char* end = in + inlen;
70 const char* numbers =
"0123456789-+.eE";
71 const char* whitespace =
" \t\n";
72 const char* numEnd =
nullptr;
73 auto isNumber = [](
char c) ->
bool {
74 if (c >=
'0' && c <=
'9')
return true;
75 if (c ==
'-' || c ==
'+' || c ==
'.' || c ==
'e' || c ==
'E')
return true;
78 auto isControl = [](
char c) ->
bool {
79 if (c ==
'-' || c ==
'+' || c ==
'.' || c ==
'e' || c ==
'E')
return true;
82 auto advanceToNumber = [](
const char* in,
const char* end) ->
const char* {
84 if (*in >=
'0' && *in <=
'9')
return in;
85 else if (*in ==
'-' || *in ==
'+' || *in ==
'.' || *in ==
'e' || *in ==
'E')
return in;
90 while ((cur < end) && (curout < outlen)) {
92 cur = advanceToNumber(cur, end);
93 while (isNumber(*cur)) {
94 if (!isControl(*cur)) {
97 numerator += (*cur -
'0');
98 if (pastDecimal) digits_denom++;
101 numeratorExp += (*cur -
'0');
102 if (pastDecimal) digits_denom_Exp++;
105 if (*cur ==
'.') pastDecimal =
true;
106 if (*cur ==
'-' && !inExponent) isNegative =
true;
107 if (*cur ==
'-' && inExponent) expIsNeg =
true;
108 if (*cur ==
'e' || *cur ==
'E') {
109 inExponent =
true; pastDecimal =
false; isNegative =
false;
114 if (!numerator)
continue;
119 exponent =
static_cast<float>(numeratorExp);
120 if (digits_denom_Exp) exponent /= powf(10.f, static_cast<float>(digits_denom_Exp));
121 if (expIsNeg) exponent *= -1;
125 num =
static_cast<float>(numerator);
126 if (digits_denom) num /= powf(10.f, static_cast<float>(digits_denom));
127 if (isNegative) num *= -1;
130 if (numeratorExp) fnum *= powf(10.f, exponent);
145 unsigned int remainder = 0;
146 unsigned int rembase = 1;
147 unsigned int digit = 0;
150 bool expsign =
false;
151 unsigned int expi = 0;
153 bool exponent =
false;
154 bool decimal =
false;
156 while (*p !=
'\0' && ((len) ? i<len :
true))
160 if (*p ==
'e' || *p ==
'E')
164 else if (*p ==
'.') {
167 else if (*p ==
'-') {
176 else if (*p ==
'+') {
185 else if (*p ==
' ' || *p ==
'\t') {
229 if (!decimal && !exponent)
234 else if (decimal && !exponent) {
250 res += (T)remainder / (T)rembase;
256 res *= (T)std::pow(10, (T)expi);
259 res *= (T)std::pow(10, -1.0 * (T)expi);
274 while (*p !=
'\0' && done ==
false && ((len) ? i<len :
true))
279 else if (*p ==
'+') {
282 else if (*p ==
' ' || *p ==
'\t') {
341 void readHeader(
const char* in, std::string &desc,
size_t &np,
size_t &headerEnd);
346 const std::string &filename) {
350 std::ifstream in(filename.c_str());
351 uintmax_t sz = sfs::file_size(sfs::path(filename));
352 std::string s(sz,
' ');
355 auto end = s.find_first_of(
"\n\0");
356 Expects(end != std::string::npos);
357 std::string ssub = s.substr(0, end);
358 auto spos = ssub.find_first_not_of(
"0123456789. \t\n");
360 if (std::string::npos == spos)
378 size_t headerEnd = 0, numPoints = 0;
379 readHeader(str.c_str(), desc, numPoints, headerEnd);
386 void readHeader(
const char* in, std::string &desc,
size_t &np,
394 const char* pend = in;
395 const char* pstart = in;
398 for (
size_t i = 0; i < 7; i++)
401 pend = strchr(pend,
'\n');
404 string lin(pstart, pend - pstart - 1);
405 if (*(lin.rbegin()) ==
'\r') lin.pop_back();
408 size_t posa = 0, posb = 0;
418 posa = lin.find_first_not_of(
" \t\n", posb);
420 posb = lin.find_first_of(
" \t\n", posa);
421 size_t len = posb - posa;
422 string s = lin.substr(posa, len);
423 np = boost::lexical_cast<
size_t>(s);
457 headerEnd = (pend - in) /
sizeof(
char);
466 const char* pa = &iin[headerEnd];
467 const char* pb = strchr(pa + 1,
'\0');
469 std::vector<float> parser_vals;
470 parser_vals.resize(7 * numExpectedPoints);
471 float max_element = 0;
474 assert(numRead % 7 == 0);
476 numPoints = parser_vals.size() / 7;
477 assert(numPoints == numExpectedPoints);
480 std::set<uint8_t> constituents;
482 for (
size_t i = 0; i < numPoints; ++i)
484 size_t pIndex = 7 * i;
490 constituents.emplace(static_cast<uint8_t>(parser_vals[pIndex + 4]));
496 if (constituents.size() >= UINT8_MAX)
throw (std::invalid_argument(
"Shape has too many constituents."));
499 for (
size_t i = 0; i < numPoints; ++i)
501 size_t pIndex = 7 * i;
502 uint64_t substance_id =
static_cast<uint64_t
>(parser_vals[pIndex + 4]);
504 for (
auto it = constituents.cbegin(); it != constituents.cend(); ++it, ++offset) {
505 if ((*it) == substance_id)
break;
507 size_t idx = (i*constituents.size()) + offset;
524 const char* pa = iin;
525 const char* pb = strchr(pa + 1,
'\0');
526 const char* pNumStart = pa;
529 while ((pNumStart[0] ==
'#' || pNumStart[0] ==
'N' || pNumStart[0] ==
'n') && pNumStart < pb) {
530 const char* lineEnd = strchr(pNumStart + 1,
'n');
531 pNumStart = lineEnd + 1;
533 if (pNumStart >= pb)
throw(std::invalid_argument(
"Cannot find any points in a shapefile."));
535 const char* firstLineEnd = strchr(pNumStart + 1,
'\n');
540 int guessNumPoints = 1;
542 for (
const char* c = pNumStart; c != pb; ++c)
543 if (c[0] ==
'\n') guessNumPoints++;
545 float max_element = -1, junk_f = -1;
546 std::array<float, 4> firstLineVals;
548 std::vector<float> parser_vals((guessNumPoints * 4), 0);
550 size_t actualNumReads =
strints_array_to_floats(pNumStart, pb - pNumStart, parser_vals.data(), parser_vals.size(), max_element);
551 if (actualNumReads == 0)
throw (std::invalid_argument(
"Bad read"));
552 parser_vals.resize(actualNumReads);
560 size_t numCols =
strints_array_to_floats(pNumStart, firstLineEnd - pNumStart, firstLineVals.data(), firstLineVals.size(), junk_f);
563 if (numCols == 3) good =
true;
564 if (numCols == 4) good =
true;
565 if (!good)
throw (std::invalid_argument(
"Bad read"));
567 size_t actualNumPoints = actualNumReads / numCols;
568 assert(actualNumPoints == guessNumPoints);
576 else if (numCols == 4) {
578 uint8_t max_constituent = 1;
579 for (
size_t i = 0; i < actualNumPoints; ++i) {
580 auto constit = parser_vals[(4 * i) + 3];
581 assert(static_cast<uint8_t>(constit) < UINT8_MAX);
582 if (static_cast<uint8_t>(constit) > max_constituent)
583 max_constituent =
static_cast<uint8_t
>(constit);
587 for (
size_t i = 0; i < max_constituent; ++i)
592 for (
size_t i = 0; i < actualNumPoints; ++i) {
593 size_t crdindex = (3 * i);
594 size_t parserindex = (4 * i);
std::vector< uint8_t > Int8Data_t
T m_atoi(const char *x, size_t len)
uint64_t number_of_particle_scattering_elements
ShapeDataBasic readRawText(const char *iin)
size_t strints_array_to_floats(const char *in, const size_t inlen, float *out, const size_t outlen, float &max_element)
uint8_t particle_scattering_element_coordinates_are_integral
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
T m_atof(const char *x, size_t len)
FloatData_t particle_scattering_element_coordinates
ShapeCommonOptionalData optional
Int8Data_t particle_constituent_number
ShapeRequiredData required
void readHeader(const char *in, std::string &desc, size_t &np, size_t &headerEnd)
uint8_t number_of_particle_constituents
float hint_max_scattering_element_dimension
size_t array_to_floats(const char *in, const size_t inlen, float *out, const size_t outlen)