Fraxinus  16.5.0-fx-rc9
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxUSSavingRecorder.h"
34 
35 #include <QtConcurrentRun>
36 #include "boost/bind.hpp"
37 
38 #include "cxTypeConversions.h"
39 
40 #include "cxTime.h"
41 #include "cxTool.h"
42 #include "cxVideoSource.h"
43 #include "cxLogger.h"
44 #include "cxDataLocations.h"
45 #include "cxSavingVideoRecorder.h"
46 #include "cxImageDataContainer.h"
47 #include "cxRecordSession.h"
49 
50 
51 namespace cx
52 {
53 
54 
55 USSavingRecorder::USSavingRecorder() : mDoWriteColor(true), m_rMpr(Transform3D::Identity())
56 {
57 
58 }
59 
61 {
62  std::list<QFutureWatcher<QString>*>::iterator iter;
63  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end(); ++iter)
64  {
65  (*iter)->waitForFinished();
66  }
67 }
68 
70 {
71  mDoWriteColor = on;
72 }
73 
75 {
76  m_rMpr = rMpr;
77 }
78 
79 void USSavingRecorder::startRecord(RecordSessionPtr session, ToolPtr tool, ToolPtr reference, std::vector<VideoSourcePtr> video)
80 {
81  this->clearRecording(); // clear previous data if any
82 
83  mRecordingTool = tool;
84  mReference = reference;
85  mSession = session;
86 
87  QString tempBaseFolder = DataLocations::getCachePath()+"/usacq/"+QDateTime::currentDateTime().toString(timestampSecondsFormat());
88  QString cacheFolder = UsReconstructionFileMaker::createUniqueFolder(tempBaseFolder, session->getDescription());
89 
90  for (unsigned i=0; i<video.size(); ++i)
91  {
92  SavingVideoRecorderPtr videoRecorder;
93  videoRecorder.reset(new SavingVideoRecorder(
94  video[i],
95  cacheFolder,
96  QString("%1_%2").arg(session->getDescription()).arg(video[i]->getUid()),
97  false, // no compression when saving to cache
98  mDoWriteColor));
99  videoRecorder->startRecord();
100  mVideoRecorder.push_back(videoRecorder);
101  }
102 
103  reportSuccess("Ultrasound acquisition started.");
104 }
105 
107 {
108  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
109  mVideoRecorder[i]->stopRecord();
110  reportSuccess("Ultrasound acquisition stopped.");
111 
112  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
113  {
114  // complete writing of images to temporary storage. Do this before using the image data.
115  mVideoRecorder[i]->completeSave();
116  }
117 }
118 
120 {
121  this->clearRecording();
122  report("Ultrasound acquisition cancelled.");
123 }
124 
126 {
127  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
128  {
129  if (mVideoRecorder[i]->getSource()->getUid() == streamUid)
130  return this->getDataForStream(i);
131  }
132  return USReconstructInputData();
133 }
134 
136 {
137  if (!mSession)
138  return USReconstructInputData();
139  if (videoRecorderIndex>=mVideoRecorder.size())
140  return USReconstructInputData();
141 
142  SavingVideoRecorderPtr videoRecorder = mVideoRecorder[videoRecorderIndex];
143  videoRecorder->completeSave(); // just in case - should have been done earlier.
144  TimedTransformMap trackerRecordedData = RecordSession::getToolHistory_prMt(mRecordingTool, mSession, true);
145  std::map<double, cx::ToolPositionMetadata> trackerMetadata = RecordSession::getToolHistory_metadata(mRecordingTool, mSession, true);
146  std::map<double, cx::ToolPositionMetadata> referenceTrackerMetadata = RecordSession::getToolHistory_metadata(mReference, mSession, true);
147  std::cout << "----------- "
148  "trackerMetadata : " << trackerMetadata.size() << std::endl;
149 
150  CachedImageDataContainerPtr imageData = videoRecorder->getImageData();
151  std::vector<TimeInfo> imageTimestamps = videoRecorder->getTimestamps();
152  QString streamSessionName = mSession->getDescription()+"_"+videoRecorder->getSource()->getUid();
153 
155  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
156  USReconstructInputData reconstructData = fileMaker->getReconstructData(imageData,
157  imageTimestamps,
158  trackerRecordedData,
159  trackerMetadata,
160  referenceTrackerMetadata,
161  mRecordingTool,
162  videoRecorder->getSource()->getUid(),
163  mDoWriteColor,
164  m_rMpr);
165  return reconstructData;
166 }
167 
168 void USSavingRecorder::startSaveData(QString baseFolder, bool compressImages)
169 {
170  if (!mSession)
171  return;
172 
173  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
174  {
176 
177  QString streamSessionName = mSession->getDescription()+"_"+mVideoRecorder[i]->getSource()->getUid();
178  QString saveFolder = UsReconstructionFileMaker::createFolder(baseFolder, mSession->getDescription());
179 
180  this->saveStreamSession(data, saveFolder, streamSessionName, compressImages);
181  }
182 }
183 
185 {
186  mVideoRecorder.clear();
187  mSession.reset();
188  mRecordingTool.reset();
189 }
190 
191 
193 {
194  return mSaveThreads.size();
195 }
196 
197 void USSavingRecorder::saveStreamSession(USReconstructInputData reconstructData, QString saveFolder, QString streamSessionName, bool compress)
198 {
200  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
201  fileMaker->setReconstructData(reconstructData);
202 
203  // now start saving of data to the patient folder, compressed version:
204  QFuture<QString> fileMakerFuture =
205  QtConcurrent::run(boost::bind(
207  fileMaker,
208  saveFolder,
209  compress
210  ));
211  QFutureWatcher<QString>* fileMakerFutureWatcher = new QFutureWatcher<QString>();
212  connect(fileMakerFutureWatcher, SIGNAL(finished()), this, SLOT(fileMakerWriteFinished()));
213  fileMakerFutureWatcher->setFuture(fileMakerFuture);
214  mSaveThreads.push_back(fileMakerFutureWatcher);
215  fileMaker.reset(); // filemaker is now stored in the mSaveThreads queue, clear as current.
216 }
217 
218 void USSavingRecorder::fileMakerWriteFinished()
219 {
220  std::list<QFutureWatcher<QString>*>::iterator iter;
221  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end();)
222  {
223  if (!(*iter)->isFinished())
224  {
225  ++iter;
226  continue;
227  }
228  QString result = (*iter)->future().result();
229  delete *iter;
230  //this increments the iter, so no need to do it in the for statement
231  iter = mSaveThreads.erase(iter);
232 
233  emit saveDataCompleted(result);
234  }
235 }
236 
237 }
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:39
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:93
void report(QString msg)
Definition: cxLogger.cpp:90
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
boost::shared_ptr< class Tool > ToolPtr