35 #include <QTextStream>
39 #include <vtkImageChangeInformation.h>
40 #include <vtkImageData.h>
41 #include "vtkImageAppend.h"
42 #include "vtkMetaImageWriter.h"
62 mSessionDescription(sessionDescription)
72 return mReconstructData;
80 std::vector<TimeInfo> imageTimestamps,
82 std::map<double, ToolPositionMetadata> trackerRecordedMetadata,
83 std::map<double, ToolPositionMetadata> referenceRecordedMetadata,
84 ToolPtr tool, QString streamUid,
87 if(trackerRecordedData.empty())
88 reportWarning(
"No tracking data for writing to reconstruction file.");
98 for (TimedTransformMap::iterator it = trackerRecordedData.begin(); it != trackerRecordedData.end(); ++it)
101 current.
mTime = it->first;
103 current.
mPos = it->second;
107 std::vector<TimeInfo> fts = imageTimestamps;
108 for (
unsigned i=0; i<fts.size(); ++i)
110 TimedPosition current;
113 current.mPos = Transform3D::Identity();
115 retval.
mFrames.push_back(current);
118 if (tool && tool->getProbe())
126 this->fillFramePositions(&retval);
135 void UsReconstructionFileMaker::fillFramePositions(USReconstructInputData* data)
const
141 bool UsReconstructionFileMaker::writeTrackerTimestamps(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
143 return this->writeTimestamps(reconstructionFolder+
"/"+session+
".tts",
144 ts,
"tracking timestamps");
147 bool UsReconstructionFileMaker::writeUSTimestamps(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
151 retval = this->writeTimestamps(reconstructionFolder+
"/"+session+
".fts",
152 ts,
"frame timestamps", Modified);
154 retval &= this->writeTimestamps(reconstructionFolder+
"/"+session+
".scanner.frameTimestamps",
155 ts,
"frame scanner timestamps", Scanner);
157 retval &= this->writeTimestamps(reconstructionFolder+
"/"+session+
".softwareArrive.frameTimestamps",
158 ts,
"frame arrive in software timestamps", SoftwareArrive);
162 bool UsReconstructionFileMaker::writeTimestamps(QString filename, std::vector<TimedPosition> ts, QString type, TimeStampType timeStampType)
164 bool success =
false;
166 QFile file(filename);
167 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
172 QTextStream stream(&file);
174 for (
unsigned i=0; i<ts.size(); ++i)
176 switch(timeStampType)
179 stream <<
qstring_cast(ts[i].mTimeInfo.getAcquisitionTime());
182 stream <<
qstring_cast(ts[i].mTimeInfo.getSoftwareAcquisitionTime());
185 stream <<
qstring_cast(ts[i].mTimeInfo.getScannerAcquisitionTime());
196 QFileInfo info(file);
197 mReport << QString(
"%1, %2 bytes, %3 %4.")
198 .arg(info.fileName())
207 bool UsReconstructionFileMaker::writeUSTransforms(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
209 return this->writeTransforms(reconstructionFolder+
"/"+session+
".fp", ts,
"frame transforms rMu");
212 bool UsReconstructionFileMaker::writeTrackerMetadata(QString reconstructionFolder, QString session,
const std::map<double, ToolPositionMetadata>& ts)
214 QString filename = reconstructionFolder+
"/"+session+
".probe.toolmeta";
215 return this->writeMetadata(filename, ts,
"tracker metadata");
218 bool UsReconstructionFileMaker::writeReferenceMetadata(QString reconstructionFolder, QString session,
const std::map<double, ToolPositionMetadata>& ts)
220 QString filename = reconstructionFolder+
"/"+session+
".ref.toolmeta";
221 return this->writeMetadata(filename, ts,
"tracker metadata");
224 bool UsReconstructionFileMaker::writeMetadata(QString filename,
const std::map<double, ToolPositionMetadata>& ts, QString type)
226 bool success =
false;
227 QFile file(filename);
228 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
233 QTextStream stream(&file);
235 for (std::map<double, ToolPositionMetadata>::const_iterator i=ts.begin(); i!=ts.end(); ++i)
237 stream << i->second.toString() << endl;
242 QFileInfo info(file);
248 bool UsReconstructionFileMaker::writeTrackerTransforms(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
250 return this->writeTransforms(reconstructionFolder+
"/"+session+
".tp", ts,
"tracking transforms prMt");
253 bool UsReconstructionFileMaker::writeTransforms(QString filename, std::vector<TimedPosition> ts, QString type)
255 bool success =
false;
256 QFile file(filename);
257 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
262 QTextStream stream(&file);
264 for (
unsigned i=0; i<ts.size(); ++i)
286 QFileInfo info(file);
295 void UsReconstructionFileMaker::writeProbeConfiguration(QString reconstructionFolder, QString session, ProbeDefinition data, QString uid)
297 XmlOptionFile file = XmlOptionFile(reconstructionFolder +
"/" + session +
".probedata.xml");
298 data.addXml(file.getElement(
"configuration"));
299 file.getElement(
"tool").toElement().setAttribute(
"toolID", uid);
306 QDir patientDir(patientFolder +
"/US_Acq");
308 QString subfolder = sessionDescription;
309 QString subfolderAbsolutePath = patientDir.absolutePath()+
"/"+subfolder;
310 QString newPathName = subfolderAbsolutePath;
312 while(!findNewSubfolder(newPathName))
314 newPathName = subfolderAbsolutePath+
"_"+QString::number(i++);
316 patientDir.mkpath(newPathName);
317 patientDir.cd(newPathName);
319 retval = patientDir.absolutePath();
326 QDir patientDir(patientFolder +
"/US_Acq");
328 QString subfolder = sessionDescription;
329 QString subfolderAbsolutePath = patientDir.absolutePath()+
"/"+subfolder;
330 QString newPathName = subfolderAbsolutePath;
331 patientDir.mkpath(newPathName);
332 patientDir.cd(newPathName);
334 retval = patientDir.absolutePath();
338 bool UsReconstructionFileMaker::findNewSubfolder(QString subfolderAbsolutePath)
341 if(dir.exists(subfolderAbsolutePath))
347 void UsReconstructionFileMaker::report()
349 foreach(QString
string, mReport)
355 void UsReconstructionFileMaker::writeUSImages(QString path,
ImageDataContainerPtr images,
bool compression, std::vector<TimedPosition> pos)
360 for (
unsigned i=0; i<images->size(); ++i)
363 QString filename = QString(
"%1/%2_%3.mhd").arg(path).arg(mSessionDescription).arg(i);
365 writer->SetInputData(currentImage);
367 writer->SetCompression(compression);
369 StaticMutexVtkLocker lock;
374 customReader->setTransform(pos[i].mPos);
375 customReader->setModality(
"US");
376 customReader->setImageType(mSessionDescription);
380 void UsReconstructionFileMaker::writeMask(QString path, QString session,
vtkImageDataPtr mask)
382 QString filename = QString(
"%1/%2.mask.mhd").arg(path).arg(session);
385 reportWarning(QString(
"No mask found, ignoring write to %1").arg(filename));
390 writer->SetInputData(mask);
392 writer->SetCompression(
false);
397 void UsReconstructionFileMaker::writeREADMEFile(QString reconstructionFolder, QString session)
400 "* ==== Format description \n"
402 "* http://custusx.org/uploads/developer_doc/nightly/org_custusx_acquisition.html \n"
403 "* for a description of the files. \n"
406 QFile file(reconstructionFolder+
"/"+session+
".README.txt");
407 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
412 QTextStream stream(&file);
420 mReconstructData.
mFilename = path+
"/"+mSessionDescription+
".fts";
423 mReport <<
"Made reconstruction folder: " + path;
424 QString session = mSessionDescription;
428 this->writeTrackerTimestamps(path, session, mReconstructData.
mPositions);
429 this->writeTrackerTransforms(path, session, mReconstructData.
mPositions);
430 this->writeUSTimestamps(path, session, mReconstructData.
mFrames);
431 this->writeUSTransforms(path, session, mReconstructData.
mFrames);
433 this->writeMask(path, session, mReconstructData.
getMask());
434 this->writeREADMEFile(path, session);
438 this->writeUSImages(path, imageData, compression, mReconstructData.
mFrames);
440 mReport <<
"failed to find frame data, save failed.";
443 mReport << QString(
"Completed save to %1. Spent %2s, %3fps").arg(mSessionDescription).arg(time/1000).arg(imageData->size()*1000/time);
QString qstring_cast(const T &val)
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
void reportError(QString msg)
~UsReconstructionFileMaker()
UsReconstructionFileMaker(QString sessionDescription)
#define CX_ASSERT(statement)
One position with timestamp.
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
vtkSmartPointer< vtkImageAppend > vtkImageAppendPtr
cstring_cast_Placeholder cstring_cast(const T &val)
QString writeToNewFolder(QString path, bool compression)
boost::shared_ptr< class CustomMetaImage > CustomMetaImagePtr
void setAcquisitionTime(double mSecsSinceEpoch)
void reportWarning(QString msg)
double getAcquisitionTime() const
vtkSmartPointer< class vtkMetaImageWriter > vtkMetaImageWriterPtr
static QString createFolder(QString patientFolder, QString sessionDescription)
void reportSuccess(QString msg)
USReconstructInputData getReconstructData()
static USFrameDataPtr create(ImagePtr inputFrameData)
static QString createUniqueFolder(QString patientFolder, QString sessionDescription)
std::map< double, Transform3D > TimedTransformMap
void setData(ProbeDefinition data)
boost::shared_ptr< class ImageDataContainer > ImageDataContainerPtr
boost::shared_ptr< class Tool > ToolPtr