Example #1
0
  int LoadIsawPeaks::findPixelID(Instrument_const_sptr inst, std::string bankName, int col, int row)
  {
	  boost::shared_ptr<const IComponent> parent = inst->getComponentByName(bankName);
	  if (parent->type().compare("RectangularDetector") == 0)
	  {
          boost::shared_ptr<const RectangularDetector> RDet = boost::dynamic_pointer_cast<
					const RectangularDetector>(parent);

		  boost::shared_ptr<Detector> pixel = RDet->getAtXY(col, row);
		  return pixel->getID();
	  }
	  else
	  {
          std::vector<Geometry::IComponent_const_sptr> children;
          boost::shared_ptr<const Geometry::ICompAssembly> asmb = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
          asmb->getChildren(children, false);
          int col0 = (col%2==0 ? col/2+75 : (col-1)/2);
          boost::shared_ptr<const Geometry::ICompAssembly> asmb2 = boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[col0]);
          std::vector<Geometry::IComponent_const_sptr> grandchildren;
          asmb2->getChildren(grandchildren,false);
          Geometry::IComponent_const_sptr first = grandchildren[row-1];
          Geometry::IDetector_const_sptr det = boost::dynamic_pointer_cast<const Geometry::IDetector>(first);
		  return det->getID();
	  }
  }
/** Get the list of banks, given the settings
 *
 * @return map with key = bank number; value = pointer to the rectangular
 *detector
 */
std::map<int, RectangularDetector_const_sptr>
ConvertToDetectorFaceMD::getBanks() {
  Instrument_const_sptr inst = in_ws->getInstrument();

  std::vector<int> bankNums = this->getProperty("BankNumbers");
  std::sort(bankNums.begin(), bankNums.end());

  std::map<int, RectangularDetector_const_sptr> banks;

  if (bankNums.empty()) {
    // --- Find all rectangular detectors ----
    // Get all children
    std::vector<IComponent_const_sptr> comps;
    inst->getChildren(comps, true);

    for (auto &comp : comps) {
      // Retrieve it
      RectangularDetector_const_sptr det =
          boost::dynamic_pointer_cast<const RectangularDetector>(comp);
      if (det) {
        std::string name = det->getName();
        if (name.size() < 5)
          continue;
        std::string bank = name.substr(4, name.size() - 4);
        int bankNum;
        if (Mantid::Kernel::Strings::convert(bank, bankNum))
          banks[bankNum] = det;
        g_log.debug() << "Found bank " << bank << ".\n";
      }
    }
  } else {
    // -- Find detectors using the numbers given ---
    for (auto &bankNum : bankNums) {
      std::string bankName =
          "bank" + Mantid::Kernel::Strings::toString(bankNum);
      IComponent_const_sptr comp = inst->getComponentByName(bankName);
      RectangularDetector_const_sptr det =
          boost::dynamic_pointer_cast<const RectangularDetector>(comp);
      if (det)
        banks[bankNum] = det;
    }
  }

  for (auto &bank : banks) {
    RectangularDetector_const_sptr det = bank.second;
    // Track the largest detector
    if (det->xpixels() > m_numXPixels)
      m_numXPixels = det->xpixels();
    if (det->ypixels() > m_numYPixels)
      m_numYPixels = det->ypixels();
  }

  if (banks.empty())
    throw std::runtime_error("No RectangularDetectors with a name like "
                             "'bankXX' found in the instrument.");

  return banks;
}
Example #3
0
  void AnvredCorrection::scale_init(IDetector_const_sptr det, Instrument_const_sptr inst, int& bank, double& L2, double& depth, double& pathlength, std::string bankName)
  {
	bankName = det->getParent()->getParent()->getName();
	std::string bankNameStr = bankName;
	// Take out the "bank" part of the bank name and convert to an int
	bankNameStr.erase(remove_if(bankNameStr.begin(), bankNameStr.end(), not1(std::ptr_fun (::isdigit))), bankNameStr.end());
	Strings::convert(bankNameStr, bank);
	IComponent_const_sptr sample = inst->getSample();
	double cosA = inst->getComponentByName(bankName)->getDistance(*sample) / L2;
	pathlength = depth / cosA;
  }
