예제 #1
0
void LoadSINQFocus::loadRunDetails(NXEntry & entry) {

	API::Run & runDetails = m_localWorkspace->mutableRun();

//	int runNum = entry.getInt("run_number");
//	std::string run_num = boost::lexical_cast<std::string>(runNum);
//	runDetails.addProperty("run_number", run_num);

	std::string start_time = entry.getString("start_time");
	//start_time = getDateTimeInIsoFormat(start_time);
	runDetails.addProperty("run_start", start_time);

	std::string end_time = entry.getString("end_time");
	//end_time = getDateTimeInIsoFormat(end_time);
	runDetails.addProperty("run_end", end_time);

	double wavelength = entry.getFloat(m_instrumentPath + "/monochromator/lambda");
	runDetails.addProperty<double>("wavelength", wavelength);

	double energy = entry.getFloat(m_instrumentPath + "/monochromator/energy");
	runDetails.addProperty<double>("Ei", energy, true); //overwrite

	std::string title = entry.getString("title");
	runDetails.addProperty("title", title);
	m_localWorkspace->setTitle(title);

}
예제 #2
0
파일: LoadLLB.cpp 프로젝트: mducle/mantid
void LoadLLB::loadRunDetails(NXEntry &entry) {

  API::Run &runDetails = m_localWorkspace->mutableRun();

  //	int runNum = entry.getInt("run_number");
  //	std::string run_num = boost::lexical_cast<std::string>(runNum);
  //	runDetails.addProperty("run_number", run_num);

  std::string start_time = entry.getString("start_time");
  // start_time = getDateTimeInIsoFormat(start_time);
  runDetails.addProperty("run_start", start_time);

  std::string end_time = entry.getString("end_time");
  // end_time = getDateTimeInIsoFormat(end_time);
  runDetails.addProperty("run_end", end_time);

  double wavelength = entry.getFloat("nxbeam/incident_wavelength");
  runDetails.addProperty<double>("wavelength", wavelength);

  double energy = m_loader.calculateEnergy(wavelength);
  runDetails.addProperty<double>("Ei", energy, true); // overwrite

  std::string title = entry.getString("title");
  runDetails.addProperty("title", title);
  m_localWorkspace->setTitle(title);
}
예제 #3
0
/**
 * Loads the mapping between index -> set of detector IDs
 *
 * If "detector_index", "detector_count" and "detector_list" are all present,
 * use these to get the mapping, otherwise spectrum number = detector ID
 * (one-to-one)
 *
 * The spectrum spectrum_index[i] maps to detector_count[i] detectors, whose
 * detector IDs are in detector_list starting at the index detector_index[i]
 *
 * @returns :: map of index -> detector IDs
 * @throws std::runtime_error if fails to read data from file
 */
std::map<int, std::set<int>>
LoadMuonNexus2::loadDetectorMapping(const Mantid::NeXus::NXInt &spectrumIndex) {
  std::map<int, std::set<int>> mapping;
  const int nSpectra = spectrumIndex.dim0();

  // Find and open the data group
  NXRoot root(getPropertyValue("Filename"));
  NXEntry entry = root.openEntry(m_entry_name);
  const std::string detectorName = [&entry]() {
    // Only the first NXdata found
    for (auto &group : entry.groups()) {
      std::string className = group.nxclass;
      if (className == "NXdata") {
        return group.nxname;
      }
    }
    throw std::runtime_error("No NXdata found in file");
  }();
  NXData dataGroup = entry.openNXData(detectorName);

  // Usually for muon data, detector id = spectrum number
  // If not, the optional groups "detector_index", "detector_list" and
  // "detector_count" will be present to map one to the other
  const bool hasDetectorMapping = dataGroup.containsDataSet("detector_index") &&
                                  dataGroup.containsDataSet("detector_list") &&
                                  dataGroup.containsDataSet("detector_count");
  if (hasDetectorMapping) {
    // Read detector IDs
    try {
      const auto detIndex = dataGroup.openNXInt("detector_index");
      const auto detCount = dataGroup.openNXInt("detector_count");
      const auto detList = dataGroup.openNXInt("detector_list");
      const int nSpectra = detIndex.dim0();
      for (int i = 0; i < nSpectra; ++i) {
        const int start = detIndex[i];
        const int nDetectors = detCount[i];
        std::set<int> detIDs;
        for (int jDet = 0; jDet < nDetectors; ++jDet) {
          detIDs.insert(detList[start + jDet]);
        }
        mapping[i] = detIDs;
      }
    } catch (const ::NeXus::Exception &err) {
      // Throw a more user-friendly message
      std::ostringstream message;
      message << "Failed to read detector mapping: " << err.what();
      throw std::runtime_error(message.str());
    }
  } else {
    for (int i = 0; i < nSpectra; ++i) {
      mapping[i] = std::set<int>{spectrumIndex[i]};
    }
  }

  return mapping;
}
/** Execute the algorithm.
 */
