Unverified Commit dfd9a35b authored by Harrietbrown's avatar Harrietbrown Committed by GitHub
Browse files

Merge branch 'master' into 27185_clear_variables_in_scripts_in_workbench

parents df053b77 97aa2f6e
......@@ -38,7 +38,9 @@ public:
void stopObservingManager();
virtual void progressHandle(const IAlgorithm *alg, double p,
const std::string &msg);
const std::string &msg,
const double estimatedTime,
const int progressPrecision);
virtual void startingHandle(IAlgorithm_sptr alg);
virtual void startHandle(const IAlgorithm *alg);
virtual void finishHandle(const IAlgorithm *alg);
......
......@@ -116,12 +116,18 @@ The default handler is provided (doing nothing).
@param alg :: Pointer to the algorithm sending the notification.
@param p :: Progress reported by the algorithm, 0 <= p <= 1
@param msg :: Optional message string sent by the algorithm
@param estimatedTime :: estimated time to completion in seconds
@param progressPrecision :: number of digits after the decimal
*/
void AlgorithmObserver::progressHandle(const IAlgorithm *alg, double p,
const std::string &msg) {
const std::string &msg,
const double estimatedTime,
const int progressPrecision) {
UNUSED_ARG(alg)
UNUSED_ARG(p)
UNUSED_ARG(msg)
UNUSED_ARG(estimatedTime)
UNUSED_ARG(progressPrecision)
}
/** Handler of the start notifications. Must be overriden in inherited classes.
......@@ -159,7 +165,8 @@ void AlgorithmObserver::errorHandle(const IAlgorithm *alg,
*/
void AlgorithmObserver::_progressHandle(
const Poco::AutoPtr<Algorithm::ProgressNotification> &pNf) {
this->progressHandle(pNf->algorithm(), pNf->progress, pNf->message);
this->progressHandle(pNf->algorithm(), pNf->progress, pNf->message,
pNf->estimatedTime, pNf->progressPrecision);
}
/** Poco notification handler for Algorithm::StartedNotification.
......
......@@ -307,11 +307,11 @@ MatrixWorkspace_uptr MonteCarloAbsorption::doSimulation(
for (size_t j = 0; j < packedLambdas.size(); j++) {
simulationWS.getSpectrum(i)
.dataY()[simulationWS.yIndexOfX(packedLambdas[j])] =
.dataY()[simulationWS.yIndexOfX(packedLambdas[j], i)] =
packedAttFactors[j];
simulationWS.getSpectrum(i)
.dataE()[simulationWS.yIndexOfX(packedLambdas[j])] =
.dataE()[simulationWS.yIndexOfX(packedLambdas[j], i)] =
packedAttFactorErrors[j];
}
......
......@@ -41,7 +41,7 @@ void Pause::init() {
*/
void Pause::exec() {
DateAndTime startTime = DateAndTime::getCurrentTime();
double Duration = getProperty("Duration");
const double duration = getProperty("Duration");
// Keep going until you get cancelled
while (true) {
......@@ -63,12 +63,12 @@ void Pause::exec() {
DateAndTime now = DateAndTime::getCurrentTime();
double seconds = DateAndTime::secondsFromDuration(now - startTime);
if (Duration > 0) {
if (duration > 0) {
// Break when you've waited long enough
if (seconds > Duration)
if (seconds > duration)
break;
// Report progress for non-infinite runs
this->progress(seconds / Duration);
this->progress(seconds / duration, "", duration - seconds);
}
}
}
......
......@@ -10,6 +10,7 @@
#include "MantidAPI/FileFinder.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidAPI/Sample.h"
#include "MantidAlgorithms/ConvertUnits.h"
#include "MantidAlgorithms/MonteCarloAbsorption.h"
#include "MantidDataHandling/LoadBinaryStl.h"
#include "MantidGeometry/Instrument/SampleEnvironment.h"
......@@ -254,6 +255,33 @@ public:
TS_ASSERT_DELTA(0.1121, outputWS->y(0).back(), delta);
}
void test_Workspace_With_Different_Lambda_Ranges() {
using namespace Mantid::API;
// create an instrument including some monitors so that there's a good
// variation in the wavelength range of the spectra when convert from TOF to
// wavelength
MatrixWorkspace_sptr testWS =
WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(10, 100,
true);
testWS->getAxis(0)->unit() =
Mantid::Kernel::UnitFactory::Instance().create("TOF");
Mantid::Algorithms::ConvertUnits convert;
convert.initialize();
convert.setChild(true);
convert.setProperty("InputWorkspace", testWS);
convert.setProperty("Target", "Wavelength");
convert.setProperty("OutputWorkspace", "dummy");
convert.execute();
testWS = convert.getProperty("OutputWorkspace");
auto mcAbsorb = createAlgorithm();
addSample(testWS, Environment::SampleOnly);
TS_ASSERT_THROWS_NOTHING(mcAbsorb->setProperty("InputWorkspace", testWS));
TS_ASSERT_THROWS_NOTHING(mcAbsorb->execute());
}
//---------------------------------------------------------------------------
// Failure cases
//---------------------------------------------------------------------------
......
......@@ -6,12 +6,18 @@ if(CXXTEST_FOUND)
cxxtest_add_test(BeamlineTest ${TEST_FILES} ${GMOCK_TEST_FILES})
target_include_directories(BeamlineTest SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(BeamlineTest
LINK_PRIVATE
PRIVATE
${TCMALLOC_LIBRARIES_LINKTIME}
Beamline
Kernel
${Boost_LIBRARIES}
gmock
)
)
if(OpenMP_CXX_FOUND)
# Access to config service is required
target_link_libraries(BeamlineTest PRIVATE Kernel)
endif()
add_dependencies(FrameworkTests BeamlineTest)
# Add to the 'FrameworkTests' group in VS
......
......@@ -77,7 +77,6 @@ add_subdirectory(Beamline)
set(MANTIDLIBS ${MANTIDLIBS} Parallel)
# HistogramData has header-only dependency on Kernel, so Kernel comes after.
set(MANTIDLIBS ${MANTIDLIBS} HistogramData)
# Indexing has header-only dependency on Kernel, so Kernel comes after.
set(MANTIDLIBS ${MANTIDLIBS} Indexing)
set(MANTIDLIBS ${MANTIDLIBS} Kernel)
set(MANTIDLIBS ${MANTIDLIBS} Beamline)
......
......@@ -7,12 +7,17 @@ if(CXXTEST_FOUND)
target_include_directories(HistogramDataTest SYSTEM
PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(HistogramDataTest
LINK_PRIVATE
PRIVATE
${TCMALLOC_LIBRARIES_LINKTIME}
HistogramData
Kernel
${Boost_LIBRARIES}
gmock
)
)
if(OpenMP_CXX_FOUND)
# Access to config service is required
target_link_libraries(HistogramDataTest PRIVATE Kernel)
endif()
add_dependencies(FrameworkTests HistogramDataTest)
# Add to the 'FrameworkTests' group in VS
......
......@@ -10,13 +10,17 @@ if(CXXTEST_FOUND)
cxxtest_add_test(IndexingTest ${TEST_FILES} ${GMOCK_TEST_FILES})
target_link_libraries(IndexingTest
LINK_PRIVATE
PRIVATE
${TCMALLOC_LIBRARIES_LINKTIME}
${MANTIDLIBS}
Indexing
Parallel
gmock
)
)
if(OpenMP_CXX_FOUND)
# Access to config service is required
target_link_libraries(IndexingTest PRIVATE Kernel)
endif()
add_dependencies(FrameworkTests IndexingTest)
# Add to the 'FrameworkTests' group in VS
......
......@@ -26,7 +26,8 @@ public:
AlgorithmObserverAdapter &
operator=(const AlgorithmObserverAdapter &) = delete;
void progressHandle(const API::IAlgorithm *alg, double p,
const std::string &msg) override;
const std::string &msg, const double estimatedTime,
const int progressPrecision) override;
void startingHandle(API::IAlgorithm_sptr alg) override;
void finishHandle(const API::IAlgorithm *alg) override;
void errorHandle(const API::IAlgorithm *alg,
......
......@@ -14,14 +14,19 @@ AlgorithmObserverAdapter::AlgorithmObserverAdapter(PyObject *self)
: API::AlgorithmObserver(), m_self(self) {}
void AlgorithmObserverAdapter::progressHandle(const API::IAlgorithm *alg,
double p,
const std::string &msg) {
double p, const std::string &msg,
const double estimatedTime,
const int progressPrecision) {
UNUSED_ARG(alg)
try {
return callMethod<void>(getSelf(), "progressHandle", p, msg);
} catch (UndefinedAttributeError &) {
return;
}
UNUSED_ARG(p)
UNUSED_ARG(msg)
UNUSED_ARG(estimatedTime)
UNUSED_ARG(progressPrecision)
// This method is explicitly not implemented.
// There are so many progress calls that passing these across the C++/Python
// boundary is too expensive and can slow down Mantid by up to an order of
// magnitude
return;
}
void AlgorithmObserverAdapter::startingHandle(API::IAlgorithm_sptr alg) {
......
......@@ -24,12 +24,6 @@ void observeError(AlgorithmObserver &self, const boost::python::object &alg) {
self.observeError(calg);
}
void observeProgress(AlgorithmObserver &self,
const boost::python::object &alg) {
IAlgorithm_sptr &calg = boost::python::extract<IAlgorithm_sptr &>(alg);
self.observeProgress(calg);
}
void stopObserving(AlgorithmObserver &self, const boost::python::object &alg) {
IAlgorithm_sptr &calg = boost::python::extract<IAlgorithm_sptr &>(alg);
self.stopObserving(calg);
......@@ -51,8 +45,6 @@ void export_algorithm_observer() {
"Observe algorithm for its finish notification.")
.def("observeError", &observeError, (arg("self"), arg("alg")),
"Observe algorithm for its error notification.")
.def("observeProgress", &observeProgress, (arg("self"), arg("alg")),
"Observe algorithm for its progress notification.")
.def("stopObserving", &stopObserving, (arg("self"), arg("alg")),
"Remove all observers from the algorithm.");
}
......@@ -279,7 +279,7 @@ def get_plot_fig(overplot=None, ax_properties=None, window_title=None, axes_num=
else:
fig, _, _, _ = create_subplots(axes_num)
if not ax_properties:
if not ax_properties and not overplot:
ax_properties = {}
if ConfigService.getString("plots.xAxesScale").lower() == 'log':
ax_properties['xscale'] = 'log'
......
......@@ -84,6 +84,10 @@ class LRAutoReduction(PythonAlgorithm):
self.declareProperty(IntArrayProperty("SequenceInfo", [0, 0, 0], direction=Direction.Output),
"Run sequence information (run number, sequence ID, sequence number).")
self.declareProperty("SlitTolerance", 0.02, doc="Tolerance for matching slit positions")
self.declareProperty("NormalizationType", "DirectBeam",
doc="Normalization type for reduction. Allowed values: ['DirectBeam', 'WithReference']")
self.declareProperty("Refl1DModelParameters", "",
doc="JSON string for Refl1D theoretical model parameters for 'NormalizationType'=='WithReference' ")
def load_data(self):
"""
......@@ -650,34 +654,45 @@ class LRAutoReduction(PythonAlgorithm):
# Write template before we start the computation
self._write_template(data_set, run_number, first_run_of_set, sequence_number)
# Execute the reduction
LiquidsReflectometryReduction(#RunNumbers=[int(run_number)],
InputWorkspace=self.event_data,
NormalizationRunNumber=str(data_set.norm_file),
SignalPeakPixelRange=data_set.DataPeakPixels,
SubtractSignalBackground=data_set.DataBackgroundFlag,
SignalBackgroundPixelRange=data_set.DataBackgroundRoi[:2],
NormFlag=data_set.NormFlag,
NormPeakPixelRange=data_set.NormPeakPixels,
NormBackgroundPixelRange=data_set.NormBackgroundRoi,
SubtractNormBackground=data_set.NormBackgroundFlag,
LowResDataAxisPixelRangeFlag=data_set.data_x_range_flag,
LowResDataAxisPixelRange=data_set.data_x_range,
LowResNormAxisPixelRangeFlag=data_set.norm_x_range_flag,
LowResNormAxisPixelRange=data_set.norm_x_range,
TOFRange=data_set.DataTofRange,
IncidentMediumSelected=incident_medium,
GeometryCorrectionFlag=False,
QMin=data_set.q_min,
QStep=data_set.q_step,
AngleOffset=data_set.angle_offset,
AngleOffsetError=data_set.angle_offset_error,
ScalingFactorFile=str(data_set.scaling_factor_file),
SlitsWidthFlag=data_set.slits_width_flag,
ApplyPrimaryFraction=True,
SlitTolerance=slit_tolerance,
PrimaryFractionRange=[data_set.clocking_from, data_set.clocking_to],
OutputWorkspace='reflectivity_%s_%s_%s' % (first_run_of_set, sequence_number, run_number))
# input args for both reduction
kwargs = {
"InputWorkspace": self.event_data,
"NormalizationRunNumber": str(data_set.norm_file),
"SignalPeakPixelRange": data_set.DataPeakPixels,
"SubtractSignalBackground": data_set.DataBackgroundFlag,
"SignalBackgroundPixelRange": data_set.DataBackgroundRoi[:2],
"NormFlag": data_set.NormFlag,
"NormPeakPixelRange": data_set.NormPeakPixels,
"NormBackgroundPixelRange": data_set.NormBackgroundRoi,
"SubtractNormBackground": data_set.NormBackgroundFlag,
"LowResDataAxisPixelRangeFlag": data_set.data_x_range_flag,
"LowResDataAxisPixelRange": data_set.data_x_range,
"LowResNormAxisPixelRangeFlag": data_set.norm_x_range_flag,
"LowResNormAxisPixelRange": data_set.norm_x_range,
"TOFRange": data_set.DataTofRange,
"IncidentMediumSelected": incident_medium,
"GeometryCorrectionFlag": False,
"QMin": data_set.q_min,
"QStep": data_set.q_step,
"AngleOffset": data_set.angle_offset,
"AngleOffsetError": data_set.angle_offset_error,
"ScalingFactorFile": str(data_set.scaling_factor_file),
"SlitsWidthFlag": data_set.slits_width_flag,
"ApplyPrimaryFraction": True,
"SlitTolerance": slit_tolerance,
"PrimaryFractionRange": [data_set.clocking_from, data_set.clocking_to],
"OutputWorkspace": 'reflectivity_%s_%s_%s' % (first_run_of_set, sequence_number, run_number)
}
# Execute the reduction for the selected normalization type
norm_type = self.getProperty("NormalizationType").value
if norm_type == "DirectBeam":
LiquidsReflectometryReduction(**kwargs)
elif "WithReference":
refl1d_parameters = self.getProperty("Refl1DModelParameters").value
kwargs['Refl1DModelParameters'] = refl1d_parameters
LRReductionWithReference(**kwargs)
# Put the reflectivity curve together
self._save_partial_output(data_set, first_run_of_set, sequence_number, run_number)
......
......@@ -71,7 +71,7 @@ class LRReductionWithReference(DataProcessorAlgorithm):
def PyInit(self):
self.copyProperties(LR_ALG_FOR_PROPS, PROPS_TO_COPY)
self.declareProperty("Refl1DModelParameters", "",
doc="JSON string for Refl1D theoretical model paramters")
doc="JSON string for Refl1D theoretical model parameters")
def PyExec(self):
try:
......
......@@ -343,7 +343,8 @@ void ApplicationWindow::init(bool factorySettings, const QStringList &args) {
m_sharedMenuBar = new QMenuBar(nullptr);
m_sharedMenuBar->setNativeMenuBar(true);
#endif
setWindowTitle(tr("MantidPlot - untitled")); // Mantid
setWindowTitle(
tr("MantidPlot (End of Life, use Workbench) - untitled")); // Mantid
setObjectName("main application");
initGlobalConstants();
QPixmapCache::setCacheLimit(20 * QPixmapCache::cacheLimit());
......@@ -1081,7 +1082,8 @@ void ApplicationWindow::initToolBars() {
 
void ApplicationWindow::insertTranslatedStrings() {
if (projectname == "untitled")
setWindowTitle(tr("MantidPlot - untitled")); // Mantid
setWindowTitle(
tr("MantidPlot (End of Life, use Workbench) - untitled")); // Mantid
 
QStringList labels;
labels << "Name"
......@@ -4629,7 +4631,7 @@ ApplicationWindow *ApplicationWindow::openProject(const QString &filename,
 
cacheWorkingDirectory();
projectname = filename;
setWindowTitle("MantidPlot - " + filename);
setWindowTitle("MantidPlot (End of Life, use Workbench) - " + filename);
 
d_opening_file = true;
 
......@@ -6017,7 +6019,7 @@ bool ApplicationWindow::saveProject(bool compress) {
ProjectSerialiser serialiser(this);
serialiser.save(projectname, compress);
 
setWindowTitle("MantidPlot - " + projectname);
setWindowTitle("MantidPlot (End of Life, use Workbench) - " + projectname);
savedProject();
 
if (autoSave) {
......@@ -6085,7 +6087,7 @@ void ApplicationWindow::prepareSaveProject() { execSaveProjectDialog(); }
* The project was just saved. Update the main window.
*/
void ApplicationWindow::postSaveProject() {
setWindowTitle("MantidPlot - " + projectname);
setWindowTitle("MantidPlot (End of Life, use Workbench) - " + projectname);
 
if (autoSave) {
if (savingTimerId)
......@@ -9713,7 +9715,8 @@ void ApplicationWindow::newProject(const bool doNotSave) {
folders->blockSignals(false);
 
// Reset everything else
setWindowTitle(tr("MantidPlot - untitled")); // Mantid
setWindowTitle(
tr("MantidPlot (End of Life, use Workbench) - untitled")); // Mantid
projectname = "untitled";
 
if (actionSaveProject)
......@@ -13598,7 +13601,8 @@ ApplicationWindow *ApplicationWindow::importOPJ(const QString &filename,
if (newProject)
app = new ApplicationWindow(factorySettings);
 
app->setWindowTitle("MantidPlot - " + filename); // Mantid
app->setWindowTitle("MantidPlot (End of Life, use Workbench) - " +
filename); // Mantid
app->restoreApplicationGeometry();
app->projectname = filename;
app->recentProjects.removeAll(filename);
......
......@@ -173,8 +173,8 @@ font-size: 28px</string>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QCommandLinkButton" name="clbExtendingMantid">
<item row="12" column="0">
<widget class="QCommandLinkButton" name="clbPythonInMantid">
<property name="font">
<font>
<family>Open Sans</family>
......@@ -191,11 +191,11 @@ font-size: 28px</string>
<string notr="true">color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string>Extending Mantid with Python</string>
<string>Python in Mantid</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/Icons/Plugin-Python-icon-48x48.png</normaloff>:/Icons/Plugin-Python-icon-48x48.png</iconset>
<normaloff>:/Icons/Circle_cog_48x48.png</normaloff>:/Icons/Circle_cog_48x48.png</iconset>
</property>
<property name="iconSize">
<size>
......@@ -208,8 +208,8 @@ font-size: 28px</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QCommandLinkButton" name="clbPythonInMantid">
<item row="10" column="0">
<widget class="QCommandLinkButton" name="clbMantidIntroduction">
<property name="font">
<font>
<family>Open Sans</family>
......@@ -226,11 +226,11 @@ font-size: 28px</string>
<string notr="true">color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string>Python in Mantid</string>
<string>Mantid Introduction</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/Icons/Circle_cog_48x48.png</normaloff>:/Icons/Circle_cog_48x48.png</iconset>
<normaloff>:/Icons/Misc-Tutorial-icon-48x48.png</normaloff>:/Icons/Misc-Tutorial-icon-48x48.png</iconset>
</property>
<property name="iconSize">
<size>
......@@ -243,8 +243,8 @@ font-size: 28px</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QCommandLinkButton" name="clbPythonIntroduction">
<item row="4" column="0">
<widget class="QCommandLinkButton" name="clbReleaseNotes">
<property name="font">
<font>
<family>Open Sans</family>
......@@ -258,14 +258,15 @@ font-size: 28px</string>
<enum>Qt::LeftToRight</enum>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(0, 0, 0);</string>
<string notr="true">color: rgb(0, 128, 0);
color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string>Introduction to Python</string>
<string>Release Notes</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/Icons/Python-icon-48x48.png</normaloff>:/Icons/Python-icon-48x48.png</iconset>
<normaloff>:/Icons/Notepad-Bloc-notes-icon-48x48.png</normaloff>:/Icons/Notepad-Bloc-notes-icon-48x48.png</iconset>
</property>
<property name="iconSize">
<size>
......@@ -276,10 +277,13 @@ font-size: 28px</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCommandLinkButton" name="clbMantidIntroduction">
<item row="13" column="0">
<widget class="QCommandLinkButton" name="clbExtendingMantid">
<property name="font">
<font>
<family>Open Sans</family>
......@@ -296,11 +300,11 @@ font-size: 28px</string>
<string notr="true">color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string>Mantid Introduction</string>
<string>Extending Mantid with Python</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/Icons/Misc-Tutorial-icon-48x48.png</normaloff>:/Icons/Misc-Tutorial-icon-48x48.png</iconset>
<normaloff>:/Icons/Plugin-Python-icon-48x48.png</normaloff>:/Icons/Plugin-Python-icon-48x48.png</iconset>
</property>
<property name="iconSize">
<size>
......@@ -333,8 +337,8 @@ font-size: 28px;</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCommandLinkButton" name="clbReleaseNotes">
<item row="11" column="0">
<widget class="QCommandLinkButton" name="clbPythonIntroduction">
<property name="font">
<font>
<family>Open Sans</family>
......@@ -348,15 +352,14 @@ font-size: 28px;</string>
<enum>Qt::LeftToRight</enum>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(0, 128, 0);
color: rgb(0, 0, 0);</string>
<string notr="true">color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string>Release Notes</string>
<string>Introduction to Python</string>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/Icons/Notepad-Bloc-notes-icon-48x48.png</normaloff>:/Icons/Notepad-Bloc-notes-icon-48x48.png</iconset>
<normaloff>:/Icons/Python-icon-48x48.png</normaloff>:/Icons/Python-icon-48x48.png</iconset>
</property>
<property name="iconSize">
<size>
......@@ -367,9 +370,6 @@ color: rgb(0, 0, 0);</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
......@@ -656,10 +656,134 @@ background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgb
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>30</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QGroupBox" name="grpEndOfLife">
<property name="styleSheet">
<string notr="true">QGroupBox {
border: 3px solid rgb(38, 128, 20);;
border-radius: 10px;
background-color: rgb(240, 240, 240);
}
QGroupBox#grpEndOfLife QLabel{