Ejemplo n.º 1
0
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;
  }
}
Ejemplo n.º 2
0
    /**
     * 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