14 #include <QTextStream>
18 #include <vtkImageChangeInformation.h>
19 #include <vtkImageData.h>
20 #include "vtkImageAppend.h"
21 #include "vtkMetaImageWriter.h"
41 mSessionDescription(sessionDescription)
51 return mReconstructData;
59 std::vector<TimeInfo> imageTimestamps,
61 std::map<double, ToolPositionMetadata> trackerRecordedMetadata,
62 std::map<double, ToolPositionMetadata> referenceRecordedMetadata,
63 ToolPtr tool, QString streamUid,
66 if(trackerRecordedData.empty())
67 reportWarning(
"No tracking data for writing to reconstruction file.");
77 for (TimedTransformMap::iterator it = trackerRecordedData.begin(); it != trackerRecordedData.end(); ++it)
80 current.
mTime = it->first;
82 current.
mPos = it->second;
86 std::vector<TimeInfo> fts = imageTimestamps;
87 for (
unsigned i=0; i<fts.size(); ++i)
89 TimedPosition current;
92 current.mPos = Transform3D::Identity();
94 retval.
mFrames.push_back(current);
97 if (tool && tool->getProbe())
105 this->fillFramePositions(&retval);
114 void UsReconstructionFileMaker::fillFramePositions(USReconstructInputData* data)
const
120 bool UsReconstructionFileMaker::writeTrackerTimestamps(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
122 return this->writeTimestamps(reconstructionFolder+
"/"+session+
".tts",
123 ts,
"tracking timestamps");
126 bool UsReconstructionFileMaker::writeUSTimestamps(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
130 retval = this->writeTimestamps(reconstructionFolder+
"/"+session+
".fts",
131 ts,
"frame timestamps", Modified);
133 retval &= this->writeTimestamps(reconstructionFolder+
"/"+session+
".scanner.frameTimestamps",
134 ts,
"frame scanner timestamps", Scanner);
136 retval &= this->writeTimestamps(reconstructionFolder+
"/"+session+
".softwareArrive.frameTimestamps",
137 ts,
"frame arrive in software timestamps", SoftwareArrive);
141 bool UsReconstructionFileMaker::writeTimestamps(QString filename, std::vector<TimedPosition> ts, QString type, TimeStampType timeStampType)
143 bool success =
false;
145 QFile file(filename);
146 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
151 QTextStream stream(&file);
153 for (
unsigned i=0; i<ts.size(); ++i)
155 switch(timeStampType)
158 stream <<
qstring_cast(ts[i].mTimeInfo.getAcquisitionTime());
161 stream <<
qstring_cast(ts[i].mTimeInfo.getSoftwareAcquisitionTime());
164 stream <<
qstring_cast(ts[i].mTimeInfo.getScannerAcquisitionTime());
175 QFileInfo info(file);
176 mReport << QString(
"%1, %2 bytes, %3 %4.")
177 .arg(info.fileName())
186 bool UsReconstructionFileMaker::writeUSTransforms(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
188 return this->writeTransforms(reconstructionFolder+
"/"+session+
".fp", ts,
"frame transforms rMu");
191 bool UsReconstructionFileMaker::writeTrackerMetadata(QString reconstructionFolder, QString session,
const std::map<double, ToolPositionMetadata>& ts)
193 QString filename = reconstructionFolder+
"/"+session+
".probe.toolmeta";
194 return this->writeMetadata(filename, ts,
"tracker metadata");
197 bool UsReconstructionFileMaker::writeReferenceMetadata(QString reconstructionFolder, QString session,
const std::map<double, ToolPositionMetadata>& ts)
199 QString filename = reconstructionFolder+
"/"+session+
".ref.toolmeta";
200 return this->writeMetadata(filename, ts,
"tracker metadata");
203 bool UsReconstructionFileMaker::writeMetadata(QString filename,
const std::map<double, ToolPositionMetadata>& ts, QString type)
205 bool success =
false;
206 QFile file(filename);
207 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
212 QTextStream stream(&file);
214 for (std::map<double, ToolPositionMetadata>::const_iterator i=ts.begin(); i!=ts.end(); ++i)
216 stream << i->second.toString() << endl;
221 QFileInfo info(file);
227 bool UsReconstructionFileMaker::writeTrackerTransforms(QString reconstructionFolder, QString session, std::vector<TimedPosition> ts)
229 return this->writeTransforms(reconstructionFolder+
"/"+session+
".tp", ts,
"tracking transforms prMt");
232 bool UsReconstructionFileMaker::writeTransforms(QString filename, std::vector<TimedPosition> ts, QString type)
234 bool success =
false;
235 QFile file(filename);
236 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
241 QTextStream stream(&file);
243 for (
unsigned i=0; i<ts.size(); ++i)
265 QFileInfo info(file);
274 void UsReconstructionFileMaker::writeProbeConfiguration(QString reconstructionFolder, QString session, ProbeDefinition data, QString uid)
276 XmlOptionFile file = XmlOptionFile(reconstructionFolder +
"/" + session +
".probedata.xml");
277 data.addXml(file.getElement(
"configuration"));
278 file.getElement(
"tool").toElement().setAttribute(
"toolID", uid);
285 QDir patientDir(patientFolder +
"/US_Acq");
287 QString subfolder = sessionDescription;
288 QString subfolderAbsolutePath = patientDir.absolutePath()+
"/"+subfolder;
289 QString newPathName = subfolderAbsolutePath;
291 while(!findNewSubfolder(newPathName))
293 newPathName = subfolderAbsolutePath+
"_"+QString::number(i++);
295 patientDir.mkpath(newPathName);
296 patientDir.cd(newPathName);
298 retval = patientDir.absolutePath();
305 QDir patientDir(patientFolder +
"/US_Acq");
307 QString subfolder = sessionDescription;
308 QString subfolderAbsolutePath = patientDir.absolutePath()+
"/"+subfolder;
309 QString newPathName = subfolderAbsolutePath;
310 patientDir.mkpath(newPathName);
311 patientDir.cd(newPathName);
313 retval = patientDir.absolutePath();
317 bool UsReconstructionFileMaker::findNewSubfolder(QString subfolderAbsolutePath)
320 if(dir.exists(subfolderAbsolutePath))
326 void UsReconstructionFileMaker::report()
328 foreach(QString
string, mReport)
334 void UsReconstructionFileMaker::writeUSImages(QString path,
ImageDataContainerPtr images,
bool compression, std::vector<TimedPosition> pos)
339 for (
unsigned i=0; i<images->size(); ++i)
342 QString filename = QString(
"%1/%2_%3.mhd").arg(path).arg(mSessionDescription).arg(i);
344 writer->SetInputData(currentImage);
346 writer->SetCompression(compression);
348 StaticMutexVtkLocker lock;
353 customReader->setTransform(pos[i].mPos);
354 customReader->setModality(
imUS);
359 void UsReconstructionFileMaker::writeMask(QString path, QString session,
vtkImageDataPtr mask)
361 QString filename = QString(
"%1/%2.mask.mhd").arg(path).arg(session);
364 reportWarning(QString(
"No mask found, ignoring write to %1").arg(filename));
369 writer->SetInputData(mask);
371 writer->SetCompression(
false);
376 void UsReconstructionFileMaker::writeREADMEFile(QString reconstructionFolder, QString session)
379 "* ==== Format description \n"
381 "* http://custusx.org/uploads/developer_doc/nightly/org_custusx_acquisition.html \n"
382 "* for a description of the files. \n"
385 QFile file(reconstructionFolder+
"/"+session+
".README.txt");
386 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
391 QTextStream stream(&file);
399 mReconstructData.
mFilename = path+
"/"+mSessionDescription+
".fts";
402 mReport <<
"Made reconstruction folder: " + path;
403 QString session = mSessionDescription;
407 this->writeTrackerTimestamps(path, session, mReconstructData.
mPositions);
408 this->writeTrackerTransforms(path, session, mReconstructData.
mPositions);
409 this->writeUSTimestamps(path, session, mReconstructData.
mFrames);
410 this->writeUSTransforms(path, session, mReconstructData.
mFrames);
412 this->writeMask(path, session, mReconstructData.
getMask());
413 this->writeREADMEFile(path, session);
417 this->writeUSImages(path, imageData, compression, mReconstructData.
mFrames);
419 mReport <<
"failed to find frame data, save failed.";
422 mReport << QString(
"Completed save to %1. Spent %2s, %3fps").arg(mSessionDescription).arg(time/1000).arg(imageData->size()*1000/time);