CustusX  15.8
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, std::vector<VideoSourcePtr> video)
80 {
81  this->clearRecording(); // clear previous data if any
82 
83  mRecordingTool = tool;
84  mSession = session;
85 
86  QString tempBaseFolder = DataLocations::getCachePath()+"/usacq/"+QDateTime::currentDateTime().toString(timestampSecondsFormat());
87  QString cacheFolder = UsReconstructionFileMaker::createUniqueFolder(tempBaseFolder, session->getDescription());
88 
89  for (unsigned i=0; i<video.size(); ++i)
90  {
91  SavingVideoRecorderPtr videoRecorder;
92  videoRecorder.reset(new SavingVideoRecorder(
93  video[i],
94  cacheFolder,
95  QString("%1_%2").arg(session->getDescription()).arg(video[i]->getUid()),
96  false, // no compression when saving to cache
97  mDoWriteColor));
98  videoRecorder->startRecord();
99  mVideoRecorder.push_back(videoRecorder);
100  }
101 
102  reportSuccess("Ultrasound acquisition started.");
103 }
104 
106 {
107  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
108  mVideoRecorder[i]->stopRecord();
109  reportSuccess("Ultrasound acquisition stopped.");
110 
111  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
112  {
113  // complete writing of images to temporary storage. Do this before using the image data.
114  mVideoRecorder[i]->completeSave();
115 // std::cout << QString("completed save of cached video stream %1").arg(i) << std::endl;
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);
145 
146  CachedImageDataContainerPtr imageData = videoRecorder->getImageData();
147  std::vector<double> imageTimestamps = videoRecorder->getTimestamps();
148  QString streamSessionName = mSession->getDescription()+"_"+videoRecorder->getSource()->getUid();
149 
151  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
152  USReconstructInputData reconstructData = fileMaker->getReconstructData(imageData,
153  imageTimestamps,
154  trackerRecordedData,
155  mRecordingTool,
156  mDoWriteColor,
157  m_rMpr);
158  return reconstructData;
159 }
160 
161 void USSavingRecorder::startSaveData(QString baseFolder, bool compressImages)
162 {
163  if (!mSession)
164  return;
165 
166  TimedTransformMap trackerRecordedData = RecordSession::getToolHistory_prMt(mRecordingTool, mSession);
167 
168  for (unsigned i=0; i<mVideoRecorder.size(); ++i)
169  {
171 
172  QString streamSessionName = mSession->getDescription()+"_"+mVideoRecorder[i]->getSource()->getUid();
173  QString saveFolder = UsReconstructionFileMaker::createFolder(baseFolder, mSession->getDescription());
174 
175  this->saveStreamSession(data, saveFolder, streamSessionName, compressImages);
176  }
177 
178 // this->clearRecording();
179 }
180 
182 {
183  mVideoRecorder.clear();
184  mSession.reset();
185  mRecordingTool.reset();
186 }
187 
188 
190 {
191  return mSaveThreads.size();
192 }
193 
194 void USSavingRecorder::saveStreamSession(USReconstructInputData reconstructData, QString saveFolder, QString streamSessionName, bool compress)
195 {
197  fileMaker.reset(new UsReconstructionFileMaker(streamSessionName));
198  fileMaker->setReconstructData(reconstructData);
199 
200  // now start saving of data to the patient folder, compressed version:
201  QFuture<QString> fileMakerFuture =
202  QtConcurrent::run(boost::bind(
204  fileMaker,
205  saveFolder,
206  compress
207  ));
208  QFutureWatcher<QString>* fileMakerFutureWatcher = new QFutureWatcher<QString>();
209  connect(fileMakerFutureWatcher, SIGNAL(finished()), this, SLOT(fileMakerWriteFinished()));
210  fileMakerFutureWatcher->setFuture(fileMakerFuture);
211  mSaveThreads.push_back(fileMakerFutureWatcher);
212  fileMaker.reset(); // filemaker is now stored in the mSaveThreads queue, clear as current.
213 }
214 
215 void USSavingRecorder::fileMakerWriteFinished()
216 {
217  std::list<QFutureWatcher<QString>*>::iterator iter;
218  for (iter=mSaveThreads.begin(); iter!=mSaveThreads.end();)
219  {
220  if (!(*iter)->isFinished())
221  {
222  ++iter;
223  continue;
224  }
225  QString result = (*iter)->future().result();
226  delete *iter;
227  //this increments the iter, so no need to do it in the for statement
228  iter = mSaveThreads.erase(iter);
229 
230  emit saveDataCompleted(result);
231  }
232 }
233 
234 }
void startSaveData(QString baseFolder, bool compressImages)
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
void startRecord(RecordSessionPtr session, ToolPtr tool, std::vector< VideoSourcePtr > video)
static TimedTransformMap getToolHistory_prMt(ToolPtr tool, RecordSessionPtr session)
QString timestampSecondsFormat()
Definition: cxTime.cpp:39
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