@@ -1669,7 +1669,35 @@ QStringList MoleculeParser::writeToFile(const QString &filename) const
16691669
16701670 QStringList written_files;
16711671
1672- createDirectoryForFile (filename);
1672+ // Check whether list of trajectory frames have been specified via the map.
1673+ // If so, then the name will be prefixed with "frames_names:"
1674+ QStringList frame_names;
1675+ if (filename.contains (" frames_names:" ))
1676+ {
1677+ // Split the part of the string following "frames_names:" by commas to get
1678+ // individual frame names.
1679+ const QString frames_names_str = filename.section (" frames_names:" , 1 );
1680+ frame_names = frames_names_str.split (" ," , Qt::SkipEmptyParts);
1681+
1682+ // Convert to absolute paths.
1683+ for (auto &frame_name : frame_names)
1684+ {
1685+ frame_name = QFileInfo (frame_name.trimmed ()).absoluteFilePath ();
1686+ }
1687+
1688+ if (frame_names.size () != frames_to_write.size ())
1689+ {
1690+ throw SireError::program_bug (
1691+ QObject::tr (" The number of frame names provided (%1) does not match the number of frames to write (%2)." )
1692+ .arg (frame_names.size ())
1693+ .arg (frames_to_write.size ()),
1694+ CODELOC);
1695+ }
1696+ }
1697+ else
1698+ {
1699+ createDirectoryForFile (filename);
1700+ }
16731701
16741702 if (this ->writingTrajectory () and this ->isFrame ())
16751703 {
@@ -1694,51 +1722,61 @@ QStringList MoleculeParser::writeToFile(const QString &filename) const
16941722
16951723 const int padding = QString::number (largest_frame).length ();
16961724
1697- // in this case, we are going to create a directory named after the
1698- // filename, into which all the frames will be written
1699- auto fileinfo = QFileInfo (filename) ;
1725+ QDir framedir;
1726+ QFileInfo fileinfo;
1727+ bool write_to_frame_dir = false ;
17001728
1701- if (fileinfo. exists ())
1729+ if (frame_names. isEmpty ())
17021730 {
1703- // by default, we support overwriting of files - so remove this if it is a file
1704- if (fileinfo.isDir ())
1705- {
1706- _check_and_remove_frame_dir (fileinfo);
1731+ fileinfo = QFileInfo (filename);
1732+ write_to_frame_dir = true ;
17071733
1708- // rebuild so it is not cached
1709- fileinfo = QFileInfo (filename);
1734+ // in this case, we are going to create a directory named after the
1735+ // filename, into which all the frames will be written
1736+ fileinfo = QFileInfo (filename);
17101737
1711- if (fileinfo.exists ())
1712- throw SireError::file_error (QObject::tr (
1713- " Could not write the trajectory for file '%1' as there "
1714- " is already a directory with this name that contains "
1715- " files that don't appear to have been created by sire." )
1716- .arg (filename),
1717- CODELOC);
1718- }
1719- else
1738+ if (fileinfo.exists ())
17201739 {
1721- auto dir = fileinfo.absoluteDir ();
1722-
1723- if (not dir.remove (fileinfo.fileName ()))
1724- throw SireError::file_error (QObject::tr (
1725- " Could not write the trajectory for file '%1' as "
1726- " we don't have permission to remove the existing "
1727- " file with this name." )
1728- .arg (filename),
1729- CODELOC);
1740+ // by default, we support overwriting of files - so remove this if it is a file
1741+ if (fileinfo.isDir ())
1742+ {
1743+ _check_and_remove_frame_dir (fileinfo);
1744+
1745+ // rebuild so it is not cached
1746+ fileinfo = QFileInfo (filename);
1747+
1748+ if (fileinfo.exists ())
1749+ throw SireError::file_error (QObject::tr (
1750+ " Could not write the trajectory for file '%1' as there "
1751+ " is already a directory with this name that contains "
1752+ " files that don't appear to have been created by sire." )
1753+ .arg (filename),
1754+ CODELOC);
1755+ }
1756+ else
1757+ {
1758+ auto dir = fileinfo.absoluteDir ();
1759+
1760+ if (not dir.remove (fileinfo.fileName ()))
1761+ throw SireError::file_error (QObject::tr (
1762+ " Could not write the trajectory for file '%1' as "
1763+ " we don't have permission to remove the existing "
1764+ " file with this name." )
1765+ .arg (filename),
1766+ CODELOC);
1767+ }
17301768 }
1731- }
17321769
1733- QDir framedir (fileinfo.absoluteFilePath ());
1770+ framedir = QDir (fileinfo.absoluteFilePath ());
17341771
1735- if (not framedir.mkpath (" ." ))
1736- throw SireError::file_error (QObject::tr (
1737- " Could not create the directory into which to write the "
1738- " trajectory for '%1'. Check that there is enough space "
1739- " and you have the correct permissions." )
1740- .arg (framedir.absolutePath ()),
1741- CODELOC);
1772+ if (not framedir.mkpath (" ." ))
1773+ throw SireError::file_error (QObject::tr (
1774+ " Could not create the directory into which to write the "
1775+ " trajectory for '%1'. Check that there is enough space "
1776+ " and you have the correct permissions." )
1777+ .arg (framedir.absolutePath ()),
1778+ CODELOC);
1779+ }
17421780
17431781 const auto suffix = fileinfo.completeSuffix ();
17441782
@@ -1765,13 +1803,26 @@ QStringList MoleculeParser::writeToFile(const QString &filename) const
17651803 // construct a copy of this parser for this frame
17661804 auto parser = this ->construct (thread_s, m);
17671805
1768- // now write it to the file, numbered by the frame number and time
1769- QString frame_filename = framedir.filePath (
1770- " frame_" +
1771- QString::number (i).rightJustified (padding, ' 0' ) +
1772- " _" +
1773- QString::number (time).replace (" ." , " -" ) +
1774- " ." + suffix);
1806+ QString frame_filename;
1807+
1808+ if (write_to_frame_dir)
1809+ {
1810+ // now write it to the file, numbered by the frame number and time
1811+ QDir framedir (fileinfo.absoluteFilePath ());
1812+
1813+ frame_filename = framedir.filePath (
1814+ " frame_" +
1815+ QString::number (i).rightJustified (padding, ' 0' ) +
1816+ " _" +
1817+ QString::number (time).replace (" ." , " -" ) +
1818+ " ." + suffix);
1819+ }
1820+ else
1821+ {
1822+ // write to the specified frame name
1823+ frame_filename = frame_names[i];
1824+ createDirectoryForFile (frame_filename);
1825+ }
17751826
17761827 parser.read ().writeToFile (frame_filename);
17771828
@@ -1792,13 +1843,26 @@ QStringList MoleculeParser::writeToFile(const QString &filename) const
17921843 // construct a copy of this parser for this frame
17931844 auto parser = this ->construct (s, m);
17941845
1795- // now write it to the file, numbered by the frame number
1796- QString frame_filename = framedir.filePath (
1797- " frame_" +
1798- QString::number (i).rightJustified (padding, ' 0' ) +
1799- " _" +
1800- QString::number (time).replace (" ." , " -" ) +
1801- " ." + suffix);
1846+ QString frame_filename;
1847+
1848+ if (write_to_frame_dir)
1849+ {
1850+ // now write it to the file, numbered by the frame number
1851+ QDir framedir (fileinfo.absoluteFilePath ());
1852+
1853+ frame_filename = framedir.filePath (
1854+ " frame_" +
1855+ QString::number (i).rightJustified (padding, ' 0' ) +
1856+ " _" +
1857+ QString::number (time).replace (" ." , " -" ) +
1858+ " ." + suffix);
1859+ }
1860+ else
1861+ {
1862+ // write to the specified frame name
1863+ frame_filename = frame_names[i];
1864+ createDirectoryForFile (frame_filename);
1865+ }
18021866
18031867 parser.read ().writeToFile (frame_filename);
18041868
@@ -1810,7 +1874,14 @@ QStringList MoleculeParser::writeToFile(const QString &filename) const
18101874
18111875 // only return the directory name, as we can handle
18121876 // reading all the frames contained therein
1813- written_files.append (framedir.absolutePath ());
1877+ if (write_to_frame_dir)
1878+ {
1879+ written_files.append (framedir.absolutePath ());
1880+ }
1881+ else
1882+ {
1883+ written_files.append (frame_names);
1884+ }
18141885 }
18151886 else
18161887 {
@@ -2452,6 +2523,38 @@ QStringList MoleculeParser::write(const System &system, const QString &filename,
24522523 }
24532524 }
24542525
2526+ // Check for a frame_names property in the map, which is used to control the naming of
2527+ // specific frames when writing trajectories.
2528+ if (map.specified (" frame_names" ))
2529+ {
2530+ const auto frame_names_property = map[" frame_names" ];
2531+
2532+ QStringList frame_names;
2533+
2534+ if (frame_names_property.hasSource ())
2535+ {
2536+ frame_names = frame_names_property.source ().split (" ," );
2537+ }
2538+ else
2539+ {
2540+ try
2541+ {
2542+ frame_names = frame_names_property.value ().asA <StringProperty>().toString ().split (" ," );
2543+ }
2544+ catch (...)
2545+ {
2546+ throw SireError::incompatible_error (
2547+ QObject::tr (" The 'frame_names' property must be a StringProperty containing "
2548+ " a comma-separated list of filenames to use for each frame when "
2549+ " writing trajectories." ),
2550+ CODELOC);
2551+ }
2552+ }
2553+
2554+ // add the special prefix to the first filename
2555+ filenames[0 ] = " frames_names:" + frame_names.join (" ," );
2556+ }
2557+
24552558 // now we have a list of filenames and associated formats, actually
24562559 // write the files
24572560 return ::pvt_write (system, filenames, fileformats, map);
0 commit comments