CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxUSSavingRecorder.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 #include "cxUSSavingRecorder.h"
13 
14 #include <QtConcurrentRun>
15 #include "boost/bind.hpp"
16 
17 #include "cxTypeConversions.h"
18 
19 #include "cxTime.h"
20 #include "cxTool.h"
21 #include "cxVideoSource.h"
22 #include "cxLogger.h"
23 #include "cxDataLocations.h"
24 #include "cxSavingVideoRecorder.h"
25 #include "cxImageDataContainer.h"
26 #include "cxRecordSession.h"
28 //#include "cxFileManagerServiceProxy.h"
29 //#include "cxLogicManager.h"
30 
31 namespace cx
32 {
33 
34 
35 USSavingRecorder::USSavingRecorder() : mDoWriteColor(true), m_rMpr(Transform3D::Identity())
36 {
37 
38 }
39 
41 {
42  std::list<QFutureWatcher<QString>*>::iterator iter;
43  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end(); ++iter)
44  {
45  (*iter)->waitForFinished();
46  }
47 }
48 
50 {
51  mDoWriteColor = on;
52 }
53 
55 {
56  m_rMpr = rMpr;
57 }
58 
59 void USSavingRecorder::startRecord(RecordSessionPtr session, ToolPtr tool, ToolPtr reference, std::vector<VideoSourcePtr> video, FileManagerServicePtr filemanager)
60 {
61  this->clearRecording(); // clear previous data if any
62 
63  mRecordingTool = tool;
64  mReference = reference;
65  mSession = session;
66 
67  QString tempBaseFolder = DataLocations::getCachePath()+"/usacq/"+QDateTime::currentDateTime().toString(timestampSecondsFormat());
68  QString cacheFolder = UsReconstructionFileMaker::createUniqueFolder(tempBaseFolder, session->getDescription());
69 
70  for (unsigned i=0; i<video.size(); ++i)
71  {
72  SavingVideoRecorderPtr videoRecorder;
73  videoRecorder.reset(new SavingVideoRecorder(
74  video[i],
75  cacheFolder,
76  QString("%1_%2").arg(session->getDescription()).arg(video[i]->getUid()),
77  false, // no compression when saving to cache
78  mDoWriteColor,
79  filemanager
80  ));
81  videoRecorder->startRecord();
82  mVideoRecorder.push_back(videoRecorder);
83  }
84 
85  reportSuccess("Ultrasound acquisition started.");
86 }
87 
89 {
90  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
91  mVideoRecorder[i]->stopRecord();
92  reportSuccess("Ultrasound acquisition stopped.");
93 
94  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
95  {
96  // complete writing of images to temporary storage. Do this before using the image data.
97  mVideoRecorder[i]->completeSave();
98  }
99 }
100 
102 {
103  this->clearRecording();
104  report("Ultrasound acquisition cancelled.");
105 }
106 
108 {
109  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
110  {
111  if (mVideoRecorder[i]->getSource()->getUid() == streamUid)
112  return this->getDataForStream(i);
113  }
114  return USReconstructInputData();
115 }
116 
118 {
119  if (!mSession)
120  return USReconstructInputData();
121  if (videoRecorderIndex>=mVideoRecorder.size())
122  return USReconstructInputData();
123 
124  SavingVideoRecorderPtr videoRecorder = mVideoRecorder[videoRecorderIndex];
125  videoRecorder->completeSave(); // just in case - should have been done earlier.
126  TimedTransformMap trackerRecordedData = RecordSession::getToolHistory_prMt(mRecordingTool, mSession, true);
127  std::map<double, cx::ToolPositionMetadata> trackerMetadata = RecordSession::getToolHistory_metadata(mRecordingTool, mSession, true);
128  std::map<double, cx::ToolPositionMetadata> referenceTrackerMetadata = RecordSession::getToolHistory_metadata(mReference, mSession, true);
129  std::cout << "----------- "
130  "trackerMetadata : " << trackerMetadata.size() << std::endl;
131 
132  CachedImageDataContainerPtr imageData = videoRecorder->getImageData();
133  std::vector<TimeInfo> imageTimestamps = videoRecorder->getTimestamps();
134  QString streamSessionName = mSession->getDescription()+"_"+videoRecorder->getSource()->getUid();
135 
137  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
138  USReconstructInputData reconstructData = fileMaker->getReconstructData(imageData,
139  imageTimestamps,
140  trackerRecordedData,
141  trackerMetadata,
142  referenceTrackerMetadata,
143  mRecordingTool,
144  videoRecorder->getSource()->getUid(),
145  mDoWriteColor,
146  m_rMpr);
147  return reconstructData;
148 }
149 
150 void USSavingRecorder::startSaveData(QString baseFolder, bool compressImages)
151 {
152  if (!mSession)
153  return;
154 
155  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
156  {
158 
159  QString streamSessionName = mSession->getDescription()+"_"+mVideoRecorder[i]->getSource()->getUid();
160  QString saveFolder = UsReconstructionFileMaker::createFolder(baseFolder, mSession->getDescription());
161 
162  this->saveStreamSession(data, saveFolder, streamSessionName, compressImages);
163  }
164 }
165 
167 {
168  mVideoRecorder.clear();
169  mSession.reset();
170  mRecordingTool.reset();
171 }
172 
173 
175 {
176  return mSaveThreads.size();
177 }
178 
179 void USSavingRecorder::saveStreamSession(USReconstructInputData reconstructData, QString saveFolder, QString streamSessionName, bool compress)
180 {
182  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
183  fileMaker->setReconstructData(reconstructData);
184 
185  // now start saving of data to the patient folder, compressed version:
186  QFuture<QString> fileMakerFuture =
187  QtConcurrent::run(boost::bind(
189  fileMaker,
190  saveFolder,
191  compress
192  ));
193  QFutureWatcher<QString>* fileMakerFutureWatcher = new QFutureWatcher<QString>();
194  connect(fileMakerFutureWatcher, SIGNAL(finished()), this, SLOT(fileMakerWriteFinished()));
195  fileMakerFutureWatcher->setFuture(fileMakerFuture);
196  mSaveThreads.push_back(fileMakerFutureWatcher);
197  fileMaker.reset(); // filemaker is now stored in the mSaveThreads queue, clear as current.
198 }
199 
200 void USSavingRecorder::fileMakerWriteFinished()
201 {
202  std::list<QFutureWatcher<QString>*>::iterator iter;
203  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end();)
204  {
205  if (!(*iter)->isFinished())
206  {
207  ++iter;
208  continue;
209  }
210  QString result = (*iter)->future().result();
211  delete *iter;
212  //this increments the iter, so no need to do it in the for statement
213  iter = mSaveThreads.erase(iter);
214 
215  emit saveDataCompleted(result);
216  }
217 }
218 
219 }
boost::shared_ptr< class FileManagerService > FileManagerServicePtr
void startSaveData(QString baseFolder, bool compressImages)
static std::map< double, ToolPositionMetadata > getToolHistory_metadata(ToolPtr tool, RecordSessionPtr session, bool verbose)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Handles writing files in the format the us reconstruction algorithm wants them.
QString writeToNewFolder(QString path, bool compression)
boost::shared_ptr< class SavingVideoRecorder > SavingVideoRecorderPtr
QString timestampSecondsFormat()
Definition: cxTime.cpp:18
static TimedTransformMap getToolHistory_prMt(ToolPtr tool, RecordSessionPtr session, bool verbose)
void set_rMpr(Transform3D rMpr)
boost::shared_ptr< class RecordSession > RecordSessionPtr
static QString getCachePath()
return path to a folder that is used during execution, will be cleared at start and stop...
size_t getNumberOfSavingThreads() const
static QString createFolder(QString patientFolder, QString sessionDescription)
void reportSuccess(QString msg)
Definition: cxLogger.cpp:72
void startRecord(RecordSessionPtr session, ToolPtr tool, ToolPtr reference, std::vector< VideoSourcePtr > video, FileManagerServicePtr filemanager)
void report(QString msg)
Definition: cxLogger.cpp:69
void saveDataCompleted(QString mhdFilename)
emitted when data has been saved to file
Recorder for a VideoSource.
boost::shared_ptr< class UsReconstructionFileMaker > UsReconstructionFileMakerPtr
USReconstructInputData getDataForStream(QString streamUid)
boost::shared_ptr< class CachedImageDataContainer > CachedImageDataContainerPtr
static QString createUniqueFolder(QString patientFolder, QString sessionDescription)
std::map< double, Transform3D > TimedTransformMap
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr