/* * translate #1 or lx:ly,hx:hy into a result range struct * returns absolute coords */ int sarg_area(char *str, struct range *rp) { long rlm; struct natstr *np; struct realmstr realm; char *end; if (*str == '#') { /* * realm #X where (X > 0 && X < MAXNOR) * Assumes realms are in abs coordinates */ if (*++str) { rlm = strtol(str, &end, 10); if (end == str || (*end != 0 && !isspace(*end)) || rlm < 0 || MAXNOR <= rlm) return 0; } else rlm = 0; getrealm(rlm, player->cnum, &realm); rp->lx = realm.r_xl; rp->hx = realm.r_xh; rp->ly = realm.r_yl; rp->hy = realm.r_yh; } else { /* * full map specification * LX:LY,HX:HY where * ly, hy are optional. */ rp->lx = rp->hx = strtox(str, &str); if (rp->lx < 0) return 0; if (*str == ':') { rp->hx = strtox(str + 1, &str); if (rp->hx < 0) return 0; } if (*str++ != ',') return 0; rp->ly = rp->hy = strtoy(str, &str); if (rp->ly < 0) return 0; if (*str == ':') { rp->hy = strtoy(str + 1, &str); if (rp->hy < 0) return 0; } if (*str != 0 && !isspace(*str)) return 0; np = getnatp(player->cnum); rp->lx = xabs(np, rp->lx); rp->hx = xabs(np, rp->hx); rp->ly = yabs(np, rp->ly); rp->hy = yabs(np, rp->hy); } xysize_range(rp); return 1; }
/* * translate @x,y:int into * result params */ int sarg_range(char *str, coord *xp, coord *yp, int *dist) { coord x, y; long d; char *end; struct natstr *np; if (*str++ != '@') return 0; x = strtox(str, &str); if (x < 0 || *str++ != ',') return 0; y = strtoy(str, &str); if (y < 0 || *str++ != ':') return 0; d = strtol(str, &end, 10); if (end == str || (*end != 0 && !isspace(*end)) || d < 0) return 0; *dist = d; np = getnatp(player->cnum); *xp = xabs(np, x); *yp = yabs(np, y); return 1; }
int sarg_xy(char *str, coord *xp, coord *yp) { coord x, y; struct natstr *np; x = strtox(str, &str); if (x < 0 || *str++ != ',') return 0; y = strtoy(str, &str); if (y < 0 || (*str != 0 && !isspace(*str))) return 0; if ((x ^ y) & 1) return 0; np = getnatp(player->cnum); *xp = xabs(np, x); *yp = yabs(np, y); return 1; }
/* * setup the nstr_sect structure for sector selection. * can select on either NS_ALL, NS_AREA, or NS_DIST * iterate thru the "condarg" string looking * for arguments to compile into the nstr. * Using this function for anything but command arguments is usually * incorrect, because it respects conditionals. Use the snxtsct_FOO() * instead. */ int snxtsct(struct nstr_sect *np, char *str) { struct range range; struct natstr *natp; coord cx, cy; int dist; char buf[1024]; if (!str || !*str) { if (!(str = getstring("(sects)? ", buf))) return 0; } else make_stale_if_command_arg(str); switch (sarg_type(str)) { case NS_AREA: if (!sarg_area(str, &range)) return 0; snxtsct_area(np, &range); break; case NS_DIST: if (!sarg_range(str, &cx, &cy, &dist)) return 0; snxtsct_dist(np, cx, cy, dist); break; case NS_ALL: /* * Can't use snxtsct_all(), as it would disclose the real * origin. Use a world-sized area instead. */ natp = getnatp(player->cnum); range.lx = xabs(natp, -WORLD_X / 2); range.ly = yabs(natp, -WORLD_Y / 2); range.hx = xnorm(range.lx + WORLD_X - 1); range.hy = ynorm(range.ly + WORLD_Y - 1); xysize_range(&range); snxtsct_area(np, &range); break; default: return 0; } return snxtsct_use_condarg(np); }
/** * Correct the data for absorption and multiple scattering effects. Allows * both histogram or point data. For histogram the TOF is taken to be * the mid point of a bin * * @return A histogram containing corrected values */ Mantid::HistogramData::Histogram MayersSampleCorrectionStrategy::getCorrectedHisto() { // Temporary storage std::vector<double> xmur(N_MUR_PTS + 1, 0.0), yabs(N_MUR_PTS + 1, 1.0), // absorption signals wabs(N_MUR_PTS + 1, 1.0), // absorption weights yms(0), // multiple scattering signals wms(0); // multiple scattering weights if (m_pars.mscat) { yms.resize(N_MUR_PTS + 1, 0.0); wms.resize(N_MUR_PTS + 1, 100.0); } // Main loop over mur. Limit is nrpts but vectors are nrpts+1. First value set // by initial values above const double dmuR = (muRmax() - muRmin()) / to<double>(N_MUR_PTS - 1); for (size_t i = 1; i < N_MUR_PTS + 1; ++i) { const double muR = muRmin() + to<double>(i - 1) * dmuR; xmur[i] = muR; auto attenuation = calculateSelfAttenuation(muR); const double absFactor = attenuation / (M_PI * muR * muR); // track these yabs[i] = 1. / absFactor; wabs[i] = absFactor; if (m_pars.mscat) { // ratio of second/first scatter auto mscat = calculateMS(i, muR, attenuation); yms[i] = mscat.first; wms[i] = mscat.second; } } // Fit polynomials to absorption values to interpolate to input data range ChebyshevPolyFit polyfit(N_POLY_ORDER); auto absCoeffs = polyfit(xmur, yabs, wabs); decltype(absCoeffs) msCoeffs(0); if (m_pars.mscat) msCoeffs = polyfit(xmur, yms, wms); // corrections to input const double muMin(xmur.front()), muMax(xmur.back()), flightPath(m_pars.l1 + m_pars.l2), vol(M_PI * m_pars.cylHeight * pow(m_pars.cylRadius, 2)); // Oct 2003 discussion with Jerry Mayers: // 1E-22 factor in formula for RNS was introduced by Jerry to keep // multiple scattering correction close to 1 const double rns = (vol * 1e6) * (m_pars.rho * 1e24) * 1e-22; ChebyshevSeries chebyPoly(N_POLY_ORDER); auto outputHistogram = m_histogram; auto &sigOut = outputHistogram.mutableY(); auto &errOut = outputHistogram.mutableE(); for (size_t i = 0; i < m_histoYSize; ++i) { const double yin(m_histogram.y()[i]), ein(m_histogram.e()[i]); if (yin == 0) { // Detector with 0 signal received - skip this bin continue; } const double sigt = sigmaTotal(flightPath, m_tofVals[i]); const double rmu = muR(sigt); // Varies between [-1,+1] const double xcap = ((rmu - muMin) - (muMax - rmu)) / (muMax - muMin); double corrfact = chebyPoly(absCoeffs, xcap); if (m_pars.mscat) { const double msVal = chebyPoly(msCoeffs, xcap); const double beta = m_pars.sigmaSc * msVal / sigt; corrfact *= (1.0 - beta) / rns; } // apply correction sigOut[i] = yin * corrfact; errOut[i] = sigOut[i] * ein / yin; } return outputHistogram; }