7 #include "ioPacs/SSliceIndexDicomPullerEditor.hpp" 9 #include <fwCom/Signal.hpp> 10 #include <fwCom/Signal.hxx> 11 #include <fwCom/Signals.hpp> 12 #include <fwCom/Slot.hpp> 13 #include <fwCom/Slots.hpp> 14 #include <fwCom/Slots.hxx> 16 #include <fwData/Array.hpp> 17 #include <fwData/Composite.hpp> 18 #include <fwData/Image.hpp> 19 #include <fwData/Integer.hpp> 21 #include <fwDataTools/fieldHelper/Image.hpp> 22 #include <fwDataTools/helper/Array.hpp> 23 #include <fwDataTools/helper/Composite.hpp> 25 #include <fwGui/dialog/MessageDialog.hpp> 27 #include <fwGuiQt/container/QtContainer.hpp> 29 #include <fwMedData/DicomSeries.hpp> 30 #include <fwMedData/ImageSeries.hpp> 31 #include <fwMedData/SeriesDB.hpp> 33 #include <fwMedDataTools/helper/SeriesDB.hpp> 35 #include <fwPacsIO/exceptions/Base.hpp> 37 #include <fwServices/macros.hpp> 38 #include <fwServices/registry/ActiveWorkers.hpp> 39 #include <fwServices/registry/ObjectService.hpp> 41 #include <fwThread/Timer.hpp> 43 #include <fwTools/System.hpp> 45 #include <boost/asio/placeholders.hpp> 46 #include <boost/filesystem/fstream.hpp> 47 #include <boost/filesystem/operations.hpp> 48 #include <boost/foreach.hpp> 50 #include <QApplication> 52 #include <QHBoxLayout> 53 #include <QMouseEvent> 63 const ::fwCom::Slots::SlotKeyType SSliceIndexDicomPullerEditor::s_READ_IMAGE_SLOT =
"readImage";
64 const ::fwCom::Slots::SlotKeyType SSliceIndexDicomPullerEditor::s_DISPLAY_MESSAGE_SLOT =
"displayErrorMessage";
89 _sstream <<
"SSliceIndexDicomPullerEditor::info";
98 ::fwRuntime::ConfigurationElement::sptr config =
m_configuration->findConfigurationElement(
"config");
99 SLM_ASSERT(
"The service ::ioPacs::SPacsConfigurationInitializer must have " 100 "a \"config\" element.", config);
105 ::boost::tie(success,
m_dicomReaderType) = config->getSafeAttributeValue(
"dicomReader");
106 SLM_ASSERT(
"It should be a \"dicomReader\" tag in the ::ioPacs::SSliceIndexDicomPullerEditor " 107 "config element.", success);
110 ::fwRuntime::ConfigurationElement::sptr readerConfig = config->findConfigurationElement(
"dicomReaderConfig");
112 (readerConfig && readerConfig->size() == 1) ? readerConfig->getElements()[0] :
nullptr;
115 std::string delayStr;
116 ::boost::tie(success, delayStr) = config->getSafeAttributeValue(
"delay");
119 m_delay = ::boost::lexical_cast<
unsigned int >(delayStr);
133 ::fwGuiQt::container::QtContainer::sptr qtContainer = fwGuiQt::container::QtContainer::dynamicCast(getContainer());
135 QHBoxLayout* layout =
new QHBoxLayout();
137 ::fwMedData::DicomSeries::csptr dicomSeries = this->getInOut< ::fwMedData::DicomSeries >(
"series");
138 SLM_ASSERT(
"DicomSeries should not be null !", dicomSeries);
153 std::stringstream ss;
157 qtContainer->setLayout(layout);
160 QObject::connect(
m_sliceIndexSlider, SIGNAL(valueChanged(
int)),
this, SLOT(changeSliceIndex(
int)));
168 ::fwIO::IReader::sptr dicomReader;
169 dicomReader = ::fwIO::IReader::dynamicCast(srvFactory->create(
m_dicomReaderType));
171 "::ioPacs::SSliceIndexDicomPullerEditor.", dicomReader);
172 ::fwServices::OSR::registerService(
m_tempSeriesDB, ::fwIO::s_DATA_KEY,
173 ::fwServices::IService::AccessType::INOUT, dicomReader);
179 dicomReader->configure();
180 dicomReader->start();
196 std::chrono::milliseconds duration = std::chrono::milliseconds(
m_delay);
223 QObject::disconnect(
m_sliceIndexSlider, SIGNAL(valueChanged(
int)),
this, SLOT(changeSliceIndex(
int)));
236 void SSliceIndexDicomPullerEditor::changeSliceIndex(
int value)
239 std::stringstream ss;
253 ::fwMedData::DicomSeries::csptr dicomSeries = this->getInOut< ::fwMedData::DicomSeries >(
"series");
254 SLM_ASSERT(
"DicomSeries should not be null !", dicomSeries);
257 std::size_t selectedSliceIndex =
m_sliceIndexSlider->value() + dicomSeries->getFirstInstanceNumber();
258 OSLM_TRACE(
"triggered new slice : " << selectedSliceIndex);
259 if(!dicomSeries->isInstanceAvailable(selectedSliceIndex))
267 SLM_ERROR(
"There is no instance available for selected slice index.");
282 ::fwMedData::DicomSeries::csptr dicomSeries = this->getInOut< ::fwMedData::DicomSeries >(
"series");
283 SLM_ASSERT(
"DicomSeries should not be null !", dicomSeries);
284 if( dicomSeries->getModality() !=
"CT" && dicomSeries->getModality() !=
"MR" && dicomSeries->getModality() !=
"XA")
291 sDBTempohelper.
clear();
295 ::boost::filesystem::path tmpPath = path /
"tmp";
297 SLM_INFO(
"Create " + tmpPath.string());
298 ::boost::filesystem::create_directories(tmpPath);
300 const auto& binaries = dicomSeries->getDicomContainer();
301 auto iter = binaries.find(selectedSliceIndex);
302 OSLM_ASSERT(
"Index '"<<selectedSliceIndex<<
"' is not found in DicomSeries", iter != binaries.end());
304 const ::fwMemory::BufferObject::sptr bufferObj = iter->second;
305 const ::fwMemory::BufferObject::Lock lockerDest(bufferObj);
306 const char* buffer =
static_cast<char*
>(lockerDest.getBuffer());
307 const size_t size = bufferObj->getSize();
309 ::boost::filesystem::path dest = tmpPath / std::to_string(selectedSliceIndex);
310 ::boost::filesystem::ofstream fs(dest, std::ios::binary|std::ios::trunc);
311 FW_RAISE_IF(
"Can't open '" << tmpPath <<
"' for write.", !fs.good());
313 fs.write(buffer, size);
334 ::fwMedData::ImageSeries::sptr imageSeries;
338 imageSeries = ::fwMedData::ImageSeries::dynamicCast(*(
m_tempSeriesDB->getContainer().begin()));
343 ::fwData::Image::sptr newImage = imageSeries->getImage();
355 ::boost::system::error_code ec;
356 ::boost::filesystem::remove_all(path, ec);
357 SLM_ERROR_IF(
"remove_all error for path " + path.string() +
": " + ec.message(), ec.value());
372 ::fwMedData::DicomSeries::sptr dicomSeries = this->getInOut< ::fwMedData::DicomSeries >(
"series");
373 SLM_ASSERT(
"DicomSeries should not be null !", dicomSeries);
376 std::size_t selectedSliceIndex =
m_sliceIndexSlider->value() + dicomSeries->getFirstInstanceNumber();
385 std::string seriesInstanceUID = dicomSeries->getInstanceUID();
386 std::string sopInstanceUID =
387 m_seriesEnquirer->findSOPInstanceUID(seriesInstanceUID, static_cast<unsigned int>(selectedSliceIndex));
390 if(!sopInstanceUID.empty())
393 m_seriesEnquirer->pullInstanceUsingGetRetrieveMethod(seriesInstanceUID, sopInstanceUID);
397 ::boost::filesystem::path filePath = path.string() + seriesInstanceUID +
"/" + sopInstanceUID;
398 dicomSeries->addDicomPath(selectedSliceIndex, filePath);
404 std::stringstream ss;
405 ss <<
"The selected series does not have an instance matching the selected instance number (" <<
406 selectedSliceIndex <<
").";
416 std::stringstream ss;
417 ss <<
"Unable to connect to the pacs. Please check your configuration: \n" 428 SLM_ERROR(
"Pacs pull aborted : no pacs configuration found.");
440 messageBox.
setIcon(::fwGui::dialog::IMessageDialog::CRITICAL);
441 messageBox.
addButton(::fwGui::dialog::IMessageDialog::OK);
std::shared_ptr< ::fwData::Integer > m_frontalIndex
Frontal slice index.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
ioPacs contains services use to deal with PACS using DCMTK library.
virtual FWGUI_API void setMessage(const std::string &msg) override
Set the message.
Defines the service interface managing the editor service for object.
Defines the generic message box for IHM. Use the Delegate design pattern.
IOPACS_API void displayErrorMessage(const std::string &message) const
Displays a dialog box with the error message.
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
unsigned int m_delay
Delay.
virtual IOPACS_API void starting() override
Override.
::fwThread::Worker::sptr m_pullSeriesWorker
Pull Worker.
virtual IOPACS_API void configuring() override
Configuring method. This method is used to configure the service.
std::shared_ptr< ::fwData::Integer > m_sagittalIndex
Sagittal slice index.
DisplayMessageSlotType::sptr m_slotDisplayMessage
Slot to call displayErrorMessage method;.
#define OSLM_TRACE(message)
::fwPacsIO::SeriesEnquirer::sptr m_seriesEnquirer
Series enquirer.
IOPACS_API void info(std::ostream &_sstream) override
Override.
#define SLM_WARN(message)
std::string m_dicomReaderType
IOPACS Reader.
IOPACS_API SSliceIndexDicomPullerEditor() noexcept
Constructor.
Base class of fwPacsIO Exceptions.
#define SLM_ERROR(message)
FWSERVICES_API void setOutput(const ::fwServices::IService::KeyType &key, const ::fwData::Object::sptr &object, size_t index=0)
Register an output object at a given key in the OSR, replacing it if it already exists.
virtual FWGUI_API void addButton(IMessageDialog::Buttons button) override
Add a button (OK, YES_NO, YES, NO, CANCEL)
QPointer< QSlider > m_sliceIndexSlider
Slice index slider.
virtual FWGUI_API IMessageDialog::Buttons show() override
Show the message box and return the clicked button.
#define SLM_ERROR_IF(message, cond)
IOPACS_API void updating() override
Override.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
virtual IOPACS_API void stopping() override
Override.
::fwRuntime::ConfigurationElement::sptr m_configuration
Configuration element used to configure service internal state using a generic XML like structure TOD...
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
virtual FWGUI_API void setIcon(IMessageDialog::Icons icon) override
Set the icon (CRITICAL, WARNING, INFO or QUESTION)
This editor service is used to select a slice index and pull the image from the pacs if it is not ava...
IOPACS_API void triggerNewSlice()
Function called when a new slice must be displayed.
std::size_t m_numberOfSlices
Number of instances.
QPointer< QLineEdit > m_sliceIndexLineEdit
Slice index line edit.
::fwIO::IReader::wptr m_dicomReader
Reader.
static FWSERVICES_API ServiceFactory::sptr getDefault()
Return the unique Instance, create it if required at first access.
std::shared_ptr< ::fwThread::Worker > m_associatedWorker
Associated worker.
#define SLM_INFO(message)
std::shared_ptr< fwData::Integer > m_axialIndex
Axial slice index.
std::shared_ptr< ::fwThread::Timer > m_delayTimer2
Timer used to generate the new slice selection delay.
::fwPacsIO::data::PacsConfiguration::csptr m_pacsConfiguration
Pacs Configuration object.
IOPACS_API void readImage(std::size_t selectedSliceIndex)
Read the selected image.
virtual IOPACS_API ~SSliceIndexDicomPullerEditor() noexcept
Destructor.
::fwData::Array::SizeType SizeType
Image size type.
virtual FWGUI_API void setTitle(const std::string &title) override
Set the title of the message box.
std::shared_ptr< ::fwMedData::SeriesDB > m_tempSeriesDB
Temporary SeriesDB.
ReadImageSlotType::sptr m_slotReadImage
Slot to call readLocalSeries method.
IOPACS_API void pullInstance()
Pull the selected slice from the pacs.
FWGUI_API void initialize()
Initialize managers.
std::shared_ptr< ::fwRuntime::ConfigurationElement > m_readerConfig
Optional configuration to set to reader implementation.