/** Executes the algorithm. Reading in the file and creating and populating
 *  the output workspace
 *
 *  @throw Exception::NotFoundError Error when saving the PoldiDeadWires Results data to Workspace
 *  @throw std::runtime_error Error when saving the PoldiDeadWires Results data to Workspace
 */
void PoldiAutoCorrelation5::exec()
{
	g_log.information() << "_Poldi  start conf --------------  "  << std::endl;

    /* From localWorkspace three things are used:
     *      - Count data from POLDI experiment
     *      - POLDI instrument definition
     *      - Some data from the "Log" (for example chopper-speed)
     */
    DataObjects::Workspace2D_sptr localWorkspace = this->getProperty("InputWorkspace");

    g_log.information() << "_Poldi ws loaded --------------  " << std::endl;

    double wlen_min = this->getProperty("wlenmin");
    double wlen_max = this->getProperty("wlenmax");

    double chopperSpeed = 0.0;

    try {
        chopperSpeed = localWorkspace->run().getPropertyValueAsType<std::vector<double> >("chopperspeed").front();
    } catch(std::invalid_argument&) {
        throw(std::runtime_error("Chopper speed could not be extracted from Workspace '" + localWorkspace->name() + "'. Aborting."));
    }

    // Instrument definition
    Instrument_const_sptr poldiInstrument = localWorkspace->getInstrument();

	// Chopper configuration
    PoldiChopperFactory chopperFactory;
    boost::shared_ptr<PoldiAbstractChopper> chopper(chopperFactory.createChopper(std::string("default-chopper")));
    chopper->loadConfiguration(poldiInstrument);
    chopper->setRotationSpeed(chopperSpeed);

	g_log.information() << "____________________________________________________ "  << std::endl;
	g_log.information() << "_Poldi  chopper conf ------------------------------  "  << std::endl;
    g_log.information() << "_Poldi -     Chopper speed:   " << chopper->rotationSpeed() << " rpm" << std::endl;
    g_log.information() << "_Poldi -     Number of slits: " << chopper->slitPositions().size() << std::endl;
    g_log.information() << "_Poldi -     Cycle time:      " << chopper->cycleTime() << " µs" << std::endl;
    g_log.information() << "_Poldi -     Zero offset:     " << chopper->zeroOffset() << " µs" << std::endl;
    g_log.information() << "_Poldi -     Distance:        " << chopper->distanceFromSample()  << " mm" << std::endl;

    if(g_log.is(Poco::Message::PRIO_DEBUG)) {
        for(size_t i = 0; i < chopper->slitPositions().size(); ++i) {
            g_log.information()   << "_Poldi -     Slits: " << i
                            << ": Position = " << chopper->slitPositions()[i]
                               << "\t Time = " << chopper->slitTimes()[i] << " µs" << std::endl;
        }
    }

	// Detector configuration
    PoldiDetectorFactory detectorFactory;
    boost::shared_ptr<PoldiAbstractDetector> detector(detectorFactory.createDetector(std::string("helium3-detector")));
    detector->loadConfiguration(poldiInstrument);

    g_log.information() << "_Poldi  detector conf ------------------------------  "  << std::endl;
    g_log.information() << "_Poldi -     Element count:     " << detector->elementCount() << std::endl;
    g_log.information() << "_Poldi -     Central element:   " << detector->centralElement() << std::endl;
    g_log.information() << "_Poldi -     2Theta(central):   " << detector->twoTheta(199) / M_PI * 180.0 << "°" << std::endl;
    g_log.information() << "_Poldi -     Distance(central): " << detector->distanceFromSample(199) << " mm" << std::endl;

    boost::shared_ptr<PoldiDeadWireDecorator> cleanDetector(new PoldiDeadWireDecorator(poldiInstrument, detector));

    std::set<int> deadWires = cleanDetector->deadWires();
    g_log.information() << "_Poldi -     Number of dead wires: " << deadWires.size() << std::endl;
    g_log.information() << "_Poldi -     Wire indices: ";
    for(std::set<int>::const_iterator dw = deadWires.begin(); dw != deadWires.end(); ++dw) {
        g_log.information() << *dw << " ";
    }
    g_log.information() << std::endl;


    // putting together POLDI instrument for calculations
    m_core->setInstrument(cleanDetector, chopper);
    m_core->setWavelengthRange(wlen_min, wlen_max);

	try
	{
        Mantid::DataObjects::Workspace2D_sptr outputws = m_core->calculate(localWorkspace);

		setProperty("OutputWorkspace",boost::dynamic_pointer_cast<Workspace>(outputws));

	}
	catch(Mantid::Kernel::Exception::NotFoundError& )
	{
		throw std::runtime_error("Error when saving the PoldiIPP Results data to Workspace : NotFoundError");
	}
	catch(std::runtime_error &)
	{
		throw std::runtime_error("Error when saving the PoldiIPP Results data to Workspace : runtime_error");
	}
}
Пример #2
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();
    }
