void LoadILLIndirect::moveComponent(const std::string &componentName, double twoTheta, double offSet) { try { Geometry::Instrument_const_sptr instrument = m_localWorkspace->getInstrument(); Geometry::IComponent_const_sptr component = instrument->getComponentByName(componentName); double r, theta, phi, newTheta, newR; V3D oldPos = component->getPos(); oldPos.getSpherical(r, theta, phi); newTheta = twoTheta; newR = offSet; V3D newPos; newPos.spherical(newR, newTheta, phi); // g_log.debug() << tube->getName() << " : t = " << theta << " ==> t = " << // newTheta << "\n"; Geometry::ParameterMap &pmap = m_localWorkspace->instrumentParameters(); Geometry::ComponentHelper::moveComponent( *component, pmap, newPos, Geometry::ComponentHelper::Absolute); } catch (Mantid::Kernel::Exception::NotFoundError &) { throw std::runtime_error("Error when trying to move the " + componentName + " : NotFoundError"); } catch (std::runtime_error &) { throw std::runtime_error("Error when trying to move the " + componentName + " : runtime_error"); } }
/** * Executes the algorithm * */ void ConvertToConstantL2::exec() { initWorkspaces(); // Calculate the number of spectra in this workspace const size_t numberOfSpectra = m_inputWS->getNumberHistograms(); API::Progress prog(this, 0.0, 1.0, numberOfSpectra); int64_t numberOfSpectra_i = static_cast<int64_t>(numberOfSpectra); // cast to make openmp happy const auto &inputSpecInfo = m_inputWS->spectrumInfo(); auto &outputDetInfo = m_outputWS->mutableDetectorInfo(); // Loop over the histograms (detector spectra) PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *m_outputWS)) for (int64_t i = 0; i < numberOfSpectra_i; ++i) { PARALLEL_START_INTERUPT_REGION m_outputWS->setHistogram(i, m_inputWS->histogram(i)); // Should not move the monitors if (inputSpecInfo.isMonitor(i)) continue; // Throw if detector doesn't exist or is a group if (!inputSpecInfo.hasUniqueDetector(i)) { const auto errorMsg = boost::format("The detector for spectrum number %d was either not " "found, or is a group.") % i; throw std::runtime_error(errorMsg.str()); } // subract the diference in l2 double thisDetL2 = inputSpecInfo.l2(i); double deltaL2 = std::abs(thisDetL2 - m_l2); double deltaTOF = calculateTOF(deltaL2); deltaTOF *= 1e6; // micro sec // position - set all detector distance to constant l2 double r, theta, phi; V3D oldPos = inputSpecInfo.position(i); oldPos.getSpherical(r, theta, phi); V3D newPos; newPos.spherical(m_l2, theta, phi); const auto detIndex = inputSpecInfo.spectrumDefinition(i)[0]; outputDetInfo.setPosition(detIndex, newPos); m_outputWS->mutableX(i) -= deltaTOF; prog.report("Aligning elastic line..."); PARALLEL_END_INTERUPT_REGION } // end for i PARALLEL_CHECK_INTERUPT_REGION this->setProperty("OutputWorkspace", this->m_outputWS); }
void EstimatePDDetectorResolution::estimateDetectorResolution() { Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); size_t numspec = m_inputWS->getNumberHistograms(); double mintwotheta = 10000; double maxtwotheta = 0; double mint3 = 1; double maxt3 = 0; size_t count_nodetsize = 0; for (size_t i = 0; i < numspec; ++i) { // Get detector IDetector_const_sptr det = m_inputWS->getDetector(i); double detdim; boost::shared_ptr<const Detector> realdet = boost::dynamic_pointer_cast<const Detector>(det); if (realdet) { double dy = realdet->getHeight(); double dx = realdet->getWidth(); detdim = sqrt(dx*dx + dy*dy)*0.5; } else { // Use detector dimension as 0 as no-information detdim = 0; ++ count_nodetsize; } // Get the distance from detector to source V3D detpos = det->getPos(); double l2 = detpos.distance(samplepos); if (l2 < 0) throw runtime_error("L2 is negative"); // Calculate T double centraltof = (m_L1 + l2)/m_centreVelocity; // Angle double r, twotheta, phi; detpos.getSpherical(r, twotheta, phi); double theta = (twotheta * 0.5)*M_PI/180.; // double solidangle = m_solidangleWS->readY(i)[0]; double solidangle = det->solidAngle(samplepos); double deltatheta = sqrt(solidangle); // Resolution double t1 = m_deltaT/centraltof; double t2 = detdim/(m_L1 + l2); double t3 = deltatheta * (cos(theta)/sin(theta)); double resolution = sqrt(t1*t1+t2*t2+t3*t3); m_outputWS->dataX(i)[0] = static_cast<double>(i); m_outputWS->dataY(i)[0] = resolution; if (twotheta > maxtwotheta) maxtwotheta = twotheta; else if (twotheta < mintwotheta) mintwotheta = twotheta; if (fabs(t3) < mint3) mint3 = fabs(t3); else if (fabs(t3) > maxt3) maxt3 = fabs(t3); g_log.debug() << det->type() << " " << i << "\t\t" << twotheta << "\t\tdT/T = " << t1*t1 << "\t\tdL/L = " << t2 << "\t\tdTheta*cotTheta = " << t3 << "\n"; } g_log.notice() << "2theta range: " << mintwotheta << ", " << maxtwotheta << "\n"; g_log.notice() << "t3 range: " << mint3 << ", " << maxt3 << "\n"; g_log.notice() << "Number of detector having NO size information = " << count_nodetsize << "\n"; return; }
/** Execute the algorithm. */ void ModifyDetectorDotDatFile::exec() { std::string inputFilename = getPropertyValue("InputFilename"); std::string outputFilename = getPropertyValue("OutputFilename"); Workspace_sptr ws1 = getProperty("InputWorkspace"); ExperimentInfo_sptr ws = boost::dynamic_pointer_cast<ExperimentInfo>(ws1); // Check instrument Instrument_const_sptr inst = ws->getInstrument(); if (!inst) throw std::runtime_error("No instrument in the Workspace. Cannot modify detector dot dat file"); // Open files std::ifstream in; in.open( inputFilename.c_str()); if(!in) { throw Exception::FileError("Can't open input file", inputFilename); } std::ofstream out; out.open( outputFilename.c_str()); if(!out) { in.close(); throw Exception::FileError("Can't open output file", outputFilename); } // Read first line, modify it and put into output file std::string str; getline( in, str ); out << str << " and modified by MANTID algorithm ModifyDetectorDotDatFile \n"; // Read second line to check number of detectors and columns int detectorCount, numColumns; getline( in, str ); std::istringstream header2(str); header2 >> detectorCount >> numColumns; out << str << "\n"; // check that we have at least 1 detector and six columns if( detectorCount < 1 || numColumns < 6) { out.close(); in.close(); throw Exception::FileError("Incompatible file format found when reading line 2 in the input file", inputFilename); } // Copy column title line getline( in, str ); out << str << "\n"; int i=0; // Format details int pOffset = 3; // Precision of Offset int pOther = 5; // Precision of Other floats int wDet = 9; // Field width of Detector ID int wOff = 8; // Field width of Offset int wRad = 10; // Field width of Radius int wCode = 6; // Field width of Code int wAng = 12; // Field width of angles // Read input file line by line, modify line as necessary and put line into output file while( getline( in, str ) ){ std::istringstream istr(str); detid_t detID; double offset; int code; float dump; // ignored data if (str.empty() || str[0] == '#') { // comments and empty lines are allowed and just copied out << str << "\n"; continue; } // First six columns in the file, the detector ID and a code for the type of detector CODE = 3 (psd gas tube) istr >> detID >> offset >> dump >> code >> dump >> dump; if( code == 3 ){ // This is detector will look for it in workspace and if found use its position Geometry::IDetector_const_sptr det = ws->getDetectorByID( detID ); if( det ) { V3D pos = det->getPos(); double l2; double theta; double phi; pos.getSpherical ( l2, theta, phi ); std::streampos width = istr.tellg(); // Amount of string to replace // Some experimenting with line manipulation std::ostringstream oss; oss << std::fixed << std::right ; oss.precision(pOffset); oss << std::setw(wDet) << detID << std::setw(wOff) << offset; oss.precision(pOther); oss << std::setw(wRad) << l2 << std::setw(wCode) << code << std::setw(wAng) << theta << std::setw(wAng) << phi ; std::string prefix = oss.str(); std::string suffix = str.substr( width, std::string::npos ); out << prefix << suffix << "\n"; i++; } else { // Detector not found, don't modify out << str << "\n"; } } else { // We do not modify any other type of line out << str << "\n"; } } out.close(); in.close(); }