Exemplo n.º 1
0
IPC::IPC()
    : globalMemory{"qtox-" IPC_PROTOCOL_VERSION}
{
    qRegisterMetaType<IPCEventHandler>("IPCEventHandler");

    timer.setInterval(EVENT_TIMER_MS);
    timer.setSingleShot(true);
    connect(&timer, &QTimer::timeout, this, &IPC::processEvents);

    // The first started instance gets to manage the shared memory by taking ownership
    // Every time it processes events it updates the global shared timestamp "lastProcessed"
    // If the timestamp isn't updated, that's a timeout and someone else can take ownership
    // This is a safety measure, in case one of the clients crashes
    // If the owner exits normally, it can set the timestamp to 0 first to immediately give ownership

    std::default_random_engine randEngine((std::random_device())());
    std::uniform_int_distribution<uint64_t> distribution;
    globalId = distribution(randEngine);
    qDebug() << "Our global IPC ID is " << globalId;
    if (globalMemory.create(sizeof(IPCMemory)))
    {
        if (globalMemory.lock())
        {
            IPCMemory* mem = global();
            memset(mem, 0, sizeof(IPCMemory));
            mem->globalId = globalId;
            mem->lastProcessed = time(0);
            globalMemory.unlock();
        }
        else
        {
            qWarning() << "Couldn't lock to take ownership";
        }
    }
    else if (globalMemory.attach())
    {
        qDebug() << "Attaching to the global shared memory";
    }
    else
    {
        qDebug() << "Failed to attach to the global shared memory, giving up";
        return; // We won't be able to do any IPC without being attached, let's get outta here
    }

    processEvents();
}
/** Execute the algorithm.
 */