Пример #3
0
void PoldiAnalyseResiduals::exec() {
  DataObjects::Workspace2D_sptr measured = getProperty("MeasuredCountData");
  DataObjects::Workspace2D_sptr calculated = getProperty("FittedCountData");

  PoldiInstrumentAdapter_sptr poldiInstrument =
      boost::make_shared<PoldiInstrumentAdapter>(measured);
  // Dead wires need to be taken into account
  PoldiAbstractDetector_sptr deadWireDetector =
      boost::make_shared<PoldiDeadWireDecorator>(measured->getInstrument(),
                                                 poldiInstrument->detector());

  // Since the valid workspace indices are required for some calculations, we
  // extract and keep them
  const std::vector<int> &validWorkspaceIndices =
      deadWireDetector->availableElements();

  // Subtract calculated from measured to get residuals
  DataObjects::Workspace2D_sptr residuals =
      calculateResidualWorkspace(measured, calculated);

  // Normalize residuals so that they are 0.
  normalizeResiduals(residuals, validWorkspaceIndices);

  // Residual correlation core which will be used iteratively.
  PoldiResidualCorrelationCore core(g_log, 0.1);
  core.setInstrument(deadWireDetector, poldiInstrument->chopper());

  double lambdaMin = getProperty("LambdaMin");
  double lambdaMax = getProperty("LambdaMax");
  core.setWavelengthRange(lambdaMin, lambdaMax);

  // One iteration is always necessary
  DataObjects::Workspace2D_sptr sum = core.calculate(residuals, calculated);

  // For keeping track of the relative changes the sum of measured counts is
  // required
  double sumOfMeasuredCounts = sumCounts(measured, validWorkspaceIndices);
  double relativeChange = relativeCountChange(sum, sumOfMeasuredCounts);

  int iteration = 1;

  logIteration(iteration, relativeChange);

  // Iterate until conditions are met, accumulate correlation spectra in sum.
  while (nextIterationAllowed(iteration, relativeChange)) {
    ++iteration;

    DataObjects::Workspace2D_sptr corr = core.calculate(residuals, calculated);
    relativeChange = relativeCountChange(corr, sumOfMeasuredCounts);

    sum = addWorkspaces(sum, corr);

    logIteration(iteration, relativeChange);
  }

  g_log.notice() << "Finished after " << iteration
                 << " iterations, final change=" << relativeChange << std::endl;

  // Return final correlation spectrum.
  setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(sum));
}
Пример #4
0
/** 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
 */
void PoldiLoadIPP::exec()
{



	////////////////////////////////////////////////////////////////////////
	// About the workspace
	////////////////////////////////////////////////////////////////////////

	DataObjects::Workspace2D_sptr localWorkspace = this->getProperty("InputWorkspace");


	////////////////////////////////////////////////////////////////////////
	// Load the data into the workspace
	////////////////////////////////////////////////////////////////////////


	try
	{
		ITableWorkspace_sptr outputws = WorkspaceFactory::Instance().createTable();

		outputws->addColumn("str","param");
		outputws->addColumn("str","unit");
		outputws->addColumn("double","value");


		Geometry::Instrument_const_sptr inst = localWorkspace->getInstrument();


		double distChopSampl = localWorkspace->getInstrument()->getNumberParameter("dist-chopper-sample")[0];
		g_log.debug() << "_poldi : param " <<  "dist-chopper-sample" << " : " << distChopSampl  << std::endl;
		TableRow t0 = outputws->appendRow();
		t0 << "dist-chopper-sample" << "[mm]" << distChopSampl ;

		double distSamplDet  = localWorkspace->getInstrument()->getNumberParameter("dist-sample-detector")[0];
		g_log.debug() << "_poldi : param " <<  "dist-sample-detector" << " : " << distSamplDet  << std::endl;
		TableRow t1 = outputws->appendRow();
		t1 << "dist-sample-detector" << "[mm]" << distSamplDet ;

		double x0det         = localWorkspace->getInstrument()->getNumberParameter("x0det")[0];
		g_log.debug() << "_poldi : param " <<  "x0det" << " : " << x0det  << std::endl;
		TableRow t2 = outputws->appendRow();
		t2 << "x0det" << "[mm]" << x0det ;

		double y0det         = localWorkspace->getInstrument()->getNumberParameter("y0det")[0];
		g_log.debug() << "_poldi : param " <<  "y0det" << " : " << y0det  << std::endl;
		TableRow t3 = outputws->appendRow();
		t3 << "y0det" << "[mm]" << y0det ;

		double twotheta      = localWorkspace->getInstrument()->getNumberParameter("twothet")[0];
		g_log.debug() << "_poldi : param " <<  "twothet" << " : " << twotheta  << std::endl;
		TableRow t4 = outputws->appendRow();
		t4 << "twothet" << "[deg]" << twotheta ;

		double tps0            = localWorkspace->getInstrument()->getNumberParameter("t0")[0];
		g_log.debug() << "_poldi : param " <<  "t0" << " : " << tps0  << std::endl;
		TableRow t5 = outputws->appendRow();
		t5 << "t0" << "[mysec]" << tps0 ;

		double tcycle        = localWorkspace->getInstrument()->getNumberParameter("tconst")[0];
		g_log.debug() << "_poldi : param " <<  "tconst" << " : " << tcycle  << std::endl;
		TableRow t6 = outputws->appendRow();
		t6 << "tconst" << "[mysec]" << tcycle ;

		double det_radius        = localWorkspace->getInstrument()->getNumberParameter("det_radius")[0];
		g_log.debug() << "_poldi : param " <<  "det_radius" << " : " << det_radius  << std::endl;
		TableRow t8 = outputws->appendRow();
		t8 << "det_radius" << "[mm]" << det_radius ;

		double det_nb_channel        = localWorkspace->getInstrument()->getNumberParameter("det_nb_channel")[0];
		g_log.debug() << "_poldi : param " <<  "det_nb_channel" << " : " << det_nb_channel  << std::endl;
		TableRow t9 = outputws->appendRow();
		t9 << "det_nb_channel" << "[]" << det_nb_channel ;

		double det_channel_resolution        = localWorkspace->getInstrument()->getNumberParameter("det_channel_resolution")[0];
		g_log.debug() << "_poldi : param " <<  "det_channel_resolution" << " : " << det_channel_resolution  << std::endl;
		TableRow t10 = outputws->appendRow();
		t10 << "det_channel_resolution" << "[mm]" << det_channel_resolution ;


		setProperty("PoldiIPP",outputws);

	}
	catch(Mantid::Kernel::Exception::NotFoundError& )
	{
		throw std::runtime_error("Error when saving the PoldiIPP Results data to Workspace : NotFoundError");
	}
	catch(std::runtime_error &)
	{
		throw std::runtime_error("Error when saving the PoldiIPP Results data to Workspace : runtime_error");
	}


}