void LoadILLReflectometry::exec() {
  // Retrieve filename
  std::string filenameData = getPropertyValue("Filename");

  // open the root node
  NeXus::NXRoot dataRoot(filenameData);
  NXEntry firstEntry = dataRoot.openFirstEntry();

  // Load Monitor details: n. monitors x monitor contents
  std::vector<std::vector<int>> monitorsData = loadMonitors(firstEntry);

  // Load Data details (number of tubes, channels, etc)
  loadDataDetails(firstEntry);

  std::string instrumentPath = m_loader.findInstrumentNexusPath(firstEntry);
  setInstrumentName(firstEntry, instrumentPath);

  initWorkSpace(firstEntry, monitorsData);

  g_log.debug("Building properties...");
  loadNexusEntriesIntoProperties(filenameData);

  g_log.debug("Loading data...");
  loadDataIntoTheWorkSpace(firstEntry, monitorsData);

  // load the instrument from the IDF if it exists
  g_log.debug("Loading instrument definition...");
  runLoadInstrument();

  // 1) Move

  // Get distance and tilt angle stored in nexus file
  // Mantid way
  ////	auto angleProp =
  /// dynamic_cast<PropertyWithValue<double>*>(m_localWorkspace->run().getProperty("dan.value"));
  // Nexus way
  double angle =
      firstEntry.getFloat("instrument/dan/value"); // detector angle in degrees
  double distance = firstEntry.getFloat(
      "instrument/det/value"); // detector distance in millimeter

  distance /= 1000.0; // convert to meter
  g_log.debug() << "Moving detector at angle " << angle << " and distance "
                << distance << std::endl;
  placeDetector(distance, angle);

  // Set the channel width property
  auto channel_width = dynamic_cast<PropertyWithValue<double> *>(
      m_localWorkspace->run().getProperty("monitor1.time_of_flight_0"));
  m_localWorkspace->mutableRun().addProperty<double>(
      "channel_width", *channel_width, true); // overwrite

  // Set the output workspace property
  setProperty("OutputWorkspace", m_localWorkspace);
}
예제 #5
0
/**  Log the run details from the file
* @param localWorkspace :: The workspace details to use
*/
void
LoadMuonNexus1::loadRunDetails(DataObjects::Workspace2D_sptr localWorkspace) {
  API::Run &runDetails = localWorkspace->mutableRun();

  runDetails.addProperty("run_title", localWorkspace->getTitle(), true);

  int numSpectra = static_cast<int>(localWorkspace->getNumberHistograms());
  runDetails.addProperty("nspectra", numSpectra);

  NXRoot root(m_filename);
  try {
    std::string start_time = root.getString("run/start_time");
    runDetails.addProperty("run_start", start_time);
  } catch (std::runtime_error &) {
    g_log.warning("run/start_time is not available, run_start log not added.");
  }

  try {
    std::string stop_time = root.getString("run/stop_time");
    runDetails.addProperty("run_end", stop_time);
  } catch (std::runtime_error &) {
    g_log.warning("run/stop_time is not available, run_end log not added.");
  }

  try {
    std::string dur = root.getString("run/duration");
    runDetails.addProperty("dur", dur);
    runDetails.addProperty("durunits", 1); // 1 means second here
    runDetails.addProperty("dur_secs", dur);
  } catch (std::runtime_error &) {
    g_log.warning("run/duration is not available, dur log not added.");
  }

  // Get sample parameters
  NXEntry runSample = root.openEntry("run/sample");

  if (runSample.containsDataSet("temperature")) {
    float temperature = runSample.getFloat("temperature");
    runDetails.addProperty("sample_temp", static_cast<double>(temperature));
  }

  if (runSample.containsDataSet("magnetic_field")) {
    float magn_field = runSample.getFloat("magnetic_field");
    runDetails.addProperty("sample_magn_field",
                           static_cast<double>(magn_field));
  }



}
예제 #6
0
/*
 * Load data about the Experiment.
 *
 * TODO: This is very incomplete. In ISIS they much more info in the nexus file than ILL.
 *
 * @param entry :: The Nexus entry
 */
void LoadSINQFocus::loadExperimentDetails(NXEntry & entry) {

	std::string name = boost::lexical_cast<std::string>(
			entry.getFloat("sample/name"));
	m_localWorkspace->mutableSample().setName(name);

}
예제 #7
0
    /**
    * Load data about the sample
    *   @param local_workspace :: The workspace to load the logs to.
    *   @param entry :: The Nexus entry
    */
    void LoadISISNexus2::loadSampleData(DataObjects::Workspace2D_sptr local_workspace, NXEntry & entry)
    {
      /// Sample geometry
      NXInt spb = entry.openNXInt("isis_vms_compat/SPB");
      // Just load the index we need, not the whole block. The flag is the third value in
      spb.load(1, 2);
      int geom_id = spb[0];
      local_workspace->mutableSample().setGeometryFlag(spb[0]);

      NXFloat rspb = entry.openNXFloat("isis_vms_compat/RSPB");
      // Just load the indices we need, not the whole block. The values start from the 4th onward
      rspb.load(3, 3);
      double thick(rspb[0]), height(rspb[1]), width(rspb[2]);
      local_workspace->mutableSample().setThickness(thick);
      local_workspace->mutableSample().setHeight(height);
      local_workspace->mutableSample().setWidth(width);

      g_log.debug() << "Sample geometry -  ID: " << geom_id << ", thickness: " << thick << ", height: " << height << ", width: " << width << "\n";
    }
예제 #8
0
/**  Load logs from Nexus file. Logs are expected to be in
*   /run/sample group of the file.
*   @param ws :: The workspace to load the logs to.
*   @param entry :: The Nexus entry
*   @param period :: The period of this workspace
*/
void LoadMuonNexus2::loadLogs(API::MatrixWorkspace_sptr ws, NXEntry &entry,
                              int period) {
  // Avoid compiler warning
  (void)period;

  std::string start_time = entry.getString("start_time");

  std::string sampleName = entry.getString("sample/name");
  NXMainClass runlogs = entry.openNXClass<NXMainClass>("sample");
  ws->mutableSample().setName(sampleName);

  for (std::vector<NXClassInfo>::const_iterator it = runlogs.groups().begin();
       it != runlogs.groups().end(); ++it) {
    NXLog nxLog = runlogs.openNXLog(it->nxname);
    Kernel::Property *logv = nxLog.createTimeSeries(start_time);
    if (!logv)
      continue;
    ws->mutableRun().addLogData(logv);
  }

  ws->setTitle(entry.getString("title"));

  if (entry.containsDataSet("notes")) {
    ws->setComment(entry.getString("notes"));
  }

  std::string run_num = std::to_string(entry.getInt("run_number"));
  // The sample is left to delete the property
  ws->mutableRun().addLogData(
      new PropertyWithValue<std::string>("run_number", run_num));

  ws->populateInstrumentParameters();
}
예제 #9
0
/**  Log the run details from the file
* @param localWorkspace :: The workspace details to use
*/
void LoadMuonNexus2::loadRunDetails(
    DataObjects::Workspace2D_sptr localWorkspace) {
  API::Run &runDetails = localWorkspace->mutableRun();

  runDetails.addProperty("run_title", localWorkspace->getTitle(), true);

  int numSpectra = static_cast<int>(localWorkspace->getNumberHistograms());
  runDetails.addProperty("nspectra", numSpectra);

  m_filename = getPropertyValue("Filename");
  NXRoot root(m_filename);
  NXEntry entry = root.openEntry(m_entry_name);

  std::string start_time = entry.getString("start_time");
  runDetails.addProperty("run_start", start_time);

  std::string stop_time = entry.getString("end_time");
  runDetails.addProperty("run_end", stop_time);

  if (entry.containsGroup("run")) {
    NXClass runRun = entry.openNXGroup("run");

    if (runRun.containsDataSet("good_total_frames")) {
      int dum = runRun.getInt("good_total_frames");
      runDetails.addProperty("goodfrm", dum);
    }

    if (runRun.containsDataSet("number_periods")) {
      int dum = runRun.getInt("number_periods");
      runDetails.addProperty("nperiods", dum);
    }
  }

  { // Duration taken to be stop_time minus stat_time
    auto start = createFromSanitizedISO8601(start_time);
    auto end = createFromSanitizedISO8601(stop_time);
    double duration_in_secs = DateAndTime::secondsFromDuration(end - start);
    runDetails.addProperty("dur_secs", duration_in_secs);
  }
}
예제 #10
0
    /**  Load logs from Nexus file. Logs are expected to be in
    *   /raw_data_1/runlog group of the file. Call to this method must be done
    *   within /raw_data_1 group.
    *   @param ws :: The workspace to load the logs to.
    *   @param entry :: Nexus entry
    */
    void LoadISISNexus2::loadLogs(DataObjects::Workspace2D_sptr ws, NXEntry & entry)
    {
      IAlgorithm_sptr alg = createChildAlgorithm("LoadNexusLogs", 0.0, 0.5);
      alg->setPropertyValue("Filename", this->getProperty("Filename"));
      alg->setProperty<MatrixWorkspace_sptr>("Workspace", ws);
      try
      {
        alg->executeAsChildAlg();
      }
      catch(std::runtime_error&)
      {
        g_log.warning() << "Unable to load run logs. There will be no log "
          << "data associated with this workspace\n";
        return;
      }
      // For ISIS Nexus only, fabricate an addtional log containing an array of proton charge information from the periods group.
      try
      {
        NXClass protonChargeClass = entry.openNXGroup("periods");
        NXFloat periodsCharge = protonChargeClass.openNXFloat("proton_charge");
        periodsCharge.load();
        size_t nperiods = periodsCharge.dim0();
        std::vector<double> chargesVector(nperiods);
        std::copy(periodsCharge(), periodsCharge() + nperiods, chargesVector.begin());
        ArrayProperty<double>* protonLogData = new ArrayProperty<double>("proton_charge_by_period", chargesVector);
        ws->mutableRun().addProperty(protonLogData);  
      }
      catch(std::runtime_error&)
      {
        this->g_log.debug("Cannot read periods information from the nexus file. This group may be absent.");
      }
      // Populate the instrument parameters.
      ws->populateInstrumentParameters();

      // Make log creator object and add the run status log
      m_logCreator.reset(new ISISRunLogs(ws->run(), m_numberOfPeriods));
      m_logCreator->addStatusLog(ws->mutableRun());
    }
예제 #11
0
/**
 * Read the instrument group
 * @param mtd_entry :: The node for the current workspace
 * @param local_workspace :: The workspace to attach the instrument
 */
void LoadNexusProcessed::readInstrumentGroup(NXEntry & mtd_entry, API::MatrixWorkspace_sptr local_workspace)
{
  //Instrument information
  NXInstrument inst = mtd_entry.openNXInstrument("instrument");
  if ( ! inst.containsGroup("detector") )
  {
    g_log.information() << "Detector block not found. The workspace will not contain any detector information.\n";
    return;
  }

  //Populate the spectra-detector map
  NXDetector detgroup = inst.openNXDetector("detector");

  //Read necessary arrays from the file
  // Detector list contains a list of all of the detector numbers. If it not present then we can't update the spectra
  // map
  int ndets(-1);
  boost::shared_array<int> det_list(NULL);
  try
  {
    NXInt detlist_group = detgroup.openNXInt("detector_list");
    ndets = detlist_group.dim0();
    detlist_group.load();
    det_list.swap(detlist_group.sharedBuffer());
  }
  catch(std::runtime_error &)
  {
    g_log.information() << "detector_list block not found. The workspace will not contain any detector information."
        << std::endl;
    return;
  }

  //Detector count contains the number of detectors associated with each spectra
  NXInt det_count = detgroup.openNXInt("detector_count");
  det_count.load();
  //Detector index - contains the index of the detector in the workspace
  NXInt det_index = detgroup.openNXInt("detector_index");
  det_index.load();
  int nspectra = det_index.dim0();

  //Spectra block - Contains spectrum numbers for each workspace index
  // This might not exist so wrap and check. If it doesn't exist create a default mapping
  bool have_spectra(true);
  boost::shared_array<int> spectra(NULL);
  try
  {
    NXInt spectra_block = detgroup.openNXInt("spectra");
    spectra_block.load();
    spectra.swap(spectra_block.sharedBuffer());
  }
  catch(std::runtime_error &)
  {
    have_spectra = false;
  }

  //Now build the spectra list
  int *spectra_list = new int[ndets];
  API::Axis *axis1 = local_workspace->getAxis(1);
  int index=0;

  for(int i = 1; i <= nspectra; ++i)
  { 
      int spectrum(-1);
      if( have_spectra ) spectrum = spectra[i-1];
      else spectrum = i+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()))
      {
        if( m_axis1vals.empty() )
        {
          axis1->spectraNo(index) = spectrum;
        }
        else
        {
          axis1->setValue(index, m_axis1vals[i-1]);
        }
        ++index;
      }

      int offset = det_index[i-1];
      int detcount = det_count[i-1];
      for(int j = 0; j < detcount; j++)
      {
        spectra_list[offset + j] = spectrum;
      }
     
  }
  local_workspace->replaceSpectraMap(new SpectraDetectorMap(spectra_list, det_list.get(), ndets));
  delete[] spectra_list;
}
예제 #12
0
/**
 * Load a table
 */
API::Workspace_sptr LoadNexusProcessed::loadTableEntry(NXEntry & entry)
{
  API::ITableWorkspace_sptr workspace;
  workspace = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");

  NXData nx_tw = entry.openNXData("table_workspace");

  std::vector<double> values;

  bool hasNumberOfRowBeenSet = false;
  //int numberOfRows = 0;

  int columnNumber = 1;
  do
  {
    std::string str = "column_" + boost::lexical_cast<std::string>(columnNumber);

    NXInfo info = nx_tw.getDataSetInfo(str.c_str());
    if (info.stat == NX_ERROR)
    {
      break;
    }

    if ( info.type == NX_FLOAT64 )
    {
      NXDouble nxDouble = nx_tw.openNXDouble(str.c_str());
      std::string columnTitle = nxDouble.attributes("name");
      if (!columnTitle.empty())
      {
        workspace->addColumn("double", columnTitle);
        nxDouble.load();
        int length = nxDouble.dim0();
        if ( !hasNumberOfRowBeenSet )
        { 
          workspace->setRowCount(length);
          hasNumberOfRowBeenSet = true;
        }
        for (int i = 0; i < length; i++)
          workspace->cell<double>(i,columnNumber-1) = *(nxDouble() + i);
      }
    }
    else if ( info.type == NX_CHAR )
    {
      NXChar data = nx_tw.openNXChar(str.c_str());
      std::string columnTitle = data.attributes("name");
      if (!columnTitle.empty())
      {
        workspace->addColumn("str", columnTitle);
        int nRows = info.dims[0];
        if ( !hasNumberOfRowBeenSet )
        {
          workspace->setRowCount(nRows);
          hasNumberOfRowBeenSet = true;
        }
        int maxStr = info.dims[1];

        std::string fromCrap(maxStr,' ');

        data.load();
        for (int iR = 0; iR < nRows; iR++)
        {
          for (int i = 0; i < maxStr; i++)
            fromCrap[i] = *(data()+i+maxStr*iR);
          workspace->cell<std::string>(iR,columnNumber-1) = fromCrap;
        }
      }
    } 

    columnNumber++;
  
  } while ( 1 );

  return boost::static_pointer_cast<API::Workspace>(workspace);
}
예제 #13
0
    /**
    * Load data about the run
    *   @param local_workspace :: The workspace to load the run information in to
    *   @param entry :: The Nexus entry
    */
    void LoadISISNexus2::loadRunDetails(DataObjects::Workspace2D_sptr local_workspace, NXEntry & entry)
    {
      API::Run & runDetails = local_workspace->mutableRun();
      // Charge is stored as a float
      m_proton_charge = static_cast<double>(entry.getFloat("proton_charge"));
      runDetails.setProtonCharge(m_proton_charge);

      std::string run_num = boost::lexical_cast<std::string>(entry.getInt("run_number"));
      runDetails.addProperty("run_number", run_num);
      
      //
      // Some details are only stored in the VMS compatability block so we'll pull everything from there
      // for consistency

      NXClass vms_compat = entry.openNXGroup("isis_vms_compat");
      // Run header
      NXChar char_data = vms_compat.openNXChar("HDR");
      char_data.load();
      runDetails.addProperty("run_header", std::string(char_data(),80));
      
      // Data details on run not the workspace
      runDetails.addProperty("nspectra", static_cast<int>(m_numberOfSpectraInFile));
      runDetails.addProperty("nchannels", static_cast<int>(m_numberOfChannelsInFile));
      runDetails.addProperty("nperiods", static_cast<int>(m_numberOfPeriodsInFile));

      // RPB struct info
      NXInt rpb_int = vms_compat.openNXInt("IRPB");
      rpb_int.load();
      runDetails.addProperty("dur", rpb_int[0]);        // actual run duration
      runDetails.addProperty("durunits", rpb_int[1]);   // scaler for above (1=seconds)
      runDetails.addProperty("dur_freq", rpb_int[2]);  // testinterval for above (seconds)
      runDetails.addProperty("dmp", rpb_int[3]);       // dump interval
      runDetails.addProperty("dmp_units", rpb_int[4]);  // scaler for above
      runDetails.addProperty("dmp_freq", rpb_int[5]);   // interval for above
      runDetails.addProperty("freq", rpb_int[6]);       // 2**k where source frequency = 50 / 2**k
      
      // Now double data
      NXFloat rpb_dbl = vms_compat.openNXFloat("RRPB");
      rpb_dbl.load();
      runDetails.addProperty("gd_prtn_chrg", static_cast<double>(rpb_dbl[7]));  // good proton charge (uA.hour)
      runDetails.addProperty("tot_prtn_chrg", static_cast<double>(rpb_dbl[8])); // total proton charge (uA.hour)
      runDetails.addProperty("goodfrm",rpb_int[9]);     // good frames
      runDetails.addProperty("rawfrm", rpb_int[10]);    // raw frames
      runDetails.addProperty("dur_wanted", rpb_int[11]); // requested run duration (units as for "duration" above)
      runDetails.addProperty("dur_secs", rpb_int[12]);  // actual run duration in seconds
      runDetails.addProperty("mon_sum1", rpb_int[13]);  // monitor sum 1
      runDetails.addProperty("mon_sum2", rpb_int[14]);  // monitor sum 2
      runDetails.addProperty("mon_sum3",rpb_int[15]);   // monitor sum 3

      // End date and time is stored separately in ISO format in the "raw_data1/endtime" class
      char_data = entry.openNXChar("end_time");
      char_data.load();
      std::string end_time_iso = std::string(char_data(), 19);
      runDetails.addProperty("run_end", end_time_iso);

      char_data = entry.openNXChar("start_time");
      char_data.load();
      std::string start_time_iso = std::string(char_data(), 19);
      runDetails.addProperty("run_start", start_time_iso);

      
      runDetails.addProperty("rb_proposal",rpb_int[21]); // RB (proposal) number
      vms_compat.close();
    }
