/** Execute the algorithm. */ void SetGoniometer::exec() { MatrixWorkspace_sptr ws = getProperty("Workspace"); std::string gonioDefined = getPropertyValue("Goniometers"); // Create the goniometer Goniometer gon; if(gonioDefined.compare("Universal") == 0) gon.makeUniversalGoniometer(); else for (size_t i=0; i< NUM_AXES; i++) { std::ostringstream propName; propName << "Axis" << i; std::string axisDesc = getPropertyValue(propName.str()); if (!axisDesc.empty()) { std::vector<std::string> tokens; boost::split( tokens, axisDesc, boost::algorithm::detail::is_any_ofF<char>(",")); if (tokens.size() != 5) throw std::invalid_argument("Wrong number of arguments to parameter " + propName.str() + ". Expected 5 comma-separated arguments."); std::string axisName = tokens[0]; axisName = Strings::strip(axisName); if (axisName.empty()) throw std::invalid_argument("The name must not be empty"); double x=0,y=0,z=0; if (!Strings::convert(tokens[1], x)) throw std::invalid_argument("Error converting string '" + tokens[1] + "' to a number."); if (!Strings::convert(tokens[2], y)) throw std::invalid_argument("Error converting string '" + tokens[2] + "' to a number."); if (!Strings::convert(tokens[3], z)) throw std::invalid_argument("Error converting string '" + tokens[3] + "' to a number."); V3D vec(x,y,z); if (vec.norm() < 1e-4) throw std::invalid_argument("Rotation axis vector should be non-zero!"); int ccw = 0; Strings::convert(tokens[4], ccw); if (ccw != 1 && ccw != -1) throw std::invalid_argument("The ccw parameter must be 1 (ccw) or -1 (cw) but no other value."); // Default to degrees gon.pushAxis( axisName, x, y, z, 0.0, ccw); } } if (gon.getNumberAxes() == 0) g_log.warning() << "Empty goniometer created; will always return an identity rotation matrix." << std::endl; // All went well, copy the goniometer into it. It will throw if the log values cannot be found try { ws->mutableRun().setGoniometer(gon, true); } catch (std::runtime_error &) { g_log.error("No log values for goniometers"); } }
/** * Read single SPE header from the file. It assumes the file stream * points at the start of a header section. It is left pointing at the end of * this section * @return A new ExperimentInfo object storing the data */ boost::shared_ptr<API::ExperimentInfo> LoadSQW2::readSingleSPEHeader() { auto experiment = boost::make_shared<ExperimentInfo>(); auto &sample = experiment->mutableSample(); auto &run = experiment->mutableRun(); std::string chars; // skip filename, filepath *m_reader >> chars >> chars; float efix(1.0f); int32_t emode(0); // add ei as log but skip emode *m_reader >> efix >> emode; run.addProperty("Ei", static_cast<double>(efix), true); // lattice - alatt, angdeg, cu, cv = 12 values std::vector<float> floats; m_reader->read(floats, 12); auto lattice = Kernel::make_unique<OrientedLattice>( floats[0], floats[1], floats[2], floats[3], floats[4], floats[5]); V3D uVec(floats[6], floats[7], floats[8]), vVec(floats[9], floats[10], floats[11]); lattice->setUFromVectors(uVec, vVec); // Lattice is copied into the Sample object sample.setOrientedLattice(lattice.get()); if (g_log.is(Logger::Priority::PRIO_DEBUG)) { std::stringstream os; os << "Lattice:" << " alatt: " << lattice->a1() << " " << lattice->a2() << " " << lattice->a3() << "\n" << " angdeg: " << lattice->alpha() << " " << lattice->beta() << " " << lattice->gamma() << "\n" << " cu: " << floats[6] << " " << floats[7] << " " << floats[8] << "\n" << " cv: " << floats[9] << " " << floats[10] << " " << floats[11] << "\n" << "B matrix (calculated): " << lattice->getB() << "\n" << "Inverse B matrix (calculated): " << lattice->getBinv() << "\n"; g_log.debug(os.str()); } // goniometer angles float psi(0.0f), omega(0.0f), dpsi(0.0f), gl(0.0f), gs(0.0f); *m_reader >> psi >> omega >> dpsi >> gl >> gs; V3D uvCross = uVec.cross_prod(vVec); Goniometer goniometer; goniometer.pushAxis("psi", uvCross[0], uvCross[1], uvCross[2], psi); goniometer.pushAxis("omega", uvCross[0], uvCross[1], uvCross[2], omega); goniometer.pushAxis("gl", 1.0, 0.0, 0.0, gl); goniometer.pushAxis("gs", 0.0, 0.0, 1.0, gs); goniometer.pushAxis("dpsi", 0.0, 1.0, 0.0, dpsi); run.setGoniometer(goniometer, false); if (g_log.is(Logger::Priority::PRIO_DEBUG)) { std::stringstream os; os << "Goniometer angles:\n" << " psi: " << psi << "\n" << " omega: " << omega << "\n" << " gl: " << gl << "\n" << " gs: " << gs << "\n" << " dpsi: " << dpsi << "\n" << " goniometer matrix: " << goniometer.getR() << "\n"; g_log.debug(os.str()); } // energy bins int32_t nbounds(0); *m_reader >> nbounds; std::vector<float> enBins(nbounds); m_reader->read(enBins, nbounds); run.storeHistogramBinBoundaries( std::vector<double>(enBins.begin(), enBins.end())); // Skip the per-spe file projection information. We only use the // information from the data section m_file->seekg(96, std::ios_base::cur); std::vector<int32_t> ulabel_shape(2); m_reader->read(ulabel_shape, 2); // shape[0]*shape[1]*sizeof(char) m_file->seekg(ulabel_shape[0] * ulabel_shape[1], std::ios_base::cur); return experiment; }