diff --git a/Modules/Segmentation/Interactions/mitkMonaiLabelTool.cpp b/Modules/Segmentation/Interactions/mitkMonaiLabelTool.cpp
index ce54066131..e827c1e537 100644
--- a/Modules/Segmentation/Interactions/mitkMonaiLabelTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkMonaiLabelTool.cpp
@@ -1,528 +1,562 @@
 /*============================================================================
 
 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 "mitkMonaiLabelTool.h"
 
 #ifndef CPPHTTPLIB_OPENSSL_SUPPORT
 #define CPPHTTPLIB_OPENSSL_SUPPORT
 #endif
 #include <filesystem>
 #include <httplib.h>
 #include <mitkIOUtil.h>
 #include <mitkLabelSetImageHelper.h>
 #include <mitkPointSetShapeProperty.h>
 #include <mitkProperties.h>
 #include <mitkToolManager.h>
+#include <itkIntensityWindowingImageFilter.h>
+#include "mitkImageAccessByItk.h"
 
 mitk::MonaiLabelTool::MonaiLabelTool() : SegWithPreviewTool(true, "PressMoveReleaseAndPointSetting")
 {
   this->ResetsToEmptyPreviewOn();
   this->IsTimePointChangeAwareOff();
 }
 
 mitk::MonaiLabelTool::~MonaiLabelTool()
 {
   std::filesystem::remove_all(this->GetTempDir());
 }
 
 void mitk::MonaiLabelTool::ConnectActionsAndFunctions()
 {
   CONNECT_FUNCTION("ShiftSecondaryButtonPressed", OnAddNegativePoint);
   CONNECT_FUNCTION("ShiftPrimaryButtonPressed", OnAddPositivePoint);
   CONNECT_FUNCTION("DeletePoint", OnDelete);
 }
 
 void mitk::MonaiLabelTool::Activated()
 {
   Superclass::Activated();
   m_PointSetPositive = mitk::PointSet::New();
   m_PointSetNodePositive = mitk::DataNode::New();
   m_PointSetNodePositive->SetData(m_PointSetPositive);
   m_PointSetNodePositive->SetName(std::string(this->GetName()) + "_PointSetPositive");
   m_PointSetNodePositive->SetBoolProperty("helper object", true);
   m_PointSetNodePositive->SetColor(0.0, 1.0, 0.0);
   m_PointSetNodePositive->SetVisibility(true);
   m_PointSetNodePositive->SetProperty("Pointset.2D.shape",
                                       mitk::PointSetShapeProperty::New(mitk::PointSetShapeProperty::CIRCLE));
   m_PointSetNodePositive->SetProperty("Pointset.2D.fill shape", mitk::BoolProperty::New(true));
   this->GetDataStorage()->Add(m_PointSetNodePositive, this->GetToolManager()->GetWorkingData(0));
 
   m_PointSetNegative = mitk::PointSet::New();
   m_PointSetNodeNegative = mitk::DataNode::New();
   m_PointSetNodeNegative->SetData(m_PointSetNegative);
   m_PointSetNodeNegative->SetName(std::string(this->GetName()) + "_PointSetNegative");
   m_PointSetNodeNegative->SetBoolProperty("helper object", true);
   m_PointSetNodeNegative->SetColor(1.0, 0.0, 0.0);
   m_PointSetNodeNegative->SetVisibility(true);
   m_PointSetNodeNegative->SetProperty("Pointset.2D.shape",
                                       mitk::PointSetShapeProperty::New(mitk::PointSetShapeProperty::CIRCLE));
   m_PointSetNodeNegative->SetProperty("Pointset.2D.fill shape", mitk::BoolProperty::New(true));
   this->GetDataStorage()->Add(m_PointSetNodeNegative, this->GetToolManager()->GetWorkingData(0));
 }
 
 void mitk::MonaiLabelTool::Deactivated()
 {
   this->ClearSeeds();
   this->GetDataStorage()->Remove(m_PointSetNodePositive);
   this->GetDataStorage()->Remove(m_PointSetNodeNegative);
   m_PointSetNodePositive = nullptr;
   m_PointSetNodeNegative = nullptr;
   m_PointSetPositive = nullptr;
   m_PointSetNegative = nullptr;
   Superclass::Deactivated();
 }
 
 void mitk::MonaiLabelTool::UpdatePrepare()
 {
   Superclass::UpdatePrepare();
   auto preview = this->GetPreviewSegmentation();
   preview->RemoveLabels(preview->GetAllLabelValues());
 }
 
 void mitk::MonaiLabelTool::OnDelete(StateMachineAction *, InteractionEvent *)
 {
   if (!this->IsUpdating() && m_PointSetPositive.IsNotNull())
   {
     PointSet::Pointer removeSet = m_PointSetPositive;
     itk::IdentifierType maxId = 0;
     if (m_PointSetPositive->GetSize() > 0)
     {
       maxId = m_PointSetPositive->GetMaxId().Index();
     }
     if (m_PointSetNegative->GetSize() > 0 && (maxId < m_PointSetNegative->GetMaxId().Index()))
     {
       removeSet = m_PointSetNegative;
     }
     removeSet->RemovePointAtEnd(0);
     --m_PointSetCount;
     this->UpdatePreview();
   }
 }
 
 void mitk::MonaiLabelTool::ClearPicks()
 {
   this->ClearSeeds();
   this->UpdatePreview();
 }
 
 bool mitk::MonaiLabelTool::HasPicks() const
 {
   return this->m_PointSetPositive.IsNotNull() && this->m_PointSetPositive->GetSize() > 0;
 }
 
 void mitk::MonaiLabelTool::ClearSeeds()
 {
   if (this->m_PointSetPositive.IsNotNull())
   {
     m_PointSetCount -= m_PointSetPositive->GetSize();
     this->m_PointSetPositive = mitk::PointSet::New(); // renew pointset
     this->m_PointSetNodePositive->SetData(this->m_PointSetPositive);
   }
   if (this->m_PointSetNegative.IsNotNull())
   {
     m_PointSetCount -= m_PointSetNegative->GetSize();
     this->m_PointSetNegative = mitk::PointSet::New(); // renew pointset
     this->m_PointSetNodeNegative->SetData(this->m_PointSetNegative);
   }
 }
 
 bool mitk::MonaiLabelTool::IsMonaiServerOn(const std::string &hostName, const int &port) const
 {
   httplib::SSLClient cli(hostName, port);
   cli.enable_server_certificate_verification(false);
   while (cli.is_socket_open());
   return cli.Get("/info/");
 }
 
 namespace mitk
 {
   // Converts the json GET response from the MonaiLabel server to MonaiAppMetadata object.
   void from_json(const nlohmann::json &jsonObj, mitk::MonaiAppMetadata &appData)
   {
     jsonObj["name"].get_to(appData.name);
     jsonObj["description"].get_to(appData.description);
     jsonObj["labels"].get_to(appData.labels);
     auto modelJsonMap = jsonObj["models"].get<std::map<std::string, nlohmann::json>>();
     for (const auto &[_name, _jsonObj] : modelJsonMap)
     {
       if (_jsonObj.is_discarded() || !_jsonObj.is_object())
       {
         MITK_ERROR << "Could not parse JSON object.";
       }
       mitk::MonaiModelInfo modelInfo;
       modelInfo.name = _name;
       try
       {
         auto labels = _jsonObj["labels"].get<std::unordered_map<std::string, int>>();
         modelInfo.labels = labels;
       }
       catch (const std::exception &)
       {
         auto labels = _jsonObj["labels"].get<std::vector<std::string>>();
         for (const auto &label : labels)
         {
           modelInfo.labels[label] = -1; // Hardcode -1 as label id
         }
       }
       _jsonObj["type"].get_to(modelInfo.type);
       _jsonObj["dimension"].get_to(modelInfo.dimension);
       _jsonObj["description"].get_to(modelInfo.description);
       appData.models.push_back(modelInfo);
     }
   }
 }
 
 namespace
 {
   /**
    * @brief Returns boundary string from Httplib response.
    */
   std::string GetBoundaryString(const httplib::Result &response)
   {
     httplib::Headers headers = response->headers;
     std::string contentType = headers.find("content-type")->second;
     std::string delimiter = "boundary=";
     std::string boundaryString =
       contentType.substr(contentType.find(delimiter) + delimiter.length(), std::string::npos);
     boundaryString.insert(0, "--");
     return boundaryString;
   }
 
   /**
    * @brief Returns image data string from monai label overall response.
    */
   std::string GetResponseImageString(const std::string &imagePart)
   {
     std::string contentTypeStream = "Content-Type: application/octet-stream";
     size_t ctPos = imagePart.find(contentTypeStream) + contentTypeStream.length();
     std::string imageDataPart = imagePart.substr(ctPos);
     std::string whitespaces = " \n\r";
     imageDataPart.erase(0, imageDataPart.find_first_not_of(whitespaces)); // clean up
     return imageDataPart;
   }
 
   /**
    * @brief Helper function to get the Parts of the POST response.
    */
   std::vector<std::string> GetPartsBetweenBoundary(const std::string &body, const std::string &boundary)
   {
     std::vector<std::string> retVal;
     std::string master = body;
     size_t boundaryPos = master.find(boundary);
     size_t beginPos = 0;
     while (boundaryPos != std::string::npos)
     {
       std::string part = master.substr(beginPos, boundaryPos);
       if (!part.empty())
       {
         retVal.push_back(part);
       }
       master.erase(beginPos, boundaryPos + boundary.length());
       boundaryPos = master.find(boundary);
     }
     return retVal;
   }
 
   /**
    * @brief Applies the give std::map lookup table on the preview segmentation LabelSetImage.
    */
   void MapLabelsToSegmentation(const mitk::LabelSetImage *source,
                                mitk::LabelSetImage *dest,
                                const std::map<std::string, mitk::Label::PixelType> &labelMap)
   {
     if (labelMap.empty())
     {
       auto label = mitk::LabelSetImageHelper::CreateNewLabel(dest, "object");
       label->SetValue(1);
       dest->AddLabel(label, false);
       return;
     }
     std::map<mitk::Label::PixelType, std::string> flippedLabelMap;
     for (auto const &[key, val] : labelMap)
     {
       flippedLabelMap[val] = key;
     }
     auto lookupTable = mitk::LookupTable::New();
     lookupTable->SetType(mitk::LookupTable::LookupTableType::MULTILABEL);
     for (auto const &[key, val] : flippedLabelMap)
     {
       if (source->ExistLabel(key, source->GetActiveLayer()))
       {
         auto label = mitk::Label::New(key, val);
         std::array<double, 3> lookupTableColor;
         lookupTable->GetColor(key, lookupTableColor.data());
         mitk::Color color;
         color.SetRed(lookupTableColor[0]);
         color.SetGreen(lookupTableColor[1]);
         color.SetBlue(lookupTableColor[2]);
         label->SetColor(color);
         dest->AddLabel(label, false);
       }
       else
       {
         MITK_INFO << "Label not found for " << val;
       }
     }
   }
