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); }