Esempio n. 1
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 period :: The period of this workspace
    */
    void LoadISISNexus2::loadLogs(DataObjects::Workspace2D_sptr ws, int period)
    {
      IAlgorithm_sptr alg = createSubAlgorithm("LoadNexusLogs", 0.0, 0.5);
      alg->setPropertyValue("Filename", this->getProperty("Filename"));
      alg->setProperty<MatrixWorkspace_sptr>("Workspace", ws);
      try
      {
        alg->executeAsSubAlg();
      }
      catch(std::runtime_error&)
      {
        g_log.warning() << "Unable to load run logs. There will be no log "
                        << "data associated with this workspace\n";
        return;
      }
      ws->populateInstrumentParameters();
      // If we loaded an icp_event log then create the necessary period logs 
      if( ws->run().hasProperty("icp_event") )
      {
        Kernel::Property *log = ws->run().getProperty("icp_event");
        LogParser parser(log);
        ws->mutableRun().addProperty(parser.createPeriodLog(period));
        ws->mutableRun().addProperty(parser.createAllPeriodsLog());
      }

    }
Esempio n. 2
0
/// Run the LoadLog Child Algorithm
void LoadMuonNexus1::runLoadLog(DataObjects::Workspace2D_sptr localWorkspace) {
  IAlgorithm_sptr loadLog = createChildAlgorithm("LoadMuonLog");
  // Pass through the same input filename
  loadLog->setPropertyValue("Filename", m_filename);
  // Set the workspace property to be the same one filled above
  loadLog->setProperty<MatrixWorkspace_sptr>("Workspace", localWorkspace);

  // Now execute the Child Algorithm. Catch and log any error, but don't stop.
  try {
    loadLog->execute();
  } catch (std::runtime_error &) {
    g_log.error("Unable to successfully run LoadMuonLog Child Algorithm");
  } catch (std::logic_error &) {
    g_log.error("Unable to successfully run LoadMuonLog Child Algorithm");
  }

  if (!loadLog->isExecuted())
    g_log.error("Unable to successfully run LoadMuonLog Child Algorithm");

  NXRoot root(m_filename);

  // Get main field direction
  std::string mainFieldDirection = "Longitudinal"; // default
  try {
    NXChar orientation = root.openNXChar("run/instrument/detector/orientation");
    // some files have no data there
    orientation.load();

    if (orientation[0] == 't') {
      auto p =
          Kernel::make_unique<Kernel::TimeSeriesProperty<double>>("fromNexus");
      std::string start_time = root.getString("run/start_time");
      p->addValue(start_time, -90.0);
      localWorkspace->mutableRun().addLogData(std::move(p));
      mainFieldDirection = "Transverse";
    }
  } catch (...) {
    // no data - assume main field was longitudinal
  }

  // set output property and add to workspace logs
  auto &run = localWorkspace->mutableRun();
  setProperty("MainFieldDirection", mainFieldDirection);
  run.addProperty("main_field_direction", mainFieldDirection);

  ISISRunLogs runLogs(run);
  runLogs.addStatusLog(run);
}
Esempio n. 3
0
/// Run the LoadLog Child Algorithm
void LoadMuonNexus1::runLoadLog(DataObjects::Workspace2D_sptr localWorkspace) {
  IAlgorithm_sptr loadLog = createChildAlgorithm("LoadMuonLog");
  // Pass through the same input filename
  loadLog->setPropertyValue("Filename", m_filename);
  // Set the workspace property to be the same one filled above
  loadLog->setProperty<MatrixWorkspace_sptr>("Workspace", localWorkspace);

  // Now execute the Child Algorithm. Catch and log any error, but don't stop.
  try {
    loadLog->execute();
  } catch (std::runtime_error &) {
    g_log.error("Unable to successfully run LoadLog Child Algorithm");
  } catch (std::logic_error &) {
    g_log.error("Unable to successfully run LoadLog Child Algorithm");
  }

  if (!loadLog->isExecuted())
    g_log.error("Unable to successfully run LoadLog Child Algorithm");

  NXRoot root(m_filename);

  try {
    NXChar orientation = root.openNXChar("run/instrument/detector/orientation");
    // some files have no data there
    orientation.load();

    if (orientation[0] == 't') {
      Kernel::TimeSeriesProperty<double> *p =
          new Kernel::TimeSeriesProperty<double>("fromNexus");
      std::string start_time = root.getString("run/start_time");
      p->addValue(start_time, -90.0);
      localWorkspace->mutableRun().addLogData(p);
      setProperty("MainFieldDirection", "Transverse");
    } else {
      setProperty("MainFieldDirection", "Longitudinal");
    }
  } catch (...) {
    setProperty("MainFieldDirection", "Longitudinal");
  }

  auto &run = localWorkspace->mutableRun();
  int n = static_cast<int>(m_numberOfPeriods);
  ISISRunLogs runLogs(run, n);
  runLogs.addStatusLog(run);
}
Esempio n. 4
0
/**
 * Add the 'period i' log to a workspace.
 * @param localWorkspace A workspace to add the log to.
 * @param period A period for this workspace.
 */
void LoadMuonNexus1::addPeriodLog(DataObjects::Workspace2D_sptr localWorkspace,
                                  int64_t period) {
  auto &run = localWorkspace->mutableRun();
  ISISRunLogs runLogs(run);
  if (period == 0) {
    runLogs.addPeriodLogs(1, run);
  } else {
    run.removeLogData("period 1");
    runLogs.addPeriodLog(static_cast<int>(period) + 1, run);
  }
}
Esempio n. 5
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());
    }
Esempio n. 6
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));
  }



}
Esempio n. 7
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);
  }
}
Esempio n. 8
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();
    }
Esempio n. 9
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;
      }
    }
Esempio n. 10
0
    /** Executes the algorithm. Reading in the file and creating and populating
     *  the output workspace
     *
     *  @throw Exception::FileError If the RAW file cannot be found/opened
     *  @throw std::invalid_argument If the optional properties are set to invalid values
     */
    void LoadRaw::exec()
    {
      // Retrieve the filename from the properties
      m_filename = getPropertyValue("Filename");

      LoadRawHelper *helper = new LoadRawHelper;
      FILE* file = helper->openRawFile(m_filename);
      ISISRAW iraw;
      iraw.ioRAW(file, true);

      std::string title(iraw.r_title, 80);
      g_log.information("**** Run title: "+title+ "***");
      
      // Read in the number of spectra in the RAW file
      m_numberOfSpectra = iraw.t_nsp1;
      // Read the number of periods in this file
      m_numberOfPeriods = iraw.t_nper;
      // Need to extract the user-defined output workspace name
      Property *ws = getProperty("OutputWorkspace");
      std::string localWSName = ws->value();

      // Call private method to validate the optional parameters, if set
      checkOptionalProperties();

      // Read the number of time channels (i.e. bins) from the RAW file
      const int channelsPerSpectrum = iraw.t_ntc1;
      // Read in the time bin boundaries
      const int lengthIn = channelsPerSpectrum + 1;
      float* timeChannels = new float[lengthIn];
      iraw.getTimeChannels(timeChannels, lengthIn);
      // Put the read in array into a vector (inside a shared pointer)
      boost::shared_ptr<MantidVec> timeChannelsVec
                          (new MantidVec(timeChannels, timeChannels + lengthIn));
      // Create an array to hold the read-in data
      int* spectrum = new int[lengthIn];

      // Calculate the size of a workspace, given its number of periods & spectra to read
      specid_t total_specs;
      if( m_interval || m_list)
      {
        total_specs = static_cast<specid_t>(m_spec_list.size());
        if (m_interval)
        {
          total_specs += (m_spec_max-m_spec_min+1);
          m_spec_max += 1;
        }
      }
      else
      {
        total_specs = m_numberOfSpectra;
        // In this case want all the spectra, but zeroth spectrum is garbage so go from 1 to NSP1
        m_spec_min = 1;
        m_spec_max = m_numberOfSpectra + 1;
      }

      double histTotal = static_cast<double>(total_specs * m_numberOfPeriods);
      int32_t histCurrent = -1;

      // Create the 2D workspace for the output
      DataObjects::Workspace2D_sptr localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
               (WorkspaceFactory::Instance().create("Workspace2D",total_specs,lengthIn,lengthIn-1));
      localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
      localWorkspace->setTitle(title);
      // Run parameters
      helper->loadRunParameters(localWorkspace, &iraw);
      delete helper;
      helper = NULL;


      // Loop over the number of periods in the raw file, putting each period in a separate workspace
      for (int period = 0; period < m_numberOfPeriods; ++period) {

        if ( period > 0 ) localWorkspace =  boost::dynamic_pointer_cast<DataObjects::Workspace2D>
                                              (WorkspaceFactory::Instance().create(localWorkspace));

        specid_t counter = 0;
        for (specid_t i = m_spec_min; i < m_spec_max; ++i)
        {
          // Shift the histogram to read if we're not in the first period
          int32_t histToRead = i + period*total_specs;
          loadData(timeChannelsVec,counter,histToRead,iraw,lengthIn,spectrum,localWorkspace );
          counter++;
          if (++histCurrent % 100 == 0) progress(static_cast<double>(histCurrent)/histTotal);
          interruption_point();
        }
        // Read in the spectra in the optional list parameter, if set
        if (m_list)
        {
          for(size_t i=0; i < m_spec_list.size(); ++i)
          {
            loadData(timeChannelsVec,counter,m_spec_list[i],iraw,lengthIn,spectrum, localWorkspace );
            counter++;
            if (++histCurrent % 100 == 0) progress(static_cast<double>(histCurrent)/histTotal);
            interruption_point();
          }
        }
        // Just a sanity check
        assert(counter == total_specs);

        std::string outputWorkspace = "OutputWorkspace";
        if (period == 0)
        {
          // Only run the Child Algorithms once
          runLoadInstrument(localWorkspace );
          runLoadMappingTable(localWorkspace );
          runLoadLog(localWorkspace );
          const int period_number = 1;
          Property* log=createPeriodLog(period_number);
          if(log)
          {
            localWorkspace->mutableRun().addLogData(log);
            localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
          }
          // Set the total proton charge for this run
          // (not sure how this works for multi_period files)
          localWorkspace->mutableRun().setProtonCharge(iraw.rpb.r_gd_prtn_chrg);
        }
        else   // We are working on a higher period of a multiperiod raw file
        {
          // Create a WorkspaceProperty for the new workspace of a higher period
          // The workspace name given in the OutputWorkspace property has _periodNumber appended to it
          //                (for all but the first period, which has no suffix)
          std::stringstream suffix;
          suffix << (period+1);
          outputWorkspace += suffix.str();
          std::string WSName = localWSName + "_" + suffix.str();
          declareProperty(new WorkspaceProperty<DataObjects::Workspace2D>(outputWorkspace,WSName,Direction::Output));
          g_log.information() << "Workspace " << WSName << " created. \n";
        }

        if (localWorkspace)
          localWorkspace->updateSpectraUsingMap();

        // Assign the result to the output workspace property
        setProperty(outputWorkspace,localWorkspace);

      } // loop over periods

      // Clean up
      delete[] timeChannels;
      delete[] spectrum;
    }
Esempio n. 11
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();
}
Esempio n. 12
0
/**
* Creates period log data in the workspace
* @param period :: period number
* @param local_workspace :: workspace to add period log data to.
*/
void LoadISISNexus2::createPeriodLogs(
    int64_t period, DataObjects::Workspace2D_sptr &local_workspace) {
  m_logCreator->addPeriodLogs(static_cast<int>(period),
                              local_workspace->mutableRun());
}
Esempio n. 13
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;
  }
}
Esempio n. 14
0
    /// Overwrites Algorithm exec method
    void LoadSpice2D::exec()
    {
      std::string fileName = getPropertyValue("Filename");

      const double wavelength_input = getProperty("Wavelength");
      const double wavelength_spread_input = getProperty("WavelengthSpread");

      // Set up the DOM parser and parse xml file
      DOMParser pParser;
      Document* pDoc;
      try
      {
        pDoc = pParser.parse(fileName);
      } catch (...)
      {
        throw Kernel::Exception::FileError("Unable to parse File:", fileName);
      }
      // Get pointer to root element
      Element* pRootElem = pDoc->documentElement();
      if (!pRootElem->hasChildNodes())
      {
        throw Kernel::Exception::NotFoundError("No root element in Spice XML file", fileName);
      }

      // Read in start time
      const std::string start_time = pRootElem->getAttribute("start_time");

      Element* sasEntryElem = pRootElem->getChildElement("Header");
      throwException(sasEntryElem, "Header", fileName);

      // Read in scan title
      Element* element = sasEntryElem->getChildElement("Scan_Title");
      throwException(element, "Scan_Title", fileName);
      std::string wsTitle = element->innerText();

      // Read in instrument name
      element = sasEntryElem->getChildElement("Instrument");
      throwException(element, "Instrument", fileName);
      std::string instrument = element->innerText();

      // Read sample thickness
      double sample_thickness = 0;
      from_element<double>(sample_thickness, sasEntryElem, "Sample_Thickness", fileName);

      double source_apert = 0.0;
      from_element<double>(source_apert, sasEntryElem, "source_aperture_size", fileName);

      double sample_apert = 0.0;
      from_element<double>(sample_apert, sasEntryElem, "sample_aperture_size", fileName);

      double source_distance = 0.0;
      from_element<double>(source_distance, sasEntryElem, "source_distance", fileName);

      // Read in wavelength and wavelength spread
      double wavelength = 0;
      double dwavelength = 0;
      if ( isEmpty(wavelength_input) ) {
        from_element<double>(wavelength, sasEntryElem, "wavelength", fileName);
        from_element<double>(dwavelength, sasEntryElem, "wavelength_spread", fileName);
      }
      else
      {
        wavelength = wavelength_input;
        dwavelength = wavelength_spread_input;
      }

      // Read in positions
      sasEntryElem = pRootElem->getChildElement("Motor_Positions");
      throwException(sasEntryElem, "Motor_Positions", fileName);

      // Read in the number of guides
      int nguides = 0;
      from_element<int>(nguides, sasEntryElem, "nguides", fileName);

      // Read in sample-detector distance in mm
      double distance = 0;
      from_element<double>(distance, sasEntryElem, "sample_det_dist", fileName);
      distance *= 1000.0;

      // Read in beam trap positions
      double highest_trap = 0;
      double trap_pos = 0;

      from_element<double>(trap_pos, sasEntryElem, "trap_y_25mm", fileName);
      double beam_trap_diam = 25.4;

      from_element<double>(highest_trap, sasEntryElem, "trap_y_101mm", fileName);
      if (trap_pos>highest_trap)
      {
        highest_trap = trap_pos;
        beam_trap_diam = 101.6;
      }

      from_element<double>(trap_pos, sasEntryElem, "trap_y_50mm", fileName);
      if (trap_pos>highest_trap)
      {
        highest_trap = trap_pos;
        beam_trap_diam = 50.8;
      }

      from_element<double>(trap_pos, sasEntryElem, "trap_y_76mm", fileName);
      if (trap_pos>highest_trap)
      {
        highest_trap = trap_pos;
        beam_trap_diam = 76.2;
      }

      // Read in counters
      sasEntryElem = pRootElem->getChildElement("Counters");
      throwException(sasEntryElem, "Counters", fileName);

      double countingTime = 0;
      from_element<double>(countingTime, sasEntryElem, "time", fileName);
      double monitorCounts = 0;
      from_element<double>(monitorCounts, sasEntryElem, "monitor", fileName);

      // Read in the data image
      Element* sasDataElem = pRootElem->getChildElement("Data");
      throwException(sasDataElem, "Data", fileName);

      // Read in the data buffer
      element = sasDataElem->getChildElement("Detector");
      throwException(element, "Detector", fileName);
      std::string data_str = element->innerText();

      // Read in the detector dimensions from the Detector tag
      int numberXPixels = 0;
      int numberYPixels = 0;
      std::string data_type = element->getAttribute("type");
      boost::regex b_re_sig("INT\\d+\\[(\\d+),(\\d+)\\]");
      if (boost::regex_match(data_type, b_re_sig))
      {
        boost::match_results<std::string::const_iterator> match;
        boost::regex_search(data_type, match, b_re_sig);
        // match[0] is the full string
        Kernel::Strings::convert(match[1], numberXPixels);
        Kernel::Strings::convert(match[2], numberYPixels);
      }
      if (numberXPixels==0 || numberYPixels==0)
        g_log.notice() << "Could not read in the number of pixels!" << std::endl;

      // We no longer read from the meta data because that data is wrong
      //from_element<int>(numberXPixels, sasEntryElem, "Number_of_X_Pixels", fileName);
      //from_element<int>(numberYPixels, sasEntryElem, "Number_of_Y_Pixels", fileName);

      // Store sample-detector distance
      declareProperty("SampleDetectorDistance", distance, Kernel::Direction::Output);

      // Create the output workspace

      // Number of bins: we use a single dummy TOF bin
      int nBins = 1;
      // Number of detectors: should be pulled from the geometry description. Use detector pixels for now.
      // The number of spectram also includes the monitor and the timer.
      int numSpectra = numberXPixels*numberYPixels + LoadSpice2D::nMonitors;

      DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", numSpectra, nBins+1, nBins));
      ws->setTitle(wsTitle);
      ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Wavelength");
      ws->setYUnit("");
      API::Workspace_sptr workspace = boost::static_pointer_cast<API::Workspace>(ws);
      setProperty("OutputWorkspace", workspace);

      // Parse out each pixel. Pixels can be separated by white space, a tab, or an end-of-line character
      Poco::StringTokenizer pixels(data_str, " \n\t", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
      Poco::StringTokenizer::Iterator pixel = pixels.begin();

      // Check that we don't keep within the size of the workspace
      size_t pixelcount = pixels.count();
      if( pixelcount != static_cast<size_t>(numberXPixels*numberYPixels) )
      {
        throw Kernel::Exception::FileError("Inconsistent data set: "
            "There were more data pixels found than declared in the Spice XML meta-data.", fileName);
      }
      if( numSpectra == 0 )
      {
        throw Kernel::Exception::FileError("Empty data set: the data file has no pixel data.", fileName);
      }

      // Go through all detectors/channels
      int ipixel = 0;

      // Store monitor count
      store_value(ws, ipixel++, monitorCounts, monitorCounts>0 ? sqrt(monitorCounts) : 0.0,
          wavelength, dwavelength);

      // Store counting time
      store_value(ws, ipixel++, countingTime, 0.0, wavelength, dwavelength);

      // Store detector pixels
      while (pixel != pixels.end())
      {
        //int ix = ipixel%npixelsx;
        //int iy = (int)ipixel/npixelsx;

        // Get the count value and assign it to the right bin
        double count = 0.0;
        from_string<double>(count, *pixel, std::dec);

        // Data uncertainties, computed according to the HFIR/IGOR reduction code
        // The following is what I would suggest instead...
        // error = count > 0 ? sqrt((double)count) : 0.0;
        double error = sqrt( 0.5 + fabs( count - 0.5 ));

        store_value(ws, ipixel, count, error, wavelength, dwavelength);

        // Set the spectrum number
        ws->getAxis(1)->setValue(ipixel, ipixel);

        ++pixel;
        ipixel++;
      }

      // run load instrument
      runLoadInstrument(instrument, ws);
      runLoadMappingTable(ws, numberXPixels, numberYPixels);

      // Set the run properties
      ws->mutableRun().addProperty("sample-detector-distance", distance, "mm", true);
      ws->mutableRun().addProperty("beam-trap-diameter", beam_trap_diam, "mm", true);
      ws->mutableRun().addProperty("number-of-guides", nguides, true);
      ws->mutableRun().addProperty("source-sample-distance", source_distance, "mm", true);
      ws->mutableRun().addProperty("source-aperture-diameter", source_apert, "mm", true);
      ws->mutableRun().addProperty("sample-aperture-diameter", sample_apert, "mm", true);
      ws->mutableRun().addProperty("sample-thickness", sample_thickness, "cm", true);
      ws->mutableRun().addProperty("wavelength", wavelength, "Angstrom", true);
      ws->mutableRun().addProperty("wavelength-spread", dwavelength, "Angstrom", true);
      ws->mutableRun().addProperty("timer", countingTime, "sec", true);
      ws->mutableRun().addProperty("monitor", monitorCounts, "", true);
      ws->mutableRun().addProperty("start_time", start_time, "", true);
      ws->mutableRun().addProperty("run_start", start_time, "", true);

      // Move the detector to the right position
      API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");

      // Finding the name of the detector object.
      std::string detID = ws->getInstrument()->getStringParameter("detector-name")[0];

      g_log.information("Moving "+detID);
      try
      {
        mover->setProperty<API::MatrixWorkspace_sptr> ("Workspace", ws);
        mover->setProperty("ComponentName", detID);
        mover->setProperty("Z", distance/1000.0);
        mover->execute();
      } catch (std::invalid_argument& e)
      {
        g_log.error("Invalid argument to MoveInstrumentComponent Child Algorithm");
        g_log.error(e.what());
      } catch (std::runtime_error& e)
      {
        g_log.error("Unable to successfully run MoveInstrumentComponent Child Algorithm");
        g_log.error(e.what());
      }

      // Release the XML document memory
      pDoc->release();
    }
Esempio n. 15
0
/** Executes the algorithm. Reading in the file and creating and populating
 *  the output workspace
 *
 *  @throw Exception::FileError If the RAW file cannot be found/opened
 *  @throw std::invalid_argument If the optional properties are set to invalid values
 */
void LoadRawBin0::exec()
{
	// Retrieve the filename from the properties
	m_filename = getPropertyValue("Filename");

	bool bLoadlogFiles = getProperty("LoadLogFiles");

	//open the raw file
	FILE* file=openRawFile(m_filename);

	// Need to check that the file is not a text file as the ISISRAW routines don't deal with these very well, i.e 
	// reading continues until a bad_alloc is encountered.
	if( isAscii(file) )
	{
		g_log.error() << "File \"" << m_filename << "\" is not a valid RAW file.\n";
		throw std::invalid_argument("Incorrect file type encountered.");
	}
	std::string title;
	readTitle(file,title);

	readworkspaceParameters(m_numberOfSpectra,m_numberOfPeriods,m_lengthIn,m_noTimeRegimes);

	///
	setOptionalProperties();

	// to validate the optional parameters, if set
	checkOptionalProperties();

    // Calculate the size of a workspace, given its number of periods & spectra to read
     m_total_specs = calculateWorkspaceSize();

 //no real X values for bin 0,so initialize this to zero
  boost::shared_ptr<MantidVec> channelsVec(new MantidVec(1,0));
  m_timeChannelsVec.push_back(channelsVec);

  double histTotal = static_cast<double>(m_total_specs * m_numberOfPeriods);
  int64_t histCurrent = -1;
 
  // Create the 2D workspace for the output xlength and ylength is one 
  DataObjects::Workspace2D_sptr localWorkspace = createWorkspace(m_total_specs, 1,1,title);
  Run& run = localWorkspace->mutableRun();
  if (bLoadlogFiles)
  {
    runLoadLog(m_filename,localWorkspace, 0.0, 0.0);
    const int period_number = 1;
    createPeriodLogs(period_number, localWorkspace);
  }
  // Set the total proton charge for this run
  setProtonCharge(run);

  WorkspaceGroup_sptr ws_grp = createGroupWorkspace();
  setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods, false);
    
  // Loop over the number of periods in the raw file, putting each period in a separate workspace
  for (int period = 0; period < m_numberOfPeriods; ++period)
  {
    if (period > 0)
    {
      localWorkspace=createWorkspace(localWorkspace);

      if (bLoadlogFiles)
      {
        //remove previous period data
        std::stringstream prevPeriod;
        prevPeriod << "PERIOD " << (period);
        Run& runObj = localWorkspace->mutableRun();
        runObj.removeLogData(prevPeriod.str());
        runObj.removeLogData("current_period");
        //add current period data
        const int period_number = period + 1;
        createPeriodLogs(period_number, localWorkspace);
      }

    }
    skipData(file, period * (m_numberOfSpectra + 1));
    int64_t wsIndex = 0;
    for (specid_t i = 1; i <= m_numberOfSpectra; ++i)
    {
      int64_t histToRead = i + period * (m_numberOfSpectra + 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()))
      {
        progress(m_prog, "Reading raw file data...");
        //readData(file, histToRead);
		  //read spectrum 
		  if (!readData(file, histToRead))
		  {
			  throw std::runtime_error("Error reading raw file");
		  }
		  int64_t binStart=0;
		  setWorkspaceData(localWorkspace, m_timeChannelsVec, wsIndex, i, m_noTimeRegimes,1,binStart);
		  ++wsIndex;

      if (m_numberOfPeriods == 1)
      {
        if (++histCurrent % 100 == 0)
        {
          m_prog = double(histCurrent) / histTotal;
        }
        interruption_point();
      }

    }
	  else
	  {
		  skipData(file, histToRead);
	  }
    
    }
	
	if(m_numberOfPeriods>1)
	{
		setWorkspaceProperty(localWorkspace, ws_grp, period, false);
		// progress for workspace groups 
		m_prog = static_cast<double>(period) / static_cast<double>(m_numberOfPeriods - 1);
	}
  
  } // loop over periods
  // Clean up
  isisRaw.reset();
  fclose(file);
}
Esempio n. 16
0
    /** Executes the algorithm. Reading in the file and creating and populating
     *  the output workspace
     *
     *  @throw Exception::FileError If the RAW file cannot be found/opened
     *  @throw std::invalid_argument If the optional properties are set to invalid values
     */
    void LoadRaw2::exec()
    {
      // Retrieve the filename from the properties
      m_filename = getPropertyValue("Filename");
      LoadRawHelper *helper = new LoadRawHelper;
      FILE* file = helper->openRawFile(m_filename);
      isisRaw->ioRAW(file, true);
      
      std::string title(isisRaw->r_title, 80);
      g_log.information("**** Run title: "+ title + "***");

      // Read in the number of spectra in the RAW file
      m_numberOfSpectra = isisRaw->t_nsp1;
      // Read the number of periods in this file
      m_numberOfPeriods = isisRaw->t_nper;
      // Read the number of time channels (i.e. bins) from the RAW file
      const int channelsPerSpectrum = isisRaw->t_ntc1;
      // Read in the time bin boundaries
      const int lengthIn = channelsPerSpectrum + 1;

      // Call private method to validate the optional parameters, if set
      checkOptionalProperties();

      // Calculate the size of a workspace, given its number of periods & spectra to read
      specid_t total_specs;
      if( m_interval || m_list)
      {
        if (m_interval)
        {
          total_specs = (m_spec_max-m_spec_min+1);
          m_spec_max += 1;
        }
        else
            total_specs = 0;

        if (m_list)
        {
            if (m_interval)
            {
                for(std::vector<specid_t>::iterator it=m_spec_list.begin();it!=m_spec_list.end();)
                    if (*it >= m_spec_min && *it <m_spec_max)
                    {
                        it = m_spec_list.erase(it);
                    }
                    else
                        ++it;

            }
            if (m_spec_list.size() == 0) m_list = false;
            total_specs += static_cast<specid_t>(m_spec_list.size());
        }
      }
      else
      {
        total_specs = m_numberOfSpectra;
        // In this case want all the spectra, but zeroth spectrum is garbage so go from 1 to NSP1
        m_spec_min = 1;
        m_spec_max = m_numberOfSpectra + 1;
      }

      // If there is not enough memory use ManagedRawFileWorkspace2D.
      if ( ConfigService::Instance().getString("ManagedRawFileWorkspace.DoNotUse") != "1" &&
           m_numberOfPeriods == 1 && MemoryManager::Instance().goForManagedWorkspace(total_specs,lengthIn,channelsPerSpectrum) &&
          total_specs == m_numberOfSpectra)
      {
        const std::string cache_option = getPropertyValue("Cache");
        size_t option = find(m_cache_options.begin(),m_cache_options.end(),cache_option) - m_cache_options.begin();
        DataObjects::Workspace2D_sptr localWorkspace =
          DataObjects::Workspace2D_sptr(
          new ManagedRawFileWorkspace2D(m_filename, static_cast<int>(option)));
        progress(0.,"Reading raw file...");
        helper->loadRunParameters(localWorkspace, isisRaw.get());
        runLoadInstrument(localWorkspace );
        runLoadMappingTable(localWorkspace );
        runLoadLog(localWorkspace );
        const int period_number = 1;
        Property* log=createPeriodLog(period_number);
        if(log)
        {
          localWorkspace->mutableRun().addLogData(log);
          localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
        }
              localWorkspace->mutableRun().setProtonCharge(isisRaw->rpb.r_gd_prtn_chrg);
        for (int i = 0; i < m_numberOfSpectra; ++i)
          localWorkspace->getAxis(1)->setValue(i, i+1);
        localWorkspace->populateInstrumentParameters();
        setProperty("OutputWorkspace",localWorkspace);
        return;
      }

      float* timeChannels = new float[lengthIn];
      isisRaw->getTimeChannels(timeChannels, lengthIn);
      // Put the read in array into a vector (inside a shared pointer)
      boost::shared_ptr<MantidVec> timeChannelsVec
                          (new MantidVec(timeChannels, timeChannels + lengthIn));

      // Need to extract the user-defined output workspace name
      Property *ws = getProperty("OutputWorkspace");
      std::string localWSName = ws->value();

      Progress pr(this,0.,1.,total_specs * m_numberOfPeriods);

      // Create the 2D workspace for the output
      DataObjects::Workspace2D_sptr localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
               (WorkspaceFactory::Instance().create("Workspace2D",total_specs,lengthIn,lengthIn-1));
      localWorkspace->setTitle(title);
      localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
      // Run parameters
      helper->loadRunParameters(localWorkspace, isisRaw.get());
      delete helper;
      helper = NULL;

      // Loop over the number of periods in the raw file, putting each period in a separate workspace
      for (int period = 0; period < m_numberOfPeriods; ++period) {

        if ( period > 0 )
        {
            localWorkspace =  boost::dynamic_pointer_cast<DataObjects::Workspace2D>
                (WorkspaceFactory::Instance().create(localWorkspace));
        }

        isisRaw->skipData(file,period*(m_numberOfSpectra+1));
        int counter = 0;
        for (int i = 1; i <= m_numberOfSpectra; ++i)
        {
            int histToRead = i + period*(m_numberOfSpectra+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()))
            {
                isisRaw->readData(file,histToRead);
                // Copy the data into the workspace vector, discarding the 1st entry, which is rubbish
                // But note that the last (overflow) bin is kept
                MantidVec& Y = localWorkspace->dataY(counter);
                Y.assign(isisRaw->dat1 + 1, isisRaw->dat1 + lengthIn);
                // Fill the vector for the errors, containing sqrt(count)
                MantidVec& E = localWorkspace->dataE(counter);
                std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
                // Set the X vector pointer and spectrum number
                localWorkspace->setX(counter, timeChannelsVec);
                localWorkspace->getAxis(1)->setValue(counter, i);
                // NOTE: Raw numbers go straight into the workspace
                //     - no account taken of bin widths/units etc.
                ++counter;
                pr.report();
            }
            else
            {
                isisRaw->skipData(file,histToRead);
            }
        }

        // Just a sanity check
        assert(counter == total_specs);

        std::string outputWorkspace = "OutputWorkspace";
        if (period == 0)
        {
          // Only run the Child Algorithms once
          runLoadInstrument(localWorkspace );
          runLoadMappingTable(localWorkspace );
          runLoadLog(localWorkspace );
          const int period_number = period + 1;
          Property* log=createPeriodLog(period_number);
          if(log)
          {
            localWorkspace->mutableRun().addLogData(log);
            localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
          }
          // Set the total proton charge for this run
          // (not sure how this works for multi_period files)
          localWorkspace->mutableRun().setProtonCharge(isisRaw->rpb.r_gd_prtn_chrg);
        }
        else   // We are working on a higher period of a multiperiod raw file
        {
          // Create a WorkspaceProperty for the new workspace of a higher period
          // The workspace name given in the OutputWorkspace property has _periodNumber appended to it
          //                (for all but the first period, which has no suffix)
          std::stringstream suffix;
          suffix << (period+1);
          outputWorkspace += suffix.str();
          std::string WSName = localWSName + "_" + suffix.str();
          declareProperty(new WorkspaceProperty<DataObjects::Workspace2D>(outputWorkspace,WSName,Direction::Output));
          g_log.information() << "Workspace " << WSName << " created. \n";
                         
          //remove previous period data
          std::stringstream index;
          index << (period);
          std::string prevPeriod="PERIOD "+index.str();
          localWorkspace->mutableRun().removeLogData(prevPeriod);
          localWorkspace->mutableRun().removeLogData("current_period");
          //add current period data
          const int period_number = period + 1;
          Property* log=createPeriodLog(period_number);
          if(log)
          {
            localWorkspace->mutableRun().addLogData(log);
            localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
          }
        }

        // check if values stored in logfiles should be used to define parameters of the instrument
        localWorkspace->populateInstrumentParameters();

        // Assign the result to the output workspace property
        setProperty(outputWorkspace,localWorkspace);

      } // loop over periods

      // Clean up
      delete[] timeChannels;
      //delete[] spectrum;
      fclose(file);
    }
