Exemple #1
0
/*
 * 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;
}
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
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;
}
Exemple #4
0
/*
 * 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;
}