diff --git a/Modules/Segmentation/Interactions/mitkSegWithPreviewTool.cpp b/Modules/Segmentation/Interactions/mitkSegWithPreviewTool.cpp
index 1ae00d3b1d..e20ac8569b 100644
--- a/Modules/Segmentation/Interactions/mitkSegWithPreviewTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkSegWithPreviewTool.cpp
@@ -1,849 +1,850 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "mitkSegWithPreviewTool.h"
 
 #include "mitkToolManager.h"
 
 #include "mitkColorProperty.h"
 #include "mitkProperties.h"
 
 #include "mitkDataStorage.h"
 #include "mitkRenderingManager.h"
 #include <mitkTimeNavigationController.h>
 
 #include "mitkImageAccessByItk.h"
 #include "mitkImageCast.h"
 #include "mitkLabelSetImage.h"
 #include "mitkMaskAndCutRoiImageFilter.h"
 #include "mitkPadImageFilter.h"
 #include "mitkNodePredicateGeometry.h"
 #include "mitkSegTool2D.h"
 
 mitk::SegWithPreviewTool::SegWithPreviewTool(bool lazyDynamicPreviews): Tool("dummy"), m_LazyDynamicPreviews(lazyDynamicPreviews)
 {
   m_ProgressCommand = ToolCommand::New();
 }
 
 mitk::SegWithPreviewTool::SegWithPreviewTool(bool lazyDynamicPreviews, const char* interactorType, const us::Module* interactorModule) : Tool(interactorType, interactorModule), m_LazyDynamicPreviews(lazyDynamicPreviews)
 {
   m_ProgressCommand = ToolCommand::New();
 }
 
 mitk::SegWithPreviewTool::~SegWithPreviewTool()
 {
 }
 
 void mitk::SegWithPreviewTool::SetMergeStyle(MultiLabelSegmentation::MergeStyle mergeStyle)
 {
   m_MergeStyle = mergeStyle;
   this->Modified();
 }
 
 void mitk::SegWithPreviewTool::SetOverwriteStyle(MultiLabelSegmentation::OverwriteStyle overwriteStyle)
 {
   m_OverwriteStyle = overwriteStyle;
   this->Modified();
 }
 
 void mitk::SegWithPreviewTool::SetLabelTransferScope(LabelTransferScope labelTransferScope)
 {
   m_LabelTransferScope = labelTransferScope;
   this->Modified();
 }
 
 void mitk::SegWithPreviewTool::SetLabelTransferMode(LabelTransferMode labelTransferMode)
 {
   m_LabelTransferMode = labelTransferMode;
   this->Modified();
 }
 
 void mitk::SegWithPreviewTool::SetSelectedLabels(const SelectedLabelVectorType& labelsToTransfer)
 {
   m_SelectedLabels = labelsToTransfer;
   this->Modified();
 }
 
 bool mitk::SegWithPreviewTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const
 {
   if (!Superclass::CanHandle(referenceData, workingData))
     return false;
 
   if (workingData == nullptr)
     return false;
 
   auto* referenceImage = dynamic_cast<const Image*>(referenceData);
   if (referenceImage == nullptr)
     return false;
 
   auto* labelSet = dynamic_cast<const LabelSetImage*>(workingData);
   if (labelSet != nullptr)
     return true;
 
   auto* workingImage = dynamic_cast<const Image*>(workingData);
   if (workingImage == nullptr)
     return false;
 
   // If the working image is a normal image and not a label set image
   // it must have the same pixel type as a label set.
   return MakeScalarPixelType< DefaultSegmentationDataType >() == workingImage->GetPixelType();
 }
 
 void mitk::SegWithPreviewTool::Activated()
 {
   Superclass::Activated();
 
   this->GetToolManager()->RoiDataChanged +=
     MessageDelegate<SegWithPreviewTool>(this, &SegWithPreviewTool::OnRoiDataChanged);
 
   this->GetToolManager()->SelectedTimePointChanged +=
     MessageDelegate<SegWithPreviewTool>(this, &SegWithPreviewTool::OnTimePointChanged);
 
   m_ReferenceDataNode = this->GetToolManager()->GetReferenceData(0);
   m_SegmentationInputNode = m_ReferenceDataNode;
 
   m_LastTimePointOfUpdate = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
 
   if (m_PreviewSegmentationNode.IsNull())
   {
     m_PreviewSegmentationNode = DataNode::New();
     m_PreviewSegmentationNode->SetProperty("color", ColorProperty::New(0.0, 1.0, 0.0));
     m_PreviewSegmentationNode->SetProperty("name", StringProperty::New(std::string(this->GetName())+" preview"));
     m_PreviewSegmentationNode->SetProperty("opacity", FloatProperty::New(0.3));
     m_PreviewSegmentationNode->SetProperty("binary", BoolProperty::New(true));
     m_PreviewSegmentationNode->SetProperty("helper object", BoolProperty::New(true));
   }
 
   if (m_SegmentationInputNode.IsNotNull())
   {
     this->ResetPreviewNode();
     this->InitiateToolByInput();
   }
   else
   {
     this->GetToolManager()->ActivateTool(-1);
   }
+  m_IsPreviewGenerated = false;
 }
 
 void mitk::SegWithPreviewTool::Deactivated()
 {
   this->GetToolManager()->RoiDataChanged -=
     MessageDelegate<SegWithPreviewTool>(this, &SegWithPreviewTool::OnRoiDataChanged);
 
   this->GetToolManager()->SelectedTimePointChanged -=
     MessageDelegate<SegWithPreviewTool>(this, &SegWithPreviewTool::OnTimePointChanged);
 
   m_SegmentationInputNode = nullptr;
   m_ReferenceDataNode = nullptr;
   m_WorkingPlaneGeometry = nullptr;
 
   try
   {
     if (DataStorage *storage = this->GetToolManager()->GetDataStorage())
     {
       storage->Remove(m_PreviewSegmentationNode);
       RenderingManager::GetInstance()->RequestUpdateAll();
     }
   }
   catch (...)
   {
     // don't care
   }
 
   if (m_PreviewSegmentationNode.IsNotNull())
   {
     m_PreviewSegmentationNode->SetData(nullptr);
   }
 
   Superclass::Deactivated();
 }
 
 void mitk::SegWithPreviewTool::ConfirmSegmentation()
 {
   bool labelChanged = this->EnsureUpToDateUserDefinedActiveLabel();
   if ((m_LazyDynamicPreviews && m_CreateAllTimeSteps) || labelChanged)
   { // The tool should create all time steps but is currently in lazy mode,
     // thus ensure that a preview for all time steps is available.
     this->UpdatePreview(true);
   }
 
   CreateResultSegmentationFromPreview();
 
   RenderingManager::GetInstance()->RequestUpdateAll();
 
   if (!m_KeepActiveAfterAccept)
   {
     this->GetToolManager()->ActivateTool(-1);
   }
   this->ConfirmCleanUp();
 }
 
 void  mitk::SegWithPreviewTool::InitiateToolByInput()
 {
   //default implementation does nothing.
   //implement in derived classes to change behavior
 }
 
 mitk::LabelSetImage* mitk::SegWithPreviewTool::GetPreviewSegmentation()
 {
   if (m_PreviewSegmentationNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<LabelSetImage*>(m_PreviewSegmentationNode->GetData());
 }
 
 const mitk::LabelSetImage* mitk::SegWithPreviewTool::GetPreviewSegmentation() const
 {
   if (m_PreviewSegmentationNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<LabelSetImage*>(m_PreviewSegmentationNode->GetData());
 }
 
 mitk::DataNode* mitk::SegWithPreviewTool::GetPreviewSegmentationNode()
 {
   return m_PreviewSegmentationNode;
 }
 
 const mitk::Image* mitk::SegWithPreviewTool::GetSegmentationInput() const
 {
   if (m_SegmentationInputNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<const Image*>(m_SegmentationInputNode->GetData());
 }
 
 const mitk::Image* mitk::SegWithPreviewTool::GetReferenceData() const
 {
   if (m_ReferenceDataNode.IsNull())
   {
     return nullptr;
   }
 
   return dynamic_cast<const Image*>(m_ReferenceDataNode->GetData());
 }
 
 template <typename ImageType>
 void ClearBufferProcessing(ImageType* itkImage)
 {
   itkImage->FillBuffer(0);
 }
 
 void mitk::SegWithPreviewTool::ResetPreviewContentAtTimeStep(unsigned int timeStep)
 {
   auto previewImage = GetImageByTimeStep(this->GetPreviewSegmentation(), timeStep);
   if (nullptr != previewImage)
   {
     AccessByItk(previewImage, ClearBufferProcessing);
   }
 }
 
 void mitk::SegWithPreviewTool::ResetPreviewContent()
 {
   auto previewImage = this->GetPreviewSegmentation();
   if (nullptr != previewImage)
   {
     auto castedPreviewImage =
       dynamic_cast<LabelSetImage*>(previewImage);
     if (nullptr == castedPreviewImage) mitkThrow() << "Application is on wrong state / invalid tool implementation. Preview image should always be of type LabelSetImage now.";
     castedPreviewImage->ClearBuffer();
   }
 }
 
 void mitk::SegWithPreviewTool::ResetPreviewNode()
 {
   if (m_IsUpdating)
   {
     mitkThrow() << "Used tool is implemented incorrectly. ResetPreviewNode is called while preview update is ongoing. Check implementation!";
   }
 
   itk::RGBPixel<float> previewColor;
   previewColor[0] = 0.0f;
   previewColor[1] = 1.0f;
   previewColor[2] = 0.0f;
 
   const auto image = this->GetSegmentationInput();
   if (nullptr != image)
   {
     LabelSetImage::ConstPointer workingImage =
       dynamic_cast<const LabelSetImage *>(this->GetToolManager()->GetWorkingData(0)->GetData());
 
     if (workingImage.IsNotNull())
     {
       auto newPreviewImage = workingImage->Clone();
       if (this->GetResetsToEmptyPreview())
       {
         newPreviewImage->ClearBuffer();
       }
 
       if (newPreviewImage.IsNull())
       {
         MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image";
         return;
       }
 
       m_PreviewSegmentationNode->SetData(newPreviewImage);
 
       if (newPreviewImage->GetNumberOfLayers() == 0)
       {
         newPreviewImage->AddLayer();
         newPreviewImage->SetActiveLayer(0);
       }
 
       auto* activeLabel = newPreviewImage->GetActiveLabel();
       if (nullptr == activeLabel)
       {
         activeLabel = newPreviewImage->AddLabel("toolresult", previewColor, newPreviewImage->GetActiveLayer());
         newPreviewImage->UpdateLookupTable(activeLabel->GetValue());
       }
       else if (m_UseSpecialPreviewColor)
       {
         // Let's paint the feedback node green...
         activeLabel->SetColor(previewColor);
         newPreviewImage->UpdateLookupTable(activeLabel->GetValue());
       }
       activeLabel->SetVisible(true);
     }
     else
     {
       Image::ConstPointer workingImageBin = dynamic_cast<const Image*>(this->GetToolManager()->GetWorkingData(0)->GetData());
       if (workingImageBin.IsNotNull())
       {
         Image::Pointer newPreviewImage;
         if (this->GetResetsToEmptyPreview())
         {
           newPreviewImage = Image::New();
           newPreviewImage->Initialize(workingImageBin);
         }
         else
         {
           auto newPreviewImage = workingImageBin->Clone();
         }
         if (newPreviewImage.IsNull())
         {
           MITK_ERROR << "Cannot create preview helper objects. Unable to clone working image";
           return;
         }
         m_PreviewSegmentationNode->SetData(newPreviewImage);
       }
       else
       {
         mitkThrow() << "Tool is an invalid state. Cannot setup preview node. Working data is an unsupported class and should have not been accepted by CanHandle().";
       }
     }
 
     m_PreviewSegmentationNode->SetColor(previewColor);
     m_PreviewSegmentationNode->SetOpacity(0.5);
 
     int layer(50);
     m_ReferenceDataNode->GetIntProperty("layer", layer);
     m_PreviewSegmentationNode->SetIntProperty("layer", layer + 1);
 
     if (DataStorage *ds = this->GetToolManager()->GetDataStorage())
     {
       if (!ds->Exists(m_PreviewSegmentationNode))
         ds->Add(m_PreviewSegmentationNode, m_ReferenceDataNode);
     }
   }
 }
 
 mitk::SegWithPreviewTool::LabelMappingType mitk::SegWithPreviewTool::GetLabelMapping() const
 {
   LabelSetImage::LabelValueType offset = 0;
   
   if (LabelTransferMode::AddLabel == m_LabelTransferMode && LabelTransferScope::ActiveLabel!=m_LabelTransferScope)
   {
     //If we are not just working on active label and transfer mode is add, we need to compute an offset for adding the
     //preview labels instat of just mapping them to existing segmentation labels.
     const auto segmentation = this->GetTargetSegmentation();
     if (nullptr == segmentation)
       mitkThrow() << "Invalid state of SegWithPreviewTool. Cannot GetLabelMapping if no target segmentation is set.";
 
     auto labels = segmentation->GetLabels();
     auto maxLabelIter = std::max_element(std::begin(labels), std::end(labels), [](const Label::Pointer& a, const Label::Pointer& b) {
       return a->GetValue() < b->GetValue();
     });
 
     if (maxLabelIter != labels.end())
     {
       offset = maxLabelIter->GetPointer()->GetValue();
     }
   }
 
   LabelMappingType labelMapping = {};
 
   switch (this->m_LabelTransferScope)
   {
     case LabelTransferScope::SelectedLabels:
       {
         for (auto label : this->m_SelectedLabels)
         {
           labelMapping.push_back({label, label + offset});
         }
       }
       break;
     case LabelTransferScope::AllLabels:
       {
         const auto labelValues = this->GetPreviewSegmentation()->GetLabelValuesByGroup(this->GetPreviewSegmentation()->GetActiveLayer());
         for (auto labelValue : labelValues)
         {
         labelMapping.push_back({ labelValue, labelValue + offset});
         }
       }
       break;
     default:
       {
         if (m_SelectedLabels.empty())
           mitkThrow() << "Failed to generate label transfer mapping. Tool is in an invalid state, as "
                          "LabelTransferScope==ActiveLabel but no label is indicated as selected label. Check "
                          "implementation of derived tool class.";
         if (m_SelectedLabels.size() > 1)
         mitkThrow() << "Failed to generate label transfer mapping. Tool is in an invalid state, as "
                        "LabelTransferScope==ActiveLabel but more then one selected label is indicated."
                        "Should be only one. Check implementation of derived tool class.";
         labelMapping.push_back({m_SelectedLabels.front(), this->GetUserDefinedActiveLabel()});
       }
       break;
   }
 
   return labelMapping;
 }
 
 void mitk::SegWithPreviewTool::TransferImageAtTimeStep(const Image* sourceImage, Image* destinationImage, const TimeStepType timeStep, const LabelMappingType& labelMapping)
 {
   try
   {
     Image::ConstPointer sourceImageAtTimeStep = this->GetImageByTimeStep(sourceImage, timeStep);
 
     if (sourceImageAtTimeStep->GetPixelType() != destinationImage->GetPixelType())
     {
       mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same pixel type. "
         << "Source pixel type: " << sourceImage->GetPixelType().GetTypeAsString()
         << "; destination pixel type: " << destinationImage->GetPixelType().GetTypeAsString();
     }
 
     if (!Equal(*(sourceImage->GetGeometry(timeStep)), *(destinationImage->GetGeometry(timeStep)), NODE_PREDICATE_GEOMETRY_DEFAULT_CHECK_COORDINATE_PRECISION, NODE_PREDICATE_GEOMETRY_DEFAULT_CHECK_DIRECTION_PRECISION, false))
     {
       mitkThrow() << "Cannot transfer images. Tool is in an invalid state, source image and destination image do not have the same geometry.";
     }
 
     if (nullptr != this->GetWorkingPlaneGeometry())
     {
       auto sourceSlice = SegTool2D::GetAffectedImageSliceAs2DImage(this->GetWorkingPlaneGeometry(), sourceImage, timeStep);
       auto resultSlice =
         SegTool2D::GetAffectedImageSliceAs2DImage(this->GetWorkingPlaneGeometry(), destinationImage, timeStep)->Clone();
       auto destLSImage = dynamic_cast<LabelSetImage *>(destinationImage);
       //We need to transfer explictly to a copy of the current working image to ensure that labelMapping is done and things
       //like merge style, overwrite style and locks are regarded.
       TransferLabelContentAtTimeStep(sourceSlice,
                                      resultSlice,
                                      destLSImage->GetConstLabelsByValue(destLSImage->GetLabelValuesByGroup(destLSImage->GetActiveLayer())),
                                      timeStep,
                                      0,
                                      0,
                                      destLSImage->GetUnlabeledLabelLock(),
                                      labelMapping,
                                      m_MergeStyle,
                                      m_OverwriteStyle);
       //We use WriteBackSegmentationResult to ensure undo/redo is supported also by derived tools of this class.
       SegTool2D::WriteBackSegmentationResult(this->GetTargetSegmentationNode(), m_WorkingPlaneGeometry, resultSlice, timeStep);
     }
     else
     { //take care of the full segmentation volume
       auto sourceLSImage = dynamic_cast<const LabelSetImage*>(sourceImage);
       auto destLSImage = dynamic_cast<LabelSetImage*>(destinationImage);
 
       TransferLabelContentAtTimeStep(sourceLSImage, destLSImage, timeStep, labelMapping, m_MergeStyle, m_OverwriteStyle);
     }
   }
   catch (mitk::Exception& e)
   {
     Tool::ErrorMessage(e.GetDescription());
     mitkReThrow(e);
   }
 }
 
 void mitk::SegWithPreviewTool::CreateResultSegmentationFromPreview()
 {
   const auto segInput = this->GetSegmentationInput();
   auto previewImage = this->GetPreviewSegmentation();
   if (nullptr != segInput && nullptr != previewImage)
   {
     DataNode::Pointer resultSegmentationNode = GetTargetSegmentationNode();
 
     if (resultSegmentationNode.IsNotNull())
     {
       const TimePointType timePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
       auto resultSegmentation = dynamic_cast<Image*>(resultSegmentationNode->GetData());
 
       // REMARK: the following code in this scope assumes that previewImage and resultSegmentation
       // are clones of the working referenceImage (segmentation provided to the tool). Therefore they have
       // the same time geometry.
       if (previewImage->GetTimeSteps() != resultSegmentation->GetTimeSteps())
       {
         mitkThrow() << "Cannot confirm/transfer segmentation. Internal tool state is invalid."
           << " Preview segmentation and segmentation result image have different time geometries.";
       }
 
       auto labelMapping = this->GetLabelMapping();
       this->PreparePreviewToResultTransfer(labelMapping);
       if (m_CreateAllTimeSteps)
       {
         for (unsigned int timeStep = 0; timeStep < previewImage->GetTimeSteps(); ++timeStep)
         {
           this->TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep, labelMapping);
         }
       }
       else
       {
         const auto timeStep = resultSegmentation->GetTimeGeometry()->TimePointToTimeStep(timePoint);
         this->TransferImageAtTimeStep(previewImage, resultSegmentation, timeStep, labelMapping);
       }
 
       // since we are maybe working on a smaller referenceImage, pad it to the size of the original referenceImage
       if (m_ReferenceDataNode.GetPointer() != m_SegmentationInputNode.GetPointer())
       {
         PadImageFilter::Pointer padFilter = PadImageFilter::New();
 
         padFilter->SetInput(0, resultSegmentation);
         padFilter->SetInput(1, dynamic_cast<Image*>(m_ReferenceDataNode->GetData()));
         padFilter->SetBinaryFilter(true);
         padFilter->SetUpperThreshold(1);
         padFilter->SetLowerThreshold(1);
         padFilter->Update();
 
         resultSegmentationNode->SetData(padFilter->GetOutput());
       }
       this->EnsureTargetSegmentationNodeInDataStorage();
     }
   }
 }
 
 void mitk::SegWithPreviewTool::OnRoiDataChanged()
 {
   DataNode::ConstPointer node = this->GetToolManager()->GetRoiData(0);
 
   if (node.IsNotNull())
   {
     MaskAndCutRoiImageFilter::Pointer roiFilter = MaskAndCutRoiImageFilter::New();
     Image::Pointer image = dynamic_cast<Image *>(m_SegmentationInputNode->GetData());
 
     if (image.IsNull())
       return;
 
     roiFilter->SetInput(image);
     roiFilter->SetRegionOfInterest(node->GetData());
     roiFilter->Update();
 
     DataNode::Pointer tmpNode = DataNode::New();
     tmpNode->SetData(roiFilter->GetOutput());
 
     m_SegmentationInputNode = tmpNode;
   }
   else
     m_SegmentationInputNode = m_ReferenceDataNode;
 
   this->ResetPreviewNode();
   this->InitiateToolByInput();
   this->UpdatePreview();
 }
 
 void mitk::SegWithPreviewTool::OnTimePointChanged()
 {
   if (m_IsTimePointChangeAware && m_PreviewSegmentationNode.IsNotNull() && m_SegmentationInputNode.IsNotNull())
   {
     const TimePointType timePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
 
     const bool isStaticSegOnDynamicImage = m_PreviewSegmentationNode->GetData()->GetTimeSteps() == 1 && m_SegmentationInputNode->GetData()->GetTimeSteps() > 1;
     if (timePoint!=m_LastTimePointOfUpdate && (isStaticSegOnDynamicImage || m_LazyDynamicPreviews))
     { //we only need to update either because we are lazzy
       //or because we have a static segmentation with a dynamic referenceImage 
       this->UpdatePreview();
     }
   }
 }
 
 bool mitk::SegWithPreviewTool::EnsureUpToDateUserDefinedActiveLabel()
 {
   bool labelChanged = true;
 
   const auto workingImage = dynamic_cast<const Image*>(this->GetToolManager()->GetWorkingData(0)->GetData());
   if (const auto& labelSetImage = dynamic_cast<const LabelSetImage*>(workingImage))
   {
     // this is a fix for T28131 / T28986, which should be refactored if T28524 is being worked on
     auto newLabel = labelSetImage->GetActiveLabel()->GetValue();
     labelChanged = newLabel != m_UserDefinedActiveLabel;
     m_UserDefinedActiveLabel = newLabel;
   }
   else
   {
     m_UserDefinedActiveLabel = 1;
     labelChanged = false;
   }
   return labelChanged;
 }
 
 void mitk::SegWithPreviewTool::UpdatePreview(bool ignoreLazyPreviewSetting)
 {
   const auto inputImage = this->GetSegmentationInput();
   auto previewImage = this->GetPreviewSegmentation();
   int progress_steps = 200;
 
   const auto workingImage = dynamic_cast<const Image*>(this->GetToolManager()->GetWorkingData(0)->GetData());
   this->EnsureUpToDateUserDefinedActiveLabel();
 
   this->CurrentlyBusy.Send(true);
   m_IsUpdating = true;
   m_IsPreviewGenerated = false;
   this->UpdatePrepare();
 
   const TimePointType timePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
 
   try
   {
     if (nullptr != inputImage && nullptr != previewImage)
     {
       m_ProgressCommand->AddStepsToDo(progress_steps);
 
       if (previewImage->GetTimeSteps() > 1 && (ignoreLazyPreviewSetting || !m_LazyDynamicPreviews))
       {
         for (unsigned int timeStep = 0; timeStep < previewImage->GetTimeSteps(); ++timeStep)
         {
           Image::ConstPointer feedBackImage;
           Image::ConstPointer currentSegImage;
 
           auto previewTimePoint = previewImage->GetTimeGeometry()->TimeStepToTimePoint(timeStep);
           auto inputTimeStep = inputImage->GetTimeGeometry()->TimePointToTimeStep(previewTimePoint);
 
           if (nullptr != this->GetWorkingPlaneGeometry())
           { //only extract a specific slice defined by the working plane as feedback referenceImage.
             feedBackImage = SegTool2D::GetAffectedImageSliceAs2DImage(this->GetWorkingPlaneGeometry(), inputImage, inputTimeStep);
             currentSegImage = SegTool2D::GetAffectedImageSliceAs2DImageByTimePoint(this->GetWorkingPlaneGeometry(), workingImage, previewTimePoint);
           }
           else
           { //work on the whole feedback referenceImage
             feedBackImage = this->GetImageByTimeStep(inputImage, inputTimeStep);
             currentSegImage = this->GetImageByTimePoint(workingImage, previewTimePoint);
           }
 
           this->DoUpdatePreview(feedBackImage, currentSegImage, previewImage, timeStep);
         }
       }
       else
       {
         Image::ConstPointer feedBackImage;
         Image::ConstPointer currentSegImage;
 
         if (nullptr != this->GetWorkingPlaneGeometry())
         {
           feedBackImage = SegTool2D::GetAffectedImageSliceAs2DImageByTimePoint(this->GetWorkingPlaneGeometry(), inputImage, timePoint);
           currentSegImage = SegTool2D::GetAffectedImageSliceAs2DImageByTimePoint(this->GetWorkingPlaneGeometry(), workingImage, timePoint);
         }
         else
         {
           feedBackImage = this->GetImageByTimePoint(inputImage, timePoint);
           currentSegImage = this->GetImageByTimePoint(workingImage, timePoint);
         }
 
         auto timeStep = previewImage->GetTimeGeometry()->TimePointToTimeStep(timePoint);
 
         this->DoUpdatePreview(feedBackImage, currentSegImage, previewImage, timeStep);
       }
       RenderingManager::GetInstance()->RequestUpdateAll();
-      if (previewImage->GetNumberOfLabels(previewImage->GetActiveLayer()) > 0)
+      if (!previewImage->GetAllLabelValues().empty())
       { // check if labels exits for the preview
         m_IsPreviewGenerated = true;
       }
     }
   }
   catch (itk::ExceptionObject & excep)
   {
     MITK_ERROR << "Exception caught: " << excep.GetDescription();
 
     m_ProgressCommand->SetProgress(progress_steps);
 
     std::string msg = excep.GetDescription();
     ErrorMessage.Send(msg);
   }
   catch (...)
   {
     m_ProgressCommand->SetProgress(progress_steps);
     m_IsUpdating = false;
     CurrentlyBusy.Send(false);
     throw;
   }
 
   this->UpdateCleanUp();
   m_LastTimePointOfUpdate = timePoint;
   m_ProgressCommand->SetProgress(progress_steps);
   m_IsUpdating = false;
   CurrentlyBusy.Send(false);
 }
 
 bool mitk::SegWithPreviewTool::IsUpdating() const
 {
   return m_IsUpdating;
 }
 
 void mitk::SegWithPreviewTool::UpdatePrepare()
 {
   // default implementation does nothing
   //reimplement in derived classes for special behavior
 }
 
 void mitk::SegWithPreviewTool::UpdateCleanUp()
 {
   // default implementation does nothing
   //reimplement in derived classes for special behavior
 }
 
 void mitk::SegWithPreviewTool::ConfirmCleanUp()
 {
   // default implementation does nothing
   // reimplement in derived classes for special behavior
 }
 
 void mitk::SegWithPreviewTool::TransferLabelInformation(const LabelMappingType& labelMapping,
   const mitk::LabelSetImage* source, mitk::LabelSetImage* target)
 {
   for (const auto& [sourceLabel, targetLabel] : labelMapping)
   {
     if (LabelSetImage::UNLABELED_VALUE != sourceLabel &&
         LabelSetImage::UNLABELED_VALUE != targetLabel &&
         !target->ExistLabel(targetLabel, target->GetActiveLayer()))
     {
       if (!source->ExistLabel(sourceLabel, source->GetActiveLayer()))
       {
         mitkThrow() << "Cannot prepare segmentation for preview transfer. Preview seems invalid as label is missing. Missing label: " << sourceLabel;
       }
 
       auto clonedLabel = source->GetLabel(sourceLabel)->Clone();
       clonedLabel->SetValue(targetLabel);
       target->AddLabel(clonedLabel,target->GetActiveLayer(), false, false);
     }
   }
 }
 
 void mitk::SegWithPreviewTool::PreparePreviewToResultTransfer(const LabelMappingType& labelMapping)
 {
   DataNode::Pointer resultSegmentationNode = GetTargetSegmentationNode();
 
   if (resultSegmentationNode.IsNotNull())
   {
     auto resultSegmentation = dynamic_cast<LabelSetImage*>(resultSegmentationNode->GetData());
 
     if (nullptr == resultSegmentation)
     {
       mitkThrow() << "Cannot prepare segmentation for preview transfer. Tool is in invalid state as segmentation is not existing or of right type";
     }
 
     auto preview = this->GetPreviewSegmentation();
     TransferLabelInformation(labelMapping, preview, resultSegmentation);
   }
 }
 
 mitk::TimePointType mitk::SegWithPreviewTool::GetLastTimePointOfUpdate() const
 {
   return m_LastTimePointOfUpdate;
 }
 
 mitk::LabelSetImage::LabelValueType mitk::SegWithPreviewTool::GetActiveLabelValueOfPreview() const
 {
   const auto previewImage = this->GetPreviewSegmentation();
   const auto activeLabel = previewImage->GetActiveLabel();
   if (nullptr == activeLabel)
     mitkThrow() << this->GetNameOfClass() <<" is in an invalid state, as "
                    "preview has no active label indicated. Check "
                    "implementation of the class.";
 
   return activeLabel->GetValue();
 }
 
 const char* mitk::SegWithPreviewTool::GetGroup() const
 {
   return "autoSegmentation";
 }
 
 mitk::Image::ConstPointer mitk::SegWithPreviewTool::GetImageByTimeStep(const mitk::Image* image, TimeStepType timestep)
 {
   return SelectImageByTimeStep(image, timestep);
 }
 
 mitk::Image::Pointer mitk::SegWithPreviewTool::GetImageByTimeStep(mitk::Image* image, TimeStepType timestep)
 {
   return SelectImageByTimeStep(image, timestep);
 }
 
 mitk::Image::ConstPointer mitk::SegWithPreviewTool::GetImageByTimePoint(const mitk::Image* image, TimePointType timePoint)
 {
   return SelectImageByTimePoint(image, timePoint);
 }
 
 void mitk::SegWithPreviewTool::EnsureTargetSegmentationNodeInDataStorage() const
 {
   auto targetNode = this->GetTargetSegmentationNode();
   auto dataStorage = this->GetToolManager()->GetDataStorage();
   if (!dataStorage->Exists(targetNode))
   {
     dataStorage->Add(targetNode, this->GetToolManager()->GetReferenceData(0));
   }
 }
 
 std::string mitk::SegWithPreviewTool::GetCurrentSegmentationName()
 {
   auto workingData = this->GetToolManager()->GetWorkingData(0);
 
   return nullptr != workingData
     ? workingData->GetName()
     : "";
 }
 
 mitk::DataNode* mitk::SegWithPreviewTool::GetTargetSegmentationNode() const
 {
   return this->GetToolManager()->GetWorkingData(0);
 }
 
 mitk::LabelSetImage* mitk::SegWithPreviewTool::GetTargetSegmentation() const
 {
   auto node = this->GetTargetSegmentationNode();
 
   if (nullptr == node)
     return nullptr;
 
   return dynamic_cast<LabelSetImage*>(node->GetData());
 }
 
 void mitk::SegWithPreviewTool::TransferLabelSetImageContent(const LabelSetImage* source, LabelSetImage* target, TimeStepType timeStep)
 {
   mitk::ImageReadAccessor newMitkImgAcc(source);
 
   LabelMappingType labelMapping;
   const auto labelValues = source->GetLabelValuesByGroup(source->GetActiveLayer());
   for (const auto& labelValue : labelValues)
   {
     labelMapping.push_back({ labelValue,labelValue });
   }
   TransferLabelInformation(labelMapping, source, target);
 
   target->SetVolume(newMitkImgAcc.GetData(), timeStep);
 }
 
 bool mitk::SegWithPreviewTool::ConfirmBeforeDeactivation()
 {
   return m_IsPreviewGenerated && m_RequestDeactivationConfirmation;
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp
index 44b094d5dd..3557881382 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkTotalSegmentatorToolGUI.cpp
@@ -1,499 +1,501 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "QmitkTotalSegmentatorToolGUI.h"
 
 #include "mitkProcessExecutor.h"
 #include "mitkTotalSegmentatorTool.h"
 #include <QApplication>
 #include <QDir>
 #include <QDirIterator>
 #include <QFileDialog>
 #include <QIcon>
 #include <QmitkStyleManager.h>
 #include <QMessageBox>
 
 MITK_TOOL_GUI_MACRO(MITKSEGMENTATIONUI_EXPORT, QmitkTotalSegmentatorToolGUI, "")
 
 QmitkTotalSegmentatorToolGUI::QmitkTotalSegmentatorToolGUI()
   : QmitkMultiLabelSegWithPreviewToolGUIBase(), m_SuperclassEnableConfirmSegBtnFnc(m_EnableConfirmSegBtnFnc)
 {
   // Nvidia-smi command returning zero doesn't always imply lack of GPUs.
   // Pytorch uses its own libraries to communicate to the GPUs. Hence, only a warning can be given.
   if (m_GpuLoader.GetGPUCount() == 0)
   {
     std::string warning = "WARNING: No GPUs were detected on your machine. The TotalSegmentator tool can be very slow.";
     this->ShowErrorMessage(warning);
   }
   m_EnableConfirmSegBtnFnc = [this](bool enabled)
   { return !m_FirstPreviewComputation ? m_SuperclassEnableConfirmSegBtnFnc(enabled) : false; };
 }
 
 void QmitkTotalSegmentatorToolGUI::ConnectNewTool(mitk::SegWithPreviewTool *newTool)
 {
   Superclass::ConnectNewTool(newTool);
   m_FirstPreviewComputation = true;
 }
 
 void QmitkTotalSegmentatorToolGUI::InitializeUI(QBoxLayout *mainLayout)
 {
   m_Controls.setupUi(this);
 #ifndef _WIN32
   m_Controls.sysPythonComboBox->addItem("/usr/bin");
 #endif
   this->AutoParsePythonPaths();
   m_Controls.sysPythonComboBox->addItem("Select");
   m_Controls.sysPythonComboBox->setCurrentIndex(0);
   m_Controls.pythonEnvComboBox->addItem("Select");
   m_Controls.pythonEnvComboBox->setDuplicatesEnabled(false);
   m_Controls.pythonEnvComboBox->setDisabled(true);
   m_Controls.previewButton->setDisabled(true);
   m_Controls.statusLabel->setTextFormat(Qt::RichText);
   m_Controls.subtaskComboBox->addItems(VALID_TASKS);
   QString welcomeText;
   this->SetGPUInfo();
   if (m_GpuLoader.GetGPUCount() != 0)
   {
     welcomeText = "<b>STATUS: </b><i>Welcome to TotalSegmentator tool. You're in luck: " +
                                QString::number(m_GpuLoader.GetGPUCount()) + " GPU(s) were detected.</i>";
   }
   else
   {
     welcomeText = "<b>STATUS: </b><i>Welcome to TotalSegmentator tool. Sorry, " +
                               QString::number(m_GpuLoader.GetGPUCount()) + " GPUs were detected.</i>";
   }
 
   connect(m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnPreviewBtnClicked()));
   connect(m_Controls.clearButton, SIGNAL(clicked()), this, SLOT(OnClearInstall()));
   connect(m_Controls.installButton, SIGNAL(clicked()), this, SLOT(OnInstallBtnClicked()));
   connect(m_Controls.overrideBox, SIGNAL(stateChanged(int)), this, SLOT(OnOverrideChecked(int)));
   connect(m_Controls.pythonEnvComboBox,
           QOverload<int>::of(&QComboBox::activated),
           [=](int index) { OnPythonPathChanged(m_Controls.pythonEnvComboBox->itemText(index)); });
   connect(m_Controls.sysPythonComboBox,
           QOverload<int>::of(&QComboBox::activated),
           [=](int index) { OnSystemPythonChanged(m_Controls.sysPythonComboBox->itemText(index)); });
 
   QString lastSelectedPyEnv = m_Settings.value("TotalSeg/LastCustomPythonPath").toString();
   if (!lastSelectedPyEnv.isEmpty() && lastSelectedPyEnv!= "Select")
   {
     m_Controls.pythonEnvComboBox->insertItem(0, lastSelectedPyEnv);
   }
   m_Controls.fastBox->setChecked(m_Settings.value("TotalSeg/LastFast").toBool());
   const QString storageDir = m_Installer.GetVirtualEnvPath();
   m_IsInstalled = this->IsTotalSegmentatorInstalled(storageDir);
   if (m_IsInstalled)
   {
     m_PythonPath = QmitkSetupVirtualEnvUtil::GetExactPythonPath(storageDir).first;
     m_Installer.SetVirtualEnvPath(m_PythonPath);
     this->EnableAll(m_IsInstalled);
     welcomeText += " TotalSegmentator is already found installed."; 
   }
   else
   {
     welcomeText += " TotalSegmentator is not installed. Please click on \"Install TotalSegmentator\" above.";
   }
   this->WriteStatusMessage(welcomeText);
 
   QIcon deleteIcon =
     QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/edit-delete.svg"));
   QIcon arrowIcon =
     QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg"));
   m_Controls.clearButton->setIcon(deleteIcon);
   m_Controls.previewButton->setIcon(arrowIcon);
 
   mainLayout->addLayout(m_Controls.verticalLayout);
   Superclass::InitializeUI(mainLayout);
 }
 
 void QmitkTotalSegmentatorToolGUI::SetGPUInfo()
 {
   std::vector<QmitkGPUSpec> specs = m_GpuLoader.GetAllGPUSpecs();
   for (const QmitkGPUSpec &gpuSpec : specs)
   {
     m_Controls.gpuComboBox->addItem(QString::number(gpuSpec.id) + ": " + gpuSpec.name + " (" + gpuSpec.memory + ")");
   }
   if (specs.empty())
   {
     m_Controls.gpuComboBox->setEditable(true);
     m_Controls.gpuComboBox->addItem(QString::number(0));
     m_Controls.gpuComboBox->setValidator(new QIntValidator(0, 999, this));
   }
 }
 
 unsigned int QmitkTotalSegmentatorToolGUI::FetchSelectedGPUFromUI() const
 {
   QString gpuInfo = m_Controls.gpuComboBox->currentText();
   if (m_GpuLoader.GetGPUCount() == 0)
   {
     return static_cast<unsigned int>(gpuInfo.toInt());
   }
   else
   {
     QString gpuId = gpuInfo.split(":", Qt::SkipEmptyParts).first();
     return static_cast<unsigned int>(gpuId.toInt());
   }
 }
 
 void QmitkTotalSegmentatorToolGUI::EnableAll(bool isEnable)
 {
   m_Controls.previewButton->setEnabled(isEnable);
   m_Controls.subtaskComboBox->setEnabled(isEnable);
   m_Controls.installButton->setEnabled((!isEnable));
 }
 
 void QmitkTotalSegmentatorToolGUI::OnInstallBtnClicked()
 {
   bool isInstalled = false;
   const auto [path, version] = OnSystemPythonChanged(m_Controls.sysPythonComboBox->currentText());
   if (path.isEmpty())
   {
     this->WriteErrorMessage("<b>ERROR: </b>Couldn't find compatible Python.");
     return;
   }
   // check if python 3.12 and ask for confirmation
   if (version.startsWith("3.12") &&
       QMessageBox::No == QMessageBox::question(
                           nullptr,
                           "Installing TotalSegmentator",
                           QString("WARNING: This is an unsupported version of Python that may not work. "
                                   "We recommend using a supported Python version between 3.9 and 3.11.\n\n"
                                   "Continue anyway?"),
                           QMessageBox::Yes | QMessageBox::No,
                           QMessageBox::No))
   {
     return;
   }
   this->WriteStatusMessage("<b>STATUS: </b>Installing TotalSegmentator...");
   m_Installer.SetSystemPythonPath(path);
   isInstalled = m_Installer.SetupVirtualEnv(m_Installer.VENV_NAME);
   if (isInstalled)
   {
     m_PythonPath = QmitkSetupVirtualEnvUtil::GetExactPythonPath(m_Installer.GetVirtualEnvPath()).first;
     this->WriteStatusMessage("<b>STATUS: </b>Successfully installed TotalSegmentator.");
   }
   else
   {
     this->WriteErrorMessage("<b>ERROR: </b>Couldn't install TotalSegmentator.");
   }
   this->EnableAll(isInstalled);
 }
 
 void QmitkTotalSegmentatorToolGUI::OnPreviewBtnClicked()
 {
   auto tool = this->GetConnectedToolAs<mitk::TotalSegmentatorTool>();
   if (nullptr == tool)
   {
     return;
   }
   try
   {
     m_Controls.previewButton->setEnabled(false);
     qApp->processEvents();
     if (!this->IsTotalSegmentatorInstalled(m_PythonPath))
     {
       throw std::runtime_error(WARNING_TOTALSEG_NOT_FOUND);
     }
     bool isFast = m_Controls.fastBox->isChecked();
     QString subTask = m_Controls.subtaskComboBox->currentText();
     if (subTask != VALID_TASKS[0])
     {
       isFast = true;
     }
     tool->SetPythonPath(m_PythonPath.toStdString());
     tool->SetGpuId(FetchSelectedGPUFromUI());
     tool->SetFast(isFast);
     tool->SetSubTask(subTask.toStdString());
     this->WriteStatusMessage(QString("<b>STATUS: </b><i>Starting Segmentation task... This might take a while.</i>"));
+    m_FirstPreviewComputation = false;
     tool->UpdatePreview();
     m_Controls.previewButton->setEnabled(true);
-    m_FirstPreviewComputation = false;
   }
   catch (const std::exception &e)
   {
     std::stringstream errorMsg;
     errorMsg << "<b>STATUS: </b>Error while processing parameters for TotalSegmentator segmentation. Reason: "
              << e.what();
     this->ShowErrorMessage(errorMsg.str());
     this->WriteErrorMessage(QString::fromStdString(errorMsg.str()));
     m_Controls.previewButton->setEnabled(true);
+    m_FirstPreviewComputation = true;
     return;
   }
   catch (...)
   {
     std::string errorMsg = "Unkown error occured while generation TotalSegmentator segmentation.";
     this->ShowErrorMessage(errorMsg);
     m_Controls.previewButton->setEnabled(true);
+    m_FirstPreviewComputation = true;
     return;
   }
   this->SetLabelSetPreview(tool->GetPreviewSegmentation());
   this->ActualizePreviewLabelVisibility();
   this->WriteStatusMessage("<b>STATUS: </b><i>Segmentation task finished successfully.</i>");
   QString pythonPathTextItem = m_Controls.pythonEnvComboBox->currentText();
   if (!pythonPathTextItem.isEmpty() && pythonPathTextItem != "Select") // only cache if the prediction ended without errors.
   {
     QString lastSelectedPyEnv = m_Settings.value("TotalSeg/LastCustomPythonPath").toString();
     if (lastSelectedPyEnv != pythonPathTextItem)
     {
       m_Settings.setValue("TotalSeg/LastCustomPythonPath", pythonPathTextItem);
     }
   }
   m_Settings.setValue("TotalSeg/LastFast", m_Controls.fastBox->isChecked());
 }
 
 void QmitkTotalSegmentatorToolGUI::ShowErrorMessage(const std::string &message, QMessageBox::Icon icon)
 {
   this->setCursor(Qt::ArrowCursor);
   QMessageBox *messageBox = new QMessageBox(icon, nullptr, message.c_str());
   messageBox->exec();
   delete messageBox;
   MITK_WARN << message;
 }
 
 void QmitkTotalSegmentatorToolGUI::WriteStatusMessage(const QString &message)
 {
   m_Controls.statusLabel->setText(message);
   m_Controls.statusLabel->setStyleSheet("font-weight: bold; color: white");
   qApp->processEvents();
 }
 
 void QmitkTotalSegmentatorToolGUI::WriteErrorMessage(const QString &message)
 {
   m_Controls.statusLabel->setText(message);
   m_Controls.statusLabel->setStyleSheet("font-weight: bold; color: red");
   qApp->processEvents();
 }
 
 bool QmitkTotalSegmentatorToolGUI::IsTotalSegmentatorInstalled(const QString &pythonPath)
 {
   QString fullPath = pythonPath;
   bool isPythonExists = false, isExists = false;
 #ifdef _WIN32
   isPythonExists = QFile::exists(fullPath + QDir::separator() + QString("python.exe"));
   if (!(fullPath.endsWith("Scripts", Qt::CaseInsensitive) || fullPath.endsWith("Scripts/", Qt::CaseInsensitive)))
   {
     fullPath += QDir::separator() + QString("Scripts");
     isPythonExists =
       (!isPythonExists) ? QFile::exists(fullPath + QDir::separator() + QString("python.exe")) : isPythonExists;
   }
   isExists = QFile::exists(fullPath + QDir::separator() + QString("TotalSegmentator.exe")) && isPythonExists;
 #else
   isPythonExists = QFile::exists(fullPath + QDir::separator() + QString("python3"));
   if (!(fullPath.endsWith("bin", Qt::CaseInsensitive) || fullPath.endsWith("bin/", Qt::CaseInsensitive)))
   {
     fullPath += QDir::separator() + QString("bin");
     isPythonExists =
       (!isPythonExists) ? QFile::exists(fullPath + QDir::separator() + QString("python3")) : isPythonExists;
   }
   isExists = QFile::exists(fullPath + QDir::separator() + QString("TotalSegmentator")) && isPythonExists;
 #endif
   return isExists;
 }
 
 void QmitkTotalSegmentatorToolGUI::AutoParsePythonPaths()
 {
   QString homeDir = QDir::homePath();
   std::vector<QString> searchDirs;
 #ifdef _WIN32
   searchDirs.push_back(QString("C:") + QDir::separator() + QString("ProgramData") + QDir::separator() +
                        QString("anaconda3"));
 #else
   // Add search locations for possible standard python paths here
   searchDirs.push_back(homeDir + QDir::separator() + "environments");
   searchDirs.push_back(homeDir + QDir::separator() + "anaconda3");
   searchDirs.push_back(homeDir + QDir::separator() + "miniconda3");
   searchDirs.push_back(homeDir + QDir::separator() + "opt" + QDir::separator() + "miniconda3");
   searchDirs.push_back(homeDir + QDir::separator() + "opt" + QDir::separator() + "anaconda3");
 #endif
   for (QString searchDir : searchDirs)
   {
     if (searchDir.endsWith("anaconda3", Qt::CaseInsensitive))
     {
       if (QDir(searchDir).exists())
       {
         m_Controls.sysPythonComboBox->addItem("(base): " + searchDir);
         searchDir.append((QDir::separator() + QString("envs")));
       }
     }
     for (QDirIterator subIt(searchDir, QDir::AllDirs, QDirIterator::NoIteratorFlags); subIt.hasNext();)
     {
       subIt.next();
       QString envName = subIt.fileName();
       if (!envName.startsWith('.')) // Filter out irrelevent hidden folders, if any.
       {
         m_Controls.pythonEnvComboBox->addItem("(" + envName + "): " + subIt.filePath());
       }
     }
   }
 }
 
 std::pair<QString, QString> QmitkTotalSegmentatorToolGUI::OnSystemPythonChanged(const QString &pyEnv)
 {
   std::pair<QString, QString> pyPath;
   if (pyEnv == QString("Select"))
   {
     m_Controls.previewButton->setDisabled(true);
     QString path =
       QFileDialog::getExistingDirectory(m_Controls.sysPythonComboBox->parentWidget(), "Python Path", "dir");
     if (!path.isEmpty())
     {
       this->OnSystemPythonChanged(path);                                // recall same function for new path validation
       bool oldState = m_Controls.sysPythonComboBox->blockSignals(true); // block signal firing while inserting item
       m_Controls.sysPythonComboBox->insertItem(0, path);
       m_Controls.sysPythonComboBox->setCurrentIndex(0);
       m_Controls.sysPythonComboBox->blockSignals(
         oldState); // unblock signal firing after inserting item. Remove this after Qt6 migration
     }
   }
   else
   { 
     QString uiPyPath = this->GetPythonPathFromUI(pyEnv);
     pyPath = QmitkSetupVirtualEnvUtil::GetExactPythonPath(uiPyPath);
   }
   return pyPath;
 }
 
 void QmitkTotalSegmentatorToolGUI::OnPythonPathChanged(const QString &pyEnv)
 {
   if (pyEnv == QString("Select"))
   {
     m_Controls.previewButton->setDisabled(true);
     QString path =
       QFileDialog::getExistingDirectory(m_Controls.pythonEnvComboBox->parentWidget(), "Python Path", "dir");
     if (!path.isEmpty())
     {
       this->OnPythonPathChanged(path);                                  // recall same function for new path validation
       bool oldState = m_Controls.pythonEnvComboBox->blockSignals(true); // block signal firing while inserting item
       m_Controls.pythonEnvComboBox->insertItem(0, path);
       m_Controls.pythonEnvComboBox->setCurrentIndex(0);
       m_Controls.pythonEnvComboBox->blockSignals(
         oldState); // unblock signal firing after inserting item. Remove this after Qt6 migration
     }
   }
   else if (!this->IsTotalSegmentatorInstalled(this->GetPythonPathFromUI(pyEnv)))
   {
     this->ShowErrorMessage(WARNING_TOTALSEG_NOT_FOUND);
     m_Controls.previewButton->setDisabled(true);
   }
   else
   {// Show positive status meeage
     m_Controls.previewButton->setDisabled(false);
     QString uiPyPath = this->GetPythonPathFromUI(pyEnv);
     m_PythonPath = QmitkSetupVirtualEnvUtil::GetExactPythonPath(uiPyPath).first;
   }
 }
 
 QString QmitkTotalSegmentatorToolGUI::GetPythonPathFromUI(const QString &pyUI) const
 {
   QString fullPath = pyUI;
   if (-1 != fullPath.indexOf(")"))
   {
     fullPath = fullPath.mid(fullPath.indexOf(")") + 2);
   }
   return fullPath.simplified();
 }
 
 void QmitkTotalSegmentatorToolGUI::OnOverrideChecked(int state)
 {
   bool isEnabled = false;
   if (state == Qt::Checked)
   {
     isEnabled = true;
     m_Controls.previewButton->setDisabled(true);
     m_PythonPath.clear();
   }
   else
   {
     m_PythonPath.clear();
     m_Controls.previewButton->setDisabled(true);
     if (m_IsInstalled)
     {
       const QString pythonPath = m_Installer.GetVirtualEnvPath();
       auto pathObject = QmitkSetupVirtualEnvUtil::GetExactPythonPath(pythonPath);
       m_PythonPath = pathObject.first;
       this->EnableAll(m_IsInstalled);
     }
   }
   m_Controls.pythonEnvComboBox->setEnabled(isEnabled);
 }
 
 void QmitkTotalSegmentatorToolGUI::OnClearInstall()
 {
   QDir folderPath(m_Installer.GetVirtualEnvPath());
   if (folderPath.removeRecursively())
   {
     m_Controls.installButton->setEnabled(true);
     m_IsInstalled = false;
     if (!m_Controls.overrideBox->isChecked())
     {
       m_Controls.previewButton->setEnabled(false);
     }
   }
   else
   {
     MITK_ERROR
       << "The virtual environment couldn't be removed. Please check if you have the required access privileges or, some other process is accessing the folders.";
   }
 }
 
 bool QmitkTotalSegmentatorToolInstaller::SetupVirtualEnv(const QString& venvName)
 {
   if (GetSystemPythonPath().isEmpty())
   {
     return false;
   }
   QDir folderPath(GetBaseDir());
   folderPath.mkdir(venvName);
   if (!folderPath.cd(venvName))
   {
     return false; // Check if directory creation was successful.
   }
   mitk::ProcessExecutor::ArgumentListType args;
   auto spExec = mitk::ProcessExecutor::New();
   auto spCommand = itk::CStyleCommand::New();
   spCommand->SetCallback(&PrintProcessEvent);
   spExec->AddObserver(mitk::ExternalProcessOutputEvent(), spCommand);
 
   args.push_back("-m");
   args.push_back("venv");
   args.push_back(venvName.toStdString());
 #ifdef _WIN32
   QString pythonFile = GetSystemPythonPath() + QDir::separator() + "python.exe";
   QString pythonExeFolder = "Scripts";
 #else
   QString pythonFile = GetSystemPythonPath() + QDir::separator() + "python3";
   QString pythonExeFolder = "bin";
 #endif
   spExec->Execute(GetBaseDir().toStdString(), pythonFile.toStdString(), args); // Setup local virtual environment
   if (folderPath.cd(pythonExeFolder))
   {
     this->SetPythonPath(folderPath.absolutePath());
     this->SetPipPath(folderPath.absolutePath());
     this->InstallPytorch();
     for (auto &package : PACKAGES)
     {
       this->PipInstall(package.toStdString(), &PrintProcessEvent);
     }
     std::string pythonCode; // python syntax to check if torch is installed with CUDA.
     pythonCode.append("import torch;");
     pythonCode.append("print('Pytorch was installed with CUDA') if torch.cuda.is_available() else print('PyTorch was "
                       "installed WITHOUT CUDA');");
     this->ExecutePython(pythonCode, &PrintProcessEvent);
     return true;
   }
   return false;
 }
 
 QString QmitkTotalSegmentatorToolInstaller::GetVirtualEnvPath() 
 {
   return STORAGE_DIR + VENV_NAME;
 }
diff --git a/Modules/SegmentationUI/Qmitk/QmitknnUNetToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitknnUNetToolGUI.cpp
index b39262f9ad..d69d23064b 100644
--- a/Modules/SegmentationUI/Qmitk/QmitknnUNetToolGUI.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitknnUNetToolGUI.cpp
@@ -1,1197 +1,1200 @@
 /*============================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center (DKFZ)
 All rights reserved.
 
 Use of this source code is governed by a 3-clause BSD license that can be
 found in the LICENSE file.
 
 ============================================================================*/
 
 #include "QmitknnUNetToolGUI.h"
 
 #include "mitkProcessExecutor.h"
 #include "mitknnUnetTool.h"
 #include <mitkTimeNavigationController.h>
 #include <QApplication>
 #include <QDir>
 #include <QDirIterator>
 #include <QIcon>
 #include <QmitkStyleManager.h>
 #include <QmitknnUNetEnsembleLayout.h>
 #include <QtGlobal>
 #include <algorithm>
 #include <ctkCollapsibleGroupBox.h>
 #include <itksys/SystemTools.hxx>
 #include <nlohmann/json.hpp>
 #include <mitkIOUtil.h>
 
 MITK_TOOL_GUI_MACRO(MITKSEGMENTATIONUI_EXPORT, QmitknnUNetToolGUI, "")
 
 QmitknnUNetToolGUI::QmitknnUNetToolGUI() : QmitkMultiLabelSegWithPreviewToolGUIBase(), m_SuperclassEnableConfirmSegBtnFnc(m_EnableConfirmSegBtnFnc)
 {
   // Nvidia-smi command returning zero doesn't always imply lack of GPUs.
   // Pytorch uses its own libraries to communicate to the GPUs. Hence, only a warning can be given.
   if (m_GpuLoader.GetGPUCount() == 0)
   {
     std::string warning = "WARNING: No GPUs were detected on your machine. The nnUNet tool might not work.";
     this->ShowErrorMessage(warning);
   }
 
   // define predicates for multi modal data selection combobox
   auto imageType = mitk::TNodePredicateDataType<mitk::Image>::New();
   auto labelSetImageType = mitk::NodePredicateNot::New(mitk::TNodePredicateDataType<mitk::LabelSetImage>::New());
   m_MultiModalPredicate = mitk::NodePredicateAnd::New(imageType, labelSetImageType).GetPointer();
 
   m_nnUNetThread = new QThread(this);
   m_Worker = new nnUNetDownloadWorker;
   m_Worker->moveToThread(m_nnUNetThread);
   
   m_EnableConfirmSegBtnFnc = [this](bool enabled)
   {
     return !m_FirstPreviewComputation ? m_SuperclassEnableConfirmSegBtnFnc(enabled) : false;
   };
 }
 
 QmitknnUNetToolGUI::~QmitknnUNetToolGUI()
 {
   m_nnUNetThread->quit();
   m_nnUNetThread->wait();
 }
 
 void QmitknnUNetToolGUI::ConnectNewTool(mitk::SegWithPreviewTool *newTool)
 {
   Superclass::ConnectNewTool(newTool);
   newTool->IsTimePointChangeAwareOff();
   m_FirstPreviewComputation = true;
 }
 
 void QmitknnUNetToolGUI::InitializeUI(QBoxLayout *mainLayout)
 {
   m_Controls.setupUi(this);
 #ifndef _WIN32
   m_Controls.pythonEnvComboBox->addItem("/usr/bin");
 #endif
   m_Controls.pythonEnvComboBox->addItem("Select");
   AutoParsePythonPaths();
   SetGPUInfo();
   connect(m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnPreviewRequested()));
   connect(m_Controls.modeldirectoryBox,
           SIGNAL(directoryChanged(const QString &)),
           this,
           SLOT(OnDirectoryChanged(const QString &)));
   connect(
     m_Controls.modelBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnModelChanged(const QString &)));
   connect(m_Controls.taskBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnTaskChanged(const QString &)));
   connect(
     m_Controls.plannerBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnTrainerChanged(const QString &)));
   connect(m_Controls.multiModalBox, SIGNAL(stateChanged(int)), this, SLOT(OnCheckBoxChanged(int)));
   connect(m_Controls.pythonEnvComboBox,
 #if QT_VERSION >= 0x050F00 // 5.15
           SIGNAL(textActivated(const QString &)),
 #elif QT_VERSION >= 0x050C00 // 5.12
           SIGNAL(currentTextChanged(const QString &)),
 #endif
           this,
           SLOT(OnPythonPathChanged(const QString &)));
   connect(m_Controls.refreshdirectoryBox, SIGNAL(clicked()), this, SLOT(OnRefreshPresssed()));
   connect(m_Controls.clearCacheButton, SIGNAL(clicked()), this, SLOT(OnClearCachePressed()));
   connect(m_Controls.startDownloadButton, SIGNAL(clicked()), this, SLOT(OnDownloadModel()));
   connect(m_Controls.stopDownloadButton, SIGNAL(clicked()), this, SLOT(OnStopDownload()));
 
   // Qthreads
   qRegisterMetaType<mitk::ProcessExecutor::Pointer>();
   qRegisterMetaType<mitk::ProcessExecutor::ArgumentListType>();
   connect(this, &QmitknnUNetToolGUI::Operate, m_Worker, &nnUNetDownloadWorker::DoWork);
   connect(m_Worker, &nnUNetDownloadWorker::Exit, this, &QmitknnUNetToolGUI::OnDownloadWorkerExit);
   connect(m_nnUNetThread, &QThread::finished, m_Worker, &QObject::deleteLater);
 
   m_Controls.multiModalValueLabel->setStyleSheet("font-weight: bold; color: white");
   m_Controls.multiModalValueLabel->setVisible(false);
   m_Controls.requiredModalitiesLabel->setVisible(false);
   m_Controls.stopDownloadButton->setVisible(false);
   m_Controls.previewButton->setEnabled(false);
 
   QIcon refreshIcon =
     QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/view-refresh.svg"));
   m_Controls.refreshdirectoryBox->setIcon(refreshIcon);
   QIcon dirIcon =
     QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg"));
   m_Controls.modeldirectoryBox->setIcon(dirIcon);
   m_Controls.refreshdirectoryBox->setEnabled(true);
   QIcon stopIcon =
     QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/status/dialog-error.svg"));
   m_Controls.stopDownloadButton->setIcon(stopIcon);
 
   m_Controls.statusLabel->setTextFormat(Qt::RichText);
   if (m_GpuLoader.GetGPUCount() != 0)
   {
     WriteStatusMessage(QString("<b>STATUS: </b><i>Welcome to nnUNet. " + QString::number(m_GpuLoader.GetGPUCount()) +
                                " GPUs were detected.</i>"));
   }
   else
   {
     WriteErrorMessage(QString("<b>STATUS: </b><i>Welcome to nnUNet. " + QString::number(m_GpuLoader.GetGPUCount()) +
                               " GPUs were detected.</i>"));
   }
   mainLayout->addLayout(m_Controls.verticalLayout);
   Superclass::InitializeUI(mainLayout);
   m_UI_ROWS = m_Controls.advancedSettingsLayout->rowCount(); // Must do. Row count is correct only here.
   this->DisableEverything();
   QString lastSelectedPyEnv = m_Settings.value("nnUNet/LastPythonPath").toString();
   m_Controls.pythonEnvComboBox->setCurrentText(lastSelectedPyEnv);
 }
 
 void QmitknnUNetToolGUI::EnableWidgets(bool enabled)
 {
   Superclass::EnableWidgets(enabled);
 }
 
 void QmitknnUNetToolGUI::ClearAllModalities()
 {
   m_Controls.multiModalBox->setChecked(false);
   this->ClearAllModalLabels();
 }
 
 void QmitknnUNetToolGUI::ClearAllModalLabels()
 {
   for (auto modalLabel : m_ModalLabels)
   {
     delete modalLabel; // delete the layout item
     m_ModalLabels.pop_back();
   }
   m_Controls.advancedSettingsLayout->update();
 }
 
 void QmitknnUNetToolGUI::DisableEverything()
 {
   m_Controls.modeldirectoryBox->setEnabled(false);
   m_Controls.refreshdirectoryBox->setEnabled(false);
   m_Controls.previewButton->setEnabled(false);
   m_Controls.multiModalValueLabel->setVisible(false);
   m_Controls.multiModalBox->setEnabled(false);
   this->ClearAllComboBoxes();
   this->ClearAllModalities();
 }
 
 void QmitknnUNetToolGUI::ClearAllComboBoxes()
 {
   m_Controls.modelBox->clear();
   m_Controls.taskBox->clear();
   m_Controls.foldBox->clear();
   m_Controls.trainerBox->clear();
   m_Controls.plannerBox->clear();
   for (auto &layout : m_EnsembleParams)
   {
     layout->modelBox->clear();
     layout->trainerBox->clear();
     layout->plannerBox->clear();
     layout->foldBox->clear();
   }
 }
 
 std::vector<mitk::Image::ConstPointer> QmitknnUNetToolGUI::FetchMultiModalImagesFromUI()
 {
   std::vector<mitk::Image::ConstPointer> modals;
   if (m_Controls.multiModalBox->isChecked() && !m_Modalities.empty())
   {
     std::set<std::string> nodeNames; // set container for keeping names of all nodes to check if they are added twice.
     for (QmitkSingleNodeSelectionWidget *modality : m_Modalities)
     { 
       mitk::DataNode::Pointer node = modality->GetSelectedNode();
       if (nodeNames.find(node->GetName()) == nodeNames.end())
       {
         modals.push_back(dynamic_cast<const mitk::Image *>(node->GetData()));
         nodeNames.insert(node->GetName());
       }
       else
       {
         throw std::runtime_error("Same modality is selected more than once. Please change your selection.");
         break;
       }
     }
   }
   return modals;
 }
 
 bool QmitknnUNetToolGUI::IsNNUNetInstalled(const QString &pythonPath)
 {
   QString fullPath = pythonPath;
 #ifdef _WIN32
   if (!(fullPath.endsWith("Scripts", Qt::CaseInsensitive) || fullPath.endsWith("Scripts/", Qt::CaseInsensitive)))
   {
     fullPath += QDir::separator() + QString("Scripts");
   }
 #else
   if (!(fullPath.endsWith("bin", Qt::CaseInsensitive) || fullPath.endsWith("bin/", Qt::CaseInsensitive)))
   {
     fullPath += QDir::separator() + QString("bin");
   }
 #endif
   fullPath = fullPath.mid(fullPath.indexOf(" ") + 1);
   bool isExists = QFile::exists(fullPath + QDir::separator() + QString("nnUNet_predict")) &&
                   QFile::exists(fullPath + QDir::separator() + QString("python3"));
   return isExists;
 }
 
 void QmitknnUNetToolGUI::ShowErrorMessage(const std::string &message, QMessageBox::Icon icon)
 {
   this->setCursor(Qt::ArrowCursor);
   QMessageBox *messageBox = new QMessageBox(icon, nullptr, message.c_str());
   messageBox->exec();
   delete messageBox;
   MITK_WARN << message;
 }
 
 void QmitknnUNetToolGUI::WriteStatusMessage(const QString &message)
 {
   m_Controls.statusLabel->setText(message);
   m_Controls.statusLabel->setStyleSheet("font-weight: bold; color: white");
 }
 
 void QmitknnUNetToolGUI::WriteErrorMessage(const QString &message)
 {
   m_Controls.statusLabel->setText(message);
   m_Controls.statusLabel->setStyleSheet("font-weight: bold; color: red");
 }
 
 void QmitknnUNetToolGUI::ProcessEnsembleModelsParams(mitk::nnUNetTool::Pointer tool)
 {
   if (m_EnsembleParams[0]->modelBox->currentText() == m_EnsembleParams[1]->modelBox->currentText())
   {
     throw std::runtime_error("Both models you have selected for ensembling are the same.");
   }
   QString taskName = m_Controls.taskBox->currentText();
   bool isPPJson = m_Controls.postProcessingCheckBox->isChecked();
   std::vector<mitk::ModelParams> requestQ;
   QString ppDirFolderNamePart1 = "ensemble_";
   QStringList ppDirFolderNameParts;
   for (auto &layout : m_EnsembleParams)
   {
     QStringList ppDirFolderName;
     QString modelName = layout->modelBox->currentText();
     ppDirFolderName << modelName;
     ppDirFolderName << "__";
     QString trainer = layout->trainerBox->currentText();
     ppDirFolderName << trainer;
     ppDirFolderName << "__";
     QString planId = layout->plannerBox->currentText();
     ppDirFolderName << planId;
 
     if (!this->IsModelExists(modelName, taskName, QString(trainer + "__" + planId)))
     {
       std::string errorMsg = "The configuration " + modelName.toStdString() +
                              " you have selected doesn't exist. Check your Results Folder again.";
       throw std::runtime_error(errorMsg);
     }
     std::vector<std::string> testfold = FetchSelectedFoldsFromUI(layout->foldBox);
     mitk::ModelParams modelObject = MapToRequest(modelName, taskName, trainer, planId, testfold);
     requestQ.push_back(modelObject);
     ppDirFolderNameParts << ppDirFolderName.join(QString(""));
   }
   tool->EnsembleOn();
   if (isPPJson)
   {
     QString ppJsonFilePossibility1 = QDir::cleanPath(
       m_ParentFolder->getResultsFolder() + QDir::separator() + "nnUNet" + QDir::separator() + "ensembles" +
       QDir::separator() + taskName + QDir::separator() + ppDirFolderNamePart1 + ppDirFolderNameParts.first() + "--" +
       ppDirFolderNameParts.last() + QDir::separator() + "postprocessing.json");
     QString ppJsonFilePossibility2 = QDir::cleanPath(
       m_ParentFolder->getResultsFolder() + QDir::separator() + "nnUNet" + QDir::separator() + "ensembles" +
       QDir::separator() + taskName + QDir::separator() + ppDirFolderNamePart1 + ppDirFolderNameParts.last() + "--" +
       ppDirFolderNameParts.first() + QDir::separator() + "postprocessing.json");
 
     if (QFile(ppJsonFilePossibility1).exists())
     {
       tool->SetPostProcessingJsonDirectory(ppJsonFilePossibility1.toStdString());
       const QString statusMsg = "<i>Post Processing JSON file found: </i>" + ppJsonFilePossibility1;
       this->WriteStatusMessage(statusMsg);
     }
     else if (QFile(ppJsonFilePossibility2).exists())
     {
       tool->SetPostProcessingJsonDirectory(ppJsonFilePossibility2.toStdString());
       const QString statusMsg = "<i>Post Processing JSON file found:</i>" + ppJsonFilePossibility2;
       this->WriteStatusMessage(statusMsg);
     }
     else
     {
       std::string errorMsg =
         "No post processing file was found for the selected ensemble combination. Continuing anyway...";
       this->ShowErrorMessage(errorMsg);
     }
   }
   tool->m_ParamQ.clear();
   tool->m_ParamQ = requestQ;
 }
 
 void QmitknnUNetToolGUI::ProcessModelParams(mitk::nnUNetTool::Pointer tool)
 {
   tool->EnsembleOff();
   std::vector<mitk::ModelParams> requestQ;
   QString modelName = m_Controls.modelBox->currentText();
   QString taskName = m_Controls.taskBox->currentText();
   QString trainer = m_Controls.trainerBox->currentText();
   QString planId = m_Controls.plannerBox->currentText();
   std::vector<std::string> fetchedFolds = this->FetchSelectedFoldsFromUI(m_Controls.foldBox);
   mitk::ModelParams modelObject = MapToRequest(modelName, taskName, trainer, planId, fetchedFolds);
   requestQ.push_back(modelObject);
   tool->m_ParamQ.clear();
   tool->m_ParamQ = requestQ;
 }
 
 bool QmitknnUNetToolGUI::IsModelExists(const QString &modelName, const QString &taskName, const QString &trainerPlanner)
 {
   QString modelSearchPath =
     QDir::cleanPath(m_ParentFolder->getResultsFolder() + QDir::separator() + "nnUNet" + QDir::separator() + modelName +
                     QDir::separator() + taskName + QDir::separator() + trainerPlanner);
   if (QDir(modelSearchPath).exists())
   {
     return true;
   }
   return false;
 }
 
 void QmitknnUNetToolGUI::CheckAllInCheckableComboBox(ctkCheckableComboBox *foldBox)
 {
   // Recalling all added items to check-mark it.
   const QAbstractItemModel *qaim = foldBox->checkableModel();
   auto rows = qaim->rowCount();
   for (std::remove_const_t<decltype(rows)> i = 0; i < rows; ++i)
   {
     const QModelIndex mi = qaim->index(i, 0);
     foldBox->setCheckState(mi, Qt::Checked);
   }
 }
 
 std::pair<QStringList, QStringList> QmitknnUNetToolGUI::ExtractTrainerPlannerFromString(QStringList trainerPlanners)
 {
   QString splitterString = "__";
   QStringList trainers, planners;
   for (const auto &trainerPlanner : trainerPlanners)
   {
     trainers << trainerPlanner.split(splitterString, Qt::SkipEmptyParts).first();
     planners << trainerPlanner.split(splitterString, Qt::SkipEmptyParts).last();
   }
   trainers.removeDuplicates();
   planners.removeDuplicates();
   return std::make_pair(trainers, planners);
 }
 
 std::vector<std::string> QmitknnUNetToolGUI::FetchSelectedFoldsFromUI(ctkCheckableComboBox *foldBox)
 {
   std::vector<std::string> folds;
   if (foldBox->noneChecked())
   {
     this->CheckAllInCheckableComboBox(foldBox);
   }
   QModelIndexList foldList = foldBox->checkedIndexes();
   for (const auto &index : foldList)
   {
     QString foldQString = foldBox->itemText(index.row());
     if(foldQString != "dummy_element_that_nobody_can_see")
     {
     foldQString = foldQString.split("_", Qt::SkipEmptyParts).last();
     folds.push_back(foldQString.toStdString());
     }
     else
     {
       throw std::runtime_error("Folds are not recognized. Please check if your nnUNet results folder structure is legitimate");
     }
   }
   return folds;
 }
 
 void QmitknnUNetToolGUI::UpdateCacheCountOnUI()
 {
   QString cacheText = m_CACHE_COUNT_BASE_LABEL + QString::number(m_Cache.size());
   m_Controls.cacheCountLabel->setText(cacheText);
 }
 
 void QmitknnUNetToolGUI::AddToCache(size_t &hashKey, mitk::LabelSetImage::ConstPointer mlPreview)
 {
   nnUNetCache *newCacheObj = new nnUNetCache;
   newCacheObj->m_SegCache = mlPreview;
   m_Cache.insert(hashKey, newCacheObj);
   MITK_INFO << "New hash: " << hashKey << " " << newCacheObj->m_SegCache.GetPointer();
   this->UpdateCacheCountOnUI();
 }
 
 void QmitknnUNetToolGUI::SetGPUInfo()
 {
   std::vector<QmitkGPUSpec> specs = m_GpuLoader.GetAllGPUSpecs();
   for (const QmitkGPUSpec &gpuSpec : specs)
   {
     m_Controls.gpuComboBox->addItem(QString::number(gpuSpec.id) + ": " + gpuSpec.name + " (" + gpuSpec.memory + ")");
   }
   if (specs.empty())
   {
     m_Controls.gpuComboBox->setEditable(true);
     m_Controls.gpuComboBox->addItem(QString::number(0));
     m_Controls.gpuComboBox->setValidator(new QIntValidator(0, 999, this));
   }
 }
 
 unsigned int QmitknnUNetToolGUI::FetchSelectedGPUFromUI()
 {
   QString gpuInfo = m_Controls.gpuComboBox->currentText();
   if (m_GpuLoader.GetGPUCount() == 0)
   {
     return static_cast<unsigned int>(gpuInfo.toInt());
   }
   else
   {
     QString gpuId = gpuInfo.split(":", Qt::SkipEmptyParts).first();
     return static_cast<unsigned int>(gpuId.toInt());
   }
 }
 
 QString QmitknnUNetToolGUI::FetchResultsFolderFromEnv()
 {
   const char *pathVal = itksys::SystemTools::GetEnv("RESULTS_FOLDER");
   QString retVal;
   if (pathVal)
   {
     retVal = QString::fromUtf8(pathVal);
   }
   else
   {
     retVal = m_Settings.value("nnUNet/LastRESULTS_FOLDERPath").toString();
   }
   return retVal;
 }
 
 void QmitknnUNetToolGUI::DumpJSONfromPickle(const QString &picklePath)
 {
   const QString pickleFile = picklePath + QDir::separator() + m_PICKLE_FILENAME;
   const QString jsonFile = picklePath + QDir::separator() + m_MITK_EXPORT_JSON_FILENAME;
   if (!QFile::exists(jsonFile))
   {
     mitk::ProcessExecutor::Pointer spExec = mitk::ProcessExecutor::New();
     mitk::ProcessExecutor::ArgumentListType args;
     args.push_back("-c");
     std::string pythonCode; // python syntax to parse plans.pkl file and export as Json file.
     pythonCode.append("import pickle;");
     pythonCode.append("import json;");
     pythonCode.append("loaded_pickle = pickle.load(open('");
     pythonCode.append(pickleFile.toStdString());
     pythonCode.append("','rb'));");
     pythonCode.append("modal_dict = {key: loaded_pickle[key] for key in loaded_pickle.keys() if key in "
                       "['modalities','num_modalities']};");
     pythonCode.append("json.dump(modal_dict, open('");
     pythonCode.append(jsonFile.toStdString());
     pythonCode.append("', 'w'))");
 
     args.push_back(pythonCode);
     try
     {
       spExec->Execute(m_PythonPath.toStdString(), "python3", args);
     }
     catch (const mitk::Exception &e)
     {
       MITK_ERROR << "Pickle parsing FAILED!" << e.GetDescription();
       this->WriteStatusMessage(
         "Parsing failed in backend. Multiple Modalities will now have to be manually entered by the user.");
     }
   }
 }
 
 void QmitknnUNetToolGUI::ExportAvailableModelsAsJSON(const QString &resultsFolder)
 {
   const QString jsonPath = resultsFolder + QDir::separator() + m_AVAILABLE_MODELS_JSON_FILENAME;
   if (!QFile::exists(jsonPath))
   {
     auto spExec = mitk::ProcessExecutor::New();
     mitk::ProcessExecutor::ArgumentListType args;
     args.push_back("--export");
     args.push_back(resultsFolder.toStdString());
     try
     {
       spExec->Execute(m_PythonPath.toStdString(), "nnUNet_print_available_pretrained_models", args);
     }
     catch (const mitk::Exception &e)
     {
       MITK_ERROR << "Exporting information FAILED." << e.GetDescription();
       this->WriteStatusMessage("Exporting information FAILED.");
     }
   }
 }
 
 void QmitknnUNetToolGUI::DisplayMultiModalInfoFromJSON(const QString &jsonPath)
 {
   std::ifstream file(jsonPath.toStdString());
   if (file.is_open())
   {
     auto jsonObj = nlohmann::json::parse(file, nullptr, false);
     if (jsonObj.is_discarded() || !jsonObj.is_object())
     {
       MITK_ERROR << "Could not parse \"" << jsonPath.toStdString() << "\" as JSON object!";
       return;
     }
     auto num_mods = jsonObj["num_modalities"].get<int>();
     this->ClearAllModalLabels();
     if (num_mods > 1)
     {
       m_Controls.multiModalBox->setChecked(true);
       m_Controls.multiModalBox->setEnabled(false);
       m_Controls.multiModalValueLabel->setText(QString::number(num_mods));
       OnModalitiesNumberChanged(num_mods);
       m_Controls.advancedSettingsLayout->update();
       auto obj = jsonObj["modalities"];
       int count = 0;
       for (const auto &value : obj)
       {
         QLabel *label = new QLabel(QString::fromStdString("<i>" + value.get<std::string>() + "</i>"), this);
         m_ModalLabels.push_back(label);
         m_Controls.advancedSettingsLayout->addWidget(label, m_UI_ROWS + 1 + count, 0);
         count++;
       }
       m_Controls.advancedSettingsLayout->update();
     }
     else
     {
       m_Controls.multiModalBox->setChecked(false);
     }
   }
 }
 
 void QmitknnUNetToolGUI::FillAvailableModelsInfoFromJSON(const QString &jsonPath)
 {
   std::ifstream file(jsonPath.toStdString());
   if (file.is_open() && m_Controls.availableBox->count() < 1)
   {
     auto jsonObj = nlohmann::json::parse(file, nullptr, false);
     if (jsonObj.is_discarded() || !jsonObj.is_object())
     {
       MITK_ERROR << "Could not parse \"" << jsonPath.toStdString() << "\" as JSON object!";
       return;
     }
     for (const auto &obj : jsonObj.items())
     {
       m_Controls.availableBox->addItem(QString::fromStdString(obj.key()));
     }
   }
 }
 
 mitk::ModelParams QmitknnUNetToolGUI::MapToRequest(const QString &modelName,
                                                    const QString &taskName,
                                                    const QString &trainer,
                                                    const QString &planId,
                                                    const std::vector<std::string> &folds)
 {
   mitk::ModelParams requestObject;
   requestObject.model = modelName.toStdString();
   requestObject.trainer = trainer.toStdString();
   requestObject.planId = planId.toStdString();
   requestObject.task = taskName.toStdString();
   requestObject.folds = folds;
   mitk::nnUNetTool::Pointer tool = this->GetConnectedToolAs<mitk::nnUNetTool>();
   requestObject.inputName = tool->GetRefNode()->GetName();
   requestObject.timeStamp =
     std::to_string(mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint());
   return requestObject;
 }
 
 void QmitknnUNetToolGUI::SetComboBoxToNone(ctkCheckableComboBox* comboBox)
 {
   comboBox->clear();
   comboBox->addItem("dummy_element_that_nobody_can_see");
   qobject_cast<QListView *>(comboBox->view())->setRowHidden(0, true); // For the cosmetic purpose of showing "None" on the combobox.
 }
 
 /* ---------------------SLOTS---------------------------------------*/
 
 void QmitknnUNetToolGUI::OnPreviewRequested()
 {
   mitk::nnUNetTool::Pointer tool = this->GetConnectedToolAs<mitk::nnUNetTool>();
   if (nullptr != tool)
   {
     QString pythonPathTextItem = "";
     try
     {
       size_t hashKey(0);
       m_Controls.previewButton->setEnabled(false); // To prevent misclicked back2back prediction.
       qApp->processEvents();
       tool->PredictOn(); // purposefully placed to make tool->GetMTime different than before.
       QString modelName = m_Controls.modelBox->currentText();
       if (modelName.startsWith("ensemble", Qt::CaseInsensitive))
       {
         this->ProcessEnsembleModelsParams(tool);
       }
       else
       {
         this->ProcessModelParams(tool);
       }
       pythonPathTextItem = m_Controls.pythonEnvComboBox->currentText();
       QString pythonPath = m_PythonPath;
       if (!this->IsNNUNetInstalled(pythonPath))
       {
         throw std::runtime_error("nnUNet is not detected in the selected python environment. Please select a valid "
                                  "python environment or install nnUNet.");
       }
       tool->SetPythonPath(pythonPath.toStdString());
       tool->SetModelDirectory(m_ParentFolder->getResultsFolder().toStdString());
       // checkboxes
       tool->SetMirror(m_Controls.mirrorBox->isChecked());
       tool->SetMixedPrecision(m_Controls.mixedPrecisionBox->isChecked());
       tool->SetNoPip(false);
       bool doCache = m_Controls.enableCachingCheckBox->isChecked();
       // Spinboxes
       tool->SetGpuId(FetchSelectedGPUFromUI());
       // Multi-Modal
       tool->MultiModalOff();
       if (m_Controls.multiModalBox->isChecked())
       {
         tool->m_OtherModalPaths.clear();
         tool->m_OtherModalPaths = FetchMultiModalImagesFromUI();
         tool->MultiModalOn();
       }
       if (doCache)
       {
         hashKey = nnUNetCache::GetUniqueHash(tool->m_ParamQ);
         if (m_Cache.contains(hashKey))
         {
           tool->PredictOff(); // purposefully placed to make tool->GetMTime different than before.
         }
       }
       if (tool->GetPredict())
       {
         tool->m_InputBuffer = nullptr;
         this->WriteStatusMessage(
           QString("<b>STATUS: </b><i>Starting Segmentation task... This might take a while.</i>"));
+        m_FirstPreviewComputation = false;
         tool->UpdatePreview();
         if (nullptr == tool->GetOutputBuffer())
         {
           this->SegmentationProcessFailed();
         }
         else
         {
           this->SegmentationResultHandler(tool);
           if (doCache)
           {
             this->AddToCache(hashKey, tool->GetOutputBuffer());
           }
           tool->ClearOutputBuffer();
         }
         tool->PredictOff(); // purposefully placed to make tool->GetMTime different than before.
       }
       else
       {
         MITK_INFO << "won't do segmentation. Key found: " << QString::number(hashKey).toStdString();
         if (m_Cache.contains(hashKey))
         {
           nnUNetCache *cacheObject = m_Cache[hashKey];
           MITK_INFO << "fetched pointer " << cacheObject->m_SegCache.GetPointer();
           tool->SetOutputBuffer(const_cast<mitk::LabelSetImage *>(cacheObject->m_SegCache.GetPointer()));
           this->SegmentationResultHandler(tool, true);
         }
       }
       m_Controls.previewButton->setEnabled(true);
     }
     catch (const std::exception &e)
     {
       std::stringstream errorMsg;
       errorMsg << "<b>STATUS: </b>Error while processing parameters for nnUNet segmentation. Reason: " << e.what();
       this->ShowErrorMessage(errorMsg.str());
       this->WriteErrorMessage(QString::fromStdString(errorMsg.str()));
       m_Controls.previewButton->setEnabled(true);
       tool->PredictOff();
+      m_FirstPreviewComputation = true;
       return;
     }
     catch (...)
     {
       std::string errorMsg = "Unkown error occured while generation nnUNet segmentation.";
       this->ShowErrorMessage(errorMsg);
       m_Controls.previewButton->setEnabled(true);
       tool->PredictOff();
+      m_FirstPreviewComputation = true;
       return;
     }
     if (!pythonPathTextItem.isEmpty())
     { // only cache if the prediction ended without errors.
       m_Settings.setValue("nnUNet/LastPythonPath", pythonPathTextItem);
     }
   }
 }
 
 void QmitknnUNetToolGUI::OnRefreshPresssed()
 {
   const QString resultsFolder = m_Controls.modeldirectoryBox->directory();
   this->OnDirectoryChanged(resultsFolder);
 }
 
 void QmitknnUNetToolGUI::OnDirectoryChanged(const QString &resultsFolder)
 {
   m_IsResultsFolderValid = false;
   m_Controls.previewButton->setEnabled(false);
   this->ClearAllComboBoxes();
   this->ClearAllModalities();
   m_ParentFolder = std::make_shared<QmitknnUNetFolderParser>(resultsFolder);
   auto tasks = m_ParentFolder->getAllTasks<QStringList>();
   tasks.removeDuplicates();
   std::for_each(tasks.begin(), tasks.end(), [this](QString task) { m_Controls.taskBox->addItem(task); });
   m_Settings.setValue("nnUNet/LastRESULTS_FOLDERPath", resultsFolder);
 }
 
 void QmitknnUNetToolGUI::OnModelChanged(const QString &model)
 {
   if (model.isEmpty())
   {
     return;
   }
   this->ClearAllModalities();
   auto selectedTask = m_Controls.taskBox->currentText();
   ctkComboBox *box = qobject_cast<ctkComboBox *>(sender());
   if (box == m_Controls.modelBox)
   {
     if (model == m_VALID_MODELS.last())
     {
       m_Controls.trainerBox->setVisible(false);
       m_Controls.trainerLabel->setVisible(false);
       m_Controls.plannerBox->setVisible(false);
       m_Controls.plannerLabel->setVisible(false);
       m_Controls.foldBox->setVisible(false);
       m_Controls.foldLabel->setVisible(false);
       m_Controls.previewButton->setEnabled(false);
       this->ShowEnsembleLayout(true);
       auto models = m_ParentFolder->getModelsForTask<QStringList>(m_Controls.taskBox->currentText());
       models.removeDuplicates();
       models.removeOne(m_VALID_MODELS.last());
       for (auto &layout : m_EnsembleParams)
       {
         layout->modelBox->clear();
         layout->trainerBox->clear();
         layout->plannerBox->clear();
         std::for_each(models.begin(),
                       models.end(),
                       [&layout, this](QString model)
                       {
                         if (m_VALID_MODELS.contains(model, Qt::CaseInsensitive))
                           layout->modelBox->addItem(model);
                       });
       }
     }
     else
     {
       m_Controls.trainerBox->setVisible(true);
       m_Controls.trainerLabel->setVisible(true);
       m_Controls.plannerBox->setVisible(true);
       m_Controls.plannerLabel->setVisible(true);
       m_Controls.foldBox->setVisible(true);
       m_Controls.foldLabel->setVisible(true);
       m_Controls.previewButton->setEnabled(false);
       this->ShowEnsembleLayout(false);
       m_Controls.trainerBox->clear();
       m_Controls.plannerBox->clear();
       auto trainerPlanners = m_ParentFolder->getTrainerPlannersForTask<QStringList>(selectedTask, model);
       if(trainerPlanners.isEmpty())
       {
         this->ShowErrorMessage("No plans.pkl found for "+model.toStdString()+". Check your directory or download the task again.");
         this->SetComboBoxToNone(m_Controls.foldBox);
         return;
       }
       QStringList trainers, planners;
       std::tie(trainers, planners) = ExtractTrainerPlannerFromString(trainerPlanners);
       std::for_each(
         trainers.begin(), trainers.end(), [this](QString trainer) { m_Controls.trainerBox->addItem(trainer); });
       std::for_each(
         planners.begin(), planners.end(), [this](QString planner) { m_Controls.plannerBox->addItem(planner); });
     }
   }
   else if (!m_EnsembleParams.empty())
   { 
     m_Controls.previewButton->setEnabled(false);
     for (auto &layout : m_EnsembleParams)
     {
       if (box == layout->modelBox)
       {
         layout->trainerBox->clear();
         layout->plannerBox->clear();
         auto trainerPlanners = m_ParentFolder->getTrainerPlannersForTask<QStringList>(selectedTask, model);
         if(trainerPlanners.isEmpty())
         {
           this->ShowErrorMessage("No plans.pkl found for "+model.toStdString()+". Check your directory or download the task again.");
           this->SetComboBoxToNone(layout->foldBox);
           return;
         }
         QStringList trainers, planners;
         std::tie(trainers, planners) = ExtractTrainerPlannerFromString(trainerPlanners);
         std::for_each(trainers.begin(),
                       trainers.end(),
                       [&layout](const QString &trainer) { layout->trainerBox->addItem(trainer); });
         std::for_each(planners.begin(),
                       planners.end(),
                       [&layout](const QString &planner) { layout->plannerBox->addItem(planner); });
         break;
       }
     }
   }
 }
 
 void QmitknnUNetToolGUI::OnTaskChanged(const QString &task)
 {
   if (task.isEmpty())
   {
     return;
   }
   m_Controls.modelBox->clear();
   auto models = m_ParentFolder->getModelsForTask<QStringList>(task);
   models.removeDuplicates();
   if (!models.contains(m_VALID_MODELS.last(), Qt::CaseInsensitive))
   {
     models << m_VALID_MODELS.last(); // add ensemble even if folder doesn't exist
   }
   std::for_each(models.begin(),
                 models.end(),
                 [this](QString model)
                 {
                   if (m_VALID_MODELS.contains(model, Qt::CaseInsensitive))
                     m_Controls.modelBox->addItem(model);
                 });
 }
 
 void QmitknnUNetToolGUI::OnTrainerChanged(const QString &plannerSelected)
 {
   if (plannerSelected.isEmpty())
   {
     return;
   }
   m_IsResultsFolderValid = false;
   QString parentPath;
   auto *box = qobject_cast<ctkComboBox *>(sender());
   if (box == m_Controls.plannerBox)
   {
     m_Controls.foldBox->clear();
     auto selectedTrainer = m_Controls.trainerBox->currentText();
     auto selectedTask = m_Controls.taskBox->currentText();
     auto selectedModel = m_Controls.modelBox->currentText();
     auto folds = m_ParentFolder->getFoldsForTrainerPlanner<QStringList>(
       selectedTrainer, plannerSelected, selectedTask, selectedModel);
     if(folds.isEmpty())
     {
       this->ShowErrorMessage("No valid folds found. Check your directory or download the task again.");
       this->SetComboBoxToNone(m_Controls.foldBox);
       return;
     }
     std::for_each(folds.begin(),
                   folds.end(),
                   [this](QString fold)
                   {
                     if (fold.startsWith("fold_", Qt::CaseInsensitive)) // imposed by nnUNet
                       m_Controls.foldBox->addItem(fold);
                   });
     if (m_Controls.foldBox->count() != 0)
     {
       m_IsResultsFolderValid = true;
       this->CheckAllInCheckableComboBox(m_Controls.foldBox);
       auto tempPath = QStringList() << m_ParentFolder->getResultsFolder() << "nnUNet" << selectedModel << selectedTask
                                     << QString("%1__%2").arg(selectedTrainer, plannerSelected);
       parentPath = QDir::cleanPath(tempPath.join(QDir::separator()));
     }
   }
   else if (!m_EnsembleParams.empty())
   {
     for (auto &layout : m_EnsembleParams)
     {
       if (box == layout->plannerBox)
       {
         layout->foldBox->clear();
         auto selectedTrainer = layout->trainerBox->currentText();
         auto selectedTask = m_Controls.taskBox->currentText();
         auto selectedModel = layout->modelBox->currentText();
         auto folds = m_ParentFolder->getFoldsForTrainerPlanner<QStringList>(
           selectedTrainer, plannerSelected, selectedTask, selectedModel);
         if(folds.isEmpty())
         {
           this->ShowErrorMessage("No valid folds found. Check your directory.");
           this->SetComboBoxToNone(layout->foldBox);
           return;
         }
         std::for_each(folds.begin(),
                       folds.end(),
                       [&layout](const QString &fold)
                       {
                         if (fold.startsWith("fold_", Qt::CaseInsensitive)) // imposed by nnUNet
                           layout->foldBox->addItem(fold);
                       });
         if (layout->foldBox->count() != 0)
         {
           this->CheckAllInCheckableComboBox(layout->foldBox);
           m_IsResultsFolderValid = true;
           auto tempPath = QStringList() << m_ParentFolder->getResultsFolder() << "nnUNet" << selectedModel
                                         << selectedTask << QString("%1__%2").arg(selectedTrainer, plannerSelected);
           parentPath = QDir::cleanPath(tempPath.join(QDir::separator()));
         }
         break;
       }
     }
   }
   if (m_IsResultsFolderValid)
   {
     m_Controls.previewButton->setEnabled(true);
     const QString mitkJsonFile = parentPath + QDir::separator() + m_MITK_EXPORT_JSON_FILENAME;
     this->DumpJSONfromPickle(parentPath);
     if (QFile::exists(mitkJsonFile))
     {
       this->DisplayMultiModalInfoFromJSON(mitkJsonFile);
     }
   }
 }
 
 void QmitknnUNetToolGUI::OnPythonPathChanged(const QString &pyEnv)
 {
   if (pyEnv == QString("Select"))
   {
     QString path =
       QFileDialog::getExistingDirectory(m_Controls.pythonEnvComboBox->parentWidget(), "Python Path", "dir");
     if (!path.isEmpty())
     {
       this->OnPythonPathChanged(path); // recall same function for new path validation
       m_Controls.pythonEnvComboBox->insertItem(0, path);
       m_Controls.pythonEnvComboBox->setCurrentIndex(0);
     }
   }
   else if (!this->IsNNUNetInstalled(pyEnv))
   {
     std::string warning =
       "WARNING: nnUNet is not detected on the Python environment you selected. Please select another "
       "environment or create one. For more info refer https://github.com/MIC-DKFZ/nnUNet";
     this->ShowErrorMessage(warning);
     this->DisableEverything();
     m_Controls.availableBox->clear();
   }
   else
   {
     m_Controls.modeldirectoryBox->setEnabled(true);
     m_Controls.refreshdirectoryBox->setEnabled(true);
     m_Controls.multiModalBox->setEnabled(true);
     QString setVal = this->FetchResultsFolderFromEnv();
     if (!setVal.isEmpty())
     {
       m_Controls.modeldirectoryBox->setDirectory(setVal);
     }
     this->OnRefreshPresssed();
     m_PythonPath = pyEnv.mid(pyEnv.indexOf(" ") + 1);
 #ifdef _WIN32
     if (!(m_PythonPath.endsWith("Scripts", Qt::CaseInsensitive) || m_PythonPath.endsWith("Scripts/", Qt::CaseInsensitive)))
     {
       m_PythonPath += QDir::separator() + QString("Scripts");
     }
 #else
     if (!(m_PythonPath.endsWith("bin", Qt::CaseInsensitive) || m_PythonPath.endsWith("bin/", Qt::CaseInsensitive)))
     {
       m_PythonPath += QDir::separator() + QString("bin");
     }
 #endif
     // Export available model info as json and fill them for Download
     QString tempPath = QString::fromStdString(mitk::IOUtil::GetTempPath());
     this->ExportAvailableModelsAsJSON(tempPath);
     const QString jsonPath = tempPath + QDir::separator() + m_AVAILABLE_MODELS_JSON_FILENAME;
     if (QFile::exists(jsonPath))
     {
       this->FillAvailableModelsInfoFromJSON(jsonPath);
     }
   }
 }
 
 void QmitknnUNetToolGUI::OnCheckBoxChanged(int state)
 {
   bool visibility = false;
   if (state == Qt::Checked)
   {
     visibility = true;
   }
   ctkCheckBox *box = qobject_cast<ctkCheckBox *>(sender());
   if (box != nullptr)
   {
     if (box->objectName() == QString("multiModalBox"))
     {
       m_Controls.requiredModalitiesLabel->setVisible(visibility);
       m_Controls.multiModalValueLabel->setVisible(visibility);
       if (!visibility)
       {
         this->OnModalitiesNumberChanged(0);
         m_Controls.multiModalValueLabel->setText("0");
         this->ClearAllModalLabels();
       }
     }
   }
 }
 
 void QmitknnUNetToolGUI::OnModalitiesNumberChanged(int num)
 {
   while (num > static_cast<int>(m_Modalities.size()))
   {
     QmitkSingleNodeSelectionWidget *multiModalBox = new QmitkSingleNodeSelectionWidget(this);
     mitk::nnUNetTool::Pointer tool = this->GetConnectedToolAs<mitk::nnUNetTool>();
     multiModalBox->SetDataStorage(tool->GetDataStorage());
     multiModalBox->SetInvalidInfo("Select corresponding modalities");
     multiModalBox->SetNodePredicate(m_MultiModalPredicate);
     multiModalBox->setObjectName(QString("multiModal_" + QString::number(m_Modalities.size() + 1)));
     m_Controls.advancedSettingsLayout->addWidget(multiModalBox, m_UI_ROWS + m_Modalities.size() + 1, 1, 1, 3);
     m_Modalities.push_back(multiModalBox);
   }
   while (num < static_cast<int>(m_Modalities.size()) && !m_Modalities.empty())
   {
     QmitkSingleNodeSelectionWidget *child = m_Modalities.back();
     delete child; // delete the layout item
     m_Modalities.pop_back();
   }
   m_Controls.advancedSettingsLayout->update();
 }
 
 void QmitknnUNetToolGUI::AutoParsePythonPaths()
 {
   QString homeDir = QDir::homePath();
   std::vector<QString> searchDirs;
 #ifdef _WIN32
   searchDirs.push_back(QString("C:") + QDir::separator() + QString("ProgramData") + QDir::separator() +
                        QString("anaconda3"));
 #else
   // Add search locations for possible standard python paths here
   searchDirs.push_back(homeDir + QDir::separator() + "environments");
   searchDirs.push_back(homeDir + QDir::separator() + "anaconda3");
   searchDirs.push_back(homeDir + QDir::separator() + "miniconda3");
   searchDirs.push_back(homeDir + QDir::separator() + "opt" + QDir::separator() + "miniconda3");
   searchDirs.push_back(homeDir + QDir::separator() + "opt" + QDir::separator() + "anaconda3");
 #endif
   for (QString searchDir : searchDirs)
   {
     if (searchDir.endsWith("anaconda3", Qt::CaseInsensitive))
     {
       if (QDir(searchDir).exists())
       {
         m_Controls.pythonEnvComboBox->insertItem(0, "(base): " + searchDir);
         searchDir.append((QDir::separator() + QString("envs")));
       }
     }
     for (QDirIterator subIt(searchDir, QDir::AllDirs, QDirIterator::NoIteratorFlags); subIt.hasNext();)
     {
       subIt.next();
       QString envName = subIt.fileName();
       if (!envName.startsWith('.')) // Filter out irrelevent hidden folders, if any.
       {
         m_Controls.pythonEnvComboBox->insertItem(0, "(" + envName + "): " + subIt.filePath());
       }
     }
   }
   m_Controls.pythonEnvComboBox->setCurrentIndex(-1);
 }
 
 void QmitknnUNetToolGUI::SegmentationProcessFailed()
 {
+  m_FirstPreviewComputation = true;
   this->WriteErrorMessage(
     "<b>STATUS: </b><i>Error in the segmentation process. <br>No resulting segmentation can be loaded.</i>");
   this->setCursor(Qt::ArrowCursor);
   std::stringstream stream;
   stream << "Error in the segmentation process. No resulting segmentation can be loaded.";
   this->ShowErrorMessage(stream.str());
 }
 
 void QmitknnUNetToolGUI::SegmentationResultHandler(mitk::nnUNetTool *tool, bool forceRender)
 {
   if (forceRender)
   {
     tool->RenderOutputBuffer();
   }
-  m_FirstPreviewComputation = false;
   this->SetLabelSetPreview(tool->GetPreviewSegmentation());
   this->WriteStatusMessage("<b>STATUS: </b><i>Segmentation task finished successfully.</i>");
   this->ActualizePreviewLabelVisibility();
 }
 
 void QmitknnUNetToolGUI::ShowEnsembleLayout(bool visible)
 {
   if (m_EnsembleParams.empty())
   {
     ctkCollapsibleGroupBox *groupBoxModel1 = new ctkCollapsibleGroupBox(this);
     auto lay1 = std::make_unique<QmitknnUNetTaskParamsUITemplate>(groupBoxModel1);
     groupBoxModel1->setObjectName(QString::fromUtf8("model_1_Box"));
     groupBoxModel1->setTitle(QString::fromUtf8("Model 1"));
     groupBoxModel1->setMinimumSize(QSize(0, 0));
     groupBoxModel1->setCollapsedHeight(5);
     groupBoxModel1->setCollapsed(false);
     groupBoxModel1->setFlat(true);
     groupBoxModel1->setAlignment(Qt::AlignRight);
     m_Controls.advancedSettingsLayout->addWidget(groupBoxModel1, 5, 0, 1, 2);
 
     connect(lay1->modelBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnModelChanged(const QString &)));
     connect(
       lay1->plannerBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnTrainerChanged(const QString &)));
     m_EnsembleParams.push_back(std::move(lay1));
 
     ctkCollapsibleGroupBox *groupBoxModel2 = new ctkCollapsibleGroupBox(this);
     auto lay2 = std::make_unique<QmitknnUNetTaskParamsUITemplate>(groupBoxModel2);
     groupBoxModel2->setObjectName(QString::fromUtf8("model_2_Box"));
     groupBoxModel2->setTitle(QString::fromUtf8("Model 2"));
     groupBoxModel2->setMinimumSize(QSize(0, 0));
     groupBoxModel2->setCollapsedHeight(5);
     groupBoxModel2->setCollapsed(false);
     groupBoxModel2->setFlat(true);
     groupBoxModel2->setAlignment(Qt::AlignLeft);
     m_Controls.advancedSettingsLayout->addWidget(groupBoxModel2, 5, 2, 1, 2);
 
     connect(lay2->modelBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnModelChanged(const QString &)));
     connect(
       lay2->plannerBox, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnTrainerChanged(const QString &)));
     m_EnsembleParams.push_back(std::move(lay2));
   }
   for (auto &layout : m_EnsembleParams)
   {
     layout->setVisible(visible);
   }
 }
 
 void QmitknnUNetToolGUI::OnDownloadModel()
 {
   auto selectedTask = m_Controls.availableBox->currentText();
   if(!selectedTask.isEmpty())
   {
     auto spExec = mitk::ProcessExecutor::New();
     mitk::ProcessExecutor::ArgumentListType args;
     args.push_back(selectedTask.toStdString());
     this->WriteStatusMessage(
       "Downloading the requested task in to the selected Results Folder. This might take some time "
       "depending on your internet connection...");
     m_Processes["DOWNLOAD"] = spExec;
     if (!m_nnUNetThread->isRunning())
     {
       MITK_DEBUG << "Starting thread...";
       m_nnUNetThread->start();
     }
     QString resultsFolder = m_ParentFolder->getResultsFolder();
     emit Operate(resultsFolder, m_PythonPath, spExec, args);
     m_Controls.stopDownloadButton->setVisible(true);
     m_Controls.startDownloadButton->setVisible(false);
   }
 }
 
 void QmitknnUNetToolGUI::OnDownloadWorkerExit(const bool isSuccess, const QString message)
 {
   if (isSuccess)
   {
     this->WriteStatusMessage(message + QString(" Click Refresh Results Folder to use the new Task."));
   }
   else
   {
     MITK_ERROR << "Download FAILED! " << message.toStdString();
     this->WriteStatusMessage(QString("Download failed. Check your internet connection. " + message));
   }
   m_Controls.stopDownloadButton->setVisible(false);
   m_Controls.startDownloadButton->setVisible(true);
 }
 
 void QmitknnUNetToolGUI::OnStopDownload()
 {
   mitk::ProcessExecutor::Pointer spExec = m_Processes["DOWNLOAD"];
   spExec->KillProcess();
   this->WriteStatusMessage("Download Killed by the user.");
   m_Controls.stopDownloadButton->setVisible(false);
   m_Controls.startDownloadButton->setVisible(true);
 }
 
 void QmitknnUNetToolGUI::OnClearCachePressed()
 {
   m_Cache.clear();
   this->UpdateCacheCountOnUI();
 }