예제 #14
0
    /**
    * Load a given period into the workspace
    * @param period :: The period number to load (starting from 1) 
    * @param entry :: The opened root entry node for accessing the monitor and data nodes
    * @param local_workspace :: The workspace to place the data in
    */
    void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry & entry, DataObjects::Workspace2D_sptr local_workspace)
    {
      int64_t hist_index = 0;
      int64_t period_index(period - 1);
      int64_t first_monitor_spectrum = 0;

      if( !m_monitors.empty() )
      {
        first_monitor_spectrum = m_monitors.begin()->first;
        hist_index = first_monitor_spectrum - 1;
        for(std::map<int64_t,std::string>::const_iterator it = m_monitors.begin();
          it != m_monitors.end(); ++it)
        {
          NXData monitor = entry.openNXData(it->second);
          NXInt mondata = monitor.openIntData();
          m_progress->report("Loading monitor");
          mondata.load(1,static_cast<int>(period-1)); // TODO this is just wrong
          MantidVec& Y = local_workspace->dataY(hist_index);
          Y.assign(mondata(),mondata() + m_numberOfChannels);
          MantidVec& E = local_workspace->dataE(hist_index);
          std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
          local_workspace->getAxis(1)->spectraNo(hist_index) = static_cast<specid_t>(it->first);

          NXFloat timeBins = monitor.openNXFloat("time_of_flight");
          timeBins.load();
          local_workspace->dataX(hist_index).assign(timeBins(),timeBins() + timeBins.dim0());
          hist_index++;
        }

        if (first_monitor_spectrum > 1)
        {
          hist_index = 0;
        }
      }
      
      if( m_have_detector )
      {
        NXData nxdata = entry.openNXData("detector_1");
        NXDataSetTyped<int> data = nxdata.openIntData();
        data.open();
        //Start with thelist members that are lower than the required spectrum
        const int * const spec_begin = m_spec.get();
        std::vector<int64_t>::iterator min_end = m_spec_list.end();
        if( !m_spec_list.empty() )
        {
          // If we have a list, by now it is ordered so first pull in the range below the starting block range
          // Note the reverse iteration as we want the last one
          if( m_range_supplied )
          {
            min_end = std::find_if(m_spec_list.begin(), m_spec_list.end(), std::bind2nd(std::greater<int>(), m_spec_min));
          }

          for( std::vector<int64_t>::iterator itr = m_spec_list.begin(); itr < min_end; ++itr )
          {
            // Load each
            int64_t spectra_no = (*itr);
            // For this to work correctly, we assume that the spectrum list increases monotonically
            int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin;
            m_progress->report("Loading data");
            loadBlock(data, static_cast<int64_t>(1), period_index, filestart, hist_index, spectra_no, local_workspace);
          }
        }    

        if( m_range_supplied )
        {
          // When reading in blocks we need to be careful that the range is exactly divisible by the blocksize
          // and if not have an extra read of the left overs
          const int64_t blocksize = 8;
          const int64_t rangesize = (m_spec_max - m_spec_min + 1) - m_monitors.size();
          const int64_t fullblocks = rangesize / blocksize;
          int64_t read_stop = 0;
          int64_t spectra_no = m_spec_min;
          if (first_monitor_spectrum == 1)
          {// this if crudely checks whether the monitors are at the begining or end of the spectra
            spectra_no += static_cast<int>(m_monitors.size());
          }
          // For this to work correctly, we assume that the spectrum list increases monotonically
          int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin;
          if( fullblocks > 0 )
          {
            read_stop = (fullblocks * blocksize);// + m_monitors.size(); //RNT: I think monitors are excluded from the data
            //for( ; hist_index < read_stop; )
            for(int64_t i = 0; i < fullblocks; ++i)
            {
              loadBlock(data, blocksize, period_index, filestart, hist_index, spectra_no, local_workspace);
              filestart += blocksize;
            }
          }
          int64_t finalblock = rangesize - (fullblocks * blocksize);
          if( finalblock > 0 )
          {
            loadBlock(data, finalblock, period_index, filestart, hist_index, spectra_no,  local_workspace);
          }
        }

        //Load in the last of the list indices
        for( std::vector<int64_t>::iterator itr = min_end; itr < m_spec_list.end(); ++itr )
        {
          // Load each
          int64_t spectra_no = (*itr);
          // For this to work correctly, we assume that the spectrum list increases monotonically
          int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin;
          loadBlock(data, 1, period_index, filestart, hist_index, spectra_no, local_workspace);
        }
      }

      try
      {
        const std::string title = entry.getString("title");
        local_workspace->setTitle(title);
        // write the title into the log file (run object)
        local_workspace->mutableRun().addProperty("run_title", title, true);
      }
      catch (std::runtime_error &)
      {
        g_log.debug() << "No title was found in the input file, " << getPropertyValue("Filename") << std::endl;
      }
    }
