Пример #1
0
void benchFilter(const std::vector<byte>& data) {
	CM<kCMTypeMax> comp(6);
	// data = randomArray(kBenchDataSize);
	check(!data.empty());
	const uint64_t expected_sum = std::accumulate(data.begin(), data.end(), 0UL);
	std::vector<byte> out_data;
	out_data.resize(20 * MB + static_cast<uint32_t>(data.size() * FilterType::getMaxExpansion() * 1.2));
	uint64_t start = clock();
	uint64_t write_count;
	uint64_t old_sum = 0;
	uint32_t best_size = std::numeric_limits<uint32_t>::max();
	uint32_t best_spec;
	for (uint32_t i = 0; i < kIterations; ++i) {
		WriteMemoryStream wms(&out_data[0]);
		ReadMemoryStream rms(&data);
		FilterType f(&rms); // , 1 + (i & 3), 1 + (i / 4));
		// f.setSpecific(100 + i);
		comp.setOpt(i);
		clock_t start = clock();
		comp.compress(&f, &wms, std::numeric_limits<uint64_t>::max());
		write_count = wms.tell();
		f.dumpInfo();
		if (write_count < best_size) {
			best_size = static_cast<uint32_t>(write_count);
			best_spec = i;
		}
		std::cout << "Cur=" << i << " size=" << write_count << " best(" << best_spec << ")=" << best_size << " time=" << clock() - start << std::endl;
#if 0
		uint64_t checksum = std::accumulate(&out_data[0], &out_data[write_count], 0UL);
		if (old_sum != 0) {
			check(old_sum == checksum);
		}
		old_sum = checksum;
#endif
	}	
	std::cout << "Forward: " << data.size() << "->" << write_count << " rate=" << prettySize(computeRate(data.size() * kIterations, clock() - start)) << "/S" << std::endl;

	std::vector<byte> result;
	result.resize(data.size());
	start = clock();
	for (uint32_t i = 0; i < kIterations; ++i) {
		WriteMemoryStream wvs(&result[0]);
		FilterType reverse_filter(&wvs); 
		comp.decompress(&ReadMemoryStream(&out_data[0], &out_data[0] + write_count), &reverse_filter, std::numeric_limits<uint64_t>::max());
		reverse_filter.flush();
	}
	uint64_t rate = computeRate(data.size() * kIterations, clock() - start);
	std::cout << "Reverse: " << prettySize(rate) << "/S" << std::endl;
	// Check tht the shit matches.
	check(result.size() == data.size());
	for (uint32_t i = 0; i < data.size(); ++i) {
		check(result[i] == data[i]);
	}
}
/**
 * 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;
}