Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxReconstructCore.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 
13 #include "cxReconstructCore.h"
14 #include <vtkImageData.h>
15 #include "cxTime.h"
16 #include "cxTypeConversions.h"
18 #include "cxVolumeHelpers.h"
20 #include "cxTimeKeeper.h"
21 #include "cxLogger.h"
22 #include "cxUSFrameData.h"
24 #include "vtkPointData.h"
25 #include "vtkDataArray.h"
26 #include "cxPatientModelService.h"
27 
28 namespace cx
29 {
30 
31 
33  mInput(InputParams()),
34  mPatientModelService(patientModelService)
35 {
36 // mMaxTimeDiff = 100; // TODO: Change default value for max allowed time difference between tracking and image time tags
37  mSuccess = false;
38 }
39 
41 {
42 }
43 
45 {
46  mInput = input;
47  mAlgorithm = algorithm;
48 }
49 
51 {
52  mOutputVolumeParams = outputVolumeParams;
53  mFileData = fileData;
54 }
55 
57 {
58  this->threadedPreReconstruct();
59 // this->threadablePreReconstruct();
60  this->threadedReconstruct();
62  return mOutput;
63 }
64 
69 {
70  if (!this->validInputData())
71  return;
72  mRawOutput = this->generateRawOutputVolume();
73 }
74 
79 {
80  if (!this->validInputData())
81  return;
82  CX_ASSERT(mRawOutput);
83 
84  TimeKeeper timer;
85 
86  mSuccess = mAlgorithm->reconstruct(mFileData, mRawOutput, mInput.mAlgoSettings);
87 
88  timer.printElapsedSeconds("Reconstruct core time");
89 }
90 
95 {
96  if (!this->validInputData())
97  return;
98 
99  if (mSuccess)
100  {
101  mOutput = this->generateOutputVolume(mRawOutput);
102 
103  Eigen::Array3i outputDims(mRawOutput->GetDimensions());
104  int total = outputDims[0] * outputDims[1] * outputDims[2];
105  report(QString("US Reconstruction complete: %1Mb, output=%2, algo=%3, preset=%4, angio=%5")
106  .arg(total/1024/1024)
107  .arg(mOutput->getName())
108  .arg(mAlgorithm->getName())
109  .arg(mInput.mTransferFunctionPreset)
110  .arg(mInput.mAngio));
111 
112  mPatientModelService->insertData(mOutput);
113  }
114  else
115  {
116  reportError("Reconstruction failed");
117  }
118 }
119 
124 ImagePtr ReconstructCore::generateOutputVolume(vtkImageDataPtr rawOutput)
125 {
126  setDeepModified(rawOutput);
127 
128 // //If no output path is selecetd, use the same path as the input
129 // QString filePath;
130 // if (mInput.mOutputBasePath.isEmpty() && mInput.mOutputRelativePath.isEmpty())
131 // filePath = qstring_cast(mFileData->getFilePath());
132 // else
133 // filePath = mInput.mOutputRelativePath;
134 
135  QString uid = this->generateOutputUid();
136  QString name = this->generateImageName(uid);
137 
138  ImagePtr image = mPatientModelService->createSpecificData<Image>(uid + "_%1", name + " %1");
139  image->setVtkImageData(rawOutput);
140 
141 // ImagePtr image = mPatientModelService->createImage(rawOutput, uid + "_%1", name + " %1", filePath);
142  image->get_rMd_History()->setRegistration(mOutputVolumeParams.get_rMd());
143  image->setModality(imUS);
144  if (mInput.mAngio)
145  image->setImageType(istANGIO);
146  else
147  image->setImageType(istUSBMODE);
148 
149  PresetTransferFunctions3DPtr presets = mPatientModelService->getPresetTransferFunctions3D();
150  presets->load(mInput.mTransferFunctionPreset, image, true, false);//Only apply to 2D, not 3D
151  presets->load("US B-Mode", image, false, true);//Only apply to 3D, not 2D
152 
153  return image;
154 }
155 
160 vtkImageDataPtr ReconstructCore::generateRawOutputVolume()
161 {
162  Eigen::Array3i dim = mOutputVolumeParams.getDim();
163  Vector3D spacing = Vector3D(1, 1, 1) * mOutputVolumeParams.getSpacing();
164  vtkImageDataPtr data = generateVtkImageData(dim, spacing, 0);
165  return data;
166 }
167 
173 QString ReconstructCore::generateOutputUid()
174 {
175  QString base = mFileData->getUid();
176  QString name = mFileData->getFilePath().split("/").back();
177  name = name.split(".").front();
178 
179  QStringList split = name.split("_");
180  QStringList prefix = split.front().split("-");
181  if (prefix.size() == 2)
182  {
183  split[0] = prefix[0];
184  }
185  else
186  {
187  split[0] += "_rec";
188  }
189 
190  return split.join("_");
191 }
192 
198 QString ReconstructCore::generateImageName(QString uid) const
199 {
200  QString name = uid.split("/").back();
201  name = name.split(".").front();
202  QString prefix = name.split("_").front(); // retrieve US-Acq part
203  prefix = prefix.split("-").front(); // retrieve US part.
204  if (prefix.isEmpty())
205  prefix = "US";
206 
207 // std::cout << "reconstruct input uid " << uid << std::endl;
208  if (mInput.mAngio) // tag angio images as such
209  prefix += "A";
210 
211  // retrieve index counter from _99_
212  QString counter = "";
213  QRegExp countReg("_[0-9]{1,2}_");
214  if (countReg.indexIn(name) > 0)
215  {
216  counter = countReg.cap(0).remove("_");
217  }
218 
219  // retrieve timestamp as HH:MM
220  QRegExp tsReg("[0-9]{8}T[0-9]{6}");
221  if (tsReg.indexIn(name) > 0)
222  {
223  QString postfix = name.split("_").back();
224  QDateTime datetime = QDateTime::fromString(tsReg.cap(0), timestampSecondsFormat());
225  QString timestamp = datetime.toString("hh:mm");
226  return prefix + " " + counter + " " + postfix + " " + timestamp;
227  }
228 
229  return name;
230 }
231 
233 {
234  return mOutput;
235 }
236 
237 bool ReconstructCore::validInputData() const
238 {
239  return mAlgorithm!=0;
240 }
241 
242 } /* namespace cx */
void reportError(QString msg)
Definition: cxLogger.cpp:71
Abstract interface for reconstruction algorithm.
#define CX_ASSERT(statement)
Definition: cxLogger.h:116
virtual void setVtkImageData(const vtkImageDataPtr &data, bool resetTransferFunctions=true)
Definition: cxImage.cpp:268
boost::shared_ptr< class TransferFunctions3DPresets > PresetTransferFunctions3DPtr
Definition: cxDataManager.h:36
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
istANGIO
Helper struct for sending and controlling output volume properties.
QString timestampSecondsFormat()
Definition: cxTime.cpp:18
istUSBMODE
A volumetric data set.
Definition: cxImage.h:45
virtual QString getName() const =0
void initialize(InputParams input, ReconstructionMethodService *algorithm)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
virtual bool reconstruct(ProcessedUSInputDataPtr input, vtkImageDataPtr outputData, QDomElement settings)=0
vtkImageDataPtr generateVtkImageData(Eigen::Array3i dim, Vector3D spacing, const unsigned char initValue, int components)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
void printElapsedSeconds(QString text="Elapsed time")
void report(QString msg)
Definition: cxLogger.cpp:69
void setDeepModified(vtkImageDataPtr image)
imUS
bool mAngio
true for angio data, false is B-mode.
ReconstructCore(PatientModelServicePtr patientModelService)
boost::shared_ptr< class ProcessedUSInputData > ProcessedUSInputDataPtr
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
Namespace for all CustusX production code.