CustusX  18.04
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 
29 
30 namespace cx
31 {
32 
33 
34 USSavingRecorder::USSavingRecorder() : mDoWriteColor(true), m_rMpr(Transform3D::Identity())
35 {
36 
37 }
38 
40 {
41  std::list<QFutureWatcher<QString>*>::iterator iter;
42  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end(); ++iter)
43  {
44  (*iter)->waitForFinished();
45  }
46 }
47 
49 {
50  mDoWriteColor = on;
51 }
52 
54 {
55  m_rMpr = rMpr;
56 }
57 
58 void USSavingRecorder::startRecord(RecordSessionPtr session, ToolPtr tool, ToolPtr reference, std::vector<VideoSourcePtr> video)
59 {
60  this->clearRecording(); // clear previous data if any
61 
62  mRecordingTool = tool;
63  mReference = reference;
64  mSession = session;
65 
66  QString tempBaseFolder = DataLocations::getCachePath()+"/usacq/"+QDateTime::currentDateTime().toString(timestampSecondsFormat());
67  QString cacheFolder = UsReconstructionFileMaker::createUniqueFolder(tempBaseFolder, session->getDescription());
68 
69  for (unsigned i=0; i<video.size(); ++i)
70  {
71  SavingVideoRecorderPtr videoRecorder;
72  videoRecorder.reset(new SavingVideoRecorder(
73  video[i],
74  cacheFolder,
75  QString("%1_%2").arg(session->getDescription()).arg(video[i]->getUid()),
76  false, // no compression when saving to cache
77  mDoWriteColor));
78  videoRecorder->startRecord();
79  mVideoRecorder.push_back(videoRecorder);
80  }
81 
82  reportSuccess("Ultrasound acquisition started.");
83 }
84 
86 {
87  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
88  mVideoRecorder[i]->stopRecord();
89  reportSuccess("Ultrasound acquisition stopped.");
90 
91  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
92  {
93  // complete writing of images to temporary storage. Do this before using the image data.
94  mVideoRecorder[i]->completeSave();
95  }
96 }
97 
99 {
100  this->clearRecording();
101  report("Ultrasound acquisition cancelled.");
102 }
103 
105 {
106  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
107  {
108  if (mVideoRecorder[i]->getSource()->getUid() == streamUid)
109  return this->getDataForStream(i);
110  }
111  return USReconstructInputData();
112 }
113 
115 {
116  if (!mSession)
117  return USReconstructInputData();
118  if (videoRecorderIndex>=mVideoRecorder.size())
119  return USReconstructInputData();
120 
121  SavingVideoRecorderPtr videoRecorder = mVideoRecorder[videoRecorderIndex];
122  videoRecorder->completeSave(); // just in case - should have been done earlier.
123  TimedTransformMap trackerRecordedData = RecordSession::getToolHistory_prMt(mRecordingTool, mSession, true);
124  std::map<double, cx::ToolPositionMetadata> trackerMetadata = RecordSession::getToolHistory_metadata(mRecordingTool, mSession, true);
125  std::map<double, cx::ToolPositionMetadata> referenceTrackerMetadata = RecordSession::getToolHistory_metadata(mReference, mSession, true);
126  std::cout << "----------- "
127  "trackerMetadata : " << trackerMetadata.size() << std::endl;
128 
129  CachedImageDataContainerPtr imageData = videoRecorder->getImageData();
130  std::vector<TimeInfo> imageTimestamps = videoRecorder->getTimestamps();
131  QString streamSessionName = mSession->getDescription()+"_"+videoRecorder->getSource()->getUid();
132 
134  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
135  USReconstructInputData reconstructData = fileMaker->getReconstructData(imageData,
136  imageTimestamps,
137  trackerRecordedData,
138  trackerMetadata,
139  referenceTrackerMetadata,
140  mRecordingTool,
141  videoRecorder->getSource()->getUid(),
142  mDoWriteColor,
143  m_rMpr);
144  return reconstructData;
145 }
146 
147 void USSavingRecorder::startSaveData(QString baseFolder, bool compressImages)
148 {
149  if (!mSession)
150  return;
151 
152  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
153  {
155 
156  QString streamSessionName = mSession->getDescription()+"_"+mVideoRecorder[i]->getSource()->getUid();
157  QString saveFolder = UsReconstructionFileMaker::createFolder(baseFolder, mSession->getDescription());
158 
159  this->saveStreamSession(data, saveFolder, streamSessionName, compressImages);
160  }
161 }
162 
164 {
165  mVideoRecorder.clear();
166  mSession.reset();
167  mRecordingTool.reset();
168 }
169 
170 
172 {
173  return mSaveThreads.size();
174 }
175 
176 void USSavingRecorder::saveStreamSession(USReconstructInputData reconstructData, QString saveFolder, QString streamSessionName, bool compress)
177 {
179  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
180  fileMaker->setReconstructData(reconstructData);
181 
182  // now start saving of data to the patient folder, compressed version:
183  QFuture<QString> fileMakerFuture =
184  QtConcurrent::run(boost::bind(
186  fileMaker,
187  saveFolder,
188  compress
189  ));
190  QFutureWatcher<QString>* fileMakerFutureWatcher = new QFutureWatcher<QString>();
191  connect(fileMakerFutureWatcher, SIGNAL(finished()), this, SLOT(fileMakerWriteFinished()));
192  fileMakerFutureWatcher->setFuture(fileMakerFuture);
193  mSaveThreads.push_back(fileMakerFutureWatcher);
194  fileMaker.reset(); // filemaker is now stored in the mSaveThreads queue, clear as current.
195 }
196 
197 void USSavingRecorder::fileMakerWriteFinished()
198 {
199  std::list<QFutureWatcher<QString>*>::iterator iter;
200  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end();)
201  {
202  if (!(*iter)->isFinished())
203  {
204  ++iter;
205  continue;
206  }
207  QString result = (*iter)->future().result();
208  delete *iter;
209  //this increments the iter, so no need to do it in the for statement
210  iter = mSaveThreads.erase(iter);
211 
212  emit saveDataCompleted(result);
213  }
214 }
215 
216 }
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)
void startRecord(RecordSessionPtr session, ToolPtr tool, ToolPtr reference, std::vector< VideoSourcePtr > video)
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 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