Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
*
* @param t_beg -- initial time for current time interval
* @param t_end -- final time for current time interval
* @param inSelection -- the boolean indicating if previous interval
* was selected on input and current selected on
* output
* @param startTime -- total selection time start moment
* @param endTime -- total selection time final moments
*
*@return true if selection interval is completed
* (current interval is not selected) and false otherwise
*/
bool SelectInterval(const Kernel::DateAndTime &t_beg,
const Kernel::DateAndTime &t_end,
double value, bool &inSelection,
Kernel::DateAndTime &startTime, Kernel::DateAndTime &endTime){
if (value > 0) {
if (!inSelection) {
startTime = t_beg;
}
inSelection = true;
} else {
if (inSelection) {
inSelection = false;
if (endTime > startTime)
return true;
}
}
endTime = t_end;
return false;
};
}
/**Analyze chopper logs and identify chopper speed and delay
@param inputWS -- sp to workspace with attached logs.
@param chop_speed -- output value for chopper speed in uSec
@param chop_delay -- output value for chopper delay in uSec
*/
void GetAllEi::findChopSpeedAndDelay(const API::MatrixWorkspace_sptr &inputWS,
double &chop_speed, double &chop_delay) {
// TODO: Make it dependent on inputWS time range
std::vector<Kernel::SplittingInterval> splitter;
std::unique_ptr<Kernel::TimeSeriesProperty<double>> pDerivative;
// Define selecting function
bool inSelection(false);
// time interval to select (start-end)
Kernel::DateAndTime startTime, endTime;
//
// Analyze filtering log
auto dateAndTimes = m_pFilterLog->valueAsCorrectMap();
auto it = dateAndTimes.begin();
auto next = it;
next++;
std::map<Kernel::DateAndTime, double> derivMap;
auto itder = it;
if (m_FilterWithDerivative) {
pDerivative = m_pFilterLog->getDerivative();
derivMap = pDerivative->valueAsCorrectMap();
itder = derivMap.begin();
}
// initialize selection log
if (dateAndTimes.size() <= 1) {
SelectInterval(it->first, it->first, itder->second,
inSelection,startTime,endTime);
if (inSelection) {
startTime = inputWS->run().startTime();
endTime = inputWS->run().endTime();
Kernel::SplittingInterval interval(startTime, endTime, 0);
splitter.push_back(interval);
} else {
throw std::runtime_error("filtered all data points. Nothing to do");
}
} else {
SelectInterval(it->first, next->first, itder->second,
inSelection,startTime,endTime);
}
// if its filtered using log, both iterator walk through the same values
// if use derivative, derivative's values are used for filtering
// and derivative assumed in a center of an interval
for (; next != dateAndTimes.end(); ++next, ++itder) {
if (SelectInterval(it->first, next->first, itder->second,
inSelection,startTime,endTime)) {
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
Kernel::SplittingInterval interval(startTime, endTime, 0);
splitter.push_back(interval);
}
it = next;
}
// final interval
if (inSelection && (endTime > startTime)) {
Kernel::SplittingInterval interval(startTime, endTime, 0);
splitter.push_back(interval);
}
} // End of USE filter log.
chop_speed = this->getAvrgLogValue(inputWS, "ChopperSpeedLog", splitter);
chop_speed = std::fabs(chop_speed);
if (chop_speed < 1.e-7) {
throw std::runtime_error("Chopper speed can not be zero ");
}
chop_delay =
std::fabs(this->getAvrgLogValue(inputWS, "ChopperDelayLog", splitter));
// process chopper delay in the units of degree (phase)
auto pProperty = getPLogForProperty(inputWS, "ChopperDelayLog");
if (!pProperty)
throw std::runtime_error("ChopperDelayLog has been removed from workspace "
"during the algorithm execution");
std::string units = pProperty->units();
// its chopper phase provided
if (units == "deg" || units.c_str()[0] == -80) { //<- userd in ISIS ASCII representation of o(deg)
chop_delay *= 1.e+6 / (360. * chop_speed); // convert in uSec
}
chop_delay += m_phase / chop_speed;
}
namespace { // namespace for lambda functions, used in validators
/* former Lambda to validate if appropriate log is present in workspace
and if it's present, it is a time-series property
* @param prop_name -- the name of the log to check
* @param err_presence -- core error message to return if no log found
* @param err_type -- core error message to return if
* log is of incorrect type
* @param fail -- fail or warn if appropriate log is not available.
*
* @param result -- map to add the result of check for errors
* if no error found the map is not modified and remains
* empty.
* @return -- false if all checks are fine, or true if check is
* failed
*/
bool check_time_series_property(
const GetAllEi *algo, const API::MatrixWorkspace_sptr &inputWS,
const boost::shared_ptr<const Geometry::IComponent> &chopper,
const std::string &prop_name, const std::string &err_presence,
const std::string &err_type, bool fail,
std::map<std::string, std::string> &result) {
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
std::string LogName = algo->getProperty(prop_name);
if (boost::iequals(LogName, "Defined in IDF")) {
try {
auto theLogs = chopper->getStringParameter(prop_name);
if (theLogs.size() == 0) {
if (fail)
result[prop_name] = "Can not retrieve parameter " + prop_name +
" from the instrument definition file.";
return true;
}
LogName = theLogs[0];
} catch (...) {
result[prop_name] = "Can not retrieve parameter " + prop_name +
" from the instrument definition file.";
return true;
}
}
try {
Kernel::Property *pProp = inputWS->run().getProperty(LogName);
auto pTSProp = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(pProp);
if (!pTSProp) {
if (fail)
result[prop_name] = "Workspace contains " + err_type + LogName +
" But its type is not a timeSeries property";
return true;
}
} catch (std::runtime_error &) {
if (fail)
result[prop_name] = "Workspace has to contain " + err_presence + LogName;
return true;
}
return false;
};
/**Validates if input workspace contains all necessary logs and if all
* these logs are the logs of appropriate type
@return list of invalid logs or empty list if no errors is found.
*/
std::map<std::string, std::string> GetAllEi::validateInputs() {
// Do Validation
std::map<std::string, std::string> result;
API::MatrixWorkspace_sptr inputWS = getProperty("Workspace");
if (!inputWS) {
result["Workspace"] = "Input workspace can not be identified";
return result;
}
if (!inputWS->isHistogramData()) {
result["Workspace"] = "Only histogram workspaces are currently supported. "
"Rebin input workspace first.";
}
specid_t specNum1 = getProperty("Monitor1SpecID");
try {
inputWS->getIndexFromSpectrumNumber(specNum1);
} catch (std::runtime_error &) {
result["Monitor1SpecID"] =
"Input workspace does not contain spectra with ID: " +
boost::lexical_cast<std::string>(specNum1);
}
specid_t specNum2 = getProperty("Monitor2SpecID");
try {
inputWS->getIndexFromSpectrumNumber(specNum2);
} catch (std::runtime_error &) {
result["Monitor2SpecID"] =
"Input workspace does not contain spectra with ID: " +
boost::lexical_cast<std::string>(specNum2);
}
// check chopper and initiate it if present (for debugging)
m_chopper = inputWS->getInstrument()->getComponentByName("chopper-position");
result["Workspace_chopper"] =
" For this algorithm to work workspace has"
" to contain well defined 'chopper-position' component";
return result;
}
check_time_series_property(this, inputWS, m_chopper, "ChopperSpeedLog",
"chopper speed log with name: ",
"chopper speed log ", true, result);
check_time_series_property(
this, inputWS, m_chopper, "ChopperDelayLog",
"property related to chopper delay log with name: ", "chopper delay log ",
true, result);
bool failed = check_time_series_property(
this, inputWS, m_chopper, "FilterBaseLog", "filter base log named: ",
"filter base log: ", false, result);
if (failed) {
g_log.warning()
<< " Can not find a log to identify good DAE operations.\n"
" Assuming that good operations start from experiment time=0";
} else {
this->setFilterLog(inputWS);