double EstimateResolutionDiffraction::getWavelength() { double wavelength = getProperty("Wavelength"); if (!isEmpty(wavelength)) { return wavelength; } Property *cwlproperty = m_inputWS->run().getProperty("LambdaRequest"); if (!cwlproperty) throw runtime_error( "Unable to locate property LambdaRequest as central wavelength. "); TimeSeriesProperty<double> *cwltimeseries = dynamic_cast<TimeSeriesProperty<double> *>(cwlproperty); if (!cwltimeseries) throw runtime_error( "LambdaReqeust is not a TimeSeriesProperty in double. "); string unit = cwltimeseries->units(); if (unit.compare("Angstrom") != 0) { throw runtime_error("Unit is not recognized: " + unit); } return cwltimeseries->timeAverageValue(); }
/** Try to load the "Veto_pulse" field in DASLogs * and convert it to a sample log. * * @param file :: open nexus file at the DASLogs group * @param workspace :: workspace to add to. */ void LoadNexusLogs::loadVetoPulses( ::NeXus::File &file, boost::shared_ptr<API::MatrixWorkspace> workspace) const { try { file.openGroup("Veto_pulse", "NXgroup"); } catch (::NeXus::Exception &) { // No group. This is common in older files return; } file.openData("veto_pulse_time"); // Load the start date/time as ISO8601 string. std::string start_time; file.getAttr("start_time", start_time); DateAndTime start(start_time); // Read the offsets std::vector<double> time_double; file.getData(time_double); // Fake values with zeroes. std::vector<double> values(time_double.size(), 0.0); TimeSeriesProperty<double> *tsp = new TimeSeriesProperty<double>("veto_pulse_time"); tsp->create(start, time_double, values); tsp->setUnits(""); // Add the log workspace->mutableRun().addProperty(tsp); file.closeData(); file.closeGroup(); }
void EstimatePDDetectorResolution::retrieveInstrumentParameters() { #if 0 // Call SolidAngle to get solid angles for all detectors Algorithm_sptr calsolidangle = createChildAlgorithm("SolidAngle", -1, -1, true); calsolidangle->initialize(); calsolidangle->setProperty("InputWorkspace", m_inputWS); calsolidangle->execute(); if (!calsolidangle->isExecuted()) throw runtime_error("Unable to run solid angle. "); m_solidangleWS = calsolidangle->getProperty("OutputWorkspace"); if (!m_solidangleWS) throw runtime_error("Unable to get solid angle workspace from SolidAngle(). "); size_t numspec = m_solidangleWS->getNumberHistograms(); for (size_t i = 0; i < numspec; ++i) g_log.debug() << "[DB]: " << m_solidangleWS->readY(i)[0] << "\n"; #endif // Calculate centre neutron velocity Property* cwlproperty = m_inputWS->run().getProperty("LambdaRequest"); if (!cwlproperty) throw runtime_error("Unable to locate property LambdaRequest as central wavelength. "); TimeSeriesProperty<double>* cwltimeseries = dynamic_cast<TimeSeriesProperty<double>* >(cwlproperty); if (!cwltimeseries) throw runtime_error("LambdaReqeust is not a TimeSeriesProperty in double. "); if (cwltimeseries->size() != 1) throw runtime_error("LambdaRequest should contain 1 and only 1 entry. "); double centrewavelength = cwltimeseries->nthValue(0); string unit = cwltimeseries->units(); if (unit.compare("Angstrom") == 0) centrewavelength *= 1.0E-10; else throw runtime_error("Unit is not recognized"); m_centreVelocity = PhysicalConstants::h/PhysicalConstants::NeutronMass/centrewavelength; g_log.notice() << "Centre wavelength = " << centrewavelength << ", Centre neutron velocity = " << m_centreVelocity << "\n"; // Calcualte L1 sample to source Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); V3D sourcepos = instrument->getSource()->getPos(); m_L1 = samplepos.distance(sourcepos); g_log.notice() << "L1 = " << m_L1 << "\n"; return; }
/// Do the actual work of modifying the log in the workspace. void ChangeLogTime::exec() { // check that a log was specified string logname = this->getProperty("LogName"); if (logname.empty()) { throw std::runtime_error("Failed to supply a LogName"); } // everything will need an offset double offset = this->getProperty("TimeOffset"); // make sure the log is in the input workspace MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); Kernel::TimeSeriesProperty<double> * oldlog = dynamic_cast<Kernel::TimeSeriesProperty<double> *>( inputWS->run().getLogData(logname) ); if (!oldlog) { stringstream msg; msg << "InputWorkspace \'" << this->getPropertyValue("InputWorkspace") << "\' does not have LogName \'" << logname << "\'"; throw std::runtime_error(msg.str()); } // Create the new log TimeSeriesProperty<double>* newlog = new TimeSeriesProperty<double>(logname); newlog->setUnits(oldlog->units()); int size = oldlog->realSize(); vector<double> values = oldlog->valuesAsVector(); vector<DateAndTime> times = oldlog->timesAsVector(); for (int i = 0; i < size; i++) { newlog->addValue(times[i] + offset, values[i]); } // Just overwrite if the change is in place MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace"); if (outputWS != inputWS) { IAlgorithm_sptr duplicate = createChildAlgorithm("CloneWorkspace"); duplicate->initialize(); duplicate->setProperty<Workspace_sptr>("InputWorkspace", boost::dynamic_pointer_cast<Workspace>(inputWS)); duplicate->execute(); Workspace_sptr temp = duplicate->getProperty("OutputWorkspace"); outputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(temp); setProperty("OutputWorkspace", outputWS); } outputWS->mutableRun().addProperty(newlog, true); }
/** * Add a sample environment log for the proton chage (charge of the pulse in *picoCoulombs) * and set the scalar value (total proton charge, microAmps*hours, on the *sample) * * @param workspace :: Event workspace to set the proton charge on */ void LoadEventPreNexus::setProtonCharge( DataObjects::EventWorkspace_sptr &workspace) { if (this->proton_charge.empty()) // nothing to do return; Run &run = workspace->mutableRun(); // Add the proton charge entries. TimeSeriesProperty<double> *log = new TimeSeriesProperty<double>("proton_charge"); log->setUnits("picoCoulombs"); // Add the time and associated charge to the log log->addValues(this->pulsetimes, this->proton_charge); /// TODO set the units for the log run.addLogData(log); double integ = run.integrateProtonCharge(); // run.setProtonCharge(this->proton_charge_tot); //This is now redundant this->g_log.information() << "Total proton charge of " << integ << " microAmp*hours found by integrating.\n"; }
/** * Check if the file is SNS text; load it if it is, return false otherwise. * @return true if the file was a SNS style; false otherwise. */ bool LoadLog::LoadSNSText() { // Get the SNS-specific parameter std::vector<std::string> names = getProperty("Names"); std::vector<std::string> units = getProperty("Units"); // Get the input workspace and retrieve run from workspace. // the log file(s) will be loaded into the run object of the workspace const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace"); // open log file std::ifstream inLogFile(m_filename.c_str()); // Get the first line std::string aLine; if (!Mantid::Kernel::Strings::extractToEOL(inLogFile,aLine)) return false; std::vector<double> cols; bool ret = SNSTextFormatColumns(aLine, cols); // Any error? if (!ret || cols.size() < 2) return false; size_t numCols = static_cast<size_t>(cols.size()-1); if (names.size() != numCols) throw std::invalid_argument("The Names parameter should have one fewer entry as the number of columns in a SNS-style text log file."); if ((!units.empty()) && (units.size() != numCols)) throw std::invalid_argument("The Units parameter should have either 0 entries or one fewer entry as the number of columns in a SNS-style text log file."); // Ok, create all the logs std::vector<TimeSeriesProperty<double>*> props; for(size_t i=0; i < numCols; i++) { TimeSeriesProperty<double>* p = new TimeSeriesProperty<double>(names[i]); if (units.size() == numCols) p->setUnits(units[i]); props.push_back(p); } // Go back to start inLogFile.seekg(0); while(Mantid::Kernel::Strings::extractToEOL(inLogFile,aLine)) { if (aLine.size() == 0) break; if (SNSTextFormatColumns(aLine, cols)) { if (cols.size() == numCols+1) { DateAndTime time(cols[0], 0.0); for(size_t i=0; i<numCols; i++) props[i]->addValue(time, cols[i+1]); } else throw std::runtime_error("Inconsistent number of columns while reading SNS-style text file."); } else throw std::runtime_error("Error while reading columns in SNS-style text file."); } // Now add all the full logs to the workspace for(size_t i=0; i < numCols; i++) { std::string name = props[i]->name(); if (localWorkspace->mutableRun().hasProperty(name)) { localWorkspace->mutableRun().removeLogData(name); g_log.information() << "Log data named " << name << " already existed and was overwritten.\n"; } localWorkspace->mutableRun().addLogData(props[i]); } return true; }
/** * Executes the algorithm */ void PlotAsymmetryByLogValue::exec() { m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); m_autogroup = ( m_forward_list.size() == 0 && m_backward_list.size() == 0); //double alpha = getProperty("Alpha"); std::string logName = getProperty("LogValue"); int red = getProperty("Red"); int green = getProperty("Green"); std::string stype = getProperty("Type"); m_int = stype == "Integral"; std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); std::string ext = firstFN.substr(firstFN.find_last_of(".")); firstFN.erase(firstFN.size()-4); lastFN.erase(lastFN.size()-4); std::string fnBase = firstFN; size_t i = fnBase.size()-1; while(isdigit(fnBase[i])) i--; if (i == fnBase.size()-1) { g_log.error("File name must end with a number."); throw Exception::FileError("File name must end with a number.",firstFN); } fnBase.erase(i+1); firstFN.erase(0,fnBase.size()); lastFN.erase(0,fnBase.size()); size_t is = atoi(firstFN.c_str()); // starting run number size_t ie = atoi(lastFN.c_str()); // last run number int w = static_cast<int>(firstFN.size()); // The number of runs size_t npoints = ie - is + 1; // Create the 2D workspace for the output int nplots = green != EMPTY_INT() ? 4 : 1; MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create("Workspace2D", nplots, // the number of plots npoints, // the number of data points on a plot npoints // it's not a histogram ); TextAxis* tAxis = new TextAxis(nplots); if (nplots == 1) { tAxis->setLabel(0,"Asymmetry"); } else { tAxis->setLabel(0,"Red-Green"); tAxis->setLabel(1,"Red"); tAxis->setLabel(2,"Green"); tAxis->setLabel(3,"Red+Green"); } outWS->replaceAxis(1,tAxis); Progress progress(this,0,1,ie-is+2); for(size_t i=is; i<=ie; i++) { std::ostringstream fn,fnn; fnn << std::setw(w) << std::setfill('0') << i ; fn << fnBase << fnn.str() << ext; // Load a muon nexus file with auto_group set to true IAlgorithm_sptr loadNexus = createChildAlgorithm("LoadMuonNexus"); loadNexus->setPropertyValue("Filename", fn.str()); loadNexus->setPropertyValue("OutputWorkspace","tmp"+fnn.str()); if (m_autogroup) loadNexus->setPropertyValue("AutoGroup","1"); loadNexus->execute(); std::string wsProp = "OutputWorkspace"; DataObjects::Workspace2D_sptr ws_red; DataObjects::Workspace2D_sptr ws_green; // Run through the periods of the loaded file and do calculations on the selected ones Workspace_sptr tmp = loadNexus->getProperty(wsProp); WorkspaceGroup_sptr wsGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(tmp); if (!wsGroup) { ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmp); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; calcIntAsymmetry(ws_red,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else { for( int period = 1; period <= wsGroup->getNumberOfEntries(); ++period ) { std::stringstream suffix; suffix << period; wsProp = "OutputWorkspace_" + suffix.str();// form the property name for higher periods // Do only one period if (green == EMPTY_INT() && period == red) { Workspace_sptr tmpff = loadNexus->getProperty(wsProp); ws_red = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(tmpff); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; calcIntAsymmetry(ws_red,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else // red & green { if (period == red) { Workspace_sptr temp = loadNexus->getProperty(wsProp); ws_red = boost::dynamic_pointer_cast<Workspace2D>(temp); } if (period == green) { Workspace_sptr temp = loadNexus->getProperty(wsProp); ws_green = boost::dynamic_pointer_cast<Workspace2D>(temp); } } } // red & green claculation if (green != EMPTY_INT()) { if (!ws_red || !ws_green) throw std::invalid_argument("Red or green period is out of range"); TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(ws_red->run().getLogData(logName)); if (!logp) { throw std::invalid_argument("Log "+logName+" does not exist or not a double type"); } double Y,E; double Y1,E1; calcIntAsymmetry(ws_red,Y,E); calcIntAsymmetry(ws_green,Y1,E1); outWS->dataY(1)[i-is] = Y; outWS->dataX(1)[i-is] = logp->lastValue(); outWS->dataE(1)[i-is] = E; outWS->dataY(2)[i-is] = Y1; outWS->dataX(2)[i-is] = logp->lastValue(); outWS->dataE(2)[i-is] = E1; outWS->dataY(3)[i-is] = Y + Y1; outWS->dataX(3)[i-is] = logp->lastValue(); outWS->dataE(3)[i-is] = sqrt(E*E+E1*E1); // move to last for safety since some grouping takes place in the // calcIntAsymmetry call below calcIntAsymmetry(ws_red,ws_green,Y,E); outWS->dataY(0)[i-is] = Y; outWS->dataX(0)[i-is] = logp->lastValue(); outWS->dataE(0)[i-is] = E; } else if (!ws_red) throw std::invalid_argument("Red period is out of range"); } progress.report(); } outWS->getAxis(0)->title() = logName; outWS->setYUnitLabel("Asymmetry"); // Assign the result to the output workspace property setProperty("OutputWorkspace", outWS); }
/** * Executes the algorithm */ void PlotPeakByLogValue::exec() { // Create a list of the input workspace const std::vector<InputData> wsNames = makeNames(); std::string fun = getPropertyValue("Function"); //int wi = getProperty("WorkspaceIndex"); std::string logName = getProperty("LogValue"); bool sequential = getPropertyValue("FitType") == "Sequential"; bool isDataName = false; // if true first output column is of type string and is the data source name ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace"); if (logName == "SourceName") { result->addColumn("str","Source name"); isDataName = true; } else if (logName.empty()) { result->addColumn("double","axis-1"); } else { result->addColumn("double",logName); } // Create an instance of the fitting function to obtain the names of fitting parameters IFitFunction* ifun = FunctionFactory::Instance().createInitialized(fun); if (!ifun) { throw std::invalid_argument("Fitting function failed to initialize"); } for(size_t iPar=0;iPar<ifun->nParams();++iPar) { result->addColumn("double",ifun->parameterName(iPar)); result->addColumn("double",ifun->parameterName(iPar)+"_Err"); } result->addColumn("double","Chi_squared"); delete ifun; setProperty("OutputWorkspace",result); double dProg = 1./static_cast<double>(wsNames.size()); double Prog = 0.; for(int i=0;i<static_cast<int>(wsNames.size());++i) { InputData data = getWorkspace(wsNames[i]); if (!data.ws) { g_log.warning() << "Cannot access workspace " << wsNames[i].name << '\n'; continue; } if (data.i < 0 && data.indx.empty()) { g_log.warning() << "Zero spectra selected for fitting in workspace " << wsNames[i].name << '\n'; continue; } int j,jend; if (data.i >= 0) { j = data.i; jend = j + 1; } else {// no need to check data.indx.empty() j = data.indx.front(); jend = data.indx.back() + 1; } dProg /= abs(jend - j); for(;j < jend;++j) { // Find the log value: it is either a log-file value or simply the workspace number double logValue; if (logName.empty()) { API::Axis* axis = data.ws->getAxis(1); logValue = (*axis)(j); } else if (logName != "SourceName") { Kernel::Property* prop = data.ws->run().getLogData(logName); if (!prop) { throw std::invalid_argument("Log value "+logName+" does not exist"); } TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(prop); logValue = logp->lastValue(); } std::string resFun = fun; std::vector<double> errors; double chi2; try { // Fit the function API::IAlgorithm_sptr fit = createSubAlgorithm("Fit"); fit->initialize(); fit->setProperty("InputWorkspace",data.ws); //fit->setPropertyValue("InputWorkspace",data.ws->getName()); fit->setProperty("WorkspaceIndex",j); fit->setPropertyValue("Function",fun); fit->setPropertyValue("StartX",getPropertyValue("StartX")); fit->setPropertyValue("EndX",getPropertyValue("EndX")); fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer")); fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction")); fit->execute(); resFun = fit->getPropertyValue("Function"); errors = fit->getProperty("Errors"); chi2 = fit->getProperty("OutputChi2overDoF"); } catch(...) { g_log.error("Error in Fit subalgorithm"); throw; } if (sequential) { fun = resFun; } // Extract the fitted parameters and put them into the result table TableRow row = result->appendRow(); if (isDataName) { row << wsNames[i].name; } else { row << logValue; } ifun = FunctionFactory::Instance().createInitialized(resFun); for(size_t iPar=0;iPar<ifun->nParams();++iPar) { row << ifun->getParameter(iPar) << errors[iPar]; } row << chi2; delete ifun; Prog += dProg; progress(Prog); interruption_point(); } // for(;j < jend;++j) } }
/** Execute the algorithm. */ void LoadDNSSCD::exec() { MultipleFileProperty *multiFileProp = dynamic_cast<MultipleFileProperty *>(getPointerToProperty("Filenames")); if (!multiFileProp) { throw std::logic_error( "Filenames property must have MultipleFileProperty type."); } std::vector<std::string> filenames = VectorHelper::flattenVector(multiFileProp->operator()()); if (filenames.empty()) throw std::invalid_argument("Must specify at least one filename."); // set type of normalization std::string normtype = getProperty("Normalization"); if (normtype == "monitor") { m_normtype = "Monitor"; m_normfactor = 1.0; } else { m_normtype = "Timer"; m_normfactor = 0.0; // error for time should be 0 } g_log.notice() << "The normalization workspace will contain " << m_normtype << ".\n"; ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>(); API::Run &run = expinfo->mutableRun(); for (auto fname : filenames) { std::map<std::string, std::string> str_metadata; std::map<std::string, double> num_metadata; try { read_data(fname, str_metadata, num_metadata); // if no stop_time, take file_save_time std::string time(str_metadata["stop_time"]); if (time.empty()) { g_log.warning() << "stop_time is empty! File save time will be used instead." << std::endl; time = str_metadata["file_save_time"]; } updateProperties<std::string>(run, str_metadata, time); updateProperties<double>(run, num_metadata, time); } catch (...) { g_log.warning() << "Failed to read file " << fname; g_log.warning() << ". This file will be ignored. " << std::endl; g_log.debug() << boost::current_exception_diagnostic_information() << std::endl; } } if (m_data.empty()) throw std::runtime_error( "No valid DNS files have been provided. Nothing to load."); m_OutWS = MDEventFactory::CreateMDWorkspace(m_nDims, "MDEvent"); m_OutWS->addExperimentInfo(expinfo); // load huber angles from a table workspace if given ITableWorkspace_sptr huberWS = getProperty("LoadHuberFrom"); if (huberWS) { g_log.notice() << "Huber angles will be loaded from " << huberWS->getName() << std::endl; loadHuber(huberWS); } // get wavelength TimeSeriesProperty<double> *wlprop = dynamic_cast<TimeSeriesProperty<double> *>( expinfo->run().getProperty("Lambda")); // assume, that lambda is in nm double wavelength = wlprop->minValue() * 10.0; // needed to estimate extents => minValue run.addProperty("wavelength", wavelength); run.getProperty("wavelength")->setUnits("Angstrom"); fillOutputWorkspace(wavelength); std::string saveHuberTableWS = getProperty("SaveHuberTo"); if (!saveHuberTableWS.empty()) { Mantid::API::ITableWorkspace_sptr huber_table = saveHuber(); setProperty("SaveHuberTo", huber_table); } setProperty("OutputWorkspace", m_OutWS); }