예제 #15
0
/**
* Load data about the run
*   @param local_workspace :: The workspace to load the run information in to
*   @param entry :: The Nexus entry
*/
void
LoadISISNexus2::loadRunDetails(DataObjects::Workspace2D_sptr &local_workspace,
                               NXEntry &entry) {
  API::Run &runDetails = local_workspace->mutableRun();
  // Charge is stored as a float
  m_proton_charge = static_cast<double>(entry.getFloat("proton_charge"));
  runDetails.setProtonCharge(m_proton_charge);

  std::string run_num =
      boost::lexical_cast<std::string>(entry.getInt("run_number"));
  runDetails.addProperty("run_number", run_num);

  //
  // Some details are only stored in the VMS comparability block so we'll pull
  // everything from there
  // for consistency

  NXClass vms_compat = entry.openNXGroup("isis_vms_compat");
  // Run header
  NXChar char_data = vms_compat.openNXChar("HDR");
  char_data.load();

  // Space-separate the fields
  char *nxsHdr = char_data();
  char header[86] = {};
  const size_t byte = sizeof(char);
  const char fieldSep(' ');
  size_t fieldWidths[7] = {3, 5, 20, 24, 12, 8, 8};

  char *srcStart = nxsHdr;
  char *destStart = header;
  for (size_t i = 0; i < 7; ++i) {
    size_t width = fieldWidths[i];
    memcpy(destStart, srcStart, width * byte);
    if (i < 6) // no space after last field
    {
      srcStart += width;
      destStart += width;
      memset(destStart, fieldSep, byte); // insert separator
      destStart += 1;
    }
  }
  runDetails.addProperty("run_header", std::string(header, header + 86));

  // Data details on run not the workspace
  runDetails.addProperty("nspectra",
                         static_cast<int>(m_loadBlockInfo.numberOfSpectra));
  runDetails.addProperty("nchannels",
                         static_cast<int>(m_loadBlockInfo.numberOfChannels));
  runDetails.addProperty("nperiods",
                         static_cast<int>(m_loadBlockInfo.numberOfPeriods));

  // RPB struct info
  NXInt rpb_int = vms_compat.openNXInt("IRPB");
  rpb_int.load();
  runDetails.addProperty("dur", rpb_int[0]); // actual run duration
  runDetails.addProperty("durunits",
                         rpb_int[1]); // scaler for above (1=seconds)
  runDetails.addProperty("dur_freq",
                         rpb_int[2]);        // testinterval for above (seconds)
  runDetails.addProperty("dmp", rpb_int[3]); // dump interval
  runDetails.addProperty("dmp_units", rpb_int[4]); // scaler for above
  runDetails.addProperty("dmp_freq", rpb_int[5]);  // interval for above
  runDetails.addProperty("freq",
                         rpb_int[6]); // 2**k where source frequency = 50 / 2**k

  // Now double data
  NXFloat rpb_dbl = vms_compat.openNXFloat("RRPB");
  rpb_dbl.load();
  runDetails.addProperty(
      "gd_prtn_chrg",
      static_cast<double>(rpb_dbl[7])); // good proton charge (uA.hour)
  runDetails.addProperty(
      "tot_prtn_chrg",
      static_cast<double>(rpb_dbl[8])); // total proton charge (uA.hour)
  runDetails.addProperty("goodfrm", rpb_int[9]); // good frames
  runDetails.addProperty("rawfrm", rpb_int[10]); // raw frames
  runDetails.addProperty(
      "dur_wanted",
      rpb_int[11]); // requested run duration (units as for "duration" above)
  runDetails.addProperty("dur_secs",
                         rpb_int[12]); // actual run duration in seconds
  runDetails.addProperty("mon_sum1", rpb_int[13]); // monitor sum 1
  runDetails.addProperty("mon_sum2", rpb_int[14]); // monitor sum 2
  runDetails.addProperty("mon_sum3", rpb_int[15]); // monitor sum 3

  // End date and time is stored separately in ISO format in the
  // "raw_data1/endtime" class
  char_data = entry.openNXChar("end_time");
  char_data.load();
  std::string end_time_iso = std::string(char_data(), 19);
  runDetails.addProperty("run_end", end_time_iso);

  char_data = entry.openNXChar("start_time");
  char_data.load();
  std::string start_time_iso = std::string(char_data(), 19);
  runDetails.addProperty("run_start", start_time_iso);

  runDetails.addProperty("rb_proposal", rpb_int[21]); // RB (proposal) number
  vms_compat.close();
}
예제 #16
0
/**
* Load a given period into the workspace
* @param period :: The period number to load (starting from 1)
* @param entry :: The opened root entry node for accessing the monitor and data
* nodes
* @param local_workspace :: The workspace to place the data in
* @param update_spectra2det_mapping :: reset spectra-detector map to the one
* calculated earlier. (Warning! -- this map has to be calculated correctly!)
*/
void
LoadISISNexus2::loadPeriodData(int64_t period, NXEntry &entry,
                               DataObjects::Workspace2D_sptr &local_workspace,
                               bool update_spectra2det_mapping) {
  int64_t hist_index = 0;
  int64_t period_index(period - 1);
  // int64_t first_monitor_spectrum = 0;

  for (auto block = m_spectraBlocks.begin(); block != m_spectraBlocks.end();
       ++block) {
    if (block->isMonitor) {
      NXData monitor = entry.openNXData(block->monName);
      NXInt mondata = monitor.openIntData();
      m_progress->report("Loading monitor");
      mondata.load(1, static_cast<int>(period - 1)); // TODO this is just wrong
      MantidVec &Y = local_workspace->dataY(hist_index);
      Y.assign(mondata(), mondata() + m_monBlockInfo.numberOfChannels);
      MantidVec &E = local_workspace->dataE(hist_index);
      std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);

      if (update_spectra2det_mapping) {
        // local_workspace->getAxis(1)->setValue(hist_index,
        // static_cast<specid_t>(it->first));
        auto spec = local_workspace->getSpectrum(hist_index);
        specid_t specID = m_specInd2specNum_map.at(hist_index);
        spec->setDetectorIDs(
            m_spec2det_map.getDetectorIDsForSpectrumNo(specID));
        spec->setSpectrumNo(specID);
      }

      NXFloat timeBins = monitor.openNXFloat("time_of_flight");
      timeBins.load();
      local_workspace->dataX(hist_index)
          .assign(timeBins(), timeBins() + timeBins.dim0());
      hist_index++;
    } else if (m_have_detector) {
      NXData nxdata = entry.openNXData("detector_1");
      NXDataSetTyped<int> data = nxdata.openIntData();
      data.open();
      // Start with the list members that are lower than the required spectrum
      const int *const spec_begin = m_spec.get();
      // When reading in blocks we need to be careful that the range is exactly
      // divisible by the block-size
      // and if not have an extra read of the left overs
      const int64_t blocksize = 8;
      const int64_t rangesize = block->last - block->first + 1;
      const int64_t fullblocks = rangesize / blocksize;
      int64_t spectra_no = block->first;

      // For this to work correctly, we assume that the spectrum list increases
      // monotonically
      int64_t filestart =
          std::lower_bound(spec_begin, m_spec_end, spectra_no) - spec_begin;
      if (fullblocks > 0) {
        for (int64_t i = 0; i < fullblocks; ++i) {
          loadBlock(data, blocksize, period_index, filestart, hist_index,
                    spectra_no, local_workspace);
          filestart += blocksize;
        }
      }
      int64_t finalblock = rangesize - (fullblocks * blocksize);
      if (finalblock > 0) {
        loadBlock(data, finalblock, period_index, filestart, hist_index,
                  spectra_no, local_workspace);
      }
    }
  }

  try {
    const std::string title = entry.getString("title");
    local_workspace->setTitle(title);
    // write the title into the log file (run object)
    local_workspace->mutableRun().addProperty("run_title", title, true);
  } catch (std::runtime_error &) {
    g_log.debug() << "No title was found in the input file, "
                  << getPropertyValue("Filename") << std::endl;
  }
}
예제 #17
0
/**Method takes input parameters which describe  monitor loading and analyze
*them against spectra/monitor block information in the file.
* The result is the option if monitors can  be loaded together with spectra or
*mast be treated separately
* and additional information on how to treat monitor spectra.
*
*@param entry                :: entry to the NeXus file, opened at root folder
*@param spectrum_index       :: array of spectra indexes of the data present in
*the file
*@param ndets                :: size of the spectrum index array
*@param n_vms_compat_spectra :: number of data entries containing common time
*bins (e.g. all spectra, or all spectra and monitors or some spectra (this is
*not fully supported)
*@param monitors             :: map connecting monitor spectra ID against
*monitor group name in the file.
*@param excludeMonitors      :: input property indicating if it is requested to
*exclude monitors from the target workspace
*@param separateMonitors     :: input property indicating if it is requested to
*load monitors separately (and exclude them from target data workspace this way)
*
*@param OvelapMonitors       :: output property containing the list of monitors
*ID for monitors, which are also included with spectra.
*@return excludeMonitors     :: indicator if monitors should or mast be excluded
*from the main data workspace if they can not be loaded with the data
*                               (contain different number of time channels)
*
*/
bool LoadISISNexus2::findSpectraDetRangeInFile(
    NXEntry &entry, boost::shared_array<int> &spectrum_index, int64_t ndets,
    int64_t n_vms_compat_spectra, std::map<int64_t, std::string> &monitors,
    bool excludeMonitors, bool separateMonitors,
    std::map<int64_t, std::string> &OvelapMonitors) {
  OvelapMonitors.clear();
  size_t nmons = monitors.size();

  if (nmons > 0) {
    NXInt chans = entry.openNXInt(m_monitors.begin()->second + "/data");

    m_monBlockInfo = DataBlock(chans);
    m_monBlockInfo.numberOfSpectra = nmons; // each monitor is in separate group
                                            // so number of spectra is equal to
                                            // number of groups.

    // identify monitor ID range.
    for (auto it = monitors.begin(); it != monitors.end(); it++) {
      int64_t mon_id = static_cast<int64_t>(it->first);
      if (m_monBlockInfo.spectraID_min > mon_id)
        m_monBlockInfo.spectraID_min = mon_id;
      if (m_monBlockInfo.spectraID_max < mon_id)
        m_monBlockInfo.spectraID_max = mon_id;
    }
    if (m_monBlockInfo.spectraID_max - m_monBlockInfo.spectraID_min + 1 !=
        static_cast<int64_t>(nmons)) {
      g_log.warning() << "When trying to find the range of monitor spectra: "
                         "non-consequent monitor ID-s in the monitor block. "
                         "Unexpected situation for the loader\n";
    }
    // at this stage we assume that the only going to load monitors
    m_loadBlockInfo = m_monBlockInfo;
  }

  if (ndets == 0) {
    separateMonitors = false; // only monitors in the main workspace. No
                              // detectors. Will be loaded in the main workspace
    // Possible function exit point
    return separateMonitors;
  }

  // detectors are present in the file
  NXData nxData = entry.openNXData("detector_1");
  NXInt data = nxData.openIntData();

  m_detBlockInfo = DataBlock(data);
  // We assume again that this spectrum list ID increase monotonically
  m_detBlockInfo.spectraID_min = spectrum_index[0];
  m_detBlockInfo.spectraID_max = spectrum_index[ndets - 1];
  if (m_detBlockInfo.spectraID_max - m_detBlockInfo.spectraID_min + 1 !=
      static_cast<int64_t>(m_detBlockInfo.numberOfSpectra)) {
    g_log.warning() << "When trying to find the range of monitor spectra:  "
                       "non-consequent spectra ID-s in the detectors block. "
                       "Unexpected situation for the loader\n";
  }

  m_loadBlockInfo = m_detBlockInfo;

  // now we are analyzing what is actually going or can be loaded

  bool removeMonitors = excludeMonitors || separateMonitors;
  if (((m_detBlockInfo.numberOfPeriods != m_monBlockInfo.numberOfPeriods) ||
       (m_detBlockInfo.numberOfChannels != m_monBlockInfo.numberOfChannels)) &&
      nmons > 0) {
    // detectors and monitors have different characteristics. Can be loaded only
    // to separate workspaces.
    if (!removeMonitors) {
      g_log.warning() << " Performing separate loading as can not load spectra "
                         "and monitors in the single workspace:\n";
      g_log.warning() << " Monitors data contain :"
                      << m_monBlockInfo.numberOfChannels
                      << " time channels and: "
                      << m_monBlockInfo.numberOfPeriods << " period(s)\n";
      g_log.warning() << " Spectra  data contain :"
                      << m_detBlockInfo.numberOfChannels
                      << " time channels and: "
                      << m_detBlockInfo.numberOfPeriods << " period(s)\n";
    }
    separateMonitors = true;
    removeMonitors = true;
  }

  int64_t spectraID_min =
      std::min(m_monBlockInfo.spectraID_min, m_detBlockInfo.spectraID_min);
  int64_t spectraID_max =
      std::max(m_monBlockInfo.spectraID_max, m_detBlockInfo.spectraID_max);
  size_t totNumOfSpectra =
      m_monBlockInfo.numberOfSpectra + m_detBlockInfo.numberOfSpectra;
  if (!removeMonitors) {
    m_loadBlockInfo.numberOfSpectra = totNumOfSpectra;
    m_loadBlockInfo.spectraID_min = spectraID_min;
    m_loadBlockInfo.spectraID_max = spectraID_max;
  }
  if (separateMonitors)
    m_loadBlockInfo = m_detBlockInfo;

  // verify integrity of the monitor and detector information

  if ((totNumOfSpectra == static_cast<size_t>(n_vms_compat_spectra)) &&
      (spectraID_max - spectraID_min + 1 ==
       static_cast<int64_t>(n_vms_compat_spectra))) {
    // all information written in the file is correct, there are no spurious
    // spectra and detectors & monitors form continuous block on HDD
    return separateMonitors;
  }

  // something is wrong and we need to analyze spectra map.  Currently we can
  // identify and manage the case when all monitor's spectra are written
  // together with detectors
  // make settings for this situation
  m_detBlockInfo.numberOfSpectra -= m_monBlockInfo.numberOfSpectra;
  m_loadBlockInfo.numberOfSpectra -= m_monBlockInfo.numberOfSpectra;

  std::map<int64_t, std::string> remaining_monitors;
  if (removeMonitors) {
    for (auto it = monitors.begin(); it != monitors.end(); it++) {
      if (it->first >= m_detBlockInfo.spectraID_min &&
          it->first <= m_detBlockInfo.spectraID_max) { // monitors ID-s are
                                                       // included with spectra
                                                       // ID-s -- let's try not
                                                       // to load it twice.
        OvelapMonitors.insert(*it);
      } else {
        remaining_monitors.insert(*it);
      }
    }
  }
  monitors.swap(remaining_monitors);

  return separateMonitors;
}