std::pair<double, double> LoadILLSANS::calculateQMaxQMin() { double min = std::numeric_limits<double>::max(), max = std::numeric_limits<double>::min(); g_log.debug("Calculating Qmin Qmax..."); std::size_t nHist = m_localWorkspace->getNumberHistograms(); for (std::size_t i = 0; i < nHist; ++i) { Geometry::IDetector_const_sptr det = m_localWorkspace->getDetector(i); if (!det->isMonitor()) { const MantidVec &lambdaBinning = m_localWorkspace->readX(i); Kernel::V3D detPos = det->getPos(); double r, theta, phi; detPos.getSpherical(r, theta, phi); double v1 = calculateQ(*(lambdaBinning.begin()), theta); double v2 = calculateQ(*(lambdaBinning.end() - 1), theta); // std::cout << "i=" << i << " theta="<<theta << " lambda_i=" << // *(lambdaBinning.begin()) << " lambda_f=" << *(lambdaBinning.end()-1) << // " v1=" << v1 << " v2=" << v2 << '\n'; if (i == 0) { min = v1; max = v1; } if (v1 < min) { min = v1; } if (v2 < min) { min = v2; } if (v1 > max) { max = v1; } if (v2 > max) { max = v2; } } else g_log.debug() << "Detector " << i << " is a Monitor : " << det->getID() << '\n'; } g_log.debug() << "Calculating Qmin Qmax. Done : [" << min << "," << max << "]\n"; return std::pair<double, double>(min, max); }
/** method to cacluate the detectors parameters and add them to the detectors *averages *@param spDet -- shared pointer to the Mantid Detector *@param Observer -- sample position or the centre of the polar system of *coordinates to calculate detector's parameters. */ void AvrgDetector::addDetInfo(const Geometry::IDetector_const_sptr &spDet, const Kernel::V3D &Observer) { m_nComponents++; Kernel::V3D detPos = spDet->getPos(); Kernel::V3D toDet = (detPos - Observer); double dist2Det, Polar, Azimut, ringPolar, ringAzim; // identify the detector' position in the beam coordinate system: toDet.getSpherical(dist2Det, Polar, Azimut); if (m_nComponents <= 1) { m_FlightPathSum = dist2Det; m_PolarSum = Polar; m_AzimutSum = Azimut; m_AzimBase = Polar; m_PolarBase = Azimut; ringPolar = Polar; ringAzim = Azimut; } else { ringPolar = nearAngle(m_AzimBase, Polar); ringAzim = nearAngle(m_PolarBase, Azimut); m_FlightPathSum += dist2Det; m_PolarSum += ringPolar; m_AzimutSum += ringAzim; } // centre of the azimuthal ring (the ring detectors form around the beam) Kernel::V3D ringCentre(0, 0, toDet.Z()); // Get the bounding box Geometry::BoundingBox bbox; std::vector<Kernel::V3D> coord(3); Kernel::V3D er(0, 1, 0), e_th, ez(0, 0, 1); // ez along beamline, which is always oz; if (dist2Det) er = toDet / dist2Det; // direction to the detector Kernel::V3D e_tg = er.cross_prod(ez); // tangential to the ring and anticloakwise; e_tg.normalize(); // make orthogonal -- projections are calculated in this coordinate system ez = e_tg.cross_prod(er); coord[0] = er; // new X coord[1] = ez; // new y coord[2] = e_tg; // new z bbox.setBoxAlignment(ringCentre, coord); spDet->getBoundingBox(bbox); // linear extensions of the bounding box orientied tangentially to the equal // scattering angle circle double azimMin = bbox.zMin(); double azimMax = bbox.zMax(); double polarMin = bbox.yMin(); // bounding box has been rotated according to // coord above, so z is along e_tg double polarMax = bbox.yMax(); if (m_useSphericalSizes) { if (dist2Det == 0) dist2Det = 1; // convert to angular units double polarHalfSize = rad2deg * atan2(0.5 * (polarMax - polarMin), dist2Det); double azimHalfSize = rad2deg * atan2(0.5 * (azimMax - azimMin), dist2Det); polarMin = ringPolar - polarHalfSize; polarMax = ringPolar + polarHalfSize; azimMin = ringAzim - azimHalfSize; azimMax = ringAzim + azimHalfSize; } if (m_AzimMin > azimMin) m_AzimMin = azimMin; if (m_AzimMax < azimMax) m_AzimMax = azimMax; if (m_PolarMin > polarMin) m_PolarMin = polarMin; if (m_PolarMax < polarMax) m_PolarMax = polarMax; }