/** Write out all of the event lists in the given workspace * @param ws :: an EventWorkspace */ int NexusFileIO::writeNexusProcessedDataEvent( const DataObjects::EventWorkspace_const_sptr& ws) { //write data entry NXstatus status=NXmakegroup(fileID,"event_workspace","NXdata"); if(status==NX_ERROR) return(2); NXopengroup(fileID,"event_workspace","NXdata"); for (size_t wi=0; wi < ws->getNumberHistograms(); wi++) { std::ostringstream group_name; group_name << "event_list_" << wi; this->writeEventList( ws->getEventList(wi), group_name.str()); } // Close up the overall group status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }
void ConvertToMatrixWorkspace::exec() { MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace"); // Let's see if we have to do anything first. Basically we want to avoid the data copy if we can DataObjects::EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>(inputWorkspace); MatrixWorkspace_sptr outputWorkspace; if( eventW ) { g_log.information() << "Converting EventWorkspace to Workspace2D.\n"; const size_t numHists = inputWorkspace->getNumberHistograms(); Progress prog(this,0.0,1.0,numHists*2); // Sort the input workspace in-place by TOF. This can be faster if there are few event lists. eventW->sortAll(TOF_SORT, &prog); // Create the output workspace. This will copy many aspects fron the input one. outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace); // ...but not the data, so do that here. PARALLEL_FOR2(inputWorkspace,outputWorkspace) for (int64_t i = 0; i < (int64_t)numHists; ++i) { PARALLEL_START_INTERUPT_REGION const ISpectrum * inSpec = inputWorkspace->getSpectrum(i); ISpectrum * outSpec = outputWorkspace->getSpectrum(i); outSpec->copyInfoFrom(*inSpec); outSpec->setX(inSpec->ptrX()); outSpec->dataY() = inSpec->dataY(); outSpec->dataE() = inSpec->dataE(); prog.report("Binning"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWorkspace->generateSpectraMap(); } else {
/** Write out a combined chunk of event data * * @param ws :: an EventWorkspace * @param indices :: array of event list indexes * @param tofs :: array of TOFs * @param weights :: array of event weights * @param errorSquareds :: array of event squared errors * @param pulsetimes :: array of pulsetimes * @param compress :: if true, compress the entry */ int NexusFileIO::writeNexusProcessedDataEventCombined( const DataObjects::EventWorkspace_const_sptr& ws, std::vector<int64_t> & indices, double * tofs, float * weights, float * errorSquareds, int64_t * pulsetimes, bool compress) const { NXopengroup(fileID,"event_workspace","NXdata"); // The array of indices for each event list # int dims_array[1] = { static_cast<int>(indices.size()) }; if (indices.size() > 0) { if (compress) NXcompmakedata(fileID, "indices", NX_INT64, 1, dims_array, m_nexuscompression, dims_array); else NXmakedata(fileID, "indices", NX_INT64, 1, dims_array); NXopendata(fileID, "indices"); NXputdata(fileID, (void*)(indices.data()) ); std::string yUnits=ws->YUnit(); std::string yUnitLabel=ws->YUnitLabel(); NXputattr (fileID, "units", reinterpret_cast<void*>(const_cast<char*>(yUnits.c_str())), static_cast<int>(yUnits.size()), NX_CHAR); NXputattr (fileID, "unit_label", reinterpret_cast<void*>(const_cast<char*>(yUnitLabel.c_str())), static_cast<int>(yUnitLabel.size()), NX_CHAR); NXclosedata(fileID); } // Write out each field dims_array[0] = static_cast<int>(indices.back()); // TODO big truncation error! This is the # of events if (tofs) NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress); if (pulsetimes) NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress); if (weights) NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress); if (errorSquareds) NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress); // Close up the overall group NXstatus status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }
/** * 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::moveOthersEvent(const std::set<int64_t> &unGroupedSet, DataObjects::EventWorkspace_const_sptr inputWS, DataObjects::EventWorkspace_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 EventList & inputSpec = inputWS->getEventList(sourceIndex); // Destination of the copying EventList & outputSpec=outputWS->getEventList(outIndex); // Copy the data outputSpec+=inputSpec; // 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->doneAddingEventLists(); g_log.debug() << name() << " copied " << unGroupedSet.size()-1 << " ungrouped spectra\n"; }
/** * Create an output EventWorkspace w/o any events */ DataObjects::EventWorkspace_sptr CountEventsInPulses::createEventWorkspace( DataObjects::EventWorkspace_const_sptr parentws, bool sumspectrum) { size_t numspec; bool diffsize; if (sumspectrum) { numspec = 1; diffsize = true; } else { numspec = parentws->getNumberHistograms(); diffsize = false; } DataObjects::EventWorkspace_sptr outputWS = boost::dynamic_pointer_cast<DataObjects::EventWorkspace>( API::WorkspaceFactory::Instance().create("EventWorkspace", numspec, 1, 1)); API::WorkspaceFactory::Instance().initializeFromParent(parentws, outputWS, diffsize); outputWS->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Time"); return outputWS; }
/** * 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; }
/** Executes the algorithm */ void FilterByTime2::exec() { DataObjects::EventWorkspace_const_sptr inWS = this->getProperty("InputWorkspace"); if (!inWS) { g_log.error() << "Input is not EventWorkspace" << std::endl; throw std::invalid_argument("Input is not EventWorksapce"); } else { g_log.debug() << "DB5244 InputWorkspace Name = " << inWS->getName() << std::endl; } double starttime = this->getProperty("StartTime"); double stoptime = this->getProperty("StopTime"); std::string absstarttime = this->getProperty("AbsoluteStartTime"); std::string absstoptime = this->getProperty("AbsoluteStopTime"); std::string start, stop; if ((absstarttime != "") && (absstoptime != "") && (starttime <= 0.0) && (stoptime <= 0.0)) { // Use the absolute string start = absstarttime; stop = absstoptime; } else if ((absstarttime != "" || absstoptime != "") && (starttime > 0.0 || stoptime > 0.0)) { throw std::invalid_argument( "It is not allowed to provide both absolute time and relative time."); } else { // Use second std::stringstream ss; ss << starttime; start = ss.str(); std::stringstream ss2; ss2 << stoptime; stop = ss2.str(); } // 1. Generate Filters g_log.debug() << "\nDB441: About to generate Filter. StartTime = " << starttime << " StopTime = " << stoptime << std::endl; API::Algorithm_sptr genfilter = createChildAlgorithm("GenerateEventsFilter", 0.0, 20.0, true, 1); genfilter->initialize(); genfilter->setPropertyValue("InputWorkspace", inWS->getName()); genfilter->setPropertyValue("OutputWorkspace", "FilterWS"); genfilter->setProperty("StartTime", start); genfilter->setProperty("StopTime", stop); genfilter->setProperty("UnitOfTime", "Seconds"); genfilter->setProperty("FastLog", false); bool sucgen = genfilter->execute(); if (!sucgen) { g_log.error() << "Unable to generate event filters" << std::endl; throw std::runtime_error("Unable to generate event filters"); } else { g_log.debug() << "Filters are generated. " << std::endl; } API::Workspace_sptr filterWS = genfilter->getProperty("OutputWorkspace"); if (!filterWS) { g_log.error() << "Unable to retrieve generated SplittersWorkspace object " "from AnalysisDataService." << std::endl; throw std::runtime_error("Unable to retrieve Splittersworkspace. "); } // 2. Filter events g_log.debug() << "\nAbout to filter events. " << "\n"; API::Algorithm_sptr filter = createChildAlgorithm("FilterEvents", 20.0, 100.0, true, 1); filter->initialize(); filter->setPropertyValue("InputWorkspace", inWS->getName()); filter->setPropertyValue("OutputWorkspaceBaseName", "ResultWS"); filter->setProperty("SplitterWorkspace", filterWS); filter->setProperty("FilterByPulseTime", true); bool sucfilt = filter->execute(); if (!sucfilt) { g_log.error() << "Unable to filter events" << std::endl; throw std::runtime_error("Unable to filter events"); } else { g_log.debug() << "Filter events is successful. " << std::endl; } DataObjects::EventWorkspace_sptr optws = filter->getProperty("OutputWorkspace_0"); this->setProperty("OutputWorkspace", optws); }
/** Check whether 2 event lists are identical */ bool CompareWorkspaces::compareEventWorkspaces( DataObjects::EventWorkspace_const_sptr ews1, DataObjects::EventWorkspace_const_sptr ews2) { bool checkallspectra = getProperty("CheckAllData"); int numspec2print = getProperty("NumberMismatchedSpectraToPrint"); int wsindex2print = getProperty("DetailedPrintIndex"); // Compare number of spectra if (ews1->getNumberHistograms() != ews2->getNumberHistograms()) { recordMismatch("Mismatched number of histograms."); return false; } if (ews1->getEventType() != ews2->getEventType()) { recordMismatch("Mismatched type of events in the EventWorkspaces."); return false; } // Both will end up sorted anyway ews1->sortAll(PULSETIMETOF_SORT, m_Prog); ews2->sortAll(PULSETIMETOF_SORT, m_Prog); // Determine the tolerance for "tof" attribute and "weight" of events double toleranceWeight = Tolerance; // Standard tolerance int64_t tolerancePulse = 1; double toleranceTOF = 0.05; if ((ews1->getAxis(0)->unit()->label().ascii() != "microsecond") || (ews2->getAxis(0)->unit()->label().ascii() != "microsecond")) { g_log.warning() << "Event workspace has unit as " << ews1->getAxis(0)->unit()->label().ascii() << " and " << ews2->getAxis(0)->unit()->label().ascii() << ". Tolerance of TOF is set to 0.05 still. " << "\n"; toleranceTOF = 0.05; } g_log.notice() << "TOF Tolerance = " << toleranceTOF << "\n"; bool mismatchedEvent = false; int mismatchedEventWI = 0; size_t numUnequalNumEventsSpectra = 0; size_t numUnequalEvents = 0; size_t numUnequalTOFEvents = 0; size_t numUnequalPulseEvents = 0; size_t numUnequalBothEvents = 0; std::vector<int> vec_mismatchedwsindex; PARALLEL_FOR_IF(m_ParallelComparison && ews1->threadSafe() && ews2->threadSafe()) for (int i = 0; i < static_cast<int>(ews1->getNumberHistograms()); ++i) { PARALLEL_START_INTERUPT_REGION m_Prog->report("EventLists"); if (!mismatchedEvent || checkallspectra) // This guard will avoid checking unnecessarily { const EventList &el1 = ews1->getEventList(i); const EventList &el2 = ews2->getEventList(i); bool printdetail = (i == wsindex2print); if (printdetail) { g_log.information() << "Spectrum " << i << " is set to print out in details. " << "\n"; } if (!el1.equals(el2, toleranceTOF, toleranceWeight, tolerancePulse)) { size_t tempNumTof = 0; size_t tempNumPulses = 0; size_t tempNumBoth = 0; int tempNumUnequal = 0; if (el1.getNumberEvents() != el2.getNumberEvents()) { // Number of events are different tempNumUnequal = -1; } else { tempNumUnequal = compareEventsListInDetails( el1, el2, toleranceTOF, toleranceWeight, tolerancePulse, printdetail, tempNumPulses, tempNumTof, tempNumBoth); } mismatchedEvent = true; mismatchedEventWI = i; PARALLEL_CRITICAL(CompareWorkspaces) { if (tempNumUnequal == -1) { // 2 spectra have different number of events ++numUnequalNumEventsSpectra; } else { // 2 spectra have some events different to each other numUnequalEvents += static_cast<size_t>(tempNumUnequal); numUnequalTOFEvents += tempNumTof; numUnequalPulseEvents += tempNumPulses; numUnequalBothEvents += tempNumBoth; } vec_mismatchedwsindex.push_back(i); } // Parallel critical region } // If elist 1 is not equal to elist 2 } PARALLEL_END_INTERUPT_REGION }
//---------------------------------------------------------------------------------------------- /// @copydoc Mantid::API::Algorithm::exec() void ResetNegatives::exec() { MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace"); MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace"); // get the minimum for each spectrum IAlgorithm_sptr alg = this->createChildAlgorithm("Min", 0., .1); alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS); alg->executeAsChildAlg(); MatrixWorkspace_const_sptr minWS = alg->getProperty("OutputWorkspace"); // determine if there is anything to do int64_t nHist = static_cast<int64_t>(minWS->getNumberHistograms()); bool hasNegative = false; for (int64_t i = 0; i < nHist; i++) { if (minWS->readY(i)[0] < 0) { hasNegative = true; } break; } // get out early if there is nothing to do if (!hasNegative) { g_log.information() << "No values are negative. Copying InputWorkspace to OutputWorkspace\n"; if (inputWS != outputWS) { IAlgorithm_sptr alg = this->createChildAlgorithm("CloneWorkspace", .1, 1.); alg->setProperty<Workspace_sptr>("InputWorkspace", inputWS); alg->executeAsChildAlg(); Workspace_sptr temp = alg->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(temp)); } return; } // sort the event list to make it fast and thread safe DataObjects::EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const DataObjects::EventWorkspace>( inputWS ); if (eventWS) eventWS->sortAll(DataObjects::TOF_SORT, NULL); Progress prog(this, .1, 1., 2*nHist); // generate output workspace - copy X and dY outputWS = API::WorkspaceFactory::Instance().create(inputWS); PARALLEL_FOR2(inputWS,outputWS) for (int64_t i = 0; i < nHist; i++) { PARALLEL_START_INTERUPT_REGION outputWS->dataY(i) = inputWS->readY(i); outputWS->dataE(i) = inputWS->readE(i); outputWS->setX(i, inputWS->refX(i)); // share the pointer more prog.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // do the actual work if (this->getProperty("AddMinimum")) { this->pushMinimum(minWS, outputWS, prog); } else { this->changeNegatives(minWS, this->getProperty("ResetValue"), outputWS, prog); } setProperty("OutputWorkspace",outputWS); }