47#include <QDirIterator>
48#include <QRegularExpression>
67 const QString& sSubject,
68 const QString& sSession,
70 const QString& sDatatype,
71 const QString& sSuffix,
72 const QString& sExtension)
74 , m_sSubject(sSubject)
75 , m_sSession(sSession)
77 , m_sDatatype(sDatatype)
79 , m_sExtension(sExtension)
86 : m_sRoot(other.m_sRoot)
87 , m_sSubject(other.m_sSubject)
88 , m_sSession(other.m_sSession)
89 , m_sTask(other.m_sTask)
90 , m_sAcquisition(other.m_sAcquisition)
91 , m_sRun(other.m_sRun)
92 , m_sProcessing(other.m_sProcessing)
93 , m_sSpace(other.m_sSpace)
94 , m_sRecording(other.m_sRecording)
95 , m_sSplit(other.m_sSplit)
96 , m_sDescription(other.m_sDescription)
97 , m_sDatatype(other.m_sDatatype)
98 , m_sSuffix(other.m_sSuffix)
99 , m_sExtension(other.m_sExtension)
156 if(!m_sSubject.isEmpty())
157 parts << QStringLiteral(
"sub-") + m_sSubject;
158 if(!m_sSession.isEmpty())
159 parts << QStringLiteral(
"ses-") + m_sSession;
160 if(!m_sTask.isEmpty())
161 parts << QStringLiteral(
"task-") + m_sTask;
162 if(!m_sAcquisition.isEmpty())
163 parts << QStringLiteral(
"acq-") + m_sAcquisition;
164 if(!m_sRun.isEmpty())
165 parts << QStringLiteral(
"run-") + m_sRun;
166 if(!m_sProcessing.isEmpty())
167 parts << QStringLiteral(
"proc-") + m_sProcessing;
168 if(!m_sSpace.isEmpty())
169 parts << QStringLiteral(
"space-") + m_sSpace;
170 if(!m_sRecording.isEmpty())
171 parts << QStringLiteral(
"rec-") + m_sRecording;
172 if(!m_sSplit.isEmpty())
173 parts << QStringLiteral(
"split-") + m_sSplit;
174 if(!m_sDescription.isEmpty())
175 parts << QStringLiteral(
"desc-") + m_sDescription;
178 if(!m_sSuffix.isEmpty())
181 QString name = parts.join(QStringLiteral(
"_"));
184 if(!m_sExtension.isEmpty())
185 name += m_sExtension;
196 if(!m_sSubject.isEmpty())
197 dir = QDir(dir.filePath(QStringLiteral(
"sub-") + m_sSubject));
199 if(!m_sSession.isEmpty())
200 dir = QDir(dir.filePath(QStringLiteral(
"ses-") + m_sSession));
202 if(!m_sDatatype.isEmpty())
203 dir = QDir(dir.filePath(m_sDatatype));
205 return dir.path() + QDir::separator();
222 result.m_sSuffix = sSuffix;
223 result.m_sExtension = sExtension;
231 return withSuffix(QStringLiteral(
"channels"), QStringLiteral(
".tsv"));
240 result.m_sTask.clear();
241 result.m_sRun.clear();
242 result.m_sSuffix = QStringLiteral(
"electrodes");
243 result.m_sExtension = QStringLiteral(
".tsv");
253 result.m_sTask.clear();
254 result.m_sRun.clear();
255 result.m_sSuffix = QStringLiteral(
"coordsystem");
256 result.m_sExtension = QStringLiteral(
".json");
264 return withSuffix(QStringLiteral(
"events"), QStringLiteral(
".tsv"));
271 return withSuffix(m_sSuffix.isEmpty() ? m_sDatatype : m_sSuffix,
272 QStringLiteral(
".json"));
279 return QFileInfo::exists(
filePath());
289 return dir.mkpath(QStringLiteral(
"."));
296 QList<BIDSPath> results;
303 QString pattern = QStringLiteral(
"sub-") + (m_sSubject.isEmpty() ? QStringLiteral(
"*") : m_sSubject);
305 if(!m_sSession.isEmpty())
306 pattern += QStringLiteral(
"_ses-") + m_sSession;
308 pattern += QStringLiteral(
"*");
310 pattern += QStringLiteral(
"*");
312 if(!m_sSuffix.isEmpty())
313 pattern += QStringLiteral(
"_") + m_sSuffix;
315 if(!m_sExtension.isEmpty())
316 pattern += m_sExtension;
318 pattern += QStringLiteral(
".*");
320 QStringList entries = dir.entryList({pattern}, QDir::Files);
323 static const QRegularExpression entityRx(QStringLiteral(
"(\\w+)-(\\w+)"));
324 for(
const QString& entry : entries) {
330 auto it = entityRx.globalMatch(entry);
331 while(it.hasNext()) {
332 auto match = it.next();
333 const QString key =
match.captured(1);
334 const QString val =
match.captured(2);
336 if(key == QStringLiteral(
"sub")) p.
setSubject(val);
337 else if(key == QStringLiteral(
"ses")) p.
setSession(val);
338 else if(key == QStringLiteral(
"task")) p.
setTask(val);
340 else if(key == QStringLiteral(
"run")) p.
setRun(val);
342 else if(key == QStringLiteral(
"space")) p.
setSpace(val);
343 else if(key == QStringLiteral(
"rec")) p.
setRecording(val);
344 else if(key == QStringLiteral(
"split")) p.
setSplit(val);
350 int dotIdx = entry.lastIndexOf(QLatin1Char(
'.'));
353 QString nameWithoutExt = entry.left(dotIdx);
354 int lastUnder = nameWithoutExt.lastIndexOf(QLatin1Char(
'_'));
356 p.
setSuffix(nameWithoutExt.mid(lastUnder + 1));
375 static const QRegularExpression forbidden(QStringLiteral(
"[\\-_/]"));
376 return !sValue.contains(forbidden);
386 m_sRoot = other.m_sRoot;
387 m_sSubject = other.m_sSubject;
388 m_sSession = other.m_sSession;
389 m_sTask = other.m_sTask;
390 m_sAcquisition = other.m_sAcquisition;
391 m_sRun = other.m_sRun;
392 m_sProcessing = other.m_sProcessing;
393 m_sSpace = other.m_sSpace;
394 m_sRecording = other.m_sRecording;
395 m_sSplit = other.m_sSplit;
396 m_sDescription = other.m_sDescription;
397 m_sDatatype = other.m_sDatatype;
398 m_sSuffix = other.m_sSuffix;
399 m_sExtension = other.m_sExtension;
428QString BIDSPath::zeroPad(
const QString& sValue)
434 int num = sValue.toInt(&ok);
436 return QStringLiteral(
"%1").arg(num, 2, 10, QLatin1Char(
'0'));
BIDS constants, channel type mappings, and allowed values.
bool operator==(const BIDSPath &a, const BIDSPath &b)
BIDSPath class declaration — BIDS-compliant path construction and entity management.
BIDS dataset reading, writing, path construction, and sidecar metadata handling for iEEG/EEG/MEG.
void setSession(const QString &sSession)
void setSpace(const QString &sSpace)
void setRecording(const QString &sRecording)
void setSubject(const QString &sSubject)
void setDatatype(const QString &sDatatype)
QString description() const
BIDSPath electrodesTsvPath() const
void setDescription(const QString &sDescription)
void setRun(const QString &sRun)
void setAcquisition(const QString &sAcquisition)
void setSplit(const QString &sSplit)
BIDSPath channelsTsvPath() const
static bool isValidEntityValue(const QString &sValue)
QString directory() const
QString acquisition() const
void setTask(const QString &sTask)
BIDSPath & operator=(const BIDSPath &other)
QString extension() const
void setProcessing(const QString &sProcessing)
void setRoot(const QString &sRoot)
void setSuffix(const QString &sSuffix)
QString processing() const
QString recording() const
BIDSPath coordsystemJsonPath() const
QList< BIDSPath > match() const
BIDSPath withSuffix(const QString &sSuffix, const QString &sExtension) const
BIDSPath eventsTsvPath() const
void setExtension(const QString &sExtension)
BIDSPath sidecarJsonPath() const