-} // namespace
+
+  template <typename TPixel, unsigned int VImageDimension>
+  void ITKWindowing(const itk::Image<TPixel, VImageDimension> *inputImage,
+                    mitk::Image *mitkImage, mitk::ScalarType min, mitk::ScalarType max)
+  {
+    typedef itk::Image<TPixel, VImageDimension> ImageType;
+    typedef itk::IntensityWindowingImageFilter<ImageType, ImageType> IntensityFilterType;
+    typename IntensityFilterType::Pointer filter = IntensityFilterType::New();
+    filter->SetInput(inputImage);
+    filter->SetWindowMinimum(min);
+    filter->SetWindowMaximum(max);
+    filter->SetOutputMinimum(min);
+    filter->SetOutputMaximum(max);
+    filter->Update();
+
+    mitkImage->SetImportVolume(
+      (void *)(filter->GetOutput()->GetPixelContainer()->GetBufferPointer()), 0, 0, mitk::Image::ManageMemory);
+    filter->GetOutput()->GetPixelContainer()->ContainerManageMemoryOff();
+  }
+}
+
+mitk::Image::Pointer mitk::MonaiLabelTool::ApplyLevelWindowEffect(const Image *inputAtTimeStep) const
+{
+  mitk::LevelWindow levelWindow;
+  this->GetToolManager()->GetReferenceData(0)->GetLevelWindow(levelWindow);
+  auto filteredImage = mitk::Image::New();
+  filteredImage->Initialize(inputAtTimeStep);
+  AccessByItk_n(inputAtTimeStep,
+                ::ITKWindowing, // apply level window filter
+                (filteredImage, levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound()));
+  return filteredImage;
+}
 
 void mitk::MonaiLabelTool::DoUpdatePreview(const Image *inputAtTimeStep,
                                            const Image * /*oldSegAtTimeStep*/,
                                            LabelSetImage *previewImage,
                                            TimeStepType timeStep)
 {
   const std::string &hostName = m_RequestParameters->hostName;
   const int port = m_RequestParameters->port;
   if (!IsMonaiServerOn(hostName, port))
   {
     mitkThrow() << m_SERVER_503_ERROR_TEXT;
   }
   if (this->m_TempDir.empty())
   {
     this->SetTempDir(IOUtil::CreateTemporaryDirectory("mitk-XXXXXX"));
   }
 
   std::string inputImagePath, outputImagePath;
   std::tie(inputImagePath, outputImagePath) = this->CreateTempDirs(m_TEMPLATE_FILENAME);
 
   try
   {
-    this->WriteImage(inputAtTimeStep, inputImagePath);
+    mitk::Image::Pointer filteredImage = this->ApplyLevelWindowEffect(inputAtTimeStep);
+    this->WriteImage(filteredImage, inputImagePath);
     this->PostInferRequest(hostName, port, inputImagePath, outputImagePath, inputAtTimeStep->GetGeometry());
     Image::Pointer outputImage = IOUtil::Load<Image>(outputImagePath);
     auto outputBuffer = mitk::LabelSetImage::New();
     outputBuffer->InitializeByLabeledImage(outputImage);
     std::map<std::string, mitk::Label::PixelType> labelMap; // empty map
     if (m_RequestParameters->model.IsInteractive())
     {
       this->SetLabelTransferMode(LabelTransferMode::MapLabel);
       this->SetSelectedLabels({MASK_VALUE});
     }
     else
     {
       outputBuffer->SetGeometry(inputAtTimeStep->GetGeometry());
       labelMap = m_ResultMetadata["label_names"];
       this->SetLabelTransferMode(LabelTransferMode::AddLabel);
     }
     ::MapLabelsToSegmentation(outputBuffer, previewImage, labelMap);
     this->WriteBackResults(previewImage, outputBuffer.GetPointer(), timeStep);
     MonaiStatusEvent.Send(true);
   }
   catch (const mitk::Exception &e)
   {
     MITK_ERROR << e.GetDescription();
     mitkThrow() << e.GetDescription();
     MonaiStatusEvent.Send(false);
   }
 }
 
 void mitk::MonaiLabelTool::GetOverallInfo(const std::string &hostName, const int &port)
 {
   if (!IsMonaiServerOn(hostName, port))
   {
     Tool::ErrorMessage.Send(m_SERVER_503_ERROR_TEXT);
     mitkThrow() << m_SERVER_503_ERROR_TEXT;
   }
   httplib::SSLClient cli(hostName, port);
   cli.enable_server_certificate_verification(false);
   if (auto response = cli.Get("/info/"))
   {
     if (response->status == 200)
     {
       auto jsonObj = nlohmann::json::parse(response->body);
       if (jsonObj.is_discarded() || !jsonObj.is_object())
       {
         MITK_ERROR << "Could not parse response from MONAILabel server as JSON object!";
         return;
       }
       auto appData = jsonObj.template get<mitk::MonaiAppMetadata>();
       m_InfoParameters = std::make_unique<mitk::MonaiAppMetadata>(appData);
       if (nullptr != m_InfoParameters)
       {
         m_InfoParameters->hostName = hostName;
         m_InfoParameters->port = port;
       }
     }
   }
   else
   {
     Tool::ErrorMessage.Send(httplib::to_string(response.error()) + " error occured.");
   }
 }
 
 void mitk::MonaiLabelTool::PostInferRequest(const std::string &hostName,
                                             const int &port,
                                             const std::string &filePath,
                                             const std::string &outFile,
                                             const mitk::BaseGeometry *baseGeometry)
 {
   std::string &modelName = m_RequestParameters->model.name; // Get this from args as well.
   std::string postPath = "/infer/";                         // make this separate class of constants
   postPath.append(modelName);
   std::ifstream input(filePath, std::ios::binary);
   if (!input)
   {
     MITK_WARN << "could not read file to POST";
   }
   std::stringstream buffer_lf_img;
   buffer_lf_img << input.rdbuf();
   input.close();
   httplib::MultipartFormDataItems items;
   if (m_RequestParameters->model.IsInteractive())
   {
     std::stringstream foreground = this->GetPointsAsListString(baseGeometry, m_PointSetPositive);
     std::stringstream background = this->GetPointsAsListString(baseGeometry, m_PointSetNegative);
     std::stringstream paramString;
     paramString << "{" 
                 << "\"foreground\":" << foreground.str() 
                 << ",\"background\":" << background.str()
                 << "}";
     MITK_DEBUG << paramString.str();
     items.push_back({"params", paramString.str(), "", ""});
   }
   else // Auto models
   {
     items.push_back({"params", "{\"restore_label_idx\": true}", "", ""});
   }
   items.push_back({"file", buffer_lf_img.str(), "post_from_mitk.nii.gz", "application/octet-stream"});
   httplib::SSLClient cli(hostName, port);
   cli.set_read_timeout(60);                      // arbitary 1 minute time-out to avoid corner cases.
   cli.enable_server_certificate_verification(false);
   if (auto response = cli.Post(postPath, items))
   {
     if (response->status == 200)
     {
       // Find boundary
       std::string boundaryString = ::GetBoundaryString(response);
       MITK_DEBUG << "boundary hash: " << boundaryString;
 
       // Parse metadata JSON
       std::string resBody = response->body;
       std::vector<std::string> multiPartResponse = ::GetPartsBetweenBoundary(resBody, boundaryString);
 
       std::string metaData = multiPartResponse[0];
       std::string contentTypeJson = "Content-Type: application/json";
       size_t ctPos = metaData.find(contentTypeJson) + contentTypeJson.length();
       std::string metaDataPart = metaData.substr(ctPos);
       MITK_DEBUG << metaDataPart;
       auto jsonObj = nlohmann::json::parse(metaDataPart);
       if (jsonObj.is_discarded() || !jsonObj.is_object())
       {
         MITK_ERROR << "Could not parse response from MONAILabel server as JSON object!";
         return;
       }
       else // use the metadata
       {
         m_ResultMetadata = jsonObj;
       }
       // Parse response image string
       std::string imagePart = multiPartResponse[1];
       std::string imageData = ::GetResponseImageString(imagePart);
       std::ofstream output(outFile, std::ios::out | std::ios::app | std::ios::binary);
       output << imageData;
       output.unsetf(std::ios::skipws);
       output.flush();
     }
     else
     {
       auto err = response.error();
       MITK_ERROR << "An HTTP POST error: " << httplib::to_string(err) << " occured.";
       mitkThrow() << "An HTTP POST error: " << httplib::to_string(err) << " occured.";
     }
   }
 }
 
 std::vector<mitk::MonaiModelInfo> mitk::MonaiLabelTool::GetAutoSegmentationModels(int dim) const
 {
   std::vector<mitk::MonaiModelInfo> autoModels;
   if (nullptr != m_InfoParameters)
   {
     for (mitk::MonaiModelInfo &model : m_InfoParameters->models)
     {
       if (m_AUTO_SEG_TYPE_NAME.find(model.type) != m_AUTO_SEG_TYPE_NAME.end() && (!(dim > -1) ||
           model.dimension == dim))
       {
         autoModels.push_back(model);
       }
     }
   }
   return autoModels;
 }
 
 std::vector<mitk::MonaiModelInfo> mitk::MonaiLabelTool::GetInteractiveSegmentationModels(int dim) const
 {
   std::vector<mitk::MonaiModelInfo> interactiveModels;
   if (nullptr != m_InfoParameters)
   {
     for (mitk::MonaiModelInfo &model : m_InfoParameters->models)
     {
       if (m_INTERACTIVE_SEG_TYPE_NAME.find(model.type) != m_INTERACTIVE_SEG_TYPE_NAME.end() &&
           (!(dim > -1) || model.dimension == dim))
       {
         interactiveModels.push_back(model);
       }
     }
   }
   return interactiveModels;
 }
 
 std::vector<mitk::MonaiModelInfo> mitk::MonaiLabelTool::GetScribbleSegmentationModels(int dim) const
 {
   std::vector<mitk::MonaiModelInfo> scribbleModels;
   if (nullptr != m_InfoParameters)
   {
     for (mitk::MonaiModelInfo &model : m_InfoParameters->models)
     {
       if (m_SCRIBBLE_SEG_TYPE_NAME.find(model.type) != m_SCRIBBLE_SEG_TYPE_NAME.end() &&
           (!(dim > -1) || model.dimension == dim))
       {
         scribbleModels.push_back(model);
       }
     }
   }
   return scribbleModels;
 }
 
 mitk::MonaiModelInfo mitk::MonaiLabelTool::GetModelInfoFromName(const std::string modelName) const
 {
   if (nullptr == m_InfoParameters)
   {
     mitkThrow() << "No model information found.";
   }
   mitk::MonaiModelInfo retVal;
   for (mitk::MonaiModelInfo &model : m_InfoParameters->models)
   {
     if (model.name == modelName)
     {
       retVal = model;
       break;
     }
   }
   return retVal;
 }
 
 void mitk::MonaiLabelTool::WriteImage(const Image*, const std::string&) const {}
 
 std::pair<std::string, std::string> mitk::MonaiLabelTool::CreateTempDirs(const std::string &filePattern) const
 {
   std::string inDir, outDir, inputImagePath, outputImagePath;
   inDir = IOUtil::CreateTemporaryDirectory("monai-in-XXXXXX", this->GetTempDir());
   std::ofstream tmpStream;
   inputImagePath = IOUtil::CreateTemporaryFile(tmpStream, filePattern, inDir + IOUtil::GetDirectorySeparator());
   tmpStream.close();
   std::size_t found = inputImagePath.find_last_of(IOUtil::GetDirectorySeparator());
   std::string fileName = inputImagePath.substr(found + 1);
   std::string token = fileName.substr(0, fileName.find("_"));
   outDir = IOUtil::CreateTemporaryDirectory("monai-out-XXXXXX", this->GetTempDir());
   outputImagePath = outDir + IOUtil::GetDirectorySeparator() + token + "_000.nii.gz";
   return std::make_pair(inputImagePath, outputImagePath);
 }
diff --git a/Modules/Segmentation/Interactions/mitkMonaiLabelTool.h b/Modules/Segmentation/Interactions/mitkMonaiLabelTool.h
index 340724789a..b6fad46e23 100644
--- a/Modules/Segmentation/Interactions/mitkMonaiLabelTool.h
+++ b/Modules/Segmentation/Interactions/mitkMonaiLabelTool.h
@@ -1,250 +1,256 @@
 /*============================================================================
 
 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.
 
 ============================================================================*/
 #ifndef mitkMonaiLabelTool_h
 #define mitkMonaiLabelTool_h
 
 #include "mitkSegWithPreviewTool.h"
 #include <MitkSegmentationExports.h>
 #include <memory>
 #include <unordered_map>
 #include <set>
 #include <nlohmann/json.hpp>
 #include <mitkPointSet.h>
 #include <mitkInteractionPositionEvent.h>
 
 
 namespace us
 {
   class ModuleResource;
 }
 
 namespace mitk
 {
   /**
    * @brief Struct to hold featured models individual info
    * 
    */
   struct MonaiModelInfo
   {
     std::string name;
     std::string type;
     std::unordered_map<std::string, int> labels;
     int dimension;
     std::string description;
     std::unordered_map<bool, std::string> config;
 
     inline bool operator==(const MonaiModelInfo &rhs) const
     {
       return (this->name == rhs.name && this->type == rhs.type); // Comparing only name and type, for now.
     }
 
     inline bool IsInteractive() const
     {
       return ("deepgrow" == type || "deepedit" == type);
     }
   };
 
   /**
    * @brief Struct to store MonaiLabel server metadata including all model infos
    * 
    */
   struct MonaiAppMetadata
   {
     std::string name;
     std::string description;
     std::vector<std::string> labels;
     std::string version;
     std::string hostName;
     int port;
     std::string origin;
     std::vector<MonaiModelInfo> models;
   };
 
   /**
    * @brief Request class to pack model and other necessary server information 
    * from GUI.
    * 
    */
   struct MonaiLabelRequest
   {
     MonaiModelInfo model;
     std::string hostName;
     std::string requestLabel;
     int port;
 
     inline bool operator==(const MonaiLabelRequest &rhs) const
     { 
       return (this->model == rhs.model && this->hostName == rhs.hostName && this->port == rhs.port &&
               this->requestLabel == rhs.requestLabel);
     }
   };
 
   /**
     \brief MonaiLabel segmentation tool base class.
 
     \ingroup Interaction
     \ingroup ToolManagerEtAl
 
     \warning Only to be instantiated by mitk::ToolManager.
   */
   class MITKSEGMENTATION_EXPORT MonaiLabelTool : public SegWithPreviewTool
   {
   public:
     mitkClassMacro(MonaiLabelTool, SegWithPreviewTool);
     itkCloneMacro(Self);
     void Activated() override;
     void Deactivated() override;
     void UpdatePrepare() override;
 
     /**
      * @brief Writes image to disk as the tool desires.
      * Default implementation does nothing.
      */
     virtual void WriteImage(const Image*, const std::string&) const;
 
     /**
      * @brief Method does the GET Rest call to fetch MonaiLabel
      * server metadata including all models' info.
      */
     void GetOverallInfo(const std::string &hostName, const int &port);
 
     /**
      * @brief Holds all parameters of the server to serve the UI
      * 
      */
     std::unique_ptr<MonaiAppMetadata> m_InfoParameters;
     
     /**
      * @brief Variable to set selected model's and other data needed
      * for the POST call.
      */
     std::unique_ptr<MonaiLabelRequest> m_RequestParameters; 
 
     /**
      * @brief Get the Auto Segmentation Models info for the given 
      * dimension.
      */
     std::vector<MonaiModelInfo> GetAutoSegmentationModels(int dim = -1) const;
 
     /**
      * @brief Get the Interactive Segmentation Models info for the given 
      * dimension.
      */
     std::vector<MonaiModelInfo> GetInteractiveSegmentationModels(int dim = -1) const;
 
     /**
      * @brief Get the Scribble Segmentation Models info for the given 
      * dimension. 
      */
     std::vector<MonaiModelInfo> GetScribbleSegmentationModels(int dim = -1) const;
 
     /**
      * @brief Function to prepare the Rest request and does the POST call.
      * Writes the POST responses back to disk.
      */
     void PostInferRequest(const std::string &hostName, const int &port, const std::string &filePath, const std::string &outFile, 
                           const mitk::BaseGeometry *baseGeometry);
     /**
      * @brief Helper function to get full model info object from model name. 
      */
     MonaiModelInfo GetModelInfoFromName(const std::string) const;
 
     itkSetMacro(ModelName, std::string);
     itkGetConstMacro(ModelName, std::string);
     itkSetMacro(URL, std::string);
     itkGetConstMacro(URL, std::string);
     itkSetMacro(TempDir, std::string);
     itkGetConstMacro(TempDir, std::string);
 
     /**
      * @brief  Clears all picks and updates the preview.
      */
     void ClearPicks();
 
     /**
      * @brief Checks if any point exists in the either of the PointSetPositive
      * or PointSetNegative.
      */
     bool HasPicks() const;
 
     Message1<const bool> MonaiStatusEvent;
 
   protected:
     MonaiLabelTool();
     ~MonaiLabelTool();
     void DoUpdatePreview(const Image* inputAtTimeStep, const Image* oldSegAtTimeStep, LabelSetImage* previewImage, TimeStepType timeStep) override;
     void ConnectActionsAndFunctions() override;
 
     /*
      * @brief Add positive seed point action of StateMachine pattern. 
      */
     virtual void OnAddPositivePoint(StateMachineAction *, InteractionEvent *interactionEvent) = 0;
 
     /*
      * @brief Add negative seed point action of StateMachine pattern
      */
     virtual void OnAddNegativePoint(StateMachineAction *, InteractionEvent *interactionEvent) = 0;
 
     /*
      * @brief Delete action of StateMachine pattern
      */
     virtual void OnDelete(StateMachineAction *, InteractionEvent *);
 
     /*
      * @brief Clear all seed points and call UpdatePreview to reset the segmentation Preview
      */
     void ClearSeeds();
 
     /**
      * @brief Get the Points from given pointset as csv string.
      * 
      */
     virtual std::stringstream GetPointsAsListString(const mitk::BaseGeometry *baseGeometry,
                                                     const PointSet::Pointer pointSet) const = 0;
 
     /**
      * @brief Writes back segmentation results in 3D or 2D shape to preview LabelSetImage.
      */
     virtual void WriteBackResults(LabelSetImage *, LabelSetImage *, TimeStepType) const = 0;
 
     PointSet::Pointer m_PointSetPositive;
     PointSet::Pointer m_PointSetNegative;
     DataNode::Pointer m_PointSetNodePositive;
     DataNode::Pointer m_PointSetNodeNegative;
     int m_PointSetCount = 0;
 
   private:
 
     /**
      * @brief Helper function to create temp directory for writing/reading images
      * Returns input and output file names expected as a pair.
      */
     std::pair<std::string, std::string> CreateTempDirs(const std::string &filePattern) const;
 
     /**
      * @brief Checks if MonaiLabel server is alive.
      */
     bool IsMonaiServerOn(const std::string &hostName, const int &port) const;
+     
+    /**
+     * @brief Applies level window filter on the input image. Current Level window bounds 
+     * are captured from the tool manager.
+     */
+    mitk::Image::Pointer ApplyLevelWindowEffect(const Image *inputAtTimeStep) const;
     
     std::string m_TempDir;
     std::string m_ModelName;
     std::string m_URL;
     nlohmann::json m_ResultMetadata;
     const std::set<std::string> m_AUTO_SEG_TYPE_NAME = {"segmentation"};
     const std::set<std::string> m_SCRIBBLE_SEG_TYPE_NAME = {"scribbles"};
     const std::set<std::string> m_INTERACTIVE_SEG_TYPE_NAME = {"deepgrow"}; // deepedit not supported yet 
     const std::string m_TEMPLATE_FILENAME = "XXXXXX_000_0000.nii.gz";
     const std::string m_SERVER_503_ERROR_TEXT = "A connection to MonaiLabel server cannot be established.";
     const Label::PixelType MASK_VALUE = 1;
   };
 }
 #endif