Skip to content
Snippets Groups Projects
LoadMuonNexus.cpp 26.8 KiB
Newer Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/LoadMuonNexus.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/ArrayProperty.h"
Nick Draper's avatar
Nick Draper committed
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidAPI/SpectraDetectorMap.h"
#include "MantidKernel/TimeSeriesProperty.h"
Campbell, Stuart's avatar
Campbell, Stuart committed
#include <Poco/Path.h>
Peterson, Peter's avatar
Peterson, Peter committed
#include <limits>
#include <cmath>
#include <boost/shared_ptr.hpp>
#include "MantidNexus/MuonNexusReader.h"
#include "MantidNexus/NexusClasses.h"
#include "MantidNexus/NeXusFile.hpp"
#include "MantidNexus/NeXusException.hpp"
  {
    // Register the algorithm into the algorithm factory
    DECLARE_ALGORITHM(LoadMuonNexus)
    
    /// Sets documentation strings for this algorithm
    void LoadMuonNexus::initDocs()
    {
      this->setWikiSummary("The LoadMuonNexus algorithm will read the given NeXus Muon data file Version 1 and use the results to populate the named workspace. LoadMuonNexus may be invoked by [[LoadNexus]] if it is given a NeXus file of this type. ");
      this->setOptionalMessage("The LoadMuonNexus algorithm will read the given NeXus Muon data file Version 1 and use the results to populate the named workspace. LoadMuonNexus may be invoked by LoadNexus if it is given a NeXus file of this type.");
    using namespace Mantid::NeXus;

    /// Empty default constructor
    LoadMuonNexus::LoadMuonNexus() : 
     m_filename(), m_entrynumber(0), m_numberOfSpectra(0), m_numberOfPeriods(0), m_list(false),
      m_interval(false), m_spec_list(), m_spec_min(0), m_spec_max(EMPTY_INT())
    {}

    /// Initialisation method.
    void LoadMuonNexus::init()
    {
      declareProperty(new FileProperty("Filename", "", FileProperty::Load, ".nxs"),
        "The name of the Nexus file to load" );      
      declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace","",Direction::Output),
        "The name of the workspace to be created as the output of the\n"
        "algorithm. For multiperiod files, one workspace will be\n"
        "generated for each period");
      BoundedValidator<int64_t> *mustBePositive = new BoundedValidator<int64_t>();
      declareProperty( "SpectrumMin",(int64_t)0, mustBePositive,
        "Index number of the first spectrum to read, only used if\n"
        "spectrum_max is set and only for single period data\n"
        "(default 0)" );
      declareProperty( "SpectrumMax",(int64_t)EMPTY_INT(), mustBePositive->clone(),
        "Index of last spectrum to read, only for single period data\n"
        "(default the last spectrum)");
      declareProperty(new ArrayProperty<specid_t>("SpectrumList"), 
        "Array, or comma separated list, of indexes of spectra to\n"
        "load");
      declareProperty("AutoGroup",false,
        "Determines whether the spectra are automatically grouped\n"
        "together based on the groupings in the NeXus file, only\n"
        "for single period data (default no)");
      declareProperty("EntryNumber", (int64_t)0, mustBePositive->clone(),
        "The particular entry number to read (default: Load all workspaces and creates a workspace group)");

      std::vector<std::string> FieldOptions;
      FieldOptions.push_back("Transverse");
      FieldOptions.push_back("Longitudinal");
      declareProperty("MainFieldDirection","Transverse",new ListValidator(FieldOptions),
        "Output the main field direction if specified in Nexus file (default Transverse)", Direction::Output);

      declareProperty("TimeZero", 0.0, "Time zero in units of micro-seconds (default to 0.0)", Direction::Output);
      declareProperty("FirstGoodData", 0.0, "First good data in units of micro-seconds (default to 0.0)", Direction::Output);
    }

    /** Executes the algorithm. Reading in the file and creating and populating
    *  the output workspace
    * 
    *  @throw Exception::FileError If the Nexus file cannot be found/opened
    *  @throw std::invalid_argument If the optional properties are set to invalid values
    */
      // Retrieve the filename from the properties
      m_filename = getPropertyValue("Filename");
      // Retrieve the entry number
      m_entrynumber = getProperty("EntryNumber");
      MuonNexusReader nxload;
      if (nxload.readFromFile(m_filename) != 0)
      {
        g_log.error("Unable to open file " + m_filename);
        throw Exception::FileError("Unable to open File:" , m_filename);  
      }

      // Read in the instrument name from the Nexus file
      m_instrument_name = nxload.getInstrumentName();
      // Read in the number of spectra in the Nexus file
      m_numberOfSpectra = nxload.t_nsp1;
      if(m_entrynumber!=0)
      {
        m_numberOfPeriods=1;
        if(m_entrynumber>nxload.t_nper)
        {
          throw std::invalid_argument("Invalid Entry Number:Enter a valid number");
        }
      }
      else
      {
        // Read the number of periods in this file
        m_numberOfPeriods = nxload.t_nper;
      }
      // Need to extract the user-defined output workspace name
      Property *ws = getProperty("OutputWorkspace");
      std::string localWSName = ws->value();
      // If multiperiod, will need to hold the Instrument, Sample & SpectraDetectorMap for copying
      boost::shared_ptr<IInstrument> instrument;
      boost::shared_ptr<Sample> sample;

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

      // Read the number of time channels (i.e. bins) from the Nexus file
      const int channelsPerSpectrum = nxload.t_ntc1;
      // Read in the time bin boundaries 
      const int lengthIn = channelsPerSpectrum + 1;
      float* timeChannels = new float[lengthIn];
      nxload.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));

      // Calculate the size of a workspace, given its number of periods & spectra to read
      int64_t total_specs;
      if( m_interval || m_list)
      {
        total_specs = 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;
        // for nexus return all spectra
        m_spec_min = 0; // changed to 0 for NeXus, was 1 for Raw
        m_spec_max = m_numberOfSpectra;  // was +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));
      // Set the unit on the workspace to muon time, for now in the form of a Label Unit
      boost::shared_ptr<Kernel::Units::Label> lblUnit = 
        boost::dynamic_pointer_cast<Kernel::Units::Label>(UnitFactory::Instance().create("Label"));
      lblUnit->setLabel("Time","microsecond");
      localWorkspace->getAxis(0)->unit() = lblUnit;
      // Set y axis unit

      WorkspaceGroup_sptr wsGrpSptr=WorkspaceGroup_sptr(new WorkspaceGroup);
      if(m_numberOfPeriods>1)
        setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(wsGrpSptr));
      }

      API::Progress progress(this,0.,1.,m_numberOfPeriods * total_specs);
      // Loop over the number of periods in the Nexus file, putting each period in a separate workspace
      for (int64_t period = 0; period < m_numberOfPeriods; ++period) {
Anders Markvardsen's avatar
Anders Markvardsen committed
            loadRunDetails(localWorkspace);
            runLoadInstrument(localWorkspace );
            runLoadMappingTable(localWorkspace );
          }
Anders Markvardsen's avatar
Anders Markvardsen committed
          loadRunDetails(localWorkspace);
          runLoadInstrument(localWorkspace );
          runLoadMappingTable(localWorkspace );
          runLoadLog(localWorkspace );
          localWorkspace->populateInstrumentParameters();
        else   // We are working on a higher period of a multiperiod raw file
        {
          localWorkspace =  boost::dynamic_pointer_cast<DataObjects::Workspace2D>
            (WorkspaceFactory::Instance().create(localWorkspace));
          //localWorkspace->newInstrumentParameters(); ???
        }
        std::string outws("");
        if(m_numberOfPeriods>1)
        {
          std::string outputWorkspace = "OutputWorkspace";
          std::stringstream suffix;
          suffix << (period+1);
          outws =outputWorkspace+"_"+suffix.str();
          std::string WSName = localWSName + "_" + suffix.str();
          declareProperty(new WorkspaceProperty<Workspace>(outws,WSName,Direction::Output));
        size_t counter = 0;
Campbell, Stuart's avatar
Campbell, Stuart committed
        for (int64_t i = m_spec_min; i < m_spec_max; ++i)
        {
          // Shift the histogram to read if we're not in the first period
Campbell, Stuart's avatar
Campbell, Stuart committed
          specid_t histToRead = static_cast<specid_t>(i + period*total_specs);
          loadData(timeChannelsVec,counter,histToRead,nxload,lengthIn-1,localWorkspace ); // added -1 for NeXus
          counter++;
          progress.report();
        }
        // Read in the spectra in the optional list parameter, if set
        if (m_list)
        {
Peterson, Peter's avatar
Peterson, Peter committed
          for(size_t i=0; i < m_spec_list.size(); ++i)
          {
            loadData(timeChannelsVec,counter,m_spec_list[i],nxload,lengthIn-1, localWorkspace );
            counter++;
            progress.report();
          }
        }
        // Just a sanity check
        assert(counter == size_t(total_specs) );

        bool autogroup = getProperty("AutoGroup");

        if (autogroup)
        {

          //Get the groupings
          int64_t max_group = 0;
          // use a map for mapping group number and output workspace index in case 
          // there are group numbers > number of groups
Peterson, Peter's avatar
Peterson, Peter committed
          std::map<int64_t,int64_t> groups;
          m_groupings.resize(nxload.numDetectors);
          bool thereAreZeroes = false;
Peterson, Peter's avatar
Peterson, Peter committed
          for (int64_t i =0; i < static_cast<int64_t>(nxload.numDetectors); ++i)
Peterson, Peter's avatar
Peterson, Peter committed
            int64_t ig = static_cast<int64_t>(nxload.detectorGroupings[i]);
Campbell, Stuart's avatar
Campbell, Stuart committed
            m_groupings[i] = static_cast<specid_t>(ig);
Peterson, Peter's avatar
Peterson, Peter committed
              groups[ig] = static_cast<int64_t>(groups.size());
            if (ig > max_group) max_group = ig;
          }

          if (thereAreZeroes)
Peterson, Peter's avatar
Peterson, Peter committed
            for (int64_t i =0; i < static_cast<int64_t>(nxload.numDetectors); ++i)
Peterson, Peter's avatar
Peterson, Peter committed
              int64_t ig = static_cast<int64_t>(nxload.detectorGroupings[i]);
Campbell, Stuart's avatar
Campbell, Stuart committed
                m_groupings[i] = static_cast<specid_t>(ig);
Campbell, Stuart's avatar
Campbell, Stuart committed
          int numHists = static_cast<int>(localWorkspace->getNumberHistograms());
          size_t ngroups = groups.size(); // number of groups
Peterson, Peter's avatar
Peterson, Peter committed
            int64_t i=0;
            for(std::map<int64_t,int64_t>::iterator it=groups.begin();it!=groups.end();it++,i++)
              it->second = i;
              g_log.information()<<"group "<<it->first<<": ";
              bool first = true;
Peterson, Peter's avatar
Peterson, Peter committed
              int64_t first_i = -1 * std::numeric_limits<int64_t>::max();
              int64_t last_i = -1 * std::numeric_limits<int64_t>::max();
              for(int64_t i=0;i<static_cast<int64_t>(numHists);i++)
                if (m_groupings[i] == it->first)
                {
                  if (first) 
                  {
                    first = false;
                    g_log.information()<<i;
                    first_i = i;
                  }
                  else
                  {
                    if (first_i >= 0)
                    {
                      if (i > last_i + 1)
                      {
                        g_log.information()<<'-'<<i;
                        first_i = -1;
                      }
                    }
                    else
                    {
                      g_log.information()<<','<<i;
                      first_i = i;
                    }
                  }
                  last_i = i;
                }
                else
                  if (!first && first_i >= 0)
                  {
                    if (last_i > first_i)
                      g_log.information()<<'-'<<last_i;
                    first_i = -1;
                  }
              if (first_i >= 0 && last_i > first_i)
                g_log.information()<<'-'<<last_i;
              g_log.information()<<'\n';
            }
          }
          //Create a workspace with only two spectra for forward and back
          DataObjects::Workspace2D_sptr  groupedWS = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
            (API::WorkspaceFactory::Instance().create(localWorkspace, ngroups, localWorkspace->dataX(0).size(), localWorkspace->blocksize()));
          boost::shared_array<specid_t> spec(new specid_t[numHists]);
          boost::shared_array<detid_t> dets(new detid_t[numHists]);
Campbell, Stuart's avatar
Campbell, Stuart committed
          for (int i = 0; i < numHists; ++i)
Campbell, Stuart's avatar
Campbell, Stuart committed
            specid_t k = static_cast<specid_t>(groups[ m_groupings[numHists*period + i] ]);
            for (detid_t j = 0; j < static_cast<detid_t>(localWorkspace->blocksize()); ++j)
            {
              groupedWS->dataY(k)[j] = groupedWS->dataY(k)[j] + localWorkspace->dataY(i)[j];
              //Add the errors in quadrature
              groupedWS->dataE(k)[j] 
              = sqrt(pow(groupedWS->dataE(k)[j], 2) + pow(localWorkspace->dataE(i)[j], 2));
            }
            //Copy all the X data
            groupedWS->dataX(k) = localWorkspace->dataX(i);
            spec[i] = k + 1;
            dets[i] = i + 1;
          }
          for(detid_t k=0; k<static_cast<detid_t>(ngroups); k++)
          groupedWS->replaceSpectraMap(new API::SpectraDetectorMap(spec.get(),dets.get(),numHists));
          // Assign the result to the output workspace property
          if(m_numberOfPeriods>1)
            setProperty(outws, boost::dynamic_pointer_cast<Workspace>(groupedWS));
          else
          {
            setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(groupedWS));
        }
        else
        {
          // Assign the result to the output workspace property
          if(m_numberOfPeriods>1)
            setProperty(outws,boost::dynamic_pointer_cast<Workspace>(localWorkspace));
          else
          {
            setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(localWorkspace));
          }
    /// Validates the optional 'spectra to read' properties, if they have been set
    void LoadMuonNexus::checkOptionalProperties()
    {
      //read in the settings passed to the algorithm
      m_spec_list = getProperty("SpectrumList");
      m_spec_max = getProperty("SpectrumMax");
      //Are we using a list of spectra or all the spectra in a range?
      m_list = !m_spec_list.empty();
      m_interval = (m_spec_max != EMPTY_INT());
      if ( m_spec_max == EMPTY_INT() ) m_spec_max = 0;

      // Check validity of spectra list property, if set
      if ( m_list )
      {
        const specid_t minlist = *min_element(m_spec_list.begin(),m_spec_list.end());
        const specid_t maxlist = *max_element(m_spec_list.begin(),m_spec_list.end());
        if ( maxlist > m_numberOfSpectra || minlist == 0)
        {
          g_log.error("Invalid list of spectra");
          throw std::invalid_argument("Inconsistent properties defined"); 
        } 
      }
      // Check validity of spectra range, if set
      if ( m_interval )
      {
        m_spec_min = getProperty("SpectrumMin");
        if ( m_spec_max < m_spec_min || m_spec_max > m_numberOfSpectra )
        {
          g_log.error("Invalid Spectrum min/max properties");
          throw std::invalid_argument("Inconsistent properties defined"); 
        }
    /** Load in a single spectrum taken from a NeXus file
    *  @param tcbs ::     The vector containing the time bin boundaries
    *  @param hist ::     The workspace index
    *  @param i ::        The spectrum number
    *  @param nxload ::   A reference to the MuonNeXusReader object
    *  @param lengthIn :: The number of elements in a spectrum
    *  @param localWorkspace :: A pointer to the workspace in which the data will be stored
    void LoadMuonNexus::loadData(const MantidVecPtr::ptr_type& tcbs,size_t hist, specid_t& i,
Peterson, Peter's avatar
Peterson, Peter committed
      MuonNexusReader& nxload, const int64_t lengthIn, DataObjects::Workspace2D_sptr localWorkspace)
    {
      // Read in a spectrum
      // Put it into a vector, discarding the 1st entry, which is rubbish
      // But note that the last (overflow) bin is kept
      // For Nexus, not sure if above is the case, hence give all data for now
      MantidVec& Y = localWorkspace->dataY(hist);
      Y.assign(nxload.counts + i * lengthIn, nxload.counts + i * lengthIn + lengthIn);
      // Create and fill another vector for the errors, containing sqrt(count)
      MantidVec& E = localWorkspace->dataE(hist);
      typedef double (*uf)(double);
      uf dblSqrt = std::sqrt;
      std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
      // Populate the workspace. Loop starts from 1, hence i-1
      localWorkspace->setX(hist, tcbs);
Campbell, Stuart's avatar
Campbell, Stuart committed
      localWorkspace->getAxis(1)->spectraNo(hist)= static_cast<int>(hist) + 1;
Anders Markvardsen's avatar
Anders Markvardsen committed

    /**  Log the run details from the file
    * @param localWorkspace :: The workspace details to use
Anders Markvardsen's avatar
Anders Markvardsen committed
    */
    void LoadMuonNexus::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);
Anders Markvardsen's avatar
Anders Markvardsen committed

Anders Markvardsen's avatar
Anders Markvardsen committed
      std::string start_time = root.getString("run/start_time");
      runDetails.addProperty("run_start", start_time);
      std::string stop_time = root.getString("run/stop_time");
      runDetails.addProperty("run_end", stop_time);
      std::string dur = root.getString("run/duration");
      runDetails.addProperty("dur", dur);
      runDetails.addProperty("durunits", 1);
Anders Markvardsen's avatar
Anders Markvardsen committed
    }

    /// Run the sub-algorithm LoadInstrument (or LoadInstrumentFromNexus)
    void LoadMuonNexus::runLoadInstrument(DataObjects::Workspace2D_sptr localWorkspace)
    {
      IAlgorithm_sptr loadInst = createSubAlgorithm("LoadInstrument");
      // Now execute the sub-algorithm. Catch and log any error, but don't stop.
      bool executionSuccessful(true);
        loadInst->setPropertyValue("InstrumentName", m_instrument_name);
        loadInst->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
        loadInst->setProperty("RewriteSpectraMap", false);
      }
      catch( std::invalid_argument&)
      {
        g_log.information("Invalid argument to LoadInstrument sub-algorithm");
        executionSuccessful = false;
      catch (std::runtime_error&)
        g_log.information("Unable to successfully run LoadInstrument sub-algorithm");
        executionSuccessful = false;
      }

      // If loading instrument definition file fails, run LoadInstrumentFromNexus instead
      // This does not work at present as the example files do not hold the necessary data
      // but is a place holder. Hopefully the new version of Nexus Muon files should be more
      // complete.
      if ( ! loadInst->isExecuted() )
      {
        runLoadInstrumentFromNexus(localWorkspace);
      }
    }
    /// Run LoadInstrumentFromNexus as a sub-algorithm (only if loading from instrument definition file fails)
    void LoadMuonNexus::runLoadInstrumentFromNexus(DataObjects::Workspace2D_sptr localWorkspace)
    {
      g_log.information() << "Instrument definition file not found. Attempt to load information about \n"
        << "the instrument from nexus data file.\n";
      IAlgorithm_sptr loadInst = createSubAlgorithm("LoadInstrumentFromNexus");
      // Now execute the sub-algorithm. Catch and log any error, but don't stop.
      bool executionSuccessful(true);
        loadInst->setPropertyValue("Filename", m_filename);
        loadInst->setProperty<MatrixWorkspace_sptr> ("Workspace", localWorkspace);
        loadInst->execute();
      }
      catch( std::invalid_argument&)
      {
        g_log.information("Invalid argument to LoadInstrument sub-algorithm");
        executionSuccessful = false;
      catch (std::runtime_error&)
        g_log.information("Unable to successfully run LoadInstrument sub-algorithm");
        executionSuccessful = false;
      if ( !executionSuccessful ) g_log.error("No instrument definition loaded");      
    /// Run the LoadMappingTable sub-algorithm to fill the SpectraToDetectorMap
    void LoadMuonNexus::runLoadMappingTable(DataObjects::Workspace2D_sptr localWorkspace)
    {
      NXRoot root(m_filename);
      NXInt number = root.openNXInt("run/instrument/detector/number");
Campbell, Stuart's avatar
Campbell, Stuart committed
      detid_t ndet = static_cast<detid_t>(number[0]/m_numberOfPeriods);
      boost::shared_array<detid_t> det(new detid_t[ndet]);
      for(detid_t i=0;i<ndet;i++)
      }
      localWorkspace->replaceSpectraMap(new API::SpectraDetectorMap(det.get(),det.get(),ndet));

    /// Run the LoadLog sub-algorithm
    void LoadMuonNexus::runLoadLog(DataObjects::Workspace2D_sptr localWorkspace)
    {
      IAlgorithm_sptr loadLog = createSubAlgorithm("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 sub-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 sub-algorithm");
      }

      if ( ! loadLog->isExecuted() ) g_log.error("Unable to successfully run LoadLog sub-algorithm");
      std::string start_time = root.getString("run/start_time");
    
      NXChar orientation = root.openNXChar("run/instrument/detector/orientation");
      try
      {// some files have no data there
        orientation.load();
        // dump various Nexus numbers to outputs 
        if (orientation[0] == 't')
        {
          Kernel::TimeSeriesProperty<double>* p = new Kernel::TimeSeriesProperty<double>("fromNexus");
          p->addValue(start_time,-90.0);
          localWorkspace->mutableRun().addLogData(p);
          setProperty("MainFieldDirection", "Transverse");
        }
        else
        {
          setProperty("MainFieldDirection", "Longitudinal");
        }
      NXEntry entry = root.openEntry("run/histogram_data_1");
      NXInfo info = entry.getDataSetInfo("time_zero");
      if (info.stat != NX_ERROR)
      {
        double dum = root.getFloat("run/histogram_data_1/time_zero");
        setProperty("TimeZero", dum);
      }

      NXInfo infoResolution = entry.getDataSetInfo("resolution");
      NXInt counts = root.openNXInt("run/histogram_data_1/counts");
      std::string firstGoodBin = counts.attributes("first_good_bin");

      if ( !firstGoodBin.empty() && infoResolution.stat != NX_ERROR )
      {
        double bin = static_cast<double>(boost::lexical_cast<int>(firstGoodBin));
        double bin_size = static_cast<double>(root.getInt("run/histogram_data_1/resolution"))/1000000.0;
        setProperty("FirstGoodData", bin*bin_size);
      }

      NXEntry nxRun = root.openEntry("run");
      localWorkspace->setTitle(nxRun.getString("title"));
      std::string run_num = boost::lexical_cast<std::string>(nxRun.getInt("number"));
      //The sample is left to delete the property
      localWorkspace->mutableRun().addLogData(new PropertyWithValue<std::string>("run_number", run_num));
      /**This method does a quick file type check by looking at the first 100 bytes of the file 
    *  @param filePath- path of the file including name.
    *  @param header :: The first 100 bytes of the file as a union
    *  @return true if the given file is of type which can be loaded by this algorithm
    */
    bool LoadMuonNexus::quickFileCheck(const std::string& filePath,size_t nread,const file_header& header)
    {
      std::string extn=extension(filePath);
      bool bnexs(false);
      (!extn.compare("nxs")||!extn.compare(".nx5"))?bnexs=true:bnexs=false;
      /*
      * HDF files have magic cookie in the first 4 bytes
      if ( ((nread >= sizeof(unsigned)) && (ntohl(header.four_bytes) == g_hdf_cookie)) || bnexs )
      else if ( (nread >= sizeof(g_hdf5_signature)) && 
                (!memcmp(header.full_hdr, g_hdf5_signature, sizeof(g_hdf5_signature))) )
      { 
        //hdf5
        return true;
      }
      return false;
     
    }
    /**checks the file by opening it and reading few lines 
    *  @param filePath :: name of the file inluding its path
    *  @return an integer value how much this algorithm can load the file 
    */
    int LoadMuonNexus::fileCheck(const std::string& filePath)
    {     
        ::NeXus::File file = ::NeXus::File(filePath);
        file.openPath("/run/analysis");
        std::string analysisType = file.getStrData();
        if( analysisType == "muonTD" )
        {
          // If all this succeeded then we'll assume this is an ISIS Muon NeXus file
          confidence = 80;
        }
        file.close();
  } // namespace DataHandling
} // namespace Mantid