void LoadDNSSCD::updateProperties(API::Run &run, std::map<std::string, T> &metadata, std::string time) { typename std::map<std::string, T>::iterator it = metadata.begin(); while (it != metadata.end()) { TimeSeriesProperty<T> *timeSeries(nullptr); std::string name(it->first); std::string units; // std::regex does not work for rhel7, thus boost boost::regex reg("([-_a-zA-Z]+)\\[(.*)]"); boost::smatch match; if (boost::regex_search(name, match, reg) && match.size() > 2) { std::string new_name(match.str(1)); units.assign(match.str(2)); name = new_name; } if (run.hasProperty(name)) { timeSeries = dynamic_cast<TimeSeriesProperty<T> *>(run.getLogData(name)); if (!timeSeries) throw std::invalid_argument( "Log '" + name + "' already exists but the values are a different type."); } else { timeSeries = new TimeSeriesProperty<T>(name); if (!units.empty()) timeSeries->setUnits(units); run.addProperty(timeSeries); } timeSeries->addValue(time, it->second); ++it; } }
/** * Get a value from one of a set of logs. * @param run * @param propName * @return */ double PDDetermineCharacterizations::getLogValue(API::Run &run, const std::string &propName) { std::vector<std::string> names = getProperty(propName); std::string label = "frequency"; if (propName == WL_PROP_NAME) label = "wavelength"; std::unordered_set<std::string> validUnits; if (propName == WL_PROP_NAME) { validUnits.insert("Angstrom"); validUnits.insert("A"); } else { validUnits.insert("Hz"); } for (auto &name : names) { if (run.hasProperty(name)) { const std::string units = run.getProperty(name)->units(); if (validUnits.find(units) != validUnits.end()) { double value = run.getLogAsSingleValue(name); if (value == 0.) { std::stringstream msg; msg << "'" << name << "' has a mean value of zero " << units; g_log.information(msg.str()); } else { std::stringstream msg; msg << "Found " << label << " in log '" << name << "' with mean value " << value << " " << units; g_log.information(msg.str()); return value; } } else { std::stringstream msg; msg << "When looking at " << name << " log encountered unknown units '" << units << "' for " << label << ":" << units; g_log.warning(msg.str()); } } } g_log.warning("Failed to determine " + label); return 0.; }
/** Get run start time from the target workspace to add the property * @brief AddSampleLog::getRunStart * @param run_obj * @return */ Types::Core::DateAndTime AddSampleLog::getRunStart(API::Run &run_obj) { // TODO/ISSUE/NOW - data ws should be the target workspace with run_start or // proton_charge property! Types::Core::DateAndTime runstart(0); try { runstart = run_obj.startTime(); } catch (std::runtime_error &) { // Swallow the error - startTime will just be 0 } return runstart; }
/** * Load an ISIS log file into the local workspace. * @param logFileStream :: The stream of the log file (data). * @param logFileName :: The name of the log file to load. * @param run :: The run information object */ void LoadLog::loadTwoColumnLogFile(std::ifstream& logFileStream, std::string logFileName, API::Run& run) { if (!logFileStream) { throw std::invalid_argument("Unable to open file " + m_filename); } // figure out if second column is a number or a string std::string aLine; if( Mantid::Kernel::Strings::extractToEOL(logFileStream,aLine) ) { if ( !isDateTimeString(aLine) ) { throw std::invalid_argument("File" + m_filename + " is not a standard ISIS log file. Expected to be a two column file."); } std::string DateAndTime; std::stringstream ins(aLine); ins >> DateAndTime; // read in what follows the date-time string in the log file and figure out what type it is std::string whatType; ins >> whatType; kind l_kind = classify(whatType); if (LoadLog::string != l_kind && LoadLog::number != l_kind) { throw std::invalid_argument("ISIS log file contains unrecognised second column entries: " + m_filename); } try { Property* log = LogParser::createLogProperty(m_filename,stringToLower(logFileName)); if (log) { run.addLogData(log); } } catch(std::exception&) { } } }
/** * reads the .log stream and creates timeseries property and sets that to the run object * @param logFileStream :: The stream of the log file (data). * @param logFileName :: The name of the log file to load. * @param run :: The run information object */ void LoadLog::loadThreeColumnLogFile(std::ifstream& logFileStream, std::string logFileName, API::Run& run) { std::string str; std::string propname; Mantid::Kernel::TimeSeriesProperty<double>* logd = 0; Mantid::Kernel::TimeSeriesProperty<std::string>* logs = 0; std::map<std::string,Kernel::TimeSeriesProperty<double>*> dMap; std::map<std::string,Kernel::TimeSeriesProperty<std::string>*> sMap; typedef std::pair<std::string,Kernel::TimeSeriesProperty<double>* > dpair; typedef std::pair<std::string,Kernel::TimeSeriesProperty<std::string>* > spair; kind l_kind(LoadLog::empty); bool isNumeric(false); if (!logFileStream) { throw std::invalid_argument("Unable to open file " + m_filename); } while(Mantid::Kernel::Strings::extractToEOL(logFileStream,str)) { if ( !isDateTimeString(str) ) { throw std::invalid_argument("File" + logFileName + " is not a standard ISIS log file. Expected to be a file starting with DateTime String format."); } if (!Kernel::TimeSeriesProperty<double>::isTimeString(str) || (str[0]=='#')) { //if the line doesn't start with a time read the next line continue; } std::stringstream line(str); std::string timecolumn; line >> timecolumn; std::string blockcolumn; line >> blockcolumn; l_kind = classify(blockcolumn); if ( LoadLog::string != l_kind ) { throw std::invalid_argument("ISIS log file contains unrecognised second column entries:" + logFileName); } std::string valuecolumn; line >> valuecolumn; l_kind = classify(valuecolumn); if ( LoadLog::string != l_kind && LoadLog::number != l_kind) { continue; //no value defined, just skip this entry } // column two in .log file is called block column propname = stringToLower(blockcolumn); //check if the data is numeric std::istringstream istr(valuecolumn); double dvalue; istr >> dvalue; isNumeric = !istr.fail(); if (isNumeric) { std::map<std::string,Kernel::TimeSeriesProperty<double>*>::iterator ditr = dMap.find(propname); if(ditr != dMap.end()) { Kernel::TimeSeriesProperty<double>* prop = ditr->second; if (prop) prop->addValue(timecolumn,dvalue); } else { logd = new Kernel::TimeSeriesProperty<double>(propname); logd->addValue(timecolumn,dvalue); dMap.insert(dpair(propname,logd)); } } else { std::map<std::string,Kernel::TimeSeriesProperty<std::string>*>::iterator sitr = sMap.find(propname); if(sitr != sMap.end()) { Kernel::TimeSeriesProperty<std::string>* prop = sitr->second; if (prop) prop->addValue(timecolumn,valuecolumn); } else { logs = new Kernel::TimeSeriesProperty<std::string>(propname); logs->addValue(timecolumn,valuecolumn); sMap.insert(spair(propname,logs)); } } } try { std::map<std::string,Kernel::TimeSeriesProperty<double>*>::const_iterator itr = dMap.begin(); for(;itr != dMap.end(); ++itr) { run.addLogData(itr->second); } std::map<std::string,Kernel::TimeSeriesProperty<std::string>*>::const_iterator sitr = sMap.begin(); for(;sitr!=sMap.end();++sitr) { run.addLogData(sitr->second); } } catch(std::invalid_argument &e) { g_log.warning() << e.what(); } catch(Exception::ExistsError&e) { g_log.warning() << e.what(); } }
/** * Recursively add properties from a nexus file to * the workspace run. * * @param nxfileID :: Nexus file handle to be parsed, just after an NXopengroup * @param runDetails :: where to add properties * @param parent_name :: nexus caller name * @param parent_class :: nexus caller class * @param level :: current level in nexus tree * */ void LoadHelper::recurseAndAddNexusFieldsToWsRun(NXhandle nxfileID, API::Run& runDetails, std::string& parent_name, std::string& parent_class, int level) { std::string indent_str(level * 2, ' '); // Two space by indent level // Link ? // Attributes ? // Classes NXstatus getnextentry_status; ///< return status int datatype; ///< NX data type if a dataset, e.g. NX_CHAR, NX_FLOAT32, see napi.h char nxname[NX_MAXNAMELEN], nxclass[NX_MAXNAMELEN]; nxname[0] = '0'; nxclass[0] = '0'; bool has_entry = true; // follows getnextentry_status while (has_entry) { getnextentry_status = NXgetnextentry(nxfileID, nxname, nxclass, &datatype); if (getnextentry_status == NX_OK) { g_log.debug() << indent_str << parent_name << "." << nxname << " ; " << nxclass << std::endl; NXstatus opengroup_status; NXstatus opendata_status; if ((opengroup_status = NXopengroup(nxfileID, nxname, nxclass)) == NX_OK) { // Go down to one level std::string p_nxname(nxname); //current names can be useful for next level std::string p_nxclass(nxclass); recurseAndAddNexusFieldsToWsRun(nxfileID, runDetails, p_nxname, p_nxclass, level + 1); NXclosegroup(nxfileID); } // if(NXopengroup else if ((opendata_status = NXopendata(nxfileID, nxname)) == NX_OK) { //dump_attributes(nxfileID, indent_str); g_log.debug() << indent_str << nxname << " opened." << std::endl; if (parent_class == "NXData" || parent_class == "NXMonitor" || std::string(nxname) == "data") { g_log.debug() << indent_str << "skipping " << parent_class << " (" << nxname << ")" << std::endl; /* nothing */ } else { // create a property int rank; int dims[4]; int type; dims[0] = dims[1] = dims[2] = dims[3] = 0; std::string property_name = (parent_name.empty() ? nxname : parent_name + "." + nxname); g_log.debug() << indent_str << "considering property " << property_name << std::endl; // Get the value NXgetinfo(nxfileID, &rank, dims, &type); // Note, we choose to only build properties on small float arrays // filter logic is below bool build_small_float_array = false; // default if ((type == NX_FLOAT32) || (type == NX_FLOAT64)) { if ((rank == 1) && (dims[0] <= 9)) { build_small_float_array = true; } else { g_log.debug() << indent_str << "ignored multi dimension float data on " << property_name << std::endl; } } else if (type != NX_CHAR) { if ((rank != 1) || (dims[0] != 1) || (dims[1] != 1) || (dims[2] != 1) || (dims[3] != 1)) { g_log.debug() << indent_str << "ignored multi dimension data on " << property_name << std::endl; } } void *dataBuffer; NXmalloc(&dataBuffer, rank, dims, type); if (NXgetdata(nxfileID, dataBuffer) != NX_OK) { NXfree(&dataBuffer); throw std::runtime_error("Cannot read data from NeXus file"); } if (type == NX_CHAR) { std::string property_value((const char *) dataBuffer); if (boost::algorithm::ends_with(property_name, "_time")) { // That's a time value! Convert to Mantid standard property_value = dateTimeInIsoFormat(property_value); } runDetails.addProperty(property_name, property_value); } else if ((type == NX_FLOAT32) || (type == NX_FLOAT64) || (type == NX_INT16) || (type == NX_INT32) || (type == NX_UINT16)) { // Look for "units" NXstatus units_status; char units_sbuf[NX_MAXNAMELEN]; int units_len = NX_MAXNAMELEN; int units_type = NX_CHAR; units_status = NXgetattr(nxfileID, const_cast<char*>("units"), (void *) units_sbuf, &units_len, &units_type); if (units_status != NX_ERROR) { g_log.debug() << indent_str << "[ " << property_name << " has unit " << units_sbuf << " ]" << std::endl; } if ((type == NX_FLOAT32) || (type == NX_FLOAT64)) { // Mantid numerical properties are double only. double property_double_value = 0.0; // Simple case, one value if (dims[0] == 1) { if (type == NX_FLOAT32) { property_double_value = *((float*) dataBuffer); } else if (type == NX_FLOAT64) { property_double_value = *((double*) dataBuffer); } if (units_status != NX_ERROR) runDetails.addProperty(property_name, property_double_value, std::string(units_sbuf)); else runDetails.addProperty(property_name, property_double_value); } else if (build_small_float_array) { // An array, converted to "name_index", with index < 10 (see test above) for (int dim_index = 0; dim_index < dims[0]; dim_index++) { if (type == NX_FLOAT32) { property_double_value = ((float*) dataBuffer)[dim_index]; } else if (type == NX_FLOAT64) { property_double_value = ((double*) dataBuffer)[dim_index]; } std::string indexed_property_name = property_name + std::string("_") + boost::lexical_cast<std::string>(dim_index); if (units_status != NX_ERROR) runDetails.addProperty(indexed_property_name, property_double_value, std::string(units_sbuf)); else runDetails.addProperty(indexed_property_name, property_double_value); } } } else { // int case int property_int_value = 0; if (type == NX_INT16) { property_int_value = *((short int*) dataBuffer); } else if (type == NX_INT32) { property_int_value = *((int*) dataBuffer); } else if (type == NX_UINT16) { property_int_value = *((short unsigned int*) dataBuffer); } if (units_status != NX_ERROR) runDetails.addProperty(property_name, property_int_value, std::string(units_sbuf)); else runDetails.addProperty(property_name, property_int_value); } // if (type==... } else { g_log.debug() << indent_str << "unexpected data on " << property_name << std::endl; } // test on nxdata type NXfree(&dataBuffer); dataBuffer = NULL; } // if (parent_class == "NXData" || parent_class == "NXMonitor") else NXclosedata(nxfileID); } else { g_log.debug() << indent_str << "unexpected status (" << opendata_status << ") on " << nxname << std::endl; } } else if (getnextentry_status == NX_EOD) { g_log.debug() << indent_str << "End of Dir" << std::endl; has_entry = false; // end of loop } else { g_log.debug() << indent_str << "unexpected status (" << getnextentry_status << ")" << std::endl; has_entry = false; // end of loop } } // while } // recurseAndAddNexusFieldsToWsRun
void vtkDataSetToNonOrthogonalDataSet::execute() { // Downcast to a vtkUnstructuredGrid vtkUnstructuredGrid *data = vtkUnstructuredGrid::SafeDownCast(m_dataSet); if (NULL == data) { throw std::runtime_error("VTK dataset does not inherit from vtkPointSet"); } // Get the workspace from the ADS ADSWorkspaceProvider<API::IMDWorkspace> workspaceProvider; API::Workspace_sptr ws = workspaceProvider.fetchWorkspace(m_wsName); std::string wsType = ws->id(); Geometry::OrientedLattice oLatt; std::vector<double> wMatArr; Kernel::Matrix<coord_t> affMat; // Have to cast since inherited class doesn't provide access to all info if (boost::algorithm::find_first(wsType, "MDHistoWorkspace")) { API::IMDHistoWorkspace_const_sptr infoWs = boost::dynamic_pointer_cast<const API::IMDHistoWorkspace>(ws); m_boundingBox[0] = infoWs->getDimension(0)->getMinimum(); m_boundingBox[1] = infoWs->getDimension(0)->getMaximum(); m_boundingBox[2] = infoWs->getDimension(1)->getMinimum(); m_boundingBox[3] = infoWs->getDimension(1)->getMaximum(); m_boundingBox[4] = infoWs->getDimension(2)->getMinimum(); m_boundingBox[5] = infoWs->getDimension(2)->getMaximum(); m_numDims = infoWs->getNumDims(); m_coordType = infoWs->getSpecialCoordinateSystem(); if (Kernel::HKL != m_coordType) { throw std::invalid_argument( "Cannot create non-orthogonal view for non-HKL coordinates"); } const API::Sample sample = infoWs->getExperimentInfo(0)->sample(); if (!sample.hasOrientedLattice()) { throw std::invalid_argument( "OrientedLattice is not present on workspace"); } oLatt = sample.getOrientedLattice(); const API::Run run = infoWs->getExperimentInfo(0)->run(); if (!run.hasProperty("W_MATRIX")) { throw std::invalid_argument("W_MATRIX is not present on workspace"); } wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX"); try { API::CoordTransform const * transform = infoWs->getTransformToOriginal(); affMat = transform->makeAffineMatrix(); } catch (std::runtime_error &) { // Create identity matrix of dimension+1 std::size_t nDims = infoWs->getNumDims() + 1; Kernel::Matrix<coord_t> temp(nDims, nDims, true); affMat = temp; } } // This is only here to make the unit test run. if (boost::algorithm::find_first(wsType, "MDEventWorkspace")) { API::IMDEventWorkspace_const_sptr infoWs = boost::dynamic_pointer_cast<const API::IMDEventWorkspace>(ws); m_numDims = infoWs->getNumDims(); m_coordType = infoWs->getSpecialCoordinateSystem(); if (Kernel::HKL != m_coordType) { throw std::invalid_argument( "Cannot create non-orthogonal view for non-HKL coordinates"); } const API::Sample sample = infoWs->getExperimentInfo(0)->sample(); if (!sample.hasOrientedLattice()) { throw std::invalid_argument( "OrientedLattice is not present on workspace"); } oLatt = sample.getOrientedLattice(); const API::Run run = infoWs->getExperimentInfo(0)->run(); if (!run.hasProperty("W_MATRIX")) { throw std::invalid_argument("W_MATRIX is not present on workspace"); } wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX"); try { API::CoordTransform const *transform = infoWs->getTransformToOriginal(); affMat = transform->makeAffineMatrix(); } catch (std::runtime_error &) { // Create identity matrix of dimension+1 std::size_t nDims = infoWs->getNumDims() + 1; Kernel::Matrix<coord_t> temp(nDims, nDims, true); affMat = temp; } } Kernel::DblMatrix wTrans(wMatArr); this->createSkewInformation(oLatt, wTrans, affMat); // Get the original points vtkPoints *points = data->GetPoints(); double outPoint[3]; vtkPoints *newPoints = vtkPoints::New(); newPoints->Allocate(points->GetNumberOfPoints()); /// Put together the skew matrix for use double skew[9]; // Create from the internal skew matrix std::size_t index = 0; for (std::size_t i = 0; i < m_skewMat.numRows(); i++) { for (std::size_t j = 0; j < m_skewMat.numCols(); j++) { skew[index] = m_skewMat[i][j]; index++; } } for (int i = 0; i < points->GetNumberOfPoints(); i++) { double *inPoint = points->GetPoint(i); vtkMatrix3x3::MultiplyPoint(skew, inPoint, outPoint); newPoints->InsertNextPoint(outPoint); } data->SetPoints(newPoints); this->updateMetaData(data); }
void vtkDataSetToNonOrthogonalDataSet::execute() { // Downcast to a vtkPointSet vtkPointSet *data = vtkPointSet::SafeDownCast(m_dataSet); if (NULL == data) { throw std::runtime_error("VTK dataset does not inherit from vtkPointSet"); } // Get the workspace from the ADS ADSWorkspaceProvider<API::IMDWorkspace> workspaceProvider; API::Workspace_sptr ws = workspaceProvider.fetchWorkspace(m_wsName); std::string wsType = ws->id(); Geometry::OrientedLattice oLatt; std::vector<double> wMatArr; Kernel::Matrix<coord_t> affMat; // Have to cast since inherited class doesn't provide access to all info if (boost::algorithm::find_first(wsType, "MDHistoWorkspace")) { API::IMDHistoWorkspace_const_sptr infoWs = boost::dynamic_pointer_cast<const API::IMDHistoWorkspace>(ws); m_boundingBox[0] = infoWs->getXDimension()->getMinimum(); m_boundingBox[1] = infoWs->getXDimension()->getMaximum(); m_boundingBox[2] = infoWs->getYDimension()->getMinimum(); m_boundingBox[3] = infoWs->getYDimension()->getMaximum(); m_boundingBox[4] = infoWs->getZDimension()->getMinimum(); m_boundingBox[5] = infoWs->getZDimension()->getMaximum(); m_numDims = infoWs->getNumDims(); m_coordType = infoWs->getSpecialCoordinateSystem(); if (Kernel::HKL != m_coordType) { throw std::invalid_argument( "Cannot create non-orthogonal view for non-HKL coordinates"); } const API::Sample sample = infoWs->getExperimentInfo(0)->sample(); if (!sample.hasOrientedLattice()) { throw std::invalid_argument( "OrientedLattice is not present on workspace"); } oLatt = sample.getOrientedLattice(); const API::Run run = infoWs->getExperimentInfo(0)->run(); if (!run.hasProperty("W_MATRIX")) { throw std::invalid_argument("W_MATRIX is not present on workspace"); } wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX"); try { API::CoordTransform const *transform = infoWs->getTransformToOriginal(); affMat = transform->makeAffineMatrix(); } catch (std::runtime_error &) { // Create identity matrix of dimension+1 std::size_t nDims = infoWs->getNumDims() + 1; Kernel::Matrix<coord_t> temp(nDims, nDims, true); affMat = temp; } } // This is only here to make the unit test run. if (boost::algorithm::find_first(wsType, "MDEventWorkspace")) { API::IMDEventWorkspace_const_sptr infoWs = boost::dynamic_pointer_cast<const API::IMDEventWorkspace>(ws); m_boundingBox[0] = infoWs->getXDimension()->getMinimum(); m_boundingBox[1] = infoWs->getXDimension()->getMaximum(); m_boundingBox[2] = infoWs->getYDimension()->getMinimum(); m_boundingBox[3] = infoWs->getYDimension()->getMaximum(); m_boundingBox[4] = infoWs->getZDimension()->getMinimum(); m_boundingBox[5] = infoWs->getZDimension()->getMaximum(); m_numDims = infoWs->getNumDims(); m_coordType = infoWs->getSpecialCoordinateSystem(); if (Kernel::HKL != m_coordType) { throw std::invalid_argument( "Cannot create non-orthogonal view for non-HKL coordinates"); } const API::Sample sample = infoWs->getExperimentInfo(0)->sample(); if (!sample.hasOrientedLattice()) { throw std::invalid_argument( "OrientedLattice is not present on workspace"); } oLatt = sample.getOrientedLattice(); const API::Run run = infoWs->getExperimentInfo(0)->run(); if (!run.hasProperty("W_MATRIX")) { throw std::invalid_argument("W_MATRIX is not present on workspace"); } wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX"); try { API::CoordTransform const *transform = infoWs->getTransformToOriginal(); affMat = transform->makeAffineMatrix(); } catch (std::runtime_error &) { // Create identity matrix of dimension+1 std::size_t nDims = infoWs->getNumDims() + 1; Kernel::Matrix<coord_t> temp(nDims, nDims, true); affMat = temp; } } Kernel::DblMatrix wTrans(wMatArr); this->createSkewInformation(oLatt, wTrans, affMat); /// Put together the skew matrix for use Mantid::coord_t skew[9]; // Create from the internal skew matrix std::size_t index = 0; for (std::size_t i = 0; i < m_skewMat.numRows(); i++) { for (std::size_t j = 0; j < m_skewMat.numCols(); j++) { skew[index] = static_cast<Mantid::coord_t>(m_skewMat[i][j]); index++; } } // Get the original points vtkFloatArray *points = vtkFloatArray::SafeDownCast(data->GetPoints()->GetData()); if (points == NULL) { throw std::runtime_error("Failed to cast vtkDataArray to vtkFloatArray."); } else if (points->GetNumberOfComponents() != 3) { throw std::runtime_error("points array must have 3 components."); } float *end = points->GetPointer(points->GetNumberOfTuples() * 3); for (float *it = points->GetPointer(0); it < end; std::advance(it, 3)) { float v1 = it[0]; float v2 = it[1]; float v3 = it[2]; it[0] = v1 * skew[0] + v2 * skew[1] + v3 * skew[2]; it[1] = v1 * skew[3] + v2 * skew[4] + v3 * skew[5]; it[2] = v1 * skew[6] + v2 * skew[7] + v3 * skew[8]; } this->updateMetaData(data); }