/** Execute the algorithm.
 */
void CreateChunkingFromInstrument::exec() {
  // get the instrument
  Instrument_const_sptr inst = this->getInstrument();

  // setup the output workspace
  ITableWorkspace_sptr strategy =
      WorkspaceFactory::Instance().createTable("TableWorkspace");
  strategy->addColumn("str", "BankName");
  this->setProperty("OutputWorkspace", strategy);

  // get the correct level of grouping
  string groupLevel = this->getPropertyValue(PARAM_CHUNK_BY);
  vector<string> groupNames =
      getGroupNames(this->getPropertyValue(PARAM_CHUNK_NAMES));
  if (groupLevel.compare("All") == 0) {
    return; // nothing to do
  } else if (inst->getName().compare("SNAP") == 0 &&
             groupLevel.compare("Group") == 0) {
    groupNames.clear();
    groupNames.push_back("East");
    groupNames.push_back("West");
  }

  // set up a progress bar with the "correct" number of steps
  int maxBankNum = this->getProperty(PARAM_MAX_BANK_NUM);
  Progress progress(this, .2, 1., maxBankNum);

  // search the instrument for the bank names
  int maxRecurseDepth = this->getProperty(PARAM_MAX_RECURSE);
  map<string, vector<string>> grouping;
  // cppcheck-suppress syntaxError
    PRAGMA_OMP(parallel for schedule(dynamic, 1) )
    for (int num = 0; num < maxBankNum; ++num) {
      PARALLEL_START_INTERUPT_REGION
      ostringstream mess;
      mess << "bank" << num;
      IComponent_const_sptr comp =
          inst->getComponentByName(mess.str(), maxRecurseDepth);
      PARALLEL_CRITICAL(grouping)
      if (comp) {
        // get the name of the correct parent
        string parent;
        if (groupNames.empty()) {
          parent = parentName(comp, groupLevel);
        } else {
          parent = parentName(comp, groupNames);
        }

        // add it to the correct chunk
        if (!parent.empty()) {
          if (grouping.count(parent) == 0)
            grouping[parent] = vector<string>();

          grouping[parent].push_back(comp->getName());
        }
      }
      progress.report();
      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    // check to see that something happened
    if (grouping.empty())
      throw std::runtime_error("Failed to find any banks in the instrument");

    // fill in the table workspace
    for (auto group = grouping.begin(); group != grouping.end(); ++group) {
      stringstream banks;
      for (auto bank = group->second.begin(); bank != group->second.end();
           ++bank)
        banks << (*bank) << ",";

      // remove the trailing comma
      string banksStr = banks.str();
      banksStr = banksStr.substr(0, banksStr.size() - 1);

      // add it to the table
      TableRow row = strategy->appendRow();
      row << banksStr;
    }
}
Example #5
0
  /** Execute the algorithm.
   */
  void SaveIsawPeaks::exec()
  {
    // Section header
    std::string header = "2   SEQN    H    K    L     COL      ROW     CHAN        L2   2_THETA        AZ         WL         D      IPK          INTI    SIGI  RFLG";

    std::string filename = getPropertyValue("Filename");
    PeaksWorkspace_sptr ws = getProperty("InputWorkspace");
    std::vector<Peak> peaks = ws->getPeaks();

    // We must sort the peaks first by run, then bank #, and save the list of workspace indices of it
    typedef std::map<int, std::vector<size_t> > bankMap_t;
    typedef std::map<int, bankMap_t> runMap_t;
    std::set<int> uniqueBanks;
    runMap_t runMap;

    for (size_t i=0; i < peaks.size(); ++i)
    {
      Peak & p = peaks[i];
      int run = p.getRunNumber();
      int bank = 0;
      std::string bankName = p.getBankName();
      if (bankName.size() <= 4)
      {
        g_log.information() << "Could not interpret bank number of peak " << i << "(" << bankName << ")\n";
        continue;
      }
      // Take out the "bank" part of the bank name and convert to an int
      bankName = bankName.substr(4, bankName.size()-4);
      Strings::convert(bankName, bank);

      // Save in the map
      runMap[run][bank].push_back(i);
      // Track unique bank numbers
      uniqueBanks.insert(bank);
    }

    Instrument_const_sptr inst = ws->getInstrument();
    if (!inst) throw std::runtime_error("No instrument in PeaksWorkspace. Cannot save peaks file.");

    double l1; V3D beamline; double beamline_norm; V3D samplePos;
    inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);

    std::ofstream out;
    bool append = getProperty("AppendFile");
    if (append)
    {
      out.open( filename.c_str(), std::ios::app);
    }
    else
    {
      out.open( filename.c_str());


    out << "Version: 2.0  Facility: SNS " ;
    out <<  " Instrument: " <<  inst->getName() <<  "  Date: " ;

    //TODO: The experiment date might be more useful than the instrument date.
    // For now, this allows the proper instrument to be loaded back after saving.
    Kernel::DateAndTime expDate = inst->getValidFromDate() + 1.0;
    out <<  expDate.to_ISO8601_string() << std::endl;

    out << "6         L1    T0_SHIFT" <<  std::endl;
    out << "7 "<< std::setw( 10 )  ;
    out <<   std::setprecision( 4 ) <<  std::fixed <<  ( l1*100 ) ;
    out << std::setw( 12 ) <<  std::setprecision( 3 ) <<  std::fixed  ;
    // Time offset of 0.00 for now
    out << "0.000" <<  std::endl;


    // ============================== Save .detcal info =========================================
    if (true)
    {
      out <<  "4 DETNUM  NROWS  NCOLS   WIDTH   HEIGHT   DEPTH   DETD   CenterX   CenterY   CenterZ    BaseX    BaseY    BaseZ      UpX      UpY      UpZ"
          <<  std::endl;
      // Here would save each detector...
      std::set<int>::iterator it;
      for (it = uniqueBanks.begin(); it != uniqueBanks.end(); it++)
      {
        // Build up the bank name
        int bank = *it;
        std::ostringstream mess;
        mess << "bank" << bank;
        std::string bankName = mess.str();
        // Retrieve it
        RectangularDetector_const_sptr det = boost::dynamic_pointer_cast<const RectangularDetector>(inst->getComponentByName(bankName));
        if (det)
        {
          // Center of the detector
          V3D center = det->getPos();
          // Distance to center of detector
          double detd = (center - inst->getSample()->getPos()).norm();

          // Base unit vector (along the horizontal, X axis)
          V3D base = det->getAtXY(det->xpixels()-1,0)->getPos() - det->getAtXY(0,0)->getPos();
          base.normalize();
          // Up unit vector (along the vertical, Y axis)
          V3D up = det->getAtXY(0,det->ypixels()-1)->getPos() - det->getAtXY(0,0)->getPos();
          up.normalize();

          // Write the line
          out << "5 "
           << std::setw(6) << std::right << bank << " "
           << std::setw(6) << std::right << det->xpixels() << " "
           << std::setw(6) << std::right << det->ypixels() << " "
           << std::setw(7) << std::right << std::fixed << std::setprecision(4) << 100.0*det->xsize() << " "
           << std::setw(7) << std::right << std::fixed << std::setprecision(4) << 100.0*det->ysize() << " "
           << "  0.2000 "
           << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0*detd << " "
           << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0*center.X() << " "
           << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0*center.Y() << " "
           << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0*center.Z() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.X() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.Y() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.Z() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.X() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.Y() << " "
           << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.Z() << " "
           << std::endl;

        }
      }
    }
    }


    // ============================== Save all Peaks =========================================
    // Sequence number
    int seqNum = 1;

    // Go in order of run numbers
    runMap_t::iterator runMap_it;
    for (runMap_it = runMap.begin(); runMap_it != runMap.end(); runMap_it++)
    {
      // Start of a new run
      int run = runMap_it->first;
      bankMap_t & bankMap = runMap_it->second;

      bankMap_t::iterator bankMap_it;
      for (bankMap_it = bankMap.begin(); bankMap_it != bankMap.end(); bankMap_it++)
      {
        // Start of a new bank.
        int bank = bankMap_it->first;
        std::vector<size_t> & ids = bankMap_it->second;

        if (ids.size() > 0)
        {
          // Write the bank header
          out << "0 NRUN DETNUM    CHI      PHI    OMEGA   MONCNT" << std::endl;
          out <<  "1" <<  std::setw( 5 ) <<  run <<  std::setw( 7 ) <<
              std::right <<  bank;

          // Determine goniometer angles by calculating from the goniometer matrix of a peak in the list
          Goniometer gon(peaks[ids[0]].getGoniometerMatrix());
          std::vector<double> angles = gon.getEulerAngles("yzy");

          double phi = angles[2];
          double chi = angles[1];
          double omega = angles[0];

          out  <<  std::setw( 7 ) <<  std::fixed <<  std::setprecision( 2 )  <<  chi << " ";
          out  <<  std::setw( 7 ) <<  std::fixed <<  std::setprecision( 2 )  <<  phi << " ";
          out  <<  std::setw( 7 ) <<  std::fixed <<  std::setprecision( 2 )  <<  omega << " ";
          out  <<  std::setw( 7 ) <<  (int)( 0 ) <<  std::endl;

          out << header << std::endl;

          // Go through each peak at this run / bank
          for (size_t i=0; i < ids.size(); i++)
          {
            size_t wi = ids[i];
            Peak & p = peaks[wi];

            // Sequence (run) number
            out <<  "3" <<  std::setw( 7 ) << seqNum;

            // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
            out <<  std::setw( 5 ) << Utils::round(-p.getH())
                <<  std::setw( 5 ) << Utils::round(-p.getK())
                <<  std::setw( 5 ) << Utils::round(-p.getL());

            // Row/column
            out <<  std::setw( 8 ) <<  std::fixed << std::setprecision( 2 )
              << static_cast<double>(p.getCol()) << " ";

            out << std::setw( 8 ) << std::fixed << std::setprecision( 2 )
              << static_cast<double>(p.getRow()) << " ";

            out << std::setw( 8 ) << std::fixed << std::setprecision( 0 )
              << p.getTOF() << " ";


            out << std::setw( 9 ) << std::fixed << std::setprecision( 3 )
              << (p.getL2()*100.0) << " ";

            // This is the scattered beam direction
            V3D dir = p.getDetPos() - inst->getSample()->getPos();
            double scattering, azimuth;

            // Two-theta = polar angle = scattering angle = between +Z vector and the scattered beam
            scattering = dir.angle( V3D(0.0, 0.0, 1.0) );

            // "Azimuthal" angle: project the beam onto the XY plane, and measure the angle between that and the +X axis (right-handed)
            azimuth = atan2( dir.Y(), dir.X() );

            out << std::setw( 9 ) << std::fixed << std::setprecision( 5 )
              << scattering << " "; //two-theta scattering

            out << std::setw( 9 ) << std::fixed << std::setprecision( 5 )
              << azimuth << " ";

            out << std::setw( 10 ) << std::fixed << std::setprecision( 6 )
              << p.getWavelength() << " ";

            out << std::setw( 9 ) << std::fixed << std::setprecision( 4 )
              << p.getDSpacing() << " ";

            out << std::setw( 8 ) << std::fixed << int(p.getBinCount()) << std::setw( 10 ) << " "
              << std::fixed << std::setprecision( 2 ) << p.getIntensity() << " ";

            out << std::setw( 7 ) << std::fixed << std::setprecision( 2 )
              << p.getSigmaIntensity() << " ";

            int thisReflag = 310;
            out << std::setw( 5 ) << thisReflag;

            out << std::endl;

            // Count the sequence
            seqNum++;
          }
        }
      }
    }

    out.flush();
    out.close();

//    //REMOVE:
//    std::string line;
//    std::ifstream myfile (filename.c_str());
//    if (myfile.is_open())
//    {
//      while ( myfile.good() )
//      {
//        getline (myfile,line);
//        std::cout << line << std::endl;
//      }
//      myfile.close();
//    }


  }
Example #6
0
  /** Read one peak in a line of an ISAW peaks file.
   *
   * @param outWS :: workspace to add peaks to
   * @param lastStr [in,out] :: last word (the one at the start of the line)
   * @param in :: input stream
   * @param seqNum [out] :: the sequence number of the peak
   * @param bankName :: the bank number from the ISAW file.
   * @return the Peak the Peak object created
   */
  Mantid::DataObjects::Peak readPeak( PeaksWorkspace_sptr outWS, std::string & lastStr,  std::ifstream& in, int & seqNum, std::string bankName)
  {
    double h ; double k ;  double l ;  double col ;
    double row ; double wl ;
    double IPK ; double Inti ;
    double SigI ;

    seqNum = -1;

    std::string s = lastStr;
    if( s.length() < 1 && in.good() )//blank line
    {
      readToEndOfLine( in ,  true );
      s = getWord( in ,  false );;
    }

    if( s.length() < 1 )
      throw std::runtime_error("Empty peak line encountered.");

    if( s.compare( "2" ) == 0 )
    {
      readToEndOfLine( in ,  true );
      for( s = getWord( in ,  false ) ; s.length() < 1 && in.good() ;
          s = getWord( in ,  true ) )
      {
        s = getWord( in ,  false );
      }
    }

    if( s.length() < 1 )
      throw std::runtime_error("Empty peak line encountered.");

    if( s.compare( "3" ) != 0 )
      throw std::runtime_error("Empty peak line encountered.");

    seqNum = atoi( getWord( in ,  false ).c_str() );

    h = strtod( getWord( in ,  false ).c_str() ,  0 ) ;
    k = strtod( getWord( in ,  false ).c_str() ,  0 ) ;
    l = strtod( getWord( in ,  false ).c_str() ,  0 ) ;

    col = strtod( getWord( in ,  false ).c_str() ,  0 ) ;
    row = strtod( getWord( in ,  false ).c_str() ,  0 ) ;
    strtod( getWord( in ,  false ).c_str() ,  0 ) ; //chan
    strtod( getWord( in ,  false ).c_str() ,  0 ) ; //L2
    strtod( getWord( in ,  false ).c_str() ,  0 ) ; //ScatAng

    strtod( getWord( in , false ).c_str() , 0 ) ; //Az
    wl = strtod( getWord( in , false ).c_str() , 0 ) ;
    strtod( getWord( in , false ).c_str() , 0 ) ; //D
    IPK = strtod( getWord( in , false ).c_str() , 0 ) ;

    Inti = strtod( getWord( in , false ).c_str() , 0 ) ;
    SigI = strtod( getWord( in , false ).c_str() , 0 ) ;
    atoi( getWord( in , false ).c_str() ) ; // iReflag

    // Finish the line and get the first word of next line
    readToEndOfLine( in ,  true );
    lastStr = getWord( in , false );

    // Find the detector ID from row/col
    Instrument_const_sptr inst = outWS->getInstrument();
    if (!inst) throw std::runtime_error("No instrument in PeaksWorkspace!");
    IComponent_const_sptr bank = inst->getComponentByName(bankName);
    if (!bank) throw std::runtime_error("Bank named " + bankName + " not found!");
    RectangularDetector_const_sptr rect = boost::dynamic_pointer_cast<const RectangularDetector>(bank);
    if (!rect) throw std::runtime_error("Bank named " + bankName + " is not a RectangularDetector!");
    IDetector_sptr det = rect->getAtXY(int(col), int(row));
    if (!det) throw std::runtime_error("Detector not found on " + bankName + "!");

    //Create the peak object
    Peak peak(outWS->getInstrument(), det->getID(), wl);
    // HKL's are flipped by -1 because of the internal Q convention
    peak.setHKL(-h,-k,-l);
    peak.setIntensity(Inti);
    peak.setSigmaIntensity(SigI);
    peak.setBinCount(IPK);
    // Return the peak
    return peak;
  }
/** Execute the algorithm.
 */
void CreateGroupingWorkspace::exec() {
  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  std::string InstrumentName = getPropertyValue("InstrumentName");
  std::string InstrumentFilename = getPropertyValue("InstrumentFilename");
  std::string OldCalFilename = getPropertyValue("OldCalFilename");
  std::string GroupNames = getPropertyValue("GroupNames");
  std::string grouping = getPropertyValue("GroupDetectorsBy");
  int numGroups = getProperty("FixedGroupCount");
  std::string componentName = getPropertyValue("ComponentName");

  // Some validation
  int numParams = 0;
  if (inWS)
    numParams++;
  if (!InstrumentName.empty())
    numParams++;
  if (!InstrumentFilename.empty())
    numParams++;

  if (numParams > 1)
    throw std::invalid_argument("You must specify exactly ONE way to get an "
                                "instrument (workspace, instrument name, or "
                                "IDF file). You specified more than one.");
  if (numParams == 0)
    throw std::invalid_argument("You must specify exactly ONE way to get an "
                                "instrument (workspace, instrument name, or "
                                "IDF file). You specified none.");

  if (!OldCalFilename.empty() && !GroupNames.empty())
    throw std::invalid_argument("You must specify either to use the "
                                "OldCalFilename parameter OR GroupNames but "
                                "not both!");

  bool sortnames = false;

  // ---------- Get the instrument one of 3 ways ---------------------------
  Instrument_const_sptr inst;
  if (inWS) {
    inst = inWS->getInstrument();
  } else {
    Algorithm_sptr childAlg = createChildAlgorithm("LoadInstrument", 0.0, 0.2);
    MatrixWorkspace_sptr tempWS = boost::make_shared<Workspace2D>();
    childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS);
    childAlg->setPropertyValue("Filename", InstrumentFilename);
    childAlg->setProperty("RewriteSpectraMap",
                          Mantid::Kernel::OptionalBool(true));
    childAlg->setPropertyValue("InstrumentName", InstrumentName);
    childAlg->executeAsChildAlg();
    inst = tempWS->getInstrument();
  }

  if (GroupNames.empty() && OldCalFilename.empty()) {
    if (grouping.compare("All") == 0) {
      GroupNames = inst->getName();
    } else if (inst->getName().compare("SNAP") == 0 &&
               grouping.compare("Group") == 0) {
      GroupNames = "East,West";
    } else {
      sortnames = true;
      GroupNames = "";
      int maxRecurseDepth = this->getProperty("MaxRecursionDepth");

      // cppcheck-suppress syntaxError
          PRAGMA_OMP(parallel for schedule(dynamic, 1) )
          for (int num = 0; num < 300; ++num) {
            PARALLEL_START_INTERUPT_REGION
            std::ostringstream mess;
            mess << grouping << num;
            IComponent_const_sptr comp =
                inst->getComponentByName(mess.str(), maxRecurseDepth);
            PARALLEL_CRITICAL(GroupNames)
            if (comp)
              GroupNames += mess.str() + ",";
            PARALLEL_END_INTERUPT_REGION
          }
          PARALLEL_CHECK_INTERUPT_REGION
    }
  }

  // --------------------------- Create the output --------------------------
  auto outWS = boost::make_shared<GroupingWorkspace>(inst);
  this->setProperty("OutputWorkspace", outWS);

  // This will get the grouping
  std::map<detid_t, int> detIDtoGroup;

  Progress prog(this, 0.2, 1.0, outWS->getNumberHistograms());
  // Make the grouping one of three ways:
  if (!GroupNames.empty())
    detIDtoGroup = makeGroupingByNames(GroupNames, inst, prog, sortnames);
  else if (!OldCalFilename.empty())
    detIDtoGroup = readGroupingFile(OldCalFilename, prog);
  else if ((numGroups > 0) && !componentName.empty())
    detIDtoGroup =
        makeGroupingByNumGroups(componentName, numGroups, inst, prog);

  g_log.information() << detIDtoGroup.size()
                      << " entries in the detectorID-to-group map.\n";
  setProperty("NumberGroupedSpectraResult",
              static_cast<int>(detIDtoGroup.size()));

  if (detIDtoGroup.empty()) {
    g_log.warning() << "Creating empty group workspace\n";
    setProperty("NumberGroupsResult", static_cast<int>(0));
  } else {
    size_t numNotFound = 0;

    // Make the groups, if any
    std::map<detid_t, int>::const_iterator it_end = detIDtoGroup.end();
    std::map<detid_t, int>::const_iterator it;
    std::unordered_set<int> groupCount;
    for (it = detIDtoGroup.begin(); it != it_end; ++it) {
      int detID = it->first;
      int group = it->second;
      groupCount.insert(group);
      try {
        outWS->setValue(detID, double(group));
      } catch (std::invalid_argument &) {
        numNotFound++;
      }
    }
    setProperty("NumberGroupsResult", static_cast<int>(groupCount.size()));

    if (numNotFound > 0)
      g_log.warning() << numNotFound << " detector IDs (out of "
                      << detIDtoGroup.size()
                      << ") were not found in the instrument\n.";
  }
}
Example #8
0
/** Executes the algorithm. 
 * 
 *  @throw std::runtime_error Thrown with Workspace problems
 */
void RotateInstrumentComponent::exec()
{
  // Get the workspace
  MatrixWorkspace_sptr WS = getProperty("Workspace");
  const std::string ComponentName = getProperty("ComponentName");
  const int DetID = getProperty("DetectorID");
  const double X = getProperty("X");
  const double Y = getProperty("Y");
  const double Z = getProperty("Z");
  const double angle = getProperty("Angle");
  const bool RelativeRotation = getProperty("RelativeRotation");

  if (X + Y + Z == 0.0) throw std::invalid_argument("The rotation axis must not be a zero vector");

  Instrument_const_sptr inst = WS->getInstrument();
  IComponent_const_sptr comp;

  // Find the component to move
  if (DetID != -1)
  {
      comp = inst->getDetector(DetID);
      if (comp == 0)
      {
          std::ostringstream mess;
          mess<<"Detector with ID "<<DetID<<" was not found.";
          g_log.error(mess.str());
          throw std::runtime_error(mess.str());
      }
  }
  else if (!ComponentName.empty())
  {
      comp = inst->getComponentByName(ComponentName);
      if (comp == 0)
      {
          std::ostringstream mess;
          mess<<"Component with name "<<ComponentName<<" was not found.";
          g_log.error(mess.str());
          throw std::runtime_error(mess.str());
      }
  }
  else
  {
      g_log.error("DetectorID or ComponentName must be given.");
      throw std::invalid_argument("DetectorID or ComponentName must be given.");
  }

  // First set new relative or absolute rotation
  Quat Rot;
  if (RelativeRotation)
  {
      Quat Rot0 = comp->getRelativeRot();
      Rot = Rot0 * Quat(angle,V3D(X,Y,Z));
  }
  else
  {
      Rot = Quat(angle,V3D(X,Y,Z));
      // Then find the corresponding relative position
      boost::shared_ptr<const IComponent> parent = comp->getParent();
      if (parent)
      {
          Quat rot0 = parent->getRelativeRot();
          rot0.inverse();
          Rot = Rot * rot0;
      }
  }

  //Need to get the address to the base instrument component
  Geometry::ParameterMap& pmap = WS->instrumentParameters();
  // Add a parameter for the new rotation
  pmap.addQuat(comp.get(), "rot", Rot);

  return;
}