Commit ab0daa8b authored by Bruno Colombet's avatar Bruno Colombet

Recoding the BIDS parsing...

parent f60effe8
......@@ -1039,6 +1039,7 @@
<ClCompile Include="IO\BIDS\AwBIDSGUI.cpp" />
<ClCompile Include="IO\BIDS\AwBIDSItem.cpp" />
<ClCompile Include="IO\BIDS\AwBIDSManager.cpp" />
<ClCompile Include="IO\BIDS\AwBIDSNode.cpp" />
<ClCompile Include="IO\BIDS\AwBIDSParser.cpp" />
<ClCompile Include="IO\BIDS\AwBIDSSession.cpp" />
<ClCompile Include="IO\BIDS\AwBIDSSubject.cpp" />
......@@ -1651,6 +1652,7 @@
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_OPENGL_LIB -DQT_SVG_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -DQT_CONCURRENT_LIB -DMKL -DQT_PRINTSUPPORT_LIB -DQWT_DLL -DH5_BUILT_AS_DYNAMIC_LIB -DAW_DISABLE_EPOCHING -DQT_QML_LIB -DAW_PLATFORM="Win" -DAW_MAJOR_VERSION="1809" -DAW_MINOR_VERSION="0" -DQT_MULTIMEDIAWIDGETS_LIB -DQT_MULTIMEDIA_LIB -D%(PreprocessorDefinitions) "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtSvg" "-I$(QTDIR)\include\QtWidgets" "-I$(AWROOT)\include" "-I$(DEV_ROOT)\win64\VS2015\HDF5\1.8.18\include" "-I$(QTDIR)\include\QtAngle" "-ID:\Dev\win64\VS2012\VTK630\include\vtk-6.3" "-I$(QTDIR)\include\QtXml" "-I$(QTDIR)\include\QtConcurrent" "-I.\ICA" "-I.\Process" "-I$(DEV_ROOT)\win64\armadillo-7.800.2\include" "-I$(QTDIR)\include\QtPrintSupport" "-I.\Script" "-I.\Display" "-I.\Carto" "-I.\Epoch" "-ID:\Dev\win64\VS2015\Qwt-6.1.3\include" "-I$(QTDIR)\include\QtCharts" "-I.\Marker" "-ID:\Dev\win64\matio\include" "-I$(QTDIR)\include\QtQml" "-I.\IO\BIDS" "-I.\Filter" "-I.\Montage" "-ID:\Dev\vcpkg\packages\libzip_x64-windows\include" "-I.\Signal" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtMultimedia" "-I.\Widgets"</Command>
</CustomBuild>
<ClInclude Include="GeneratedFiles\ui_AwVideoSettingsDial.h" />
<ClInclude Include="IO\BIDS\AwBIDSNode.h" />
<ClInclude Include="IO\BIDS\AwBIDSItem.h" />
<CustomBuild Include="IO\BIDS\AwBIDSParser.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
......@@ -1297,6 +1297,9 @@
<ClCompile Include="IO\BIDS\AwBIDSParser.cpp">
<Filter>IO\BIDS</Filter>
</ClCompile>
<ClCompile Include="IO\BIDS\AwBIDSNode.cpp">
<Filter>IO\BIDS</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="Data\AwDataConnection.h">
......@@ -2018,6 +2021,9 @@
<ClInclude Include="GeneratedFiles\ui_AwVideoSettingsDial.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="IO\BIDS\AwBIDSNode.h">
<Filter>IO\BIDS</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\resources\eeg_sensors_locations.txt">
......
......@@ -317,7 +317,7 @@ void AnyWave::openBIDS()
void AnyWave::openBIDS(const QString& path)
{
if (!AwBIDSManager::isInstantiated()) {
AwBIDSManager::instance(path);
AwBIDSManager::instance()->setRootDir(path);
connect(AwBIDSManager::instance()->ui(), SIGNAL(dataFileClicked(const QString&)), this, SLOT(openFile(const QString&)));
}
else
......
/////////////////////////////////////////////////////////////////////////////////////////
//
// Universit dAix Marseille (AMU) -
// Institut National de la Sant et de la Recherche Mdicale (INSERM)
// Copyright 2013 AMU, INSERM
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
//
// Author: Bruno Colombet Laboratoire UMR INS INSERM 1106 - Bruno.Colombet@univ-amu.fr
//
//////////////////////////////////////////////////////////////////////////////////////////
#include "AwBIDSFileItem.h"
#include <QFileInfo>
QVariant AwBIDSFileItem::data(int column, int role)
AwBIDSFileItem::AwBIDSFileItem(AwBIDSFileItem::FileType type)
{
m_type = type;
}
// return m_itemData.value(column);
return QVariant();
///
/// tsvFile:
///
QString AwBIDSFileItem::tsvFile(AwBIDSFileItem::TsvFiles tsvFile)
{
QFileInfo fi(m_fullPath);
auto base = fi.baseName();
switch (m_type) {
case AwBIDSFileItem::FileType::eeg:
base = base.remove("_eeg");
break;
case AwBIDSFileItem::FileType::ieeg:
base = base.remove("_ieeg");
break;
case AwBIDSFileItem::FileType::meg:
base = base.remove("_meg");
break;
}
QString tsv;
switch (tsvFile) {
case AwBIDSFileItem::TsvFiles::channels:
tsv = "channels.tsv";
break;
case AwBIDSFileItem::TsvFiles::events:
tsv = "events.tsv";
break;
}
auto res = QString("%1/%2_%3").arg(m_fullPath).arg(base).arg(tsv);
if (QFile::exists(res))
return res;
return QString();
}
\ No newline at end of file
/////////////////////////////////////////////////////////////////////////////////////////
//
// Universit dAix Marseille (AMU) -
// Institut National de la Sant et de la Recherche Mdicale (INSERM)
// Copyright 2013 AMU, INSERM
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
//
// Author: Bruno Colombet Laboratoire UMR INS INSERM 1106 - Bruno.Colombet@univ-amu.fr
//
//////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "AwBIDSTreeItem.h"
class AwBIDSFileItem : public AwBIDSTreeItem
#include <QString>
class AwBIDSFileItem
{
public:
explicit AwBIDSFileItem(const QVector<QVariant>& data, AwBIDSTreeItem *parent = 0) :
AwBIDSTreeItem(data, parent) {}
enum class FileType : int { ieeg, meg, eeg };
enum class TsvFiles : int { channels, events };
AwBIDSFileItem(AwBIDSFileItem::FileType type);
/// return either associated channels or events tsv file path. Only works for ieeg, meg, eeg
/// return empty string if no tsv file found.
QString tsvFile(AwBIDSFileItem::TsvFiles tsvFile);
QVariant data(int column, int role = Qt::DisplayRole) override;
};
\ No newline at end of file
protected:
AwBIDSFileItem::FileType m_type;
QString m_fullPath; // full path to file item
QStringList m_items;
};
......@@ -15,6 +15,7 @@
#include "Debug/AwDebugLog.h"
#include <QJsonArray>
#include <utils/AwUtilities.h>
#include "AwBIDSParser.h"
// statics
AwBIDSManager *AwBIDSManager::m_instance = 0;
......@@ -631,33 +632,40 @@ int AwBIDSManager::convertToEDF(const QString& file, AwFileIO *reader)
}
AwBIDSManager *AwBIDSManager::instance(const QString& rootDir)
//AwBIDSManager *AwBIDSManager::instance(const QString& rootDir)
//{
// if (!m_instance)
// m_instance = new AwBIDSManager(rootDir);
// else
// m_instance->setRootDir(rootDir);
// return m_instance;
//}
AwBIDSManager *AwBIDSManager::instance()
{
if (!m_instance)
m_instance = new AwBIDSManager(rootDir);
else
m_instance->setRootDir(rootDir);
m_instance = new AwBIDSManager;
return m_instance;
}
AwBIDSManager::AwBIDSManager(const QString& rootDir)
AwBIDSManager::AwBIDSManager()
{
m_ui = NULL;
m_currentSubject = Q_NULLPTR;
// Get extensions readers can handle.
auto pm = AwPluginManager::getInstance();
for (auto r : pm->readers())
m_fileExtensions += r->fileExtensions;
//m_currentSubject = Q_NULLPTR;
//// Get extensions readers can handle.
//auto pm = AwPluginManager::getInstance();
//for (auto r : pm->readers())
// m_fileExtensions += r->fileExtensions;
setRootDir(rootDir);
// setRootDir(rootDir);
m_mustValidateModifications = false;
// init settings
m_settings["parsing_path"] = QString("derivatives/parsing");
m_settings["aw_derivatives"] = QString("derivatives/anywave");
m_knownDerivativesPaths[AwBIDSManager::AnyWave] = QString("%1/derivatives/anywave").arg(rootDir);
m_knownDerivativesPaths[AwBIDSManager::EpiTools] = QString("%1/derivatives/epitools").arg(rootDir);
//m_settings["parsing_path"] = QString("derivatives/parsing");
//m_settings["aw_derivatives"] = QString("derivatives/anywave");
//m_knownDerivativesPaths[AwBIDSManager::AnyWave] = QString("%1/derivatives/anywave").arg(rootDir);
//m_knownDerivativesPaths[AwBIDSManager::EpiTools] = QString("%1/derivatives/epitools").arg(rootDir);
}
AwBIDSManager::~AwBIDSManager()
......@@ -700,26 +708,30 @@ void AwBIDSManager::setRootDir(const QString& path)
m_ui = new AwBIDSGUI(this, path);
else
m_ui->setRootDir(path);
// check that the root dir contains subjects
getSubjects();
// check for source_data dir
bool source = false, derivatives = false;
QDirIterator it(m_rootDir, QDir::Dirs);
while (it.hasNext()) {
it.next();
QString name = it.fileName();
if (name == "sourcedata")
source = true;
else if (name == "derivatives")
derivatives = true;
if (source && derivatives)
break;
}
if (source)
getSubjects(AwBIDSManager::source);
if (derivatives)
getSubjects(AwBIDSManager::derivatives);
//// check that the root dir contains subjects
//getSubjects();
//// check for source_data dir
//bool source = false, derivatives = false;
//QDirIterator it(m_rootDir, QDir::Dirs);
//while (it.hasNext()) {
// it.next();
// QString name = it.fileName();
// if (name == "sourcedata")
// source = true;
// else if (name == "derivatives")
// derivatives = true;
// if (source && derivatives)
// break;
//}
//if (source)
// getSubjects(AwBIDSManager::source);
//if (derivatives)
// getSubjects(AwBIDSManager::derivatives);
AwBIDSParser parser;
parser.parse();
m_nodes = parser.nodes();
m_ui->refresh();
}
......@@ -761,7 +773,7 @@ void AwBIDSManager::parseSubject(AwBIDSSubject *subject)
for (auto d : dirs) {
if (d.startsWith("ses-")) {
// get session label
auto label = AwBIDSTools::getSessionLabel(d);
auto label = AwBIDS::getSessionLabel(d);
subject->addSession(label);
}
}
......
......@@ -26,6 +26,7 @@
#pragma once
#include <qobject.h>
#include "AwBIDSSubject.h"
#include "AwBIDSNode.h"
#include "AwBIDSGUI.h"
#include <AwFileIO.h>
#include <AwCommandLine.h>
......@@ -44,14 +45,14 @@ class AwBIDSManager : public QObject
public:
enum itemTypes { iEEG, MEG, EEG };
enum dataSources { raw = 0, source = 1, derivatives = 2 }; // indicates the type of data ordering (source data are place in a source_data folder).
enum KnownDerivativesDirs { AnyWave, EpiTools, BIDSUpdates};
enum Modifications { ChannelsTsv, EventsTsv };
enum supportedMEGFormats { Bti4DNI, Elekta, CTF };
// destructor
~AwBIDSManager();
// utilities static methods
static AwBIDSManager *instance(const QString& rootDir = QString());
//static AwBIDSManager *instance(const QString& rootDir = QString());
static AwBIDSManager *instance();
static bool isInstantiated() { return m_instance != NULL; }
static void destroy();
......@@ -95,7 +96,7 @@ signals:
void log(const QString& message);
void BIDSClosed();
protected:
AwBIDSManager(const QString& rootDir);
AwBIDSManager();
static AwBIDSManager *m_instance;
QHash<QString, QVariant> m_settings;
......@@ -118,5 +119,6 @@ protected:
QStringList m_fileExtensions; // contains all file extensions that reader plugins can handle.
// keep the subject associated with the current open file in AnyWave
AwBIDSSubject *m_currentSubject;
AwBIDSNodes m_nodes;
bool m_mustValidateModifications;
};
\ No newline at end of file
/////////////////////////////////////////////////////////////////////////////////////////
//
// Universit dAix Marseille (AMU) -
// Institut National de la Sant et de la Recherche Mdicale (INSERM)
// Copyright 2013 AMU, INSERM
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
//
// Author: Bruno Colombet Laboratoire UMR INS INSERM 1106 - Bruno.Colombet@univ-amu.fr
//
//////////////////////////////////////////////////////////////////////////////////////////
#include "AwBIDSNode.h"
AwBIDSNode::AwBIDSNode(const QString& parentDir, const QString& relativePath, int type, const QString& ID)
{
m_parentDir = parentDir;
m_type = type;
m_ID = ID;
m_fullPath = QString("%1/%2").arg(parentDir).arg(relativePath);
}
AwBIDSNode::~AwBIDSNode()
{
while (!m_children.isEmpty())
delete m_children.takeFirst();
}
\ No newline at end of file
/////////////////////////////////////////////////////////////////////////////////////////
//
// Universit dAix Marseille (AMU) -
// Institut National de la Sant et de la Recherche Mdicale (INSERM)
// Copyright 2013 AMU, INSERM
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
//
// Author: Bruno Colombet Laboratoire UMR INS INSERM 1106 - Bruno.Colombet@univ-amu.fr
//
//////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
#include <QList>
class AwBIDSNode
{
public:
explicit AwBIDSNode(const QString& parentDir, const QString& relativePath, int type, const QString& ID = QString());
~AwBIDSNode();
// items aht could be found in a BIDS structure:
// Folder means a simple folder (for example MEG 4DNI data files are stored in folders)
enum Types { subject, session, ieeg, meg, eeg, Folder};
inline QString& fullPath() { return m_fullPath; }
inline int type() { return m_type; }
AwBIDSNode * addChild(AwBIDSNode *node) { m_children.append(node); return node; }
void addFiles(const QStringList& files) { m_files.append(files); }
protected:
QString m_parentDir, m_ID, m_fullPath;
// a node may contain files
QStringList m_files;
// a node may contain child nodes
QList<AwBIDSNode *> m_children;
int m_type;
};
using AwBIDSNodes = QList<AwBIDSNode *>;
\ No newline at end of file
......@@ -3,7 +3,7 @@
AwBIDSSubject::AwBIDSSubject(const QString& root, const QString& ID)
{
m_ID = ID;
m_fullPath = QString("%1/sub-%2").arg(root).arg(ID);
m_rootDir = root;
}
......@@ -15,6 +15,11 @@ AwBIDSSubject::~AwBIDSSubject()
delete m_items.takeFirst();
}
QString AwBIDSSubject::fullPath()
{
return QString("%1/%2").arg(m_rootDir).arg(m_ID);
}
AwBIDSSession *AwBIDSSubject::addSession(const QString& label)
{
m_sessions.append(new AwBIDSSession(this, label));
......
......@@ -35,7 +35,7 @@ public:
AwBIDSSubject(const QString& root, const QString& ID);
~AwBIDSSubject();
inline QString& fullPath() { return m_fullPath; }
QString fullPath();
inline QString& ID() { return m_ID; }
inline bool hasSessions() { return !m_sessions.isEmpty(); }
AwBIDSSession *addSession(const QString& label);
......@@ -45,9 +45,11 @@ public:
QStringList findFile(const QString& filePath);
AwFileItemList findFileItems(const QString& filePath);
QString getDerivativesPath(int softwareKind);
protected:
QString m_ID;
QString m_fullPath;
//QString m_fullPath;
QString m_rootDir; // BIDS root folder path.
AwBIDSSessionList m_sessions;
QList<AwFileItem *> m_items;
};
......
......@@ -2,7 +2,7 @@
#include <qregularexpression.h>
QString AwBIDSTools::getSessionLabel(const QString& data)
QString AwBIDS::getSessionLabel(const QString& data)
{
QRegularExpression re("^(?<session>ses-)(?<label>\\w+)$");
QRegularExpressionMatch match = re.match(data);
......@@ -11,11 +11,28 @@ QString AwBIDSTools::getSessionLabel(const QString& data)
return match.captured("label");
}
QString AwBIDSTools::getSubjectID(const QString& data)
QString AwBIDS::getSubjectID(const QString& data)
{
QRegularExpression re("^(?<subject>sub-)(?<ID>\\w+)$");
QRegularExpressionMatch match = re.match(data);
if (!match.hasMatch())
return QString();
return match.captured("ID");
}
///
/// convert enum class value to string.
/// SearchFolder string will be the relative path to the BIDS structure where to search for subjects.
QString AwBIDS::searchFoldersEnumToString(const SearchFolders& sf)
{
switch (sf) {
case SearchFolders::AnyWave:
return QString("derivatives/anywave");
case SearchFolders::EpiTools:
return QString("derivatives/epitools");
case SearchFolders::Source:
return QString("sourcedata");
default:
return QString();
}
}
\ No newline at end of file
......@@ -27,8 +27,11 @@
#include <QString>
namespace AwBIDSTools
namespace AwBIDS
{
QString getSessionLabel(const QString& data);
QString getSubjectID(const QString& data);
enum class SearchFolders : int { AnyWave, EpiTools, Source };
QString searchFoldersEnumToString(const SearchFolders& sf);
}
\ No newline at end of file
......@@ -113,9 +113,25 @@ int ICA::initParameters()
m_isDownsamplingActive = true;
m_modality = AwChannel::stringToType(args["modality"].toString());
m_channels = AwChannel::getChannelsOfType(pdi.input.channels(), m_modality);
// BIDS specific:
// when launching ICA in batch mode and specifying ieeg as modality:
// check for SEEG channels if none present check for EEG.
if (args["modality"].toString().toLower() == "ieeg") {
m_modality = AwChannel::SEEG;
m_channels = AwChannel::getChannelsOfType(pdi.input.channels(), m_modality);
if (m_channels.isEmpty()) {
m_modality = AwChannel::EEG;
m_channels = AwChannel::getChannelsOfType(pdi.input.channels(), m_modality);
}
}
if (m_channels.isEmpty()) {
sendMessage(QString("No channels of type %1 found in file").arg(AwChannel::typeToString(m_modality)));
return -1;
}
m_channels = AwChannel::removeDoublons(m_channels);
if (args.contains("skip_bad")) {
if (args["skip_bas"].toBool())
if (!args["skip_bad"].toBool())
pdi.input.badLabels.clear();
}
m_samplingRate = m_channels.first()->samplingRate();
......@@ -240,7 +256,13 @@ int ICA::initParameters()
void ICA::runFromCommandLine()
{
if (initParameters() == 0) {
infomax(m, n, m_nComp);
try {
infomax(m, n, m_nComp);
}
catch (std::bad_alloc& ba) {
sendMessage("MEMORY ALLOCATION ERROR. Operation canceled.");
return;
}
saveToFile();
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment