/** Put the parameters into one workspace * @param column :: [input] column of the output table workspace * @param ws :: [input/output] the group workspace parameters are to be put in * @param nProf :: the PROF Number, which is used to determine fitting function * for the parameters. * @param parameterXMLString :: string where the XML document filename is * stored */ void LoadFullprofResolution::putParametersIntoWorkspace( API::Column_const_sptr column, API::MatrixWorkspace_sptr ws, int nProf, std::string ¶meterXMLString) { // Get instrument name from matrix workspace std::string instrumentName = ws->getInstrument()->getName(); // Convert table workspace column into DOM XML document // Set up writer to Paremeter file DOMWriter writer; writer.setNewLine("\n"); writer.setOptions(XMLWriter::PRETTY_PRINT); // Get current time Kernel::DateAndTime date = Kernel::DateAndTime::getCurrentTime(); std::string ISOdate = date.toISO8601String(); std::string ISOdateShort = ISOdate.substr(0, 19); // Remove fraction of seconds // Create document AutoPtr<Document> mDoc = new Document(); AutoPtr<Element> rootElem = mDoc->createElement("parameter-file"); rootElem->setAttribute("date", ISOdateShort); mDoc->appendChild(rootElem); // Add instrument AutoPtr<Element> instrumentElem = mDoc->createElement("component-link"); instrumentElem->setAttribute("name", instrumentName); rootElem->appendChild(instrumentElem); if (nProf == 9) // put parameters into BackToBackExponential function { addBBX_S_Parameters(column, mDoc, instrumentElem); addBBX_A_Parameters(column, mDoc, instrumentElem); addBBX_B_Parameters(column, mDoc, instrumentElem); } else // Assume IkedaCarpenter PV { addALFBEParameter(column, mDoc, instrumentElem, "Alph0"); addALFBEParameter(column, mDoc, instrumentElem, "Beta0"); addALFBEParameter(column, mDoc, instrumentElem, "Alph1"); addALFBEParameter(column, mDoc, instrumentElem, "Beta1"); addSigmaParameters(column, mDoc, instrumentElem); addGammaParameters(column, mDoc, instrumentElem); } // Convert DOM XML document into string std::ostringstream outFile; writer.writeNode(outFile, mDoc); parameterXMLString = outFile.str(); // Useful code for testing upgrades commented out for production use // std::ofstream outfileDebug("C:/Temp/test4_fullprof.xml"); // outfileDebug << parameterXMLString; // outfileDebug.close(); }
/** 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 cannot assume the peaks have bank type detector modules, so we have a string to check this std::string bankPart = "?"; // 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; } // Save the "bank" part once to check whether it really is a bank if( bankPart == "?") bankPart = bankName.substr(0,4); // 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."); if( bankPart != "bank" && bankPart != "?" ) { std::ostringstream mess; mess << "Detector module of type " << bankPart << " not supported in ISAWPeaks. Cannot save peaks file"; throw std::runtime_error( mess.str() ); } double l1; V3D beamline; double beamline_norm; V3D samplePos; inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos); std::ofstream out; bool append = getProperty("AppendFile"); // do not append if file does not exist if (!Poco::File(filename.c_str()).exists())append = false; 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.toISO8601String() << 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; } else g_log.warning() << "Information about detector module " << bankName << " not found and recognised\n"; } } } // ============================== 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.empty()) { // 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( 8 ) << std::fixed << std::setprecision( 2 ) << chi << " "; out << std::setw( 8 ) << std::fixed << std::setprecision( 2 ) << phi << " "; out << std::setw( 8 ) << std::fixed << std::setprecision( 2 ) << omega << " "; // Get the monitor count from the first peak (should all be the same for one run) size_t first_peak_index = ids[0]; Peak & first_peak = peaks[ first_peak_index ]; double monct = first_peak.getMonitorCount(); out << std::setw( 12 ) << (int)( monct ) << 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 scattered beam direction onto the XY plane, // and calculate 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 << std::setprecision(0) << int(p.getBinCount()) << " "; out << 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(); // } }
/** * Set the run start and end * @param start :: The run start * @param end :: The run end */ void LogManager::setStartAndEndTime(const Kernel::DateAndTime & start, const Kernel::DateAndTime & end) { this->addProperty<std::string>("start_time", start.toISO8601String(), true); this->addProperty<std::string>("end_time", end.toISO8601String(), true); }