/// Calculate the distances traversed by the neutrons within the sample /// @param detector :: The detector we are working on /// @param L2s :: A vector of the sample-detector distance for each segment of /// the sample void AbsorptionCorrection::calculateDistances(const IDetector &detector, std::vector<double> &L2s) const { V3D detectorPos(detector.getPos()); if (detector.nDets() > 1) { // We need to make sure this is right for grouped detectors - should use // average theta & phi detectorPos.spherical(detectorPos.norm(), detector.getTwoTheta(V3D(), V3D(0, 0, 1)) * 180.0 / M_PI, detector.getPhi() * 180.0 / M_PI); } for (size_t i = 0; i < m_numVolumeElements; ++i) { // Create track for distance in cylinder between scattering point and // detector V3D direction = detectorPos - m_elementPositions[i]; direction.normalize(); Track outgoing(m_elementPositions[i], direction); int temp = m_sampleObject->interceptSurface(outgoing); /* Most of the time, the number of hits is 1. Sometime, we have more than * one intersection due to * arithmetic imprecision. If it is the case, then selecting the first * intersection is valid. * In principle, one could check the consistency of all distances if hits is * larger than one by doing: * Mantid::Geometry::Track::LType::const_iterator it=outgoing.begin(); * and looping until outgoing.end() checking the distances with it->Dist */ // Not hitting the cylinder from inside, usually means detector is badly // defined, // i.e, position is (0,0,0). if (temp < 1) { // FOR NOW AT LEAST, JUST IGNORE THIS ERROR AND USE A ZERO PATH LENGTH, // WHICH I RECKON WILL MAKE A // NEGLIGIBLE DIFFERENCE ANYWAY (ALWAYS SEEMS TO HAPPEN WITH ELEMENT RIGHT // AT EDGE OF SAMPLE) L2s[i] = 0.0; // std::ostringstream message; // message << "Problem with detector at " << detectorPos << " ID:" << // detector->getID() << '\n'; // message << "This usually means that this detector is defined inside the // sample cylinder"; // g_log.error(message.str()); // throw std::runtime_error("Problem in // AbsorptionCorrection::calculateDistances"); } else // The normal situation { L2s[i] = outgoing.cbegin()->distFromStart; } } }
AMControlInfoList REIXSXESCalibration::computeSpectrometerPosition(int gratingIndex, double eV, double focusOffsetMm, double tiltOffsetDeg) const { qDebug() << "Spectrometer Geometry calculations for: " << gratingNames().at(gratingIndex) << eV << "eV," << focusOffsetMm << "mm defocus," << tiltOffsetDeg << "deg tilt offset:"; AMControlInfoList rv; double hexU = hexapodU(gratingIndex); QVector3D hexXYZ = hexapodXYZ(gratingIndex); QVector3D hexRST = hexapodRST(gratingIndex); QVector3D detPos = detectorPos(eV, gratingIndex); double theta = spectrometerTheta(detPos); double translation = detectorTranslation(detPos, theta, focusOffsetMm); double spectrometerRotation = spectrometerRotationDrive(theta); double tilt = tiltStageDrive(eV, gratingIndex, theta, tiltOffsetDeg); rv.append(AMControlInfo("spectrometerRotationDrive", spectrometerRotation, 0,0, "mm", 0.1, "Linear drive motor for spectrometer angle")); rv.append(AMControlInfo("detectorTranslation", translation, 0,0, "mm", 0.1, "Detector translation")); rv.append(AMControlInfo("detectorTiltDrive", tilt, 0.0, 0.0, "mm", 0.1, "Linear drive motor for detector tilt")); rv.append(AMControlInfo("hexapodX", hexXYZ.x(), 0, 0, "mm", 0.1, "Hexapod X position")); rv.append(AMControlInfo("hexapodY", hexXYZ.y(), 0, 0, "mm", 0.1, "Hexapod Y position")); rv.append(AMControlInfo("hexapodZ", hexXYZ.z(), 0, 0, "mm", 0.1, "Hexapod Z position")); rv.append(AMControlInfo("hexapodU", hexU, 0,0, "deg", 0.1, "Hexapod Tilt around X axis")); rv.append(AMControlInfo("hexapodR", hexRST.x(), 0,0, "mm", 0.1, "Hexapod rotation point R")); rv.append(AMControlInfo("hexapodS", hexRST.y(), 0,0, "mm", 0.1, "Hexapod rotation point S")); rv.append(AMControlInfo("hexapodT", hexRST.z(), 0,0, "mm", 0.1, "Hexapod rotation point T")); qDebug() << " Alpha required for rowland condition (deg):" << r2d(alpha(gratingIndex)); qDebug() << " Beta using that alpha, at " << eV << "eV:" << r2d(beta(eV, gratingIndex)); qDebug() << " Angle of slit-origin ray above y axis (deg)" << r2d(sTheta(gratingIndex)); qDebug() << " Grating tilt to achieve required alpha (deg):" << hexU; qDebug() << " r (mm):" << r(gratingIndex); qDebug() << " r-prime (mm):" << rPrime(eV, gratingIndex); qDebug() << " Spectrometer dTheta: angle up from y axis to center of detector (deg):" << r2d(dTheta(eV, gratingIndex)); qDebug() << " Detector position:" << detPos; qDebug() << " Spectrometer theta: (deg)" << r2d(theta); qDebug() << " Translation: (mm)" << translation; qDebug() << " Spectrometer rotation stage translation: (mm)" << spectrometerRotation; qDebug() << " Detector tilt phi (detector angle down to positive y axis) (deg):" << r2d(detectorPhi(eV, gratingIndex)); qDebug() << " Extra tilt on top of spectrometer angle" << r2d(detectorPhi(eV, gratingIndex) - theta); qDebug() << " Tilt stage translation: (mm)" << tilt; return rv; }