Esempio n. 17
0
void LoadMuonNexus1::addGoodFrames(DataObjects::Workspace2D_sptr localWorkspace,
                                   int64_t period, int nperiods) {

  // Get handle to nexus file
  ::NeXus::File handle(m_filename, NXACC_READ);

  // For single-period datasets, read /run/instrument/beam/frames_good
  if ( nperiods == 1 ) {

    try {

      handle.openPath("run/instrument/beam");
      handle.openData("frames_good");

      // read frames_period_daq
      boost::scoped_array<int> dataVals(new int[1]);
      handle.getData(dataVals.get());

      auto &run = localWorkspace->mutableRun();
      run.addProperty("goodfrm", dataVals[0]);

    } catch (::NeXus::Exception &) {
      g_log.warning("Could not read /run/instrument/beam/frames_good");
    }

  } else {
    // For multi-period datasets, read entries in
    // /run/instrument/beam/frames_period_daq
    try {

      handle.openPath("run/instrument/beam/");
      handle.openData("frames_period_daq");

      ::NeXus::Info info = handle.getInfo();
      // Check that frames_period_daq contains values for
      // every period
      if (period >= info.dims[0]) {
        std::ostringstream error;
        error << "goodfrm not found for period " << period;
        throw std::runtime_error(error.str());
      }
      if (nperiods != info.dims[0]) {
        std::ostringstream error;
        error << "Inconsistent number of period entries found (";
        error << info.dims[0];
        error << "!=" << nperiods << ")";
        throw std::runtime_error(error.str());
      }

      // read frames_period_daq
      boost::scoped_array<int> dataVals(new int[info.dims[0]]);
      handle.getData(dataVals.get());

      auto &run = localWorkspace->mutableRun();
      if (period == 0) {
        // If this is the first period
        // localWorkspace will not contain goodfrm
        run.addProperty("goodfrm", dataVals[0]);

      } else {
        // If period > 0, we need to remove
        // previous goodfrm log value
        run.removeLogData("goodfrm");
        run.addProperty("goodfrm", dataVals[period]);
      }
    } catch (::NeXus::Exception &) {
      g_log.warning("Could not read /run/instrument/beam/frames_period_daq");
    }
  } // else

  handle.close();
}