void VesuvioL1ThetaResolution::exec() {
  // Load the instrument workspace
  loadInstrument();

  const std::string l1DistributionWsName = getPropertyValue("L1Distribution");
  const std::string thetaDistributionWsName =
      getPropertyValue("ThetaDistribution");
  const size_t numHist = m_instWorkspace->getNumberHistograms();
  const int numEvents = getProperty("NumEvents");

  // Create output workspace of resolution
  m_outputWorkspace =
      WorkspaceFactory::Instance().create("Workspace2D", 4, numHist, numHist);

  // Set vertical axis to statistic labels
  auto specAxis = new TextAxis(4);
  specAxis->setLabel(0, "l1_Mean");
  specAxis->setLabel(1, "l1_StdDev");
  specAxis->setLabel(2, "theta_Mean");
  specAxis->setLabel(3, "theta_StdDev");
  m_outputWorkspace->replaceAxis(1, specAxis);

  // Set X axis to spectrum numbers
  m_outputWorkspace->getAxis(0)->setUnit("Label");
  auto xAxis = boost::dynamic_pointer_cast<Units::Label>(
      m_outputWorkspace->getAxis(0)->unit());
  if (xAxis)
    xAxis->setLabel("Spectrum Number");

  // Create output workspaces for distributions if required
  if (!l1DistributionWsName.empty()) {
    m_l1DistributionWs = WorkspaceFactory::Instance().create(
        m_instWorkspace, numHist, numEvents, numEvents);

    // Set Y axis
    m_l1DistributionWs->setYUnitLabel("Events");

    // Set X axis
    auto distributionXAxis = m_l1DistributionWs->getAxis(0);
    distributionXAxis->setUnit("Label");
    auto labelUnit =
        boost::dynamic_pointer_cast<Units::Label>(distributionXAxis->unit());
    if (labelUnit)
      labelUnit->setLabel("l1");
  }

  if (!thetaDistributionWsName.empty()) {
    m_thetaDistributionWs = WorkspaceFactory::Instance().create(
        m_instWorkspace, numHist, numEvents, numEvents);

    // Set Y axis
    m_thetaDistributionWs->setYUnitLabel("Events");

    // Set X axis
    auto distributionXAxis = m_thetaDistributionWs->getAxis(0);
    distributionXAxis->setUnit("Label");
    auto labelUnit =
        boost::dynamic_pointer_cast<Units::Label>(distributionXAxis->unit());
    if (labelUnit)
      labelUnit->setLabel("theta");
  }

  // Set up progress reporting
  Progress prog(this, 0.0, 1.0, numHist);
  const int seed(getProperty("Seed"));
  std::mt19937 randEngine(static_cast<std::mt19937::result_type>(seed));
  std::uniform_real_distribution<> flatDistrib(0.0, 1.0);
  std::function<double()> flatVariateGen(
      [&randEngine, &flatDistrib]() { return flatDistrib(randEngine); });

  const auto &spectrumInfo = m_instWorkspace->spectrumInfo();
  // Loop for all detectors
  for (size_t i = 0; i < numHist; i++) {
    std::vector<double> l1;
    std::vector<double> theta;
    const auto &det = spectrumInfo.detector(i);

    // Report progress
    std::stringstream report;
    report << "Detector " << det.getID();
    prog.report(report.str());
    g_log.information() << "Detector ID " << det.getID() << '\n';

    // Do simulation
    calculateDetector(det, flatVariateGen, l1, theta);

    // Calculate statistics for L1 and theta
    Statistics l1Stats = getStatistics(l1);
    Statistics thetaStats = getStatistics(theta);

    g_log.information() << "l0: mean=" << l1Stats.mean
                        << ", std.dev.=" << l1Stats.standard_deviation
                        << "\ntheta: mean=" << thetaStats.mean
                        << ", std.dev.=" << thetaStats.standard_deviation
                        << '\n';

    // Set values in output workspace
    const int specNo = m_instWorkspace->getSpectrum(i).getSpectrumNo();
    m_outputWorkspace->mutableX(0)[i] = specNo;
    m_outputWorkspace->mutableX(1)[i] = specNo;
    m_outputWorkspace->mutableX(2)[i] = specNo;
    m_outputWorkspace->mutableX(3)[i] = specNo;
    m_outputWorkspace->mutableY(0)[i] = l1Stats.mean;
    m_outputWorkspace->mutableY(1)[i] = l1Stats.standard_deviation;
    m_outputWorkspace->mutableY(2)[i] = thetaStats.mean;
    m_outputWorkspace->mutableY(3)[i] = thetaStats.standard_deviation;

    // Process data for L1 distribution
    if (m_l1DistributionWs) {
      auto &x = m_l1DistributionWs->mutableX(i);

      std::sort(l1.begin(), l1.end());
      std::copy(l1.begin(), l1.end(), x.begin());

      m_l1DistributionWs->mutableY(i) = 1.0;

      auto &spec = m_l1DistributionWs->getSpectrum(i);
      spec.setSpectrumNo(specNo);
      spec.addDetectorID(det.getID());
    }

    // Process data for theta distribution
    if (m_thetaDistributionWs) {
      auto &x = m_thetaDistributionWs->mutableX(i);

      std::sort(theta.begin(), theta.end());
      std::copy(theta.begin(), theta.end(), x.begin());

      m_thetaDistributionWs->mutableY(i) = 1.0;

      auto &spec = m_thetaDistributionWs->getSpectrum(i);
      spec.setSpectrumNo(specNo);
      spec.addDetectorID(det.getID());
    }
  }

  // Process the L1 distribution workspace
  if (m_l1DistributionWs) {
    const double binWidth = getProperty("L1BinWidth");
    setProperty("L1Distribution",
                processDistribution(m_l1DistributionWs, binWidth));
  }

  // Process the theta distribution workspace
  if (m_thetaDistributionWs) {
    const double binWidth = getProperty("ThetaBinWidth");
    setProperty("ThetaDistribution",
                processDistribution(m_thetaDistributionWs, binWidth));
  }

  setProperty("OutputWorkspace", m_outputWorkspace);
}