Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create epochs on-the-fly when loading data if data has no previous epoch information #2041

Merged
merged 15 commits into from
Apr 17, 2024

Conversation

MichaelHuth
Copy link
Collaborator

@MichaelHuth MichaelHuth commented Mar 8, 2024

Idea for missing custom waves

Some files have missing custom waves for stimset recreation.

If these custom waves stimset epochs are neighboured by square epochs with amplitude 0 (check in stimset note) and assusimg the custom waves have a non-zero amplitude, these can be found in the DA wave.
From that the length can be determined and the stimset note updated.
This can be done for each custom wave from left to right until the length of all stimset epochs is present.
(How precise the intermediate backward transformation from data wave to stimset indices is, has to be determined)

Idea for missing TP information on very early MIES data

Resample recreated stimset to a temp data wave and match that with existing DA wave.
Determine TP + onsetUser as well as termination delay from there.

close #2008

requires #2015

@t-b
Copy link
Collaborator

t-b commented Mar 8, 2024

Allen FTP: epochs_issue_240308 has stimProtocol_2015_05_26_124639.h5 which holds the build stimsets. I think we could extract the custom waves from these.

@MichaelHuth
Copy link
Collaborator Author

MichaelHuth commented Mar 11, 2024

Issues:

WB Formulas in nwb2_H17.03.016.11.09.01.nwb

Determine if insert TP was on in sweep 0
nwb2_Pvalb-IRES-Cre_Ai14-214784.03.02.nwb

@MichaelHuth MichaelHuth force-pushed the feature/2015-create_dataconfiuration_from_lnb branch from 1839466 to 0733bac Compare March 19, 2024 01:09
@MichaelHuth MichaelHuth force-pushed the feature/2041-create_epochs_on_data_load branch from 3965176 to a1a5525 Compare March 19, 2024 01:31
@MichaelHuth MichaelHuth force-pushed the feature/2015-create_dataconfiuration_from_lnb branch from 0733bac to baa9234 Compare March 19, 2024 01:38
@MichaelHuth MichaelHuth force-pushed the feature/2041-create_epochs_on_data_load branch 2 times, most recently from d88f4ff to 2eb091f Compare March 21, 2024 15:39
@MichaelHuth
Copy link
Collaborator Author

@t-b How should the new feature coupled to the rest of MIES?

I currently have the fallback mechanism in BSP for displaying epochs in the SB/DB and the AB function to load Sweeps and Stimsets. Should there be a button for that in the AB or do we replace a button in the AB with loading both?

Also, what should be the update mechanism for the LBN and when do we apply that?

@MichaelHuth MichaelHuth force-pushed the feature/2015-create_dataconfiuration_from_lnb branch from baa9234 to 2400409 Compare March 23, 2024 05:02
Base automatically changed from feature/2015-create_dataconfiuration_from_lnb to main March 24, 2024 11:19
@t-b
Copy link
Collaborator

t-b commented Mar 25, 2024

I've chatted with Tim about this and here is our conclusion:

  • Overwrite the existing epoch info in NWBv2 files, existing IPNWB functions: WriteSingleChannel, WriteEpochs, AppendEpochTable
  • Should be done only on request (i.e. just implement a function)
  • We will then do the epoch overwriting with an approach like MIES_MassExperimentProcessing.ipf

We can do that in another PR given that this PR is self-contained with tests.

@t-b
Copy link
Collaborator

t-b commented Mar 25, 2024

We also would like to have retrofitted epoch info for data loaded into the databrowser/sweepbrowser (aka on-the-fly creation) either for SweepFormula or for display. Should probably be cached for speed reasons. But this should only be done if we don't have any epoch info at all.

@t-b
Copy link
Collaborator

t-b commented Apr 10, 2024

Thanks for the massive effort:

Review:

809d902 (WB: Better handling of errors when building a stimset, 2024-03-08)

  • The key added to the wave note needs to be more specific. Something like "WaveBuilder Error"?
  • Please introduce a constant for the error code 1. This makes it better discoverable (aka searching works better)
  • Please also add a test or two for the new error handling. UTF_WaveBuilder.ipf seems fitting.
  • Needs to raise STIMSET_NOTE_VERSION and adapted documentation in WB_GetWaveNoteEntry

cef5c04 (WB: Do not ASSERT in WB_StimsetHasLatestNoteVersion for non-existing stimset, 2024-03-21)

Makes sense

f51fc94 (WB: Transfer notes of stimset sweeps earlier in WB_GetStimset, 2024-03-21)

  • Should also be covered in the tests.

71eb1b0 (EP: Add error handling if certain required values are missing, 2024-03-08)

  • You seem to be working around an IP error with the "" + s.XXX. Please
    add a @todo workaround ... comment with a reference like #XXXX to the
    reported WM issue.

  • Why can't you return early in EP_GetStimEpochsOffsetAndLength instead of setting err = 1?

  • Please add an empty comment line between @param and @retval in EP_AddEpochsFromStimSetNote for visual separation

e0472f7 (DC: Recreation workaround for missing samplingInterval and baselineFrac, 2024-03-08)

  • Assertion for empty DACList

DC_RecreateDataConfigurationResultFromLNB_baselineFrac_Path2:

  • The level of 1E-3 seems to be arbitrary. As you are looking at the DA
    wave, can't we just a level of GetMachineEpsilon? I'm using that in the
    analysis functions as well.

  • Commented out code
    // s.baselineFrac ...

  • Who is responsible for setting

s.baselineFrac and friends to NaN if the following case is hit?

+    if(IsNaN(startIndex) || IsNaN(endIndex))
+        return NaN
+    endif

e4e82b7 (DC: Evaluate if the recreated stimset had an error condition, 2024-03-08)

Makes sense.

c0fb94c (DC: Better error messages for invalid stimsets after recreation by WB, 2024-03-12)

Nice!

eb56bab (DC: More flexible TP finding as fallback, 2024-03-12)

  • That should probably be part of e0472f7 or?

24043f3 (DC: Add fallbacks in recreation for MIES version < 0.7, 2024-03-20)

  • Commit message: "its necessary" -> "if necessary" ?

  • While still correct it is confusing to see mean being used in
    DC_FindStimsetOffset as we can also use V_avg from the earlier WaveStats call

4faf20c (DC: Add fallback for DataConfigurationResult recreation if no stimset wave is present, 2024-03-27)

Makes sense.

e9612a8 (AB: Introduce button to load all stimsets and sweeps for the selected entries, 2024-03-08)

  • You are duplicating code in AB_LoadStimsetsAndSweeps from
    AB_ButtonProc_LoadSweeps? Why not just PGC to both the stimset and the sweep
    buttons? Alternatively factor the code out into a common function.

3ba1af6 (EP: Change ASSERT to error return in EP_AddEpochsFromStimSet, 2024-03-12)

Fine!

c9c92e1 (Integrate epoch recreation in MIES, 2024-03-08)

I'm not particular fond of the TS/nonTS variants of EP_FetchEpochs but I also don't see another way.

  • Please add documentation for BSP_GetSweepDF and move the introduction into its own commit.

  • BSP_GetSweepDF: I don't see why we need the second if(isSweepBrowser) clause, I think this can be moved into the first one.

  • BSP_GetSweepDF: Don't use SFH_ASSERT outside of SF. You can return $"" if you want to handle the non-bound case gracefully.

  • EP_FetchEpochsFromRecreation. You need to return early if the returned epochs wave is null

  • Can we exercise the code paths for on-the-fly epoch recreation somehow in a test?

@t-b t-b assigned MichaelHuth and unassigned t-b Apr 10, 2024
@MichaelHuth
Copy link
Collaborator Author

MichaelHuth commented Apr 10, 2024

  • add test like TestExportingDataToNWB in HistoricData that executes a Epoch recreation and checks if epochs exists afterwards. This should also cover the fallback paths in the recreation.

@MichaelHuth MichaelHuth force-pushed the feature/2041-create_epochs_on_data_load branch from c9c92e1 to af6ecf0 Compare April 12, 2024 16:12
@MichaelHuth
Copy link
Collaborator Author

s.baselineFrac and friends to NaN if the following case is hit?

s.baselineFrac is set to NaN when the first LNB read attempt is done unsuccessful in DC_RecreateDataConfigurationResultFromLNB_Indep.

@MichaelHuth MichaelHuth force-pushed the feature/2041-create_epochs_on_data_load branch 2 times, most recently from c63776a to 09bbaf8 Compare April 16, 2024 12:19
@MichaelHuth MichaelHuth assigned t-b and unassigned MichaelHuth Apr 16, 2024
Better handling for Custom Wave for stimset epoch can not be resolved

- Previously in that case the wavebuilder just added the previous segment
  to the stimset wave again, whatever that was, as well as the length
  information. Thus, both was wrong and it resulted in a wrong stimset.

Fix:
- Initialize the segment to zero size at the start of the custom wave
  part, such that no garbage is added to the stimset.
  However, the stimset is still wrong as it is impossible to retrieve
  missing data.
- Add only size information for stimset segment, if there the segment
  has an actual size.
- As a missing custom wave is a not fixable error, introduce a field
  in the stimset note to store this information: STIMSET_ERROR_KEY
  When set then the stimset data and wave length is invalid.
  The stimset note is OK.

Improve error output for missing custom waves from stimset segments

Add failed COMBINED segments to error return code in stimset note
…stimset

This allows to WB_CreateAndGetStimset to return a null wave for a
stimset name that does not exist.
This change enables to have the stimset note available if the stimset
is zero sized, e.g. due to failing segment creations.

Error information can be retrieved then from the stimset note.
- if stimset size can not be determined from stimset epochs, try to use
  stimset size in data wave from s.setLength, if that also fails,
  abort early adding stimset epochs
- if stimset epoch adding fails, do not try to add baseline trail as it
  depends on knowing the stimset size
- if stimset epoch adding fails use a weaker limit of inf for the end of
  oodDAQ regions
- for samplingInterval the first DA sweep is retrieved and DimDelta is used
- if baselineFrac is missing, but s.onsetDelayAuto is > 0 then
  find edges in this range, as it indicates a onset due to TP insertion.
  Use edge positions to fill TP information and recreate TP wave.
- Use workaround to calculate setLength from the stimset wave only if
  the stimset recreation was good
The very early MIES versions did not store the offset of the stimset in
the DA wave. The offset is required for epoch recreation because it allows
to split the DA wave into the onset, stimset and trail region.

1.
Added a fallback algorithm that exploits the fact that the trail is
a zero line. So the position of the last feature of the DA wave is
matched against the last feature of the decimated stimset.

Then the decimated stimset is compared to the DA wave content in a
-2 to +2 range from the initial guess.

If that fails then the whole range from 0 to the initial guess is searched
for an optimal match between decimated stimset and DA wave content.
The intense search is time consuming and a "last option" fallback.
Checking available test data it was never required, so it should be
a very rare case if necessary (or may hint to a flaw in the method for
the initial guess).

2.
For the special case that the stimset itself is a zero line, the DA wave
is checked if there is a feature, that can only be a TP.
From that TP and its baseline symmetry the offset of the stimset start is
determined.
… wave is present

- this case happens only in testing where the LNB is filled partially
… entries

- for epoch recreation loading both is required.
adds a generic function to return a sweeps data folder for a DB or SB window
and a given sweep number.
- The recreation of epochs is by design not threadsafe, e.g. due to stimset
  recreation that can include a combine epoch, where a formula is
  executed with Execute.
  Thus, EP_FetchEpochs was split to have a separate threadsafe function that does
  not include epoch recreation.
  As epoch recreation requires to know the sweepDF to retrieve the DA waves,
  support for this argument was added in the call chain.

- BSP (SB/DB) and SweepFormula support epochs from recreation
- Exporting data to NWB does not support recreation as that module runs threadsafe.
…NNELS

The algorithm was only taking channels into account in the range up to NUM_DA_TTL_CHANNELS,
but NUM_AD_CHANNELS is larger, such that channels > 7 were missed.

Corrected the indexing and the following lookup for the headstage of the AD channel.

since 2eaa70d (DC: Add function to recreate DataConfigurationResult structure from LNB, 2024-02-21)
@MichaelHuth MichaelHuth force-pushed the feature/2041-create_epochs_on_data_load branch from 09bbaf8 to c45f7a6 Compare April 16, 2024 14:58
@t-b
Copy link
Collaborator

t-b commented Apr 16, 2024

Thanks for the adaptations. LGTM.

@t-b t-b removed their assignment Apr 16, 2024
@t-b t-b enabled auto-merge April 16, 2024 17:55
@t-b t-b merged commit bde7282 into main Apr 17, 2024
20 checks passed
@t-b t-b deleted the feature/2041-create_epochs_on_data_load branch April 17, 2024 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow recreating DA epoch info from labnotebook entries
2 participants