void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); //std::this_thread::sleep_for(std::chrono::milliseconds(10000)); cv.wait(lk); this_thread_interrupt_flag.clear_condition_variable(); interruption_point(); }
void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); clear_cv_on_destruct guard; interruption_point(); cv.wait_for(lk, std::chrono::milliseconds(1)); interruption_point(); }
void interruptible_wait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk, Predicate pred) { interruption_point(); this_thread_interrupt_flag.set_condition_variable(cv); interrupt_flag::clear_cv_on_destruct guard; while (!thie_thread_interrupt_flag.is_set() && !pred()) { cv.wait_for(lk, std::chrono::milliseconds(1)); } interruption_point(); }
/** * Execute the algorithm. */ void FakeISISHistoDAE::exec() { Mutex::ScopedLock lock(m_mutex); Poco::Net::ServerSocket socket(6789); socket.listen(); int nper = getProperty("NPeriods"); int nspec = getProperty("NSpectra"); int nbins = getProperty("NBins"); m_server = new Poco::Net::TCPServer(TestServerConnectionFactory::Ptr( new TestServerConnectionFactory(nper,nspec,nbins) ), socket ); m_server->start(); // Keep going until you get cancelled while (true) { try { // Exit if the user presses cancel interruption_point(); } catch(...) { break; } progress( 0.0, "Fake DAE" ); // Sleep for 50 msec Poco::Thread::sleep(50); } if ( m_server ) { m_server->stop(); m_server = NULL; } socket.close(); }
void contractor_sample::prune(contractor_status & cs) { DREAL_LOG_DEBUG << "contractor_sample::prune"; // Sample n points set<box> points = cs.m_box.sample_points(m_num_samples); // If ∃p. ∀c. eval(c, p) = true, return 'SAT' unsigned count = 0; for (box const & p : points) { interruption_point(); DREAL_LOG_DEBUG << "contractor_sample::prune -- sample " << ++count << "th point = " << p; bool check = true; for (shared_ptr<constraint> const ctr : m_ctrs) { if (ctr->get_type() == constraint_type::Nonlinear) { auto const nl_ctr = dynamic_pointer_cast<nonlinear_constraint>(ctr); pair<lbool, ibex::Interval> eval_result = nl_ctr->eval(p); if (eval_result.first == l_False) { check = false; DREAL_LOG_DEBUG << "contractor_sample::prune -- sampled point = " << p << " does not satisfy " << *ctr; break; } } } if (check) { DREAL_LOG_DEBUG << "contractor_sample::prune -- sampled point = " << p << " satisfies all constraints"; cs.m_box = p; cs.m_output = ibex::BitSet::all(cs.m_box.size()); cs.m_used_constraints.insert(m_ctrs.begin(), m_ctrs.end()); return; } } return; }
/// Update the percentage complete estimate assuming that the algorithm has completed a task with estimated RunTime toAdd void GetEi::advanceProgress(double toAdd) { m_fracCompl += toAdd; progress(m_fracCompl); // look out for user cancel messgages interruption_point(); }
void contractor_aggressive::prune(contractor_status & cs) { DREAL_LOG_DEBUG << "contractor_eval::aggressive"; // TODO(soonhok): set input & output // Sample n points set<box> points = cs.m_box.sample_points(m_num_samples); // ∃c. ∀p. eval(c, p) = false ===> UNSAT for (shared_ptr<constraint> const ctr : m_ctrs) { interruption_point(); if (ctr->get_type() == constraint_type::Nonlinear) { auto const nl_ctr = dynamic_pointer_cast<nonlinear_constraint>(ctr); bool check = false; for (box const & p : points) { pair<lbool, ibex::Interval> eval_result = nl_ctr->eval(p); if (eval_result.first != l_False) { check = true; break; } } if (!check) { cs.m_used_constraints.insert(ctr); pair<lbool, ibex::Interval> eval_result = nl_ctr->eval(cs.m_box); DREAL_LOG_DEBUG << "Constraint: " << *nl_ctr << " is violated by all " << points.size() << " points"; DREAL_LOG_DEBUG << "FYI, the interval evaluation gives us : " << eval_result.second; cs.m_box.set_empty(); return; } } } return; }
void contractor_fixpoint::worklist_fixpoint_alg(contractor_status & cs) { thread_local static queue<unsigned> q; q = queue<unsigned>(); // empty queue thread_local static ibex::BitSet ctc_bitset = ibex::BitSet::empty(m_clist.size()); ctc_bitset.clear(); // Add all contractors to the queue. for (int i = m_clist.size() - 1; i >= 0; --i) { contractor & c_i = m_clist[i]; contractor_status_guard csg(cs); c_i.prune(cs); if (cs.m_box.is_empty()) { return; } ibex::BitSet const & output_i = cs.m_output; if (output_i.empty()) { continue; } q.push(i); ctc_bitset.add(i); } if (q.size() == 0) { return; } // Fixed Point Loop thread_local static box old_box(cs.m_box); do { interruption_point(); old_box = cs.m_box; unsigned const idx = q.front(); q.pop(); ctc_bitset.remove(idx); assert(idx < m_clist.size()); contractor & c = m_clist[idx]; contractor_status_guard csg(cs); c.prune(cs); if (cs.m_box.is_empty()) { return; } auto const & c_output = cs.m_output; if (!c_output.empty()) { // j-th dimension is changed as a result of pruning // need to add a contractor which takes j-th dim as an input for (int j = c_output.min(); j <= c_output.max(); ++j) { if (!c_output.contain(j)) { continue; } for (unsigned k = 0; k < m_clist.size(); ++k) { // Only add if it's not in the current queue if (!ctc_bitset.contain(k)) { contractor const & c_k = m_clist[k]; if (c_k.get_input().contain(j)) { q.push(k); ctc_bitset.add(k); } } } } } } while (q.size() > 0 && cs.m_box.max_diam() >= cs.m_config.nra_precision && !m_term_cond(old_box, cs.m_box)); return; }
/** Update the percentage complete estimate assuming that the algorithm * has completed a task with the given estimated run time * @param toAdd :: the estimated additional run time passed since the last update, * where m_TotalTime holds the total algorithm run time * @return estimated fraction of algorithm runtime that has passed so far */ double DetectorDiagnostic::advanceProgress(double toAdd) { m_fracDone += toAdd/m_TotalTime; // it could go negative as sometimes the percentage is re-estimated backwards, // this is worrying about if a small negative value will cause a problem some where m_fracDone = std::abs(m_fracDone); interruption_point(); return m_fracDone; }
void contractor_seq::prune_naive(contractor_status & cs) { DREAL_LOG_DEBUG << "contractor_seq::prune"; for (contractor & c : m_vec) { interruption_point(); c.prune(cs); if (cs.m_box.is_empty()) { return; } } return; }
/** A memory efficient function that adjusts the X-value bin boundaries that only creates a new * cow_ptr array when the offset has changed * @param offsets :: an array of times to adjust all the bins in each workspace histogram by * @param spectraList :: a list of spectra numbers in the same order as the offsets * @param specs2index :: a map that allows finding a spectra indexes from spectra numbers * @param missingDetectors :: this will be filled with the array indices of the detector offsets that we can't find spectra indices for */ void LoadDetectorInfo::adjustXsCommon(const std::vector<float> &offsets, const std::vector<specid_t> &spectraList, spec2index_map &specs2index, std::vector<detid_t> missingDetectors) { // space for cached values float cachedOffSet = UNSETOFFSET; MantidVecPtr monitorXs; MantidVecPtr cachedXs; double fracCompl = 1.0/3.0; for ( std::vector<int>::size_type j = 0; j < spectraList.size(); ++j ) {// first check that our spectranumber to spectra index map is working for us if ( specs2index.find(spectraList[j]) == specs2index.end() ) {// we can't find the spectrum associated the detector prepare to log that missingDetectors.push_back(static_cast<int>(j)); // and then move on to the next detector in the loop continue; } const size_t specIndex = specs2index[spectraList[j]]; // check if we dealing with a monitor as these are dealt by a different function const std::set<detid_t> & dets = m_workspace->getSpectrum(specIndex)->getDetectorIDs(); if ( dets.size() > 0 ) {// is it in the monitors list if ( m_monitors.find(*dets.begin()) == m_monitors.end() ) {// it's not a monitor, it's a regular detector if ( offsets[j] != cachedOffSet ) { setUpXArray(cachedXs, specIndex, offsets[j]); cachedOffSet = offsets[j]; } else m_workspace->setX(specIndex, cachedXs); } else {// it's a monitor if ( (*monitorXs).empty() ) { // negative because we add the monitor offset, not take away as for detectors, the difference between the monitor delay and the detectors that counts setUpXArray(monitorXs, specIndex, -m_monitOffset); } else m_workspace->setX(specIndex, monitorXs); } } if ( j % INTERVAL == INTERVAL/2 ) { fracCompl += (2.0*INTERVAL/3.0)/static_cast<double>(spectraList.size()); progress( fracCompl ); interruption_point(); } } }
void wait(std::condition_variable_any& cv, Lockable& lk) { struct custom_lock { interrupt_flag* self; Lockable& lk; custom_lock(interrupt_flag* self_, std::condition_variable_any& cond, Lockable& lk_) : self(self_) , lk(lk_) { self->set_clear_mutex.lock(); self->thread_cond_any = &cond; } void unlock() { lk.unlock(); self->set_clear_mutex.unlock(); } void lock() { std::lock(self->set_clear_mutex, lk); } ~custom_lock() { self->thread_cond_any = 0; self->set_clear_mutex.unlock(); } }; custom_lock cl(this, cv, lk); interruption_point(); cv.wait(cl); interruption_point(); }
/** Called while reading input file to report progress (doesn't update m_FracCompl ) and * check for algorithm cancel messages, doesn't look at file size to estimate progress * @param numGroupsRead :: number of groups read from the file so far (not the number of spectra) * @param numInHists :: the total number of histograms in the input workspace * @return estimate of the amount of algorithm progress obtained by reading from the file */ double GroupDetectors2::fileReadProg(DataHandling::GroupDetectors2::storage_map::size_type numGroupsRead, DataHandling::GroupDetectors2::storage_map::size_type numInHists) { // I'm going to guess that there are half as many groups as spectra double progEstim = 2.*static_cast<double>(numGroupsRead)/static_cast<double>(numInHists); // but it might be more, in which case this complex function always increases but slower and slower progEstim = READFILE*progEstim/(1+progEstim); // now do the reporting progress(m_FracCompl + progEstim ); // check for a (user) cancel message interruption_point(); return progEstim; }
void contractor_fixpoint::naive_fixpoint_alg(contractor_status & cs) { // First Iteration (run always) for (contractor & c : m_clist) { interruption_point(); c.prune(cs); if (cs.m_box.is_empty()) { return; } } unsigned i = 0; // Next Iterations: stop when 1) a box is smaller enough or 2) termination condition holds do { interruption_point(); m_old_box = cs.m_box; contractor & c = m_clist[i]; c.prune(cs); if (cs.m_box.is_empty()) { return; } i = (i + 1) % m_clist.size(); } while (m_old_box != cs.m_box && cs.m_box.is_bisectable(cs.m_config.nra_precision) && !m_term_cond(m_old_box, cs.m_box)); return; }
/** Executes the algorithm * @throw NullPointerException if a getDetector() returns NULL or pressure or wall thickness is not set * @throw invalid_argument if the shape of a detector is isn't a cylinder aligned on axis or there is no baseInstrument * @throw runtime_error if the SpectraDetectorMap had not been filled */ void DetectorEfficiencyCor::exec() { //gets and checks the values passed to the algorithm retrieveProperties(); // wave number that the neutrons originally had m_ki = std::sqrt(m_Ei/KSquaredToE); // Store some information about the instrument setup that will not change m_samplePos = m_inputWS->getInstrument()->getSample()->getPos(); int64_t numHists = m_inputWS->getNumberHistograms(); double numHists_d = static_cast<double>(numHists); const int64_t progStep = static_cast<int64_t>(ceil(numHists_d/100.0)); PARALLEL_FOR2(m_inputWS,m_outputWS) for (int64_t i = 0; i < numHists; ++i ) { PARALLEL_START_INTERUPT_REGION m_outputWS->setX(i, m_inputWS->refX(i)); try { correctForEfficiency(i); } catch (Exception::NotFoundError &) { // if we don't have all the data there will be spectra we can't correct, avoid leaving the workspace part corrected MantidVec& dud = m_outputWS->dataY(i); std::transform(dud.begin(),dud.end(),dud.begin(), std::bind2nd(std::multiplies<double>(),0)); PARALLEL_CRITICAL(deteff_invalid) { m_spectraSkipped.push_back(m_inputWS->getAxis(1)->spectraNo(i)); } } // make regular progress reports and check for cancelling the algorithm if ( i % progStep == 0 ) { progress(static_cast<double>(i)/numHists_d); interruption_point(); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION logErrors(); setProperty("OutputWorkspace", m_outputWS); }
void contractor_fixpoint::worklist_fixpoint_alg(contractor_status & cs) { queue<int> q; ibex::BitSet ctc_bitset(m_clist.size()); // Add all contractors to the queue. for (unsigned i = 0; i < m_clist.size(); ++i) { contractor & c_i = m_clist[i]; contractor_status_guard csg(cs); c_i.prune(cs); if (cs.m_box.is_empty()) { return; } ibex::BitSet const & output_i = cs.m_output; if (!output_i.empty()) { assert(!ctc_bitset.contain(i)); q.push(i); ctc_bitset.add(i); } } if (q.size() == 0) { return; } // Fixed Point Loop do { interruption_point(); unsigned const idx = q.front(); q.pop(); ctc_bitset.remove(idx); assert(!ctc_bitset.contain(idx)); assert(idx < m_clist.size()); contractor & c = m_clist[idx]; m_old_box = cs.m_box; contractor_status_guard csg(cs); c.prune(cs); if (cs.m_box.is_empty()) { return; } auto const & c_output = cs.m_output; if (!c_output.empty()) { // j-th dimension is changed as a result of pruning // need to add a contractor which takes j-th dim as an input int j = c_output.min(); do { if (!c_output.contain(j)) { continue; } for (int const dependent_ctc_id : m_dep_map[j]) { if (!ctc_bitset.contain(dependent_ctc_id)) { q.push(dependent_ctc_id); ctc_bitset.add(dependent_ctc_id); } } j = c_output.next(j); } while (j < c_output.max()); } } while (q.size() > 0 && (m_old_box != cs.m_box) && cs.m_box.is_bisectable(cs.m_config.nra_precision) && !m_term_cond(m_old_box, cs.m_box)); return; }
/** * Only to be used if the KeepUnGrouped property is true, moves the spectra that were not selected * to be in a group to the end of the output spectrum * @param unGroupedSet :: list of WORKSPACE indexes that were included in a group * @param inputWS :: user selected input workspace for the algorithm * @param outputWS :: user selected output workspace for the algorithm * @param outIndex :: the next spectra index available after the grouped spectra */ void GroupDetectors2::moveOthers(const std::set<int64_t> &unGroupedSet, API::MatrixWorkspace_const_sptr inputWS, API::MatrixWorkspace_sptr outputWS, size_t outIndex) { g_log.debug() << "Starting to copy the ungrouped spectra" << std::endl; double prog4Copy = (1. - 1.*static_cast<double>(m_FracCompl))/static_cast<double>(unGroupedSet.size()); std::set<int64_t>::const_iterator copyFrIt = unGroupedSet.begin(); // go thorugh all the spectra in the input workspace for ( ; copyFrIt != unGroupedSet.end(); ++copyFrIt ) { if( *copyFrIt == USED ) continue; //Marked as not to be used size_t sourceIndex = static_cast<size_t>(*copyFrIt); // The input spectrum we'll copy const ISpectrum * inputSpec = inputWS->getSpectrum(sourceIndex); // Destination of the copying ISpectrum * outputSpec = outputWS->getSpectrum(outIndex); // Copy the data outputSpec->dataX() = inputSpec->dataX(); outputSpec->dataY() = inputSpec->dataY(); outputSpec->dataE() = inputSpec->dataE(); // Spectrum numbers etc. outputSpec->setSpectrumNo(inputSpec->getSpectrumNo()); outputSpec->clearDetectorIDs(); outputSpec->addDetectorIDs( inputSpec->getDetectorIDs() ); // go to the next free index in the output workspace outIndex ++; // make regular progress reports and check for cancelling the algorithm if ( outIndex % INTERVAL == 0 ) { m_FracCompl += INTERVAL*prog4Copy; if ( m_FracCompl > 1.0 ) { m_FracCompl = 1.0; } progress(m_FracCompl); interruption_point(); } } // Refresh the spectraDetectorMap outputWS->generateSpectraMap(); g_log.debug() << name() << " copied " << unGroupedSet.size()-1 << " ungrouped spectra\n"; }
void sleep_until( chrono::time_point< Clock, Duration > const& sleep_time) { if ( 0 != fibers::fm_active() ) { fibers::detail::spinlock splk; unique_lock< fibers::detail::spinlock > lk( splk); fibers::fm_wait_until( sleep_time, lk); // check if fiber was interrupted interruption_point(); } else { while ( chrono::high_resolution_clock::now() <= sleep_time) fibers::fm_run(); } }
void LoadRaw3::separateMonitors(FILE *file, const int64_t &period, const std::vector<specnum_t> &monitorList, DataObjects::Workspace2D_sptr ws_sptr, DataObjects::Workspace2D_sptr mws_sptr) { int64_t histCurrent = -1; int64_t wsIndex = 0; int64_t mwsIndex = 0; double histTotal = static_cast<double>(m_total_specs * m_numberOfPeriods); // loop through spectra for (specnum_t i = 1; i <= m_numberOfSpectra; ++i) { int64_t histToRead = i + period * (m_numberOfSpectra + 1); if ((i >= m_spec_min && i < m_spec_max) || (m_list && find(m_spec_list.begin(), m_spec_list.end(), i) != m_spec_list.end())) { progress(m_prog, "Reading raw file data..."); // read spectrum from raw file if (!readData(file, histToRead)) { throw std::runtime_error("Error reading raw file"); } // if this a monitor store that spectrum to monitor workspace if (isMonitor(monitorList, i)) { setWorkspaceData(mws_sptr, m_timeChannelsVec, mwsIndex, i, m_noTimeRegimes, m_lengthIn, 1); ++mwsIndex; } else { // not a monitor,store the spectrum to normal output workspace setWorkspaceData(ws_sptr, m_timeChannelsVec, wsIndex, i, m_noTimeRegimes, m_lengthIn, 1); ++wsIndex; } if (m_numberOfPeriods == 1) { if (++histCurrent % 100 == 0) { setProg(static_cast<double>(histCurrent) / histTotal); } interruption_point(); } } else { skipData(file, histToRead); } } }
/** This method creates outputworkspace excluding monitors *@param file :: -pointer to file *@param period :: period number *@param monitorList :: a list containing the spectrum numbers for monitors *@param ws_sptr :: shared pointer to workspace */ void LoadRaw3::excludeMonitors(FILE *file, const int &period, const std::vector<specnum_t> &monitorList, DataObjects::Workspace2D_sptr ws_sptr) { int64_t histCurrent = -1; int64_t wsIndex = 0; double histTotal = static_cast<double>(m_total_specs * m_numberOfPeriods); // loop through the spectra for (specnum_t i = 1; i <= m_numberOfSpectra; ++i) { specnum_t histToRead = i + period * (m_numberOfSpectra + 1); if ((i >= m_spec_min && i < m_spec_max) || (m_list && find(m_spec_list.begin(), m_spec_list.end(), i) != m_spec_list.end())) { progress(m_prog, "Reading raw file data..."); // skip monitor spectrum if (isMonitor(monitorList, i)) { skipData(file, histToRead); continue; } // read spectrum if (!readData(file, histToRead)) { throw std::runtime_error("Error reading raw file"); } // set the workspace data setWorkspaceData(ws_sptr, m_timeChannelsVec, wsIndex, i, m_noTimeRegimes, m_lengthIn, 1); // increment workspace index ++wsIndex; if (m_numberOfPeriods == 1) { if (++histCurrent % 100 == 0) { setProg(static_cast<double>(histCurrent) / histTotal); } interruption_point(); } } // end of if loop for spec min,max check else { skipData(file, histToRead); } } // end of for loop }
/** Calls CropWorkspace as a sub-algorithm and passes to it the InputWorkspace property * @param specInd :: the index number of the histogram to extract * @param start :: the number of the first bin to include (starts counting bins at 0) * @param end :: the number of the last bin to include (starts counting bins at 0) * @throw out_of_range if start, end or specInd are set outside of the vaild range for the workspace * @throw runtime_error if the algorithm just falls over * @throw invalid_argument if the input workspace does not have common binning */ void GetEi::extractSpec(int64_t specInd, double start, double end) { IAlgorithm_sptr childAlg = createSubAlgorithm("CropWorkspace", 100*m_fracCompl, 100*(m_fracCompl+CROP) ); m_fracCompl += CROP; childAlg->setPropertyValue( "InputWorkspace", getPropertyValue("InputWorkspace") ); childAlg->setProperty( "XMin", start); childAlg->setProperty( "XMax", end); childAlg->setProperty( "StartWorkspaceIndex", specInd); childAlg->setProperty( "EndWorkspaceIndex", specInd); childAlg->executeAsSubAlg(); m_tempWS = childAlg->getProperty("OutputWorkspace"); //DEBUGGING CODE uncomment out the line below if you want to see the TOF window that was analysed //AnalysisDataService::Instance().addOrReplace("croped_dist_del", m_tempWS); progress(m_fracCompl); interruption_point(); }
/**This method creates outputworkspace including monitors *@param file :: -pointer to file *@param period :: period number *@param ws_sptr :: shared pointer to workspace */ void LoadRaw3::includeMonitors(FILE *file, const int64_t &period, DataObjects::Workspace2D_sptr ws_sptr) { int64_t histCurrent = -1; int64_t wsIndex = 0; double histTotal = static_cast<double>(m_total_specs * m_numberOfPeriods); // loop through spectra for (specnum_t i = 1; i <= m_numberOfSpectra; ++i) { int64_t histToRead = i + period * (m_numberOfSpectra + 1); if ((i >= m_spec_min && i < m_spec_max) || (m_list && find(m_spec_list.begin(), m_spec_list.end(), i) != m_spec_list.end())) { progress(m_prog, "Reading raw file data..."); // read spectrum from raw file if (!readData(file, histToRead)) { throw std::runtime_error("Error reading raw file"); } // set workspace data setWorkspaceData(ws_sptr, m_timeChannelsVec, wsIndex, i, m_noTimeRegimes, m_lengthIn, 1); ++wsIndex; if (m_numberOfPeriods == 1) { if (++histCurrent % 100 == 0) { setProg(double(histCurrent) / histTotal); } interruption_point(); } } else { skipData(file, histToRead); } } // loadSpectra(file,period,m_total_specs,ws_sptr,m_timeChannelsVec); }
/** Read the spectra numbers in from the input file (the file format is in the * source file "GroupDetectors2.h" and make an array of spectra indexes to group * @param fname :: the full path name of the file to open * @param workspace :: a pointer to the input workspace, used to get spectra indexes from numbers * @param unUsedSpec :: the list of spectra indexes that have been included in a group (so far) * @throw FileError if there's any problem with the file or its format */ void GroupDetectors2::processFile(std::string fname, API::MatrixWorkspace_const_sptr workspace, std::vector<int64_t> &unUsedSpec) { // tring to open the file the user told us exists, skip down 20 lines to find out what happens if we can read from it g_log.debug() << "Opening input file ... " << fname; std::ifstream File(fname.c_str(), std::ios::in); std::string firstLine; std::getline( File, firstLine ); // for error reporting keep a count of where we are reading in the file size_t lineNum = 1; if (File.fail()) { g_log.debug() << " file state failbit set after read attempt\n"; throw Exception::FileError("Couldn't read file", fname); } g_log.debug() << " success opening input file " << fname << std::endl; progress(m_FracCompl += OPENINGFILE); // check for a (user) cancel message interruption_point(); // allow spectra number to spectra index look ups spec2index_map specs2index; const SpectraAxis* axis = dynamic_cast<const SpectraAxis*>(workspace->getAxis(1)); if (axis) { axis->getSpectraIndexMap(specs2index); } try { // we don't use the total number of groups report at the top of the file but we'll tell them later if there is a problem with it for their diagnostic purposes int totalNumberOfGroups = readInt(firstLine); // Reading file now ... while ( totalNumberOfGroups == EMPTY_LINE ) { if ( ! File ) throw Exception::FileError("The input file doesn't appear to contain any data", fname); std::getline( File, firstLine ), lineNum ++; totalNumberOfGroups = readInt(firstLine); } readFile(specs2index, File, lineNum, unUsedSpec); if ( m_GroupSpecInds.size() != static_cast<size_t>(totalNumberOfGroups) ) { g_log.warning() << "The input file header states there are " << totalNumberOfGroups << " but the file contains " << m_GroupSpecInds.size() << " groups\n"; } } // add some more info to the error messages, including the line number, to help users correct their files. These problems should cause the algorithm to stop catch (std::invalid_argument &e) { g_log.debug() << "Exception thrown: " << e.what() << std::endl; File.close(); std::string error(e.what() + std::string(" near line number ") + boost::lexical_cast<std::string>(lineNum)); if (File.fail()) { error = "Input output error while reading file "; } throw Exception::FileError(error, fname); } catch (boost::bad_lexical_cast &e) { g_log.debug() << "Exception thrown: " << e.what() << std::endl; File.close(); std::string error(std::string("Problem reading integer value \"") + e.what() + std::string("\" near line number ") + boost::lexical_cast<std::string>(lineNum)); if (File.fail()) { error = "Input output error while reading file "; } throw Exception::FileError(error, fname); } File.close(); g_log.debug() << "Closed file " << fname << " after reading in " << m_GroupSpecInds.size() << " groups\n"; m_FracCompl += fileReadProg( m_GroupSpecInds.size(), specs2index.size() ); return; }
void GroupDetectors2::execEvent() { // Get the input workspace const MatrixWorkspace_const_sptr matrixInputWS = getProperty("InputWorkspace"); EventWorkspace_const_sptr inputWS= boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS); const size_t numInHists = inputWS->getNumberHistograms(); progress( m_FracCompl = CHECKBINS ); interruption_point(); // some values loaded into this vector can be negative so this needs to be a signed type std::vector<int64_t> unGroupedInds; //the ungrouped list could be very big but might be none at all unGroupedInds.reserve(numInHists); for( size_t i = 0; i < numInHists ; i++ ) { unGroupedInds.push_back(i); } // read in the input parameters to make that map, if KeepUngroupedSpectra was set we'll need a list of the ungrouped spectrra too getGroups(inputWS, unGroupedInds); // converting the list into a set gets rid of repeated values, here the multiple GroupDetectors2::USED become one USED at the start const std::set<int64_t> unGroupedSet(unGroupedInds.begin(), unGroupedInds.end()); // Check what the user asked to be done with ungrouped spectra const bool keepAll = getProperty("KeepUngroupedSpectra"); // ignore the one USED value in set or ignore all the ungrouped if the user doesn't want them const size_t numUnGrouped = keepAll ? unGroupedSet.size()-1 : 0; //Make a brand new EventWorkspace EventWorkspace_sptr outputWS = boost::dynamic_pointer_cast<EventWorkspace>( WorkspaceFactory::Instance().create("EventWorkspace", m_GroupSpecInds.size()+ numUnGrouped, inputWS->readX(0).size(), inputWS->blocksize())); //Copy geometry over. WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, true); // prepare to move the requested histograms into groups, first estimate how long for progress reporting. +1 in the demonator gets rid of any divide by zero risk double prog4Copy=( (1.0 - m_FracCompl)/(static_cast<double>(numInHists-unGroupedSet.size())+1.) )* (keepAll ? static_cast<double>(numInHists-unGroupedSet.size())/static_cast<double>(numInHists): 1.); // Build a new map const size_t outIndex = formGroupsEvent(inputWS, outputWS, prog4Copy); // If we're keeping ungrouped spectra if (keepAll) { // copy them into the output workspace moveOthersEvent(unGroupedSet, inputWS, outputWS, outIndex); } //Set all X bins on the output cow_ptr<MantidVec> XValues; XValues.access() = inputWS->readX(0); outputWS->setAllX(XValues); g_log.information() << name() << " algorithm has finished\n"; setProperty("OutputWorkspace",outputWS); }
/** Executes the algorithm. Reading in the file and creating and populating * the output workspace * * @throw Exception::FileError If the RAW file cannot be found/opened * @throw std::invalid_argument If the optional properties are set to invalid values */ void LoadRaw::exec() { // Retrieve the filename from the properties m_filename = getPropertyValue("Filename"); LoadRawHelper *helper = new LoadRawHelper; FILE* file = helper->openRawFile(m_filename); ISISRAW iraw; iraw.ioRAW(file, true); std::string title(iraw.r_title, 80); g_log.information("**** Run title: "+title+ "***"); // Read in the number of spectra in the RAW file m_numberOfSpectra = iraw.t_nsp1; // Read the number of periods in this file m_numberOfPeriods = iraw.t_nper; // Need to extract the user-defined output workspace name Property *ws = getProperty("OutputWorkspace"); std::string localWSName = ws->value(); // Call private method to validate the optional parameters, if set checkOptionalProperties(); // Read the number of time channels (i.e. bins) from the RAW file const int channelsPerSpectrum = iraw.t_ntc1; // Read in the time bin boundaries const int lengthIn = channelsPerSpectrum + 1; float* timeChannels = new float[lengthIn]; iraw.getTimeChannels(timeChannels, lengthIn); // Put the read in array into a vector (inside a shared pointer) boost::shared_ptr<MantidVec> timeChannelsVec (new MantidVec(timeChannels, timeChannels + lengthIn)); // Create an array to hold the read-in data int* spectrum = new int[lengthIn]; // Calculate the size of a workspace, given its number of periods & spectra to read specid_t total_specs; if( m_interval || m_list) { total_specs = static_cast<specid_t>(m_spec_list.size()); if (m_interval) { total_specs += (m_spec_max-m_spec_min+1); m_spec_max += 1; } } else { total_specs = m_numberOfSpectra; // In this case want all the spectra, but zeroth spectrum is garbage so go from 1 to NSP1 m_spec_min = 1; m_spec_max = m_numberOfSpectra + 1; } double histTotal = static_cast<double>(total_specs * m_numberOfPeriods); int32_t histCurrent = -1; // Create the 2D workspace for the output DataObjects::Workspace2D_sptr localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D> (WorkspaceFactory::Instance().create("Workspace2D",total_specs,lengthIn,lengthIn-1)); localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); localWorkspace->setTitle(title); // Run parameters helper->loadRunParameters(localWorkspace, &iraw); delete helper; helper = NULL; // Loop over the number of periods in the raw file, putting each period in a separate workspace for (int period = 0; period < m_numberOfPeriods; ++period) { if ( period > 0 ) localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D> (WorkspaceFactory::Instance().create(localWorkspace)); specid_t counter = 0; for (specid_t i = m_spec_min; i < m_spec_max; ++i) { // Shift the histogram to read if we're not in the first period int32_t histToRead = i + period*total_specs; loadData(timeChannelsVec,counter,histToRead,iraw,lengthIn,spectrum,localWorkspace ); counter++; if (++histCurrent % 100 == 0) progress(static_cast<double>(histCurrent)/histTotal); interruption_point(); } // Read in the spectra in the optional list parameter, if set if (m_list) { for(size_t i=0; i < m_spec_list.size(); ++i) { loadData(timeChannelsVec,counter,m_spec_list[i],iraw,lengthIn,spectrum, localWorkspace ); counter++; if (++histCurrent % 100 == 0) progress(static_cast<double>(histCurrent)/histTotal); interruption_point(); } } // Just a sanity check assert(counter == total_specs); std::string outputWorkspace = "OutputWorkspace"; if (period == 0) { // Only run the Child Algorithms once runLoadInstrument(localWorkspace ); runLoadMappingTable(localWorkspace ); runLoadLog(localWorkspace ); const int period_number = 1; Property* log=createPeriodLog(period_number); if(log) { localWorkspace->mutableRun().addLogData(log); localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number)); } // Set the total proton charge for this run // (not sure how this works for multi_period files) localWorkspace->mutableRun().setProtonCharge(iraw.rpb.r_gd_prtn_chrg); } else // We are working on a higher period of a multiperiod raw file { // Create a WorkspaceProperty for the new workspace of a higher period // The workspace name given in the OutputWorkspace property has _periodNumber appended to it // (for all but the first period, which has no suffix) std::stringstream suffix; suffix << (period+1); outputWorkspace += suffix.str(); std::string WSName = localWSName + "_" + suffix.str(); declareProperty(new WorkspaceProperty<DataObjects::Workspace2D>(outputWorkspace,WSName,Direction::Output)); g_log.information() << "Workspace " << WSName << " created. \n"; } if (localWorkspace) localWorkspace->updateSpectraUsingMap(); // Assign the result to the output workspace property setProperty(outputWorkspace,localWorkspace); } // loop over periods // Clean up delete[] timeChannels; delete[] spectrum; }
/** * Move the user selected spectra in the input workspace into groups in the output workspace * @param inputWS :: user selected input workspace for the algorithm * @param outputWS :: user selected output workspace for the algorithm * @param prog4Copy :: the amount of algorithm progress to attribute to moving a single spectra * @return number of new grouped spectra */ size_t GroupDetectors2::formGroups( API::MatrixWorkspace_const_sptr inputWS, API::MatrixWorkspace_sptr outputWS, const double prog4Copy) { // get "Behaviour" string const std::string behaviour = getProperty("Behaviour"); int bhv = 0; if ( behaviour == "Average" ) bhv = 1; API::MatrixWorkspace_sptr beh = API::WorkspaceFactory::Instance().create( "Workspace2D", static_cast<int>(m_GroupSpecInds.size()), 1, 1); g_log.debug() << name() << ": Preparing to group spectra into " << m_GroupSpecInds.size() << " groups\n"; // where we are copying spectra to, we start copying to the start of the output workspace size_t outIndex = 0; // Only used for averaging behaviour. We may have a 1:1 map where a Divide would be waste as it would be just dividing by 1 bool requireDivide(false); for ( storage_map::const_iterator it = m_GroupSpecInds.begin(); it != m_GroupSpecInds.end() ; ++it ) { // This is the grouped spectrum ISpectrum * outSpec = outputWS->getSpectrum(outIndex); // The spectrum number of the group is the key outSpec->setSpectrumNo(it->first); // Start fresh with no detector IDs outSpec->clearDetectorIDs(); // Copy over X data from first spectrum, the bin boundaries for all spectra are assumed to be the same here outSpec->dataX() = inputWS->readX(0); // the Y values and errors from spectra being grouped are combined in the output spectrum // Keep track of number of detectors required for masking size_t nonMaskedSpectra(0); beh->dataX(outIndex)[0] = 0.0; beh->dataE(outIndex)[0] = 0.0; for( std::vector<size_t>::const_iterator wsIter = it->second.begin(); wsIter != it->second.end(); ++wsIter) { const size_t originalWI = *wsIter; // detectors to add to firstSpecNum const ISpectrum * fromSpectrum = inputWS->getSpectrum(originalWI); // Add up all the Y spectra and store the result in the first one // Need to keep the next 3 lines inside loop for now until ManagedWorkspace mru-list works properly MantidVec &firstY = outSpec->dataY(); MantidVec::iterator fYit; MantidVec::iterator fEit = outSpec->dataE().begin(); MantidVec::const_iterator Yit = fromSpectrum->dataY().begin(); MantidVec::const_iterator Eit = fromSpectrum->dataE().begin(); for (fYit = firstY.begin(); fYit != firstY.end(); ++fYit, ++fEit, ++Yit, ++Eit) { *fYit += *Yit; // Assume 'normal' (i.e. Gaussian) combination of errors *fEit = std::sqrt( (*fEit)*(*fEit) + (*Eit)*(*Eit) ); } // detectors to add to the output spectrum outSpec->addDetectorIDs(fromSpectrum->getDetectorIDs() ); try { Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI); if( !det->isMasked() ) ++nonMaskedSpectra; } catch(Exception::NotFoundError&) { // If a detector cannot be found, it cannot be masked ++nonMaskedSpectra; } } if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero if(!requireDivide) requireDivide = (nonMaskedSpectra > 1); beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra); // make regular progress reports and check for cancelling the algorithm if ( outIndex % INTERVAL == 0 ) { m_FracCompl += INTERVAL*prog4Copy; if ( m_FracCompl > 1.0 ) m_FracCompl = 1.0; progress(m_FracCompl); interruption_point(); } outIndex ++; } // Refresh the spectraDetectorMap outputWS->generateSpectraMap(); if ( bhv == 1 && requireDivide ) { g_log.debug() << "Running Divide algorithm to perform averaging.\n"; Mantid::API::IAlgorithm_sptr divide = createChildAlgorithm("Divide"); divide->initialize(); divide->setProperty<API::MatrixWorkspace_sptr>("LHSWorkspace", outputWS); divide->setProperty<API::MatrixWorkspace_sptr>("RHSWorkspace", beh); divide->setProperty<API::MatrixWorkspace_sptr>("OutputWorkspace", outputWS); divide->execute(); } g_log.debug() << name() << " created " << outIndex << " new grouped spectra\n"; return outIndex; }
/** * Move the user selected spectra in the input workspace into groups in the output workspace * @param inputWS :: user selected input workspace for the algorithm * @param outputWS :: user selected output workspace for the algorithm * @param prog4Copy :: the amount of algorithm progress to attribute to moving a single spectra * @return number of new grouped spectra */ size_t GroupDetectors2::formGroupsEvent( DataObjects::EventWorkspace_const_sptr inputWS, DataObjects::EventWorkspace_sptr outputWS, const double prog4Copy) { // get "Behaviour" string const std::string behaviour = getProperty("Behaviour"); int bhv = 0; if ( behaviour == "Average" ) bhv = 1; API::MatrixWorkspace_sptr beh = API::WorkspaceFactory::Instance().create( "Workspace2D", static_cast<int>(m_GroupSpecInds.size()), 1, 1); g_log.debug() << name() << ": Preparing to group spectra into " << m_GroupSpecInds.size() << " groups\n"; // where we are copying spectra to, we start copying to the start of the output workspace size_t outIndex = 0; // Only used for averaging behaviour. We may have a 1:1 map where a Divide would be waste as it would be just dividing by 1 bool requireDivide(false); for ( storage_map::const_iterator it = m_GroupSpecInds.begin(); it != m_GroupSpecInds.end() ; ++it ) { // This is the grouped spectrum EventList & outEL = outputWS->getEventList(outIndex); // The spectrum number of the group is the key outEL.setSpectrumNo(it->first); // Start fresh with no detector IDs outEL.clearDetectorIDs(); // the Y values and errors from spectra being grouped are combined in the output spectrum // Keep track of number of detectors required for masking size_t nonMaskedSpectra(0); beh->dataX(outIndex)[0] = 0.0; beh->dataE(outIndex)[0] = 0.0; for( std::vector<size_t>::const_iterator wsIter = it->second.begin(); wsIter != it->second.end(); ++wsIter) { const size_t originalWI = *wsIter; const EventList & fromEL=inputWS->getEventList(originalWI); //Add the event lists with the operator outEL += fromEL; // detectors to add to the output spectrum outEL.addDetectorIDs(fromEL.getDetectorIDs() ); try { Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI); if( !det->isMasked() ) ++nonMaskedSpectra; } catch(Exception::NotFoundError&) { // If a detector cannot be found, it cannot be masked ++nonMaskedSpectra; } } if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero if(!requireDivide) requireDivide = (nonMaskedSpectra > 1); beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra); // make regular progress reports and check for cancelling the algorithm if ( outIndex % INTERVAL == 0 ) { m_FracCompl += INTERVAL*prog4Copy; if ( m_FracCompl > 1.0 ) m_FracCompl = 1.0; progress(m_FracCompl); interruption_point(); } outIndex ++; } // Refresh the spectraDetectorMap outputWS->doneAddingEventLists(); if ( bhv == 1 && requireDivide ) { g_log.debug() << "Running Divide algorithm to perform averaging.\n"; Mantid::API::IAlgorithm_sptr divide = createChildAlgorithm("Divide"); divide->initialize(); divide->setProperty<API::MatrixWorkspace_sptr>("LHSWorkspace", outputWS); divide->setProperty<API::MatrixWorkspace_sptr>("RHSWorkspace", beh); divide->setProperty<API::MatrixWorkspace_sptr>("OutputWorkspace", outputWS); divide->execute(); } g_log.debug() << name() << " created " << outIndex << " new grouped spectra\n"; return outIndex; }
/** Execute the algorithm. */ void MaxEnt::exec() { // MaxEnt parameters // Complex data? bool complex = getProperty("ComplexData"); // Image must be positive? bool positiveImage = getProperty("PositiveImage"); // Autoshift bool autoShift = getProperty("AutoShift"); // Increase the number of points in the image by this factor size_t densityFactor = getProperty("DensityFactor"); // Background (default level, sky background, etc) double background = getProperty("A"); // Chi target double chiTarget = getProperty("ChiTarget"); // Required precision for Chi arget double chiEps = getProperty("ChiEps"); // Maximum degree of non-parallelism between S and C double angle = getProperty("MaxAngle"); // Distance penalty for current image double distEps = getProperty("DistancePenalty"); // Maximum number of iterations size_t niter = getProperty("MaxIterations"); // Maximum number of iterations in alpha chop size_t alphaIter = getProperty("AlphaChopIterations"); // Number of spectra and datapoints // Read input workspace MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); // Number of spectra size_t nspec = inWS->getNumberHistograms(); // Number of data points size_t npoints = inWS->blocksize() * densityFactor; // Number of X bins size_t npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; // The type of entropy we are going to use (depends on the type of image, // positive only, or positive and/or negative) MaxentData_sptr maxentData; if (positiveImage) { maxentData = boost::make_shared<MaxentData>( boost::make_shared<MaxentEntropyPositiveValues>()); } else { maxentData = boost::make_shared<MaxentData>( boost::make_shared<MaxentEntropyNegativeValues>()); } // Output workspaces MatrixWorkspace_sptr outImageWS; MatrixWorkspace_sptr outDataWS; MatrixWorkspace_sptr outEvolChi; MatrixWorkspace_sptr outEvolTest; nspec = complex ? nspec / 2 : nspec; outImageWS = WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); outDataWS = WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); outEvolChi = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); outEvolTest = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); npoints *= 2; for (size_t s = 0; s < nspec; s++) { // Start distribution (flat background) std::vector<double> image(npoints, background); if (complex) { auto dataRe = inWS->readY(s); auto dataIm = inWS->readY(s + nspec); auto errorsRe = inWS->readE(s); auto errorsIm = inWS->readE(s + nspec); maxentData->loadComplex(dataRe, dataIm, errorsRe, errorsIm, image, background); } else { auto data = inWS->readY(s); auto error = inWS->readE(s); maxentData->loadReal(data, error, image, background); } // To record the algorithm's progress std::vector<double> evolChi(niter, 0.); std::vector<double> evolTest(niter, 0.); // Progress Progress progress(this, 0, 1, niter); // Run maxent algorithm for (size_t it = 0; it < niter; it++) { // Calculate quadratic model coefficients // (SB eq. 21 and 24) maxentData->calculateQuadraticCoefficients(); double currAngle = maxentData->getAngle(); double currChisq = maxentData->getChisq(); auto coeffs = maxentData->getQuadraticCoefficients(); // Calculate delta to construct new image (SB eq. 25) auto delta = move(coeffs, chiTarget / currChisq, chiEps, alphaIter); // Apply distance penalty (SB eq. 33) image = maxentData->getImage(); delta = applyDistancePenalty(delta, coeffs, image, background, distEps); // Update image according to 'delta' and calculate the new Chi-square maxentData->updateImage(delta); currChisq = maxentData->getChisq(); // Record the evolution of Chi-square and angle(S,C) evolChi[it] = currChisq; evolTest[it] = currAngle; // Stop condition, solution found if ((std::abs(currChisq / chiTarget - 1.) < chiEps) && (currAngle < angle)) { break; } // Check for canceling the algorithm if (!(it % 1000)) { interruption_point(); } progress.report(); } // iterations // Get calculated data auto solData = maxentData->getReconstructedData(); auto solImage = maxentData->getImage(); // Populate the output workspaces populateDataWS(inWS, s, nspec, solData, outDataWS); populateImageWS(inWS, s, nspec, solImage, outImageWS, autoShift); // Populate workspaces recording the evolution of Chi and Test // X values for (size_t it = 0; it < niter; it++) { outEvolChi->dataX(s)[it] = static_cast<double>(it); outEvolTest->dataX(s)[it] = static_cast<double>(it); } // Y values outEvolChi->dataY(s).assign(evolChi.begin(), evolChi.end()); outEvolTest->dataY(s).assign(evolTest.begin(), evolTest.end()); // No errors } // Next spectrum setProperty("EvolChi", outEvolChi); setProperty("EvolAngle", outEvolTest); setProperty("ReconstructedImage", outImageWS); setProperty("ReconstructedData", outDataWS); }
void GroupDetectors2::exec() { // Get the input workspace const MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); //Check if it is an event workspace const bool preserveEvents = getProperty("PreserveEvents"); EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (eventW != NULL && preserveEvents) { this->execEvent(); return; } const size_t numInHists = inputWS->getNumberHistograms(); // Bin boundaries need to be the same, so do the full check on whether they actually are if (!API::WorkspaceHelpers::commonBoundaries(inputWS)) { g_log.error() << "Can only group if the histograms have common bin boundaries\n"; throw std::invalid_argument("Can only group if the histograms have common bin boundaries"); } progress( m_FracCompl = CHECKBINS ); interruption_point(); // some values loaded into this vector can be negative so this needs to be a signed type std::vector<int64_t> unGroupedInds; //the ungrouped list could be very big but might be none at all unGroupedInds.reserve(numInHists); for( size_t i = 0; i < numInHists ; i++ ) { unGroupedInds.push_back(i); } // read in the input parameters to make that map, if KeepUngroupedSpectra was set we'll need a list of the ungrouped spectrra too getGroups(inputWS, unGroupedInds); // converting the list into a set gets rid of repeated values, here the multiple GroupDetectors2::USED become one USED at the start const std::set<int64_t> unGroupedSet(unGroupedInds.begin(), unGroupedInds.end()); // Check what the user asked to be done with ungrouped spectra const bool keepAll = getProperty("KeepUngroupedSpectra"); // ignore the one USED value in set or ignore all the ungrouped if the user doesn't want them const size_t numUnGrouped = keepAll ? unGroupedSet.size()-1 : 0; MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS, m_GroupSpecInds.size()+ numUnGrouped, inputWS->readX(0).size(), inputWS->blocksize()); // prepare to move the requested histograms into groups, first estimate how long for progress reporting. +1 in the demonator gets rid of any divide by zero risk double prog4Copy=( (1.0 - m_FracCompl)/(static_cast<double>(numInHists-unGroupedSet.size())+1.) )* (keepAll ? static_cast<double>(numInHists-unGroupedSet.size())/static_cast<double>(numInHists): 1.); // Build a new map const size_t outIndex = formGroups(inputWS, outputWS, prog4Copy); // If we're keeping ungrouped spectra if (keepAll) { // copy them into the output workspace moveOthers(unGroupedSet, inputWS, outputWS, outIndex); } g_log.information() << name() << " algorithm has finished\n"; setProperty("OutputWorkspace",outputWS); }
/** Executes the rebin algorithm * * @throw runtime_error Thrown if */ void Rebunch::exec() { // retrieve the properties int n_bunch=getProperty("NBunch"); // Get the input workspace MatrixWorkspace_const_sptr inputW = getProperty("InputWorkspace"); bool dist = inputW->isDistribution(); // workspace independent determination of length int histnumber = static_cast<int>(inputW->size()/inputW->blocksize()); /* const std::vector<double>& Xold = inputW->readX(0); const std::vector<double>& Yold = inputW->readY(0); int size_x=Xold.size(); int size_y=Yold.size(); */ int size_x = static_cast<int>(inputW->readX(0).size()); int size_y = static_cast<int>(inputW->readY(0).size()); //signal is the same length for histogram and point data int ny=(size_y/n_bunch); if(size_y%n_bunch >0)ny+=1; // default is for hist int nx=ny+1; bool point=false; if (size_x==size_y) { point=true; nx=ny; } // make output Workspace the same type is the input, but with new length of signal array API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(inputW,histnumber,nx,ny); int progress_step = histnumber / 100; if (progress_step == 0) progress_step = 1; PARALLEL_FOR2(inputW,outputW) for (int hist=0; hist < histnumber;hist++) { PARALLEL_START_INTERUPT_REGION // Ensure that axis information are copied to the output workspace if the axis exists try { outputW->getAxis(1)->spectraNo(hist)=inputW->getAxis(1)->spectraNo(hist); } catch( Exception::IndexError& ) { // Not a Workspace2D } // get const references to input Workspace arrays (no copying) const MantidVec& XValues = inputW->readX(hist); const MantidVec& YValues = inputW->readY(hist); const MantidVec& YErrors = inputW->readE(hist); //get references to output workspace data (no copying) MantidVec& XValues_new=outputW->dataX(hist); MantidVec& YValues_new=outputW->dataY(hist); MantidVec& YErrors_new=outputW->dataE(hist); // output data arrays are implicitly filled by function if(point) { rebunch_point(XValues,YValues,YErrors,XValues_new,YValues_new,YErrors_new,n_bunch); } else { rebunch_hist(XValues,YValues,YErrors,XValues_new,YValues_new,YErrors_new,n_bunch, dist); } if (hist % progress_step == 0) { progress(double(hist)/histnumber); interruption_point(); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputW->isDistribution(dist); // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError&) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); return; }