/** Checks that the input workspace and table have compatible dimensions * @return a map where: Key = string name of the the property; Value = string * describing the problem with the property. */ std::map<std::string, std::string> PhaseQuadMuon::validateInputs() { std::map<std::string, std::string> result; // Check that input ws and table ws have compatible dimensions API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); API::ITableWorkspace_const_sptr tabWS = getProperty("PhaseTable"); if (!inputWS) { result["InputWorkspace"] = "InputWorkspace is of Incorrect type. Please " "provide a MatrixWorkspace as the " "InputWorkspace"; return result; } size_t nspec = inputWS->getNumberHistograms(); size_t ndet = tabWS->rowCount(); if (tabWS->columnCount() == 0) { result["PhaseTable"] = "Please provide a non-empty PhaseTable."; } if (nspec != ndet) { result["PhaseTable"] = "PhaseTable must have one row per spectrum"; } // PhaseTable should have three columns: (detector, asymmetry, phase) if (tabWS->columnCount() != 3) { result["PhaseTable"] = "PhaseTable must have three columns"; } // Check units, should be microseconds Unit_const_sptr unit = inputWS->getAxis(0)->unit(); if ((unit->caption() != "Time") || (unit->label().ascii() != "microsecond")) { result["InputWorkspace"] = "InputWorkspace units must be microseconds"; } return result; }
/** Checks that the input workspace and table have compatible dimensions * @return a map where: Key = string name of the the property; Value = string * describing the problem with the property. */ std::map<std::string, std::string> PhaseQuadMuon::validateInputs() { std::map<std::string, std::string> result; // Check that input ws and table ws have compatible dimensions API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); API::ITableWorkspace_const_sptr tabWS = getProperty("PhaseTable"); if (!inputWS) { result["InputWorkspace"] = "InputWorkspace is of Incorrect type. Please " "provide a MatrixWorkspace as the " "InputWorkspace"; return result; } size_t nspec = inputWS->getNumberHistograms(); size_t ndet = tabWS->rowCount(); if (tabWS->columnCount() == 0) { result["PhaseTable"] = "Please provide a non-empty PhaseTable."; } if (nspec != ndet) { result["PhaseTable"] = "PhaseTable must have one row per spectrum"; } // PhaseTable should have three columns: (detector, asymmetry, phase) if (tabWS->columnCount() != 3) { result["PhaseTable"] = "PhaseTable must have three columns"; } auto names = tabWS->getColumnNames(); for (auto &name : names) { std::transform(name.begin(), name.end(), name.begin(), ::tolower); } int phaseCount = 0; int asymmetryCount = 0; for (const std::string &name : names) { for (const std::string &goodName : phaseNames) { if (name == goodName) { phaseCount += 1; } } for (const std::string &goodName : asymmNames) { if (name == goodName) { asymmetryCount += 1; } } } if (phaseCount == 0) { result["PhaseTable"] = "PhaseTable needs phases column"; } if (asymmetryCount == 0) { result["PhaseTable"] = "PhaseTable needs a asymmetry/asymm/asym column"; } if (phaseCount > 1) { result["PhaseTable"] = "PhaseTable has " + std::to_string(phaseCount) + " phase columns"; } if (asymmetryCount > 1) { result["PhaseTable"] = "PhaseTable has " + std::to_string(asymmetryCount) + " asymmetry/asymm/asym columns"; } // Check units, should be microseconds Unit_const_sptr unit = inputWS->getAxis(0)->unit(); if ((unit->caption() != "Time") || (unit->label().ascii() != "microsecond")) { result["InputWorkspace"] = "InputWorkspace units must be microseconds"; } return result; }
/** Write out a table Workspace's */ int NexusFileIO::writeNexusTableWorkspace( const API::ITableWorkspace_const_sptr& itableworkspace, const char * group_name) const { NXstatus status = 0; boost::shared_ptr<const TableWorkspace> tableworkspace = boost::dynamic_pointer_cast<const TableWorkspace>(itableworkspace); boost::shared_ptr<const PeaksWorkspace> peakworkspace = boost::dynamic_pointer_cast<const PeaksWorkspace>(itableworkspace); if ( !tableworkspace && !peakworkspace ) return((status==NX_ERROR)?3:0); //write data entry status=NXmakegroup(fileID,group_name,"NXdata"); if(status==NX_ERROR) return(2); NXopengroup(fileID,group_name,"NXdata"); int nRows = static_cast<int>(itableworkspace->rowCount()); int dims_array[1] = { nRows }; for (size_t i = 0; i < itableworkspace->columnCount(); i++) { Column_const_sptr col = itableworkspace->getColumn(i); std::string str = "column_" + boost::lexical_cast<std::string>(i+1); if ( col->isType<double>() ) { double * toNexus = new double[nRows]; for (int ii = 0; ii < nRows; ii++) toNexus[ii] = col->cell<double>(ii); NXwritedata(str.c_str(), NX_FLOAT64, 1, dims_array, (void *)(toNexus), false); delete[] toNexus; // attributes NXopendata(fileID, str.c_str()); std::string units = "Not known"; std::string interpret_as = "A double"; NXputattr(fileID, "units", reinterpret_cast<void*>(const_cast<char*>(units.c_str())), static_cast<int>(units.size()), NX_CHAR); NXputattr(fileID, "interpret_as", reinterpret_cast<void*>(const_cast<char*>(interpret_as.c_str())), static_cast<int>(interpret_as.size()), NX_CHAR); NXclosedata(fileID); } else if ( col->isType<int>() ) { int * toNexus = new int[nRows]; for (int ii = 0; ii < nRows; ii++) toNexus[ii] = col->cell<int>(ii); NXwritedata(str.c_str(), NX_INT32, 1, dims_array, (void *)(toNexus), false); delete[] toNexus; // attributes NXopendata(fileID, str.c_str()); std::string units = "Not known"; std::string interpret_as = "An integer"; NXputattr(fileID, "units", reinterpret_cast<void*>(const_cast<char*>(units.c_str())), static_cast<int>(units.size()), NX_CHAR); NXputattr(fileID, "interpret_as", reinterpret_cast<void*>(const_cast<char*>(interpret_as.c_str())), static_cast<int>(interpret_as.size()), NX_CHAR); NXclosedata(fileID); } else if ( col->isType<std::string>() ) { // determine max string size size_t maxStr = 0; for (int ii = 0; ii < nRows; ii++) { if ( col->cell<std::string>(ii).size() > maxStr) maxStr = col->cell<std::string>(ii).size(); } int dims_array[2] = { nRows, static_cast<int>(maxStr) }; int asize[2]={1,dims_array[1]}; NXcompmakedata(fileID, str.c_str(), NX_CHAR, 2, dims_array,false,asize); NXopendata(fileID, str.c_str()); char* toNexus = new char[maxStr*nRows]; for(int ii = 0; ii < nRows; ii++) { std::string rowStr = col->cell<std::string>(ii); for (size_t ic = 0; ic < rowStr.size(); ic++) toNexus[ii*maxStr+ic] = rowStr[ic]; for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxStr); ic++) toNexus[ii*maxStr+ic] = ' '; } NXputdata(fileID, (void *)(toNexus)); delete[] toNexus; // attributes std::string units = "N/A"; std::string interpret_as = "A string"; NXputattr(fileID, "units", reinterpret_cast<void*>(const_cast<char*>(units.c_str())), static_cast<int>(units.size()), NX_CHAR); NXputattr(fileID, "interpret_as", reinterpret_cast<void*>(const_cast<char*>(interpret_as.c_str())), static_cast<int>(interpret_as.size()), NX_CHAR); NXclosedata(fileID); } #define IF_VECTOR_COLUMN(Type, NexusType) \ else if ( col->isType< std::vector<Type> >() ) \ { \ auto vecCol = boost::dynamic_pointer_cast< const VectorColumn<Type> >(col); \ writeNexusVectorColumn<Type>(vecCol, str, NexusType, #Type); \ } IF_VECTOR_COLUMN(int,NX_INT32) IF_VECTOR_COLUMN(double,NX_FLOAT64) // write out title NXopendata(fileID, str.c_str()); NXputattr(fileID, "name", reinterpret_cast<void*>(const_cast<char*>(col->name().c_str())), static_cast<int>(col->name().size()), NX_CHAR); NXclosedata(fileID); } status=NXclosegroup(fileID); return((status==NX_ERROR)?3:0); }