コード例 #1
0
double ConvertSpectrumAxis::getEfixed(IDetector_const_sptr detector,
                                      MatrixWorkspace_const_sptr inputWS,
                                      int emode) const {
  double efixed(0);
  double efixedProp = getProperty("Efixed");
  if (efixedProp != EMPTY_DBL()) {
    efixed = efixedProp;
    g_log.debug() << "Detector: " << detector->getID() << " Efixed: " << efixed
                  << "\n";
  } else {
    if (emode == 1) {
      if (inputWS->run().hasProperty("Ei")) {
        Kernel::Property *p = inputWS->run().getProperty("Ei");
        Kernel::PropertyWithValue<double> *doublep =
            dynamic_cast<Kernel::PropertyWithValue<double> *>(p);
        if (doublep) {
          efixed = (*doublep)();
        } else {
          efixed = 0.0;
          g_log.warning() << "Efixed could not be found for detector "
                          << detector->getID() << ", set to 0.0\n";
        }
      } else {
        efixed = 0.0;
        g_log.warning() << "Efixed could not be found for detector "
                        << detector->getID() << ", set to 0.0\n";
      }
    } else if (emode == 2) {
      std::vector<double> efixedVec = detector->getNumberParameter("Efixed");
      if (efixedVec.empty()) {
        int detid = detector->getID();
        IDetector_const_sptr detectorSingle =
            inputWS->getInstrument()->getDetector(detid);
        efixedVec = detectorSingle->getNumberParameter("Efixed");
      }
      if (!efixedVec.empty()) {
        efixed = efixedVec.at(0);
        g_log.debug() << "Detector: " << detector->getID()
                      << " EFixed: " << efixed << "\n";
      } else {
        efixed = 0.0;
        g_log.warning() << "Efixed could not be found for detector "
                        << detector->getID() << ", set to 0.0\n";
      }
    }
  }
  return efixed;
}
コード例 #2
0
double ConvertSpectrumAxis2::getEfixed(IDetector_const_sptr detector,
                                       MatrixWorkspace_const_sptr inputWS,
                                       int emode) const {
  double efixed(0);
  double efixedProp = getProperty("Efixed");
  if (efixedProp != EMPTY_DBL()) {
    efixed = efixedProp;
    g_log.debug() << "Detector: " << detector->getID() << " Efixed: " << efixed
                  << "\n";
  } else {
    if (emode == 1) {
      if (inputWS->run().hasProperty("Ei")) {
        efixed = inputWS->run().getLogAsSingleValue("Ei");
      } else {
        throw std::invalid_argument("Could not retrieve Efixed from the "
                                    "workspace. Please provide a value.");
      }
    } else if (emode == 2) {
      std::vector<double> efixedVec = detector->getNumberParameter("Efixed");
      if (efixedVec.empty()) {
        int detid = detector->getID();
        IDetector_const_sptr detectorSingle =
            inputWS->getInstrument()->getDetector(detid);
        efixedVec = detectorSingle->getNumberParameter("Efixed");
      }
      if (!efixedVec.empty()) {
        efixed = efixedVec.at(0);
        g_log.debug() << "Detector: " << detector->getID()
                      << " EFixed: " << efixed << "\n";
      } else {
        g_log.warning() << "Efixed could not be found for detector "
                        << detector->getID() << ", please provide a value\n";
        throw std::invalid_argument("Could not retrieve Efixed from the "
                                    "detector. Please provide a value.");
      }
    }
  }
  return efixed;
}
コード例 #3
0
// calculate time from sample to detector
void ModeratorTzeroLinear::calculateTfLi(MatrixWorkspace_const_sptr inputWS,
                                         size_t i, double &t_f, double &L_i) {
  static const double convFact = 1.0e-6 * sqrt(2 * PhysicalConstants::meV /
                                               PhysicalConstants::NeutronMass);
  static const double TfError = -1.0; // signal error when calculating final
                                      // time
  // Get detector position
  IDetector_const_sptr det;
  try {
    det = inputWS->getDetector(i);
  } catch (Exception::NotFoundError &) {
    t_f = TfError;
    return;
  }

  if (det->isMonitor()) {
    L_i = m_instrument->getSource()->getDistance(*det);
    t_f = 0.0; // t_f=0.0 since there is no sample to detector path
  } else {
    IComponent_const_sptr sample = m_instrument->getSample();
    try {
      L_i = m_instrument->getSource()->getDistance(*sample);
    } catch (Exception::NotFoundError &) {
      g_log.error("Unable to calculate source-sample distance");
      throw Exception::InstrumentDefinitionError(
          "Unable to calculate source-sample distance", inputWS->getTitle());
    }
    // Get final energy E_f, final velocity v_f
    std::vector<double> wsProp = det->getNumberParameter("Efixed");
    if (!wsProp.empty()) {
      double E_f = wsProp.at(0);         //[E_f]=meV
      double v_f = convFact * sqrt(E_f); //[v_f]=meter/microsec

      try {
        // obtain L_f, calculate t_f
        double L_f = det->getDistance(*sample);
        t_f = L_f / v_f;
        // g_log.debug() << "detector: " << i << " L_f=" << L_f << " t_f=" <<
        // t_f << '\n';
      } catch (Exception::NotFoundError &) {
        g_log.error("Unable to calculate detector-sample distance");
        throw Exception::InstrumentDefinitionError(
            "Unable to calculate detector-sample distance",
            inputWS->getTitle());
      }
    } else {
      g_log.debug() << "Efixed not found for detector " << i << '\n';
      t_f = TfError;
    }
  }
} // end of CalculateTf(const MatrixWorkspace_sptr inputWS, size_t i)
コード例 #4
0
//calculate time from sample to detector
double ModeratorTzero::CalculateT2(MatrixWorkspace_sptr inputWS, size_t i)
{
  static const double convFact = 1.0e-6*sqrt(2*PhysicalConstants::meV/PhysicalConstants::NeutronMass);
  double t2(-1.0); // negative initialization signals error
  // Get detector position
  IDetector_const_sptr det;
  try
  {
    det = inputWS->getDetector(i);
  }
  catch (Exception::NotFoundError&)
  {
    return t2;
  }

  if( det->isMonitor() )
  {
    t2 = 0.0; //t2=0.0 since there is no sample to detector path
  }
  else
  {
    IComponent_const_sptr sample = m_instrument->getSample();
    // Get final energy E_f, final velocity v_f
    std::vector< double >  wsProp=det->getNumberParameter("Efixed");
    if ( !wsProp.empty() )
    {
      double E2 = wsProp.at(0); //[E2]=meV
      double v2 = convFact * sqrt(E2); //[v2]=meter/microsec
      try
      {
        double L2 = det->getDistance(*sample);
        t2 = L2 / v2;
      }
      catch (Exception::NotFoundError &)
      {
        g_log.error("Unable to calculate detector-sample distance");
        throw Exception::InstrumentDefinitionError("Unable to calculate detector-sample distance", inputWS->getTitle());
      }
    }
    else
    {
      g_log.debug() <<"Efixed not found for detector "<< i << std::endl;
    }
  }
  return t2;
} // end of CalculateT2(const MatrixWorkspace_sptr inputWS, size_t i)
コード例 #5
0
void ModeratorTzero::execEvent(const std::string &emode) {
  g_log.information("Processing event workspace");

  const MatrixWorkspace_const_sptr matrixInputWS =
      getProperty("InputWorkspace");
  EventWorkspace_const_sptr inputWS =
      boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS);

  // generate the output workspace pointer
  const size_t numHists = static_cast<size_t>(inputWS->getNumberHistograms());
  Mantid::API::MatrixWorkspace_sptr matrixOutputWS =
      getProperty("OutputWorkspace");
  EventWorkspace_sptr outputWS;
  if (matrixOutputWS == matrixInputWS) {
    outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS);
  } else {
    // Make a brand new EventWorkspace
    outputWS = boost::dynamic_pointer_cast<EventWorkspace>(
        WorkspaceFactory::Instance().create("EventWorkspace", numHists, 2, 1));
    // Copy geometry over.
    WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, false);
    // You need to copy over the data as well.
    outputWS->copyDataFrom((*inputWS));
    // Cast to the matrixOutputWS and save it
    matrixOutputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWS);
    setProperty("OutputWorkspace", matrixOutputWS);
  }

  // Get pointers to sample and source
  IComponent_const_sptr source = m_instrument->getSource();
  IComponent_const_sptr sample = m_instrument->getSample();
  double Lss = source->getDistance(*sample); // distance from source to sample

  // calculate tof shift once for all neutrons if emode==Direct
  double t0_direct(-1);
  if (emode == "Direct") {
    Kernel::Property *eiprop = inputWS->run().getProperty("Ei");
    double Ei = boost::lexical_cast<double>(eiprop->value());
    mu::Parser parser;
    parser.DefineVar("incidentEnergy", &Ei); // associate E1 to this parser
    parser.SetExpr(m_formula);
    t0_direct = parser.Eval();
  }

  // Loop over the spectra
  Progress prog(this, 0.0, 1.0, numHists); // report progress of algorithm
  PARALLEL_FOR1(outputWS)
  for (int i = 0; i < static_cast<int>(numHists); ++i) {
    PARALLEL_START_INTERUPT_REGION
    size_t wsIndex = static_cast<size_t>(i);
    EventList &evlist = outputWS->getEventList(wsIndex);
    if (evlist.getNumberEvents() > 0) // don't bother with empty lists
    {
      IDetector_const_sptr det;
      double L1(Lss); // distance from source to sample
      double L2(-1);  // distance from sample to detector

      try {
        det = inputWS->getDetector(i);
        if (det->isMonitor()) {
          // redefine the sample as the monitor
          L1 = source->getDistance(*det);
          L2 = 0;
        } else {
          L2 = sample->getDistance(*det);
        }
      } catch (Exception::NotFoundError &) {
        g_log.error() << "Unable to calculate distances to/from detector" << i
                      << std::endl;
      }

      if (L2 >= 0) {
        // One parser for each parallel processor needed (except Edirect mode)
        double E1;
        mu::Parser parser;
        parser.DefineVar("incidentEnergy", &E1); // associate E1 to this parser
        parser.SetExpr(m_formula);

        // fast neutrons are shifted by min_t0_next, irrespective of tof
        double v1_max = L1 / m_t1min;
        E1 = m_convfactor * v1_max * v1_max;
        double min_t0_next = parser.Eval();

        if (emode == "Indirect") {
          double t2(-1.0); // time from sample to detector. (-1) signals error
          if (det->isMonitor()) {
            t2 = 0.0;
          } else {
            static const double convFact =
                1.0e-6 * sqrt(2 * PhysicalConstants::meV /
                              PhysicalConstants::NeutronMass);
            std::vector<double> wsProp = det->getNumberParameter("Efixed");
            if (!wsProp.empty()) {
              double E2 = wsProp.at(0);        //[E2]=meV
              double v2 = convFact * sqrt(E2); //[v2]=meter/microsec
              t2 = L2 / v2;
            } else {
              // t2 is kept to -1 if no Efixed is found
              g_log.debug() << "Efixed not found for detector " << i
                            << std::endl;
            }
          }
          if (t2 >= 0) // t2 < 0 when no detector info is available
          {
            // fix the histogram bins
            MantidVec &x = evlist.dataX();
            for (double &tof : x) {
              if (tof < m_t1min + t2)
                tof -= min_t0_next;
              else
                tof -= CalculateT0indirect(tof, L1, t2, E1, parser);
            }

            MantidVec tofs = evlist.getTofs();
            for (double &tof : tofs) {
              if (tof < m_t1min + t2)
                tof -= min_t0_next;
              else
                tof -= CalculateT0indirect(tof, L1, t2, E1, parser);
            }
            evlist.setTofs(tofs);
            evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED);
          } // end of if( t2>= 0)
        }   // end of if(emode=="Indirect")
        else if (emode == "Elastic") {
          // Apply t0 correction to histogram bins
          MantidVec &x = evlist.dataX();
          for (double &tof : x) {
            if (tof < m_t1min * (L1 + L2) / L1)
              tof -= min_t0_next;
            else
              tof -= CalculateT0elastic(tof, L1 + L2, E1, parser);
          }

          MantidVec tofs = evlist.getTofs();
          for (double &tof : tofs) {
            // add a [-0.1,0.1] microsecond noise to avoid artifacts
            // resulting from original tof data
            if (tof < m_t1min * (L1 + L2) / L1)
              tof -= min_t0_next;
            else
              tof -= CalculateT0elastic(tof, L1 + L2, E1, parser);
          }
          evlist.setTofs(tofs);
          evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED);

          MantidVec tofs_b = evlist.getTofs();
          MantidVec xarray = evlist.readX();
        } // end of else if(emode=="Elastic")
        else if (emode == "Direct") {
          // fix the histogram bins
          MantidVec &x = evlist.dataX();
          for (double &tof : x) {
            tof -= t0_direct;
          }

          MantidVec tofs = evlist.getTofs();
          for (double &tof : tofs) {
            tof -= t0_direct;
          }
          evlist.setTofs(tofs);
          evlist.setSortOrder(Mantid::DataObjects::EventSortType::UNSORTED);
        } // end of else if(emode=="Direct")
      }   // end of if(L2 >= 0)
    }     // end of if (evlist.getNumberEvents() > 0)
    prog.report();
    PARALLEL_END_INTERUPT_REGION
  } // end of for (int i = 0; i < static_cast<int>(numHists); ++i)
  PARALLEL_CHECK_INTERUPT_REGION
  outputWS->clearMRU(); // Clears the Most Recent Used lists */
} // end of void ModeratorTzero::execEvent()
コード例 #6
0
void CorrectKiKf::exec()
{
  // Get the workspaces
  this->inputWS = this->getProperty("InputWorkspace");
  this->outputWS = this->getProperty("OutputWorkspace");

  // If input and output workspaces are not the same, create a new workspace for the output
  if (this->outputWS != this->inputWS)
  {
    this->outputWS = API::WorkspaceFactory::Instance().create(this->inputWS);
  }

  //Check if it is an event workspace
  EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
  if (eventW != NULL)
  {
    this->execEvent();
    return;
  }  
  

  const size_t size = this->inputWS->blocksize();
  // Calculate the number of spectra in this workspace
  const int numberOfSpectra = static_cast<int>(this->inputWS->size() / size);
  API::Progress prog(this,0.0,1.0,numberOfSpectra);
  const bool histogram = this->inputWS->isHistogramData();
  bool negativeEnergyWarning = false;
    
  const std::string emodeStr = getProperty("EMode");
  double efixedProp = getProperty("EFixed");

  if( efixedProp == EMPTY_DBL() )
  {
    if (emodeStr == "Direct")
    {
      // Check if it has been store on the run object for this workspace
      if( this->inputWS->run().hasProperty("Ei"))
      {
        Kernel::Property* eiprop = this->inputWS->run().getProperty("Ei");
        efixedProp = boost::lexical_cast<double>(eiprop->value());
        g_log.debug() << "Using stored Ei value " << efixedProp << "\n";
      }
      else
      {
        throw std::invalid_argument("No Ei value has been set or stored within the run information.");
      }
    }
    else
    {
      // If not specified, will try to get Ef from the parameter file for indirect geometry, 
      // but it will be done for each spectrum separately, in case of different analyzer crystals
    }
  }


  PARALLEL_FOR2(inputWS,outputWS)
  for (int64_t i = 0; i < int64_t(numberOfSpectra); ++i)
  {
    PARALLEL_START_INTERUPT_REGION 
    double Efi = 0;
    // Now get the detector object for this histogram to check if monitor
    // or to get Ef for indirect geometry
    if (emodeStr == "Indirect") 
    {
      if ( efixedProp != EMPTY_DBL()) Efi = efixedProp;
      else try 
      {
        IDetector_const_sptr det = inputWS->getDetector(i);
        if (!det->isMonitor())
        {
          std::vector< double >  wsProp=det->getNumberParameter("Efixed");
          if ( wsProp.size() > 0 )
          {
            Efi=wsProp.at(0);
            g_log.debug() << i << " Ef: "<< Efi<<" (from parameter file)\n";     
          }
          else
          { 
            g_log.information() <<"Ef not found for spectrum "<< i << std::endl;
            throw std::invalid_argument("No Ef value has been set or found.");
          }
        }

      }
      catch(std::runtime_error&) { g_log.information() << "Spectrum " << i << ": cannot find detector" << "\n"; }
    }

    MantidVec& yOut = outputWS->dataY(i);
    MantidVec& eOut = outputWS->dataE(i);
    const MantidVec& xIn = inputWS->readX(i);
    const MantidVec& yIn = inputWS->readY(i);
    const MantidVec& eIn = inputWS->readE(i);
    //Copy the energy transfer axis
    outputWS->setX( i, inputWS->refX(i) );
    for (unsigned int j = 0; j < size; ++j)
    {
      const double deltaE = histogram ? 0.5*(xIn[j]+xIn[j+1]) : xIn[j];
      double Ei=0.;
      double Ef=0.;
      double kioverkf = 1.;
      if (emodeStr == "Direct")  //Ei=Efixed
      {
        Ei = efixedProp;
        Ef = Ei - deltaE;
      } else                     //Ef=Efixed
      { 
        Ef = Efi;
        Ei = Efi + deltaE;
      }
      // if Ei or Ef is negative, it should be a warning
      // however, if the intensity is 0 (histogram goes to energy transfer higher than Ei) it is still ok, so no warning.
      if ((Ei <= 0)||(Ef <= 0))
      {
        kioverkf=0.;
        if (yIn[j]!=0) negativeEnergyWarning=true;
      } 
      else kioverkf = std::sqrt( Ei / Ef );

      yOut[j] = yIn[j]*kioverkf;
      eOut[j] = eIn[j]*kioverkf;
    }
    prog.report();
    PARALLEL_END_INTERUPT_REGION
  }//end for i 
  PARALLEL_CHECK_INTERUPT_REGION

  if (negativeEnergyWarning) g_log.information() <<"Ef <= 0 or Ei <= 0 in at least one spectrum!!!!"<<std::endl;
  if ((negativeEnergyWarning) && ( efixedProp == EMPTY_DBL())) g_log.information()<<"Try to set fixed energy"<<std::endl ;
  this->setProperty("OutputWorkspace",this->outputWS);
  return;
}
コード例 #7
0
void CorrectKiKf::execEvent()
{
  g_log.information("Processing event workspace");

  const MatrixWorkspace_const_sptr matrixInputWS = this->getProperty("InputWorkspace");
  EventWorkspace_const_sptr inputWS= boost::dynamic_pointer_cast<const EventWorkspace>(matrixInputWS);

  // generate the output workspace pointer
  API::MatrixWorkspace_sptr matrixOutputWS = this->getProperty("OutputWorkspace");
  EventWorkspace_sptr outputWS;
  if (matrixOutputWS == matrixInputWS)
    outputWS = boost::dynamic_pointer_cast<EventWorkspace>(matrixOutputWS);
  else
  {
    //Make a brand new EventWorkspace
    outputWS = boost::dynamic_pointer_cast<EventWorkspace>(
            API::WorkspaceFactory::Instance().create("EventWorkspace", inputWS->getNumberHistograms(), 2, 1));
    //Copy geometry over.
    API::WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, false);
    //You need to copy over the data as well.
    outputWS->copyDataFrom( (*inputWS) );

    //Cast to the matrixOutputWS and save it
    matrixOutputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outputWS);
    this->setProperty("OutputWorkspace", matrixOutputWS);
  }

  const std::string emodeStr = getProperty("EMode");
  double efixedProp = getProperty("EFixed"),efixed;

  if( efixedProp == EMPTY_DBL() )
  {
    if (emodeStr == "Direct")
    {
      // Check if it has been store on the run object for this workspace
      if( this->inputWS->run().hasProperty("Ei"))
      {
        Kernel::Property* eiprop = this->inputWS->run().getProperty("Ei");
        efixedProp = boost::lexical_cast<double>(eiprop->value());
        g_log.debug() << "Using stored Ei value " << efixedProp << "\n";
      }
      else
      {
        throw std::invalid_argument("No Ei value has been set or stored within the run information.");
      }
    }
    else
    {
      // If not specified, will try to get Ef from the parameter file for indirect geometry, 
      // but it will be done for each spectrum separately, in case of different analyzer crystals
    }
  }

  int64_t numHistograms = static_cast<int64_t>(inputWS->getNumberHistograms());
  API::Progress prog = API::Progress(this, 0.0, 1.0, numHistograms);
  PARALLEL_FOR1(outputWS)
  for (int64_t i=0; i < numHistograms; ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    
    double Efi = 0;
    // Now get the detector object for this histogram to check if monitor
    // or to get Ef for indirect geometry
    if (emodeStr == "Indirect") 
    {
      if ( efixedProp != EMPTY_DBL()) Efi = efixedProp;
      else try 
      {
        IDetector_const_sptr det = inputWS->getDetector(i);
        if (!det->isMonitor())
        {
          std::vector< double >  wsProp=det->getNumberParameter("Efixed");
          if ( wsProp.size() > 0 )
          {
            Efi=wsProp.at(0);
            g_log.debug() << i << " Ef: "<< Efi<<" (from parameter file)\n";     
          }
          else
          { 
            g_log.information() <<"Ef not found for spectrum "<< i << std::endl;
            throw std::invalid_argument("No Ef value has been set or found.");
          }
        }

      }
      catch(std::runtime_error&) { g_log.information() << "Spectrum " << i << ": cannot find detector" << "\n"; }
    }

    if (emodeStr == "Indirect") efixed=Efi;
    else efixed=efixedProp;

    //Do the correction
		EventList *evlist=outputWS->getEventListPtr(i);
    switch (evlist->getEventType())
    {
      case TOF:
        //Switch to weights if needed.
        evlist->switchTo(WEIGHTED);
        // Fall through
  
      case WEIGHTED:
        correctKiKfEventHelper(evlist->getWeightedEvents(), efixed,emodeStr);
        break;
  
      case WEIGHTED_NOTIME:
        correctKiKfEventHelper(evlist->getWeightedEventsNoTime(), efixed,emodeStr);
        break;
    }


    prog.report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  outputWS->clearMRU();
  if (inputWS->getNumberEvents( ) != outputWS->getNumberEvents( ))
  {
    g_log.information() <<"Ef <= 0 or Ei <= 0 for "<<inputWS->getNumberEvents( )-outputWS->getNumberEvents( )<<" events, out of "<<inputWS->getNumberEvents( )<<std::endl;
    if ( efixedProp == EMPTY_DBL()) g_log.information()<<"Try to set fixed energy"<<std::endl ;
  }
}