/** Set up an Event workspace * @param numentries :: number of log entries to output * @param times :: vector of Kernel::DateAndTime * @param values :: vector of log value in double */ void ExportTimeSeriesLog::setupEventWorkspace(int numentries, vector<DateAndTime> ×, vector<double> values) { Kernel::DateAndTime runstart( m_dataWS->run().getProperty("run_start")->value()); // Get some stuff from the input workspace const size_t numberOfSpectra = 1; const int YLength = static_cast<int>(m_dataWS->blocksize()); // Make a brand new EventWorkspace EventWorkspace_sptr outEventWS = boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create( "EventWorkspace", numberOfSpectra, YLength + 1, YLength)); // Copy geometry over. API::WorkspaceFactory::Instance().initializeFromParent(m_dataWS, outEventWS, false); m_outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outEventWS); if (!m_outWS) throw runtime_error( "Output workspace cannot be casted to a MatrixWorkspace."); g_log.debug("[DBx336] An output workspace is generated.!"); // Create the output event list (empty) EventList &outEL = outEventWS->getOrAddEventList(0); outEL.switchTo(WEIGHTED_NOTIME); // Allocate all the required memory outEL.reserve(numentries); outEL.clearDetectorIDs(); for (size_t i = 0; i < static_cast<size_t>(numentries); i++) { Kernel::DateAndTime tnow = times[i]; int64_t dt = tnow.totalNanoseconds() - runstart.totalNanoseconds(); // convert to microseconds double dtmsec = static_cast<double>(dt) / 1000.0; outEL.addEventQuickly(WeightedEventNoTime(dtmsec, values[i], values[i])); } // Ensure thread-safety outEventWS->sortAll(TOF_SORT, NULL); // Now, create a default X-vector for histogramming, with just 2 bins. Kernel::cow_ptr<MantidVec> axis; MantidVec &xRef = axis.access(); xRef.resize(2); std::vector<WeightedEventNoTime> &events = outEL.getWeightedEventsNoTime(); xRef[0] = events.begin()->tof(); xRef[1] = events.rbegin()->tof(); // Set the binning axis using this. outEventWS->setX(0, axis); return; }
/** 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(); }
/* * Write a certain number of log entries (from beginning) to file */ void ProcessDasNexusLog::writeLogtoFile(API::MatrixWorkspace_sptr ws, std::string logname, size_t numentriesoutput, std::string outputfilename) { // 1. Get log Kernel::Property *log = ws->run().getProperty(logname); Kernel::TimeSeriesProperty<double> *tslog = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(log); if (!tslog) throw std::runtime_error("Invalid time series log: it could not be cast " "(interpreted) as a time series property"); std::vector<Kernel::DateAndTime> times = tslog->timesAsVector(); std::vector<double> values = tslog->valuesAsVector(); // 2. Write out std::ofstream ofs; ofs.open(outputfilename.c_str(), std::ios::out); ofs << "# Absolute Time (nanosecond)\tPulse Time (nanosecond)\tTOF (ms)\n"; Kernel::DateAndTime prevtime(0); std::vector<double> tofs; for (size_t i = 0; i < numentriesoutput; i++) { Kernel::DateAndTime tnow = times[i]; if (tnow > prevtime) { // (a) Process previous logs std::sort(tofs.begin(), tofs.end()); for (double tof : tofs) { Kernel::DateAndTime temptime = prevtime + static_cast<int64_t>(tof * 100); ofs << temptime.totalNanoseconds() << "\t" << tnow.totalNanoseconds() << "\t" << tof * 0.1 << '\n'; } // (b) Clear tofs.clear(); // (c) Update time prevtime = tnow; } // (d) Push the current value tofs.push_back(values[i]); } // ENDFOR // Clear the last if (!tofs.empty()) { // (a) Process previous logs: note value is in unit of 100 nano-second std::sort(tofs.begin(), tofs.end()); for (double tof : tofs) { Kernel::DateAndTime temptime = prevtime + static_cast<int64_t>(tof * 100); ofs << temptime.totalNanoseconds() << "\t" << prevtime.totalNanoseconds() << "\t" << tof * 0.1 << '\n'; } } else { throw std::runtime_error("Impossible for this to happen!"); } ofs.close(); } // END Function
/** 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 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; } // 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."); double l1; V3D beamline; double beamline_norm; V3D samplePos; inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos); std::ofstream out; bool append = getProperty("AppendFile"); 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.to_ISO8601_string() << 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; } } } } // ============================== 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.size() > 0) { // 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( 7 ) << std::fixed << std::setprecision( 2 ) << chi << " "; out << std::setw( 7 ) << std::fixed << std::setprecision( 2 ) << phi << " "; out << std::setw( 7 ) << std::fixed << std::setprecision( 2 ) << omega << " "; out << std::setw( 7 ) << (int)( 0 ) << 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 beam onto the XY plane, and measure 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 << int(p.getBinCount()) << 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 Run::setStartAndEndTime(const Kernel::DateAndTime & start, const Kernel::DateAndTime & end) { this->addProperty<std::string>("start_time", start.to_ISO8601_string(), true); this->addProperty<std::string>("end_time", end.to_ISO8601_string(), true); }