Skip to content

Conversation

@TomasLenc
Copy link
Contributor

Changed order in which things are done when initializing. Now, all
the "holy trinity" columns and user-specified extra columns
are saved in the structure after calling saveEventsFile('init').

Next, the user can edit column properties before calling
saveEventsFile('open') which will write the JSON.

This way, Levels of e.g. trial_type can be set by the user. Moreover,
this gives the user the freedom to set the Levels as containers.Map
data type, which describes mapping between each level name and its
corresponding description. This is super useful because sometimes
levels can have cryptic names like '1' and '2', and so it's handy
to explain what each code means (e.g. 'left' and 'right' respectively).

Here is an example:

% allocate
logFile = [];

% We can define what extra columns we want in our tsv file beyond the
% BIDS holy trinity ('onset', 'duration', 'trial_type')
logFile.extraColumns = {'rhythm', 'trigger'};

% init logfile
logFile = saveEventsFile('init',cfg,logFile);

% change info about trial_type
logFile.columns.trial_type.Levels = containers.Map({'listen','tap'}, ...
                                                   {'listen without movement','tap finger with the pulse'});

% change units to miliseconds
logFile.columns.onset.Unit = 'ms';
logFile.columns.duration.Unit = 'ms';

% add info to the extra columns
logFile.extraColumns.rhythm.bids.Description = 'name of the rhythmic pattern';
logFile.extraColumns.rhythm.bids.Levels = {'unsyncopated','syncopated'};

logFile.extraColumns.trigger.bids.Description = 'EEG trigger value';
logFile.extraColumns.trigger.bids.Levels = containers.Map({'1','2'},{'low tone','high tone'});

% open tsv and write json for events
logFile = saveEventsFile('open',cfg,logFile);

I hope this makes sense. I'm not sure about the _stim file bids rules, so I tried not to mess things up too much.

@Remi-Gau
Copy link
Contributor

Remi-Gau commented Oct 23, 2020

@TomasLenc

Thanks for this. Will try to have a look at it this weekend to give you some feedback.

Adding some tick boxes below, but that's more for me to remember to do those on the PR later (though you are more than welcome to give it a go if you fancy):

  • update unit tests till the continuous integration of Travis passes
  • apply linter to make miss_hit happy
  • update jupyter notebook with example

@TomasLenc
Copy link
Contributor Author

@Remi-Gau thanks, let me know what you think of the proposed changes. If you decide they make sense, I'm happy to update the notebooks with examples.

And sorry for the failed checks...I need to learn more about how this works!

@Remi-Gau
Copy link
Contributor

Finally taking the time to look into this.

I like the way this is going. Just a couple of point before I start an "actual" review.

tsv files have no header rows

I think there is one thing that this does is that this adds a header row to the TSV files of the stim files which is not OK by the BIDS standard.

This is because openFile calls printHeaderExtraColumns no matter if the file is a an event or a stim file.

A way to deal with this would be to create a isStim boolean field in the logFile structure and to set it to True or False depending on the initialization used.

Then printHeaderExtraColumns would only run is isStim is false.

stim files have no "holy trinity"

The other problem is that this stim files are NOT required to have onsets, durations and trial_type columns and this would make those fields "obligatory".

https://bids-specification.readthedocs.io/en/stable/04-modality-specific-files/06-physiological-and-other-continuous-recordings.html

So in this case too we could rely on logFile.isStim to decide what initializeFile should put in the logFile.columns.

Does that make sense?

@Remi-Gau
Copy link
Contributor

  • update help section

by the way @TomasLenc if you want me to guide you on how to work with the unit tests and how you can use them to see what other changes will need to be added to the code, let me know. More than happy to explain it.

@TomasLenc
Copy link
Contributor Author

Thanks for the feedback @Remi-Gau, I've looked up the rules for _stim file and changed the way the .tsv is saved. As you suggested, there is now a "isStim" field that controls the behavior depending on whether the file was initialized as _events or _stim.

Not sure what your plan was regarding the actual saving within the _stim.tsv file. Assuming you may want to use the same idea as for the _events.tsv file, I patched parts of the code to make it possible (even when saving "event-by-event"). The way I did it is not very beautiful, so feel free to reject this :D

@TomasLenc
Copy link
Contributor Author

TomasLenc commented Oct 29, 2020

by the way @TomasLenc if you want me to guide you on how to work with the unit tests and how you can use them to see what other changes will need to be added to the code, let me know. More than happy to explain it.

Thanks, that would be super nice cause it hurts my heart to see everything failing after my PR :(( Did you want to link me to some tutorial, or perhaps you may have time to chat? Let me know, I'm aware you're busy!

@Remi-Gau
Copy link
Contributor

by the way @TomasLenc if you want me to guide you on how to work with the unit tests and how you can use them to see what other changes will need to be added to the code, let me know. More than happy to explain it.

Thanks, that would be super nice cause it hurts my heart to see everything failing after my PR :(( Did you want to link me to some tutorial, or perhaps you may have time to chat? Let me know, I'm aware you're busy!

We can chat tomorrow if you have time.

In the mean time you can have a look at this.
https://the-turing-way.netlify.app/reproducible-research/testing.html

Actually they have expanded it so I should probably have a look too.

@Remi-Gau
Copy link
Contributor

Thanks for the feedback @Remi-Gau, I've looked up the rules for _stim file and changed the way the .tsv is saved. As you suggested, there is now a "isStim" field that controls the behavior depending on whether the file was initialized as _events or _stim.

Not sure what your plan was regarding the actual saving within the _stim.tsv file. Assuming you may want to use the same idea as for the _events.tsv file, I patched parts of the code to make it possible (even when saving "event-by-event"). The way I did it is not very beautiful, so feel free to reject this :D

Will try to check it tonight.

Copy link
Contributor

@Remi-Gau Remi-Gau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is my review.

A couple of things need to be changed.

Some others are a bit more up to you.

Then there are some possibility to refactor the code in a couple of places.

@Remi-Gau
Copy link
Contributor

Remi-Gau commented Nov 2, 2020

@TomasLenc I have opened another PR #119

The plan for this one is just some doc to help people contribute to this repo.

I think we should have a section on writing / using code tests.

So if you have time to help with this. 😉 No pressure.

@TomasLenc
Copy link
Contributor Author

I promise will fix at the tests tomorrow.

Copy link
Contributor

@Remi-Gau Remi-Gau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of things to change. Nothing big.

@Remi-Gau
Copy link
Contributor

Remi-Gau commented Nov 9, 2020

@all-contributors please add @TomasLenc code, ideas

@allcontributors
Copy link
Contributor

@Remi-Gau

I've put up a pull request to add @TomasLenc! 🎉

@TomasLenc
Copy link
Contributor Author

@Remi-Gau

I've put up a pull request to add @TomasLenc! 🎉

Feeling honoured

Changed order in which things are done when initializing. Now, all
the "holy trinity" columns and user-specified extra columns
are saved in the structure after calling saveEventsFile('init').

Next, the user can edit column properties before calling
saveEventsFile('open') which will write the JSON.

This way, Levels of e.g. trial_type can be set by the user. Moreover,
this gives the user the freedom to set the Levels as containers.Map
data type, which describes mapping between each level name and its
corresponding description. This is super useful because sometimes
levels can have cryptic names like '1' and '2', and so it's handy
to explain what each code means (e.g. 'left' and 'right' respectively).

Here is an example:

% allocate
logFile = [];

% We can define what extra columns we want in our tsv file beyond the
% BIDS holy trinity ('onset', 'duration', 'trial_type')
logFile.extraColumns = {'rhythm', 'trigger'};

% init logfile
logFile = saveEventsFile('init',cfg,logFile);

% change info about trial_type
logFile.columns.trial_type.Levels = containers.Map({'listen','tap'}, ...
                                                   {'listen without movement','tap finger with the pulse'});

% change units to miliseconds
logFile.columns.onset.Unit = 'ms';
logFile.columns.duration.Unit = 'ms';

% add info to the extra columns
logFile.extraColumns.rhythm.bids.Description = 'name of the rhythmic pattern';
logFile.extraColumns.rhythm.bids.Levels = {'unsyncopated','syncopated'};

logFile.extraColumns.trigger.bids.Description = 'EEG trigger value';
logFile.extraColumns.trigger.bids.Levels = containers.Map({'1','2'},{'low tone','high tone'});

% open tsv and write json for events
logFile = saveEventsFile('open',cfg,logFile);
Additional field .isStim is created in the logFile structure upon
initialization (true if _stim file is requested, false otherwise).

If _stim file is requested, no headers are printed in the .tsv file,
and the standard columns "onset", "duration", "trial_type" are omitted.
Changes based on Remi-Gau's comments.
All unit tests are working with the updated functions.

Also, applied some small changes requested in the review process for the PR.
@Remi-Gau
Copy link
Contributor

hey @TomasLenc I did a rebase of this PR on the dev branch to fix some merge conflict. So make sure you pull first before making any changes. 😉

@Remi-Gau
Copy link
Contributor

This saveEventsFile will require additional tests to define how it behaves when saving stim files but I am tempted to move that into another PR since the test suite we have requires quite a bit of refactoring anyway.

Copy link
Contributor

@Remi-Gau Remi-Gau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I am happy with this. I think that the related issues (continuous integration, documentation, jupyter book...) should be addressed in other PRs.

@codecov
Copy link

codecov bot commented Nov 16, 2020

Codecov Report

Merging #115 (91b2260) into dev (af811a0) will decrease coverage by 2.39%.
The diff coverage is 76.56%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev     #115      +/-   ##
==========================================
- Coverage   81.06%   78.67%   -2.40%     
==========================================
  Files          29       29              
  Lines         618      647      +29     
==========================================
+ Hits          501      509       +8     
- Misses        117      138      +21     
Flag Coverage Δ
unittests 78.67% <76.56%> (-2.40%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/convertSourceToRaw.m 0.00% <ø> (ø)
src/createDatasetDescription.m 0.00% <ø> (-100.00%) ⬇️
src/createFilename.m 95.89% <ø> (ø)
src/createJson.m 51.21% <ø> (ø)
src/gui/askForGroupAndOrSession.m 100.00% <ø> (ø)
src/gui/askUserCli.m 0.00% <ø> (ø)
src/gui/askUserGui.m 0.00% <ø> (ø)
src/gui/createQuestionList.m 100.00% <ø> (ø)
src/gui/getIsQuestionToAsk.m 100.00% <ø> (ø)
src/gui/setDefaultResponses.m 100.00% <ø> (ø)
... and 19 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 435eb3d...91b2260. Read the comment docs.

@Remi-Gau Remi-Gau merged commit 0cda77c into cpp-lln-lab:dev Nov 16, 2020
@Remi-Gau
Copy link
Contributor

@all-contributors please add @TomasLenc test

@allcontributors
Copy link
Contributor

@Remi-Gau

I've put up a pull request to add @TomasLenc! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants