/** Execute the algorithm for a EventWorkspace input * @param ws :: EventWorkspace */ void SmoothNeighbours::execEvent(Mantid::DataObjects::EventWorkspace_sptr ws) { m_progress->resetNumSteps(inWS->getNumberHistograms(), 0.5, 1.0); // Get some stuff from the input workspace const size_t numberOfSpectra = outWI; const int YLength = static_cast<int>(inWS->blocksize()); EventWorkspace_sptr outWS; // Make a brand new EventWorkspace outWS = boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create( "EventWorkspace", numberOfSpectra, YLength + 1, YLength)); // Copy geometry over. API::WorkspaceFactory::Instance().initializeFromParent(*ws, *outWS, false); // Ensure thread-safety outWS->sortAll(TOF_SORT, nullptr); this->setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(outWS)); // Go through all the output workspace PARALLEL_FOR_IF(Kernel::threadSafe(*ws, *outWS)) for (int outWIi = 0; outWIi < int(numberOfSpectra); outWIi++) { PARALLEL_START_INTERUPT_REGION // Create the output event list (empty) EventList &outEL = outWS->getSpectrum(outWIi); // Which are the neighbours? std::vector<weightedNeighbour> &neighbours = m_neighbours[outWIi]; std::vector<weightedNeighbour>::iterator it; for (it = neighbours.begin(); it != neighbours.end(); ++it) { size_t inWI = it->first; // if(sum)outEL.copyInfoFrom(*ws->getSpectrum(inWI)); double weight = it->second; // Copy the event list EventList tmpEL = ws->getSpectrum(inWI); // Scale it tmpEL *= weight; // Add it outEL += tmpEL; } // Copy the single detector ID (of the center) and spectrum number from the // input workspace // if (!sum) outEL.copyInfoFrom(*ws->getSpectrum(outWIi)); m_progress->report("Summing"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Give the 0-th X bins to all the output spectra. outWS->setAllX(inWS->binEdges(0)); if (expandSumAllPixels) spreadPixels(outWS); }
void EQSANSTofStructure::execEvent( Mantid::DataObjects::EventWorkspace_sptr inputWS, double threshold, double frame_offset, double tof_frame_width, double tmp_frame_width, bool frame_skipping) { const size_t numHists = inputWS->getNumberHistograms(); Progress progress(this, 0.0, 1.0, numHists); // Get the nominal sample-to-detector distance (in mm) Mantid::Kernel::Property *prop = inputWS->run().getProperty("sample_detector_distance"); auto dp = dynamic_cast<Mantid::Kernel::PropertyWithValue<double> *>(prop); if (!dp) { throw std::runtime_error("sample_detector_distance log not found."); } const double SDD = *dp / 1000.0; // Loop through the spectra and apply correction PARALLEL_FOR1(inputWS) for (int64_t ispec = 0; ispec < int64_t(numHists); ++ispec) { IDetector_const_sptr det; try { det = inputWS->getDetector(ispec); } catch (Exception::NotFoundError &) { g_log.warning() << "Workspace index " << ispec << " has no detector assigned to it - discarding\n"; // 'continue' statement moved outside catch block because Mac Intel // compiler has a problem with it being here in an openmp block. } if (!det) continue; // Get the flight path from the sample to the detector pixel const V3D samplePos = inputWS->getInstrument()->getSample()->getPos(); const V3D scattered_flight_path = det->getPos() - samplePos; // Sample-to-source distance const V3D sourcePos = inputWS->getInstrument()->getSource()->getPos(); const V3D SSD = samplePos - sourcePos; double tof_factor = (SSD.norm() + scattered_flight_path.norm()) / (SSD.norm() + SDD); PARALLEL_START_INTERUPT_REGION // Get the pointer to the output event list std::vector<TofEvent> &events = inputWS->getSpectrum(ispec).getEvents(); std::vector<TofEvent>::iterator it; std::vector<TofEvent> clean_events; for (it = events.begin(); it < events.end(); ++it) { double newtof = it->tof(); newtof += frame_offset; // Correct for the scattered neutron flight path if (flight_path_correction) newtof /= tof_factor; while (newtof < threshold) newtof += tmp_frame_width; // Remove events that don't fall within the accepted time window double rel_tof = newtof - frame_tof0; double x = (static_cast<int>(floor(rel_tof * 10)) % static_cast<int>(floor(tof_frame_width * 10))) * 0.1; if (x < low_tof_cut || x > tof_frame_width - high_tof_cut) { continue; } // At this point the events in the second frame are still off by a frame if (frame_skipping && rel_tof > tof_frame_width) newtof += tof_frame_width; clean_events.emplace_back(newtof, it->pulseTime()); } events.clear(); events.reserve(clean_events.size()); for (it = clean_events.begin(); it < clean_events.end(); ++it) { events.push_back(*it); } progress.report("TOF structure"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION }