Loading EEG/EEG.cpp +18 −24 Original line number Diff line number Diff line Loading @@ -409,18 +409,16 @@ autoEEG EEG_readFromBdfFile (MelderFile file) { } } static void detrend (double *a, integer numberOfSamples) { double firstValue = a [1], lastValue = a [numberOfSamples]; a [1] = a [numberOfSamples] = 0.0; for (integer isamp = 2; isamp < numberOfSamples; isamp ++) { a [isamp] -= ((isamp - 1.0) * lastValue + (numberOfSamples - isamp) * firstValue) / (numberOfSamples - 1); } static void detrend (VEC const& channel) { double firstValue = channel [1], lastValue = channel [channel.size]; channel [1] = channel [channel.size] = 0.0; for (integer isamp = 2; isamp < channel.size; isamp ++) channel [isamp] -= ((isamp - 1.0) * lastValue + (channel.size - isamp) * firstValue) / (channel.size - 1); } void EEG_detrend (EEG me) { for (integer ichan = 1; ichan <= my numberOfChannels - EEG_getNumberOfExtraSensors (me); ichan ++) { detrend (my sound -> z [ichan], my sound -> nx); } for (integer ichan = 1; ichan <= my numberOfChannels - EEG_getNumberOfExtraSensors (me); ichan ++) detrend (my sound -> z.row (ichan)); } void EEG_filter (EEG me, double lowFrequency, double lowWidth, double highFrequency, double highWidth, bool doNotch50Hz) { Loading @@ -441,7 +439,7 @@ void EEG_filter (EEG me, double lowFrequency, double lowWidth, double highFreque Spectrum_stopHannBand (spec.get(), 48.0, 52.0, 1.0); } autoSound him = Spectrum_to_Sound (spec.get()); NUMvector_copyElements (his z [1], my sound -> z [ichan], 1, my sound -> nx); NUMvector_copyElements (& his z [1] [0], & my sound -> z [ichan] [0], 1, my sound -> nx); } } catch (MelderError) { Melder_throw (me, U": not filtered."); Loading Loading @@ -496,25 +494,22 @@ void EEG_subtractMeanChannel (EEG me, integer fromChannel, integer toChannel) { const integer numberOfElectrodeChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); for (integer isamp = 1; isamp <= my sound -> nx; isamp ++) { double referenceValue = 0.0; for (integer ichan = fromChannel; ichan <= toChannel; ichan ++) { for (integer ichan = fromChannel; ichan <= toChannel; ichan ++) referenceValue += my sound -> z [ichan] [isamp]; } referenceValue /= (toChannel - fromChannel + 1); for (integer ichan = 1; ichan <= numberOfElectrodeChannels; ichan ++) { for (integer ichan = 1; ichan <= numberOfElectrodeChannels; ichan ++) my sound -> z [ichan] [isamp] -= referenceValue; } } } void EEG_setChannelToZero (EEG me, integer channelNumber) { try { if (channelNumber < 1 || channelNumber > my numberOfChannels) Melder_throw (U"No channel ", channelNumber, U"."); integer numberOfSamples = my sound -> nx; double *channel = my sound -> z [channelNumber]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { VEC channel = my sound -> z.row (channelNumber); for (integer isample = 1; isample <= numberOfSamples; isample ++) channel [isample] = 0.0; } } catch (MelderError) { Melder_throw (me, U": channel ", channelNumber, U" not set to zero."); } Loading Loading @@ -594,9 +589,8 @@ static void Sound_removeChannel (Sound me, integer channelNumber) { U"No channel ", channelNumber, U"."); Melder_require (my ny > 1, U"Cannot remove last remaining channel."); for (integer ichan = channelNumber; ichan < my ny; ichan ++) { NUMvector_copyElements (my z [ichan + 1], my z [ichan], 1, my nx); } for (integer ichan = channelNumber; ichan < my ny; ichan ++) NUMvector_copyElements (& my z [ichan + 1] [0], & my z [ichan] [0], 1, my nx); my ymax -= 1.0; my ny -= 1; } catch (MelderError) { Loading Loading @@ -636,7 +630,7 @@ autoEEG EEGs_concatenate (OrderedOf<structEEG>* me) { Melder_throw (U"Cannot concatenate zero EEG objects."); EEG first = my at [1]; integer numberOfChannels = first -> numberOfChannels; autostring32vector channelNames = STRVECclone (first -> channelNames.get()); autostring32vector channelNames = newSTRVECcopy (first -> channelNames.get()); for (integer ieeg = 2; ieeg <= my size; ieeg ++) { EEG other = my at [ieeg]; if (other -> numberOfChannels != numberOfChannels) Loading Loading @@ -671,7 +665,7 @@ autoEEG EEG_extractPart (EEG me, double tmin, double tmax, bool preserveTimes) { try { autoEEG thee = Thing_new (EEG); thy numberOfChannels = my numberOfChannels; thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); thy sound = Sound_extractPart (my sound.get(), tmin, tmax, kSound_windowShape::RECTANGULAR, 1.0, preserveTimes); thy textgrid = TextGrid_extractPart (my textgrid.get(), tmin, tmax, preserveTimes); thy xmin = thy textgrid -> xmin; Loading Loading @@ -723,7 +717,7 @@ autoEEG EEG_MixingMatrix_to_EEG_unmix (EEG me, MixingMatrix you) { his sound = Sound_MixingMatrix_unmix (my sound.get(), you); his textgrid = Data_copy (my textgrid.get()); his numberOfChannels = your numberOfColumns; his channelNames = STRVECclone (your columnLabels.get()); his channelNames = newSTRVECcopy (your columnLabels.get()); return him; } Loading @@ -741,7 +735,7 @@ autoEEG EEG_MixingMatrix_to_EEG_mix (EEG me, MixingMatrix you) { his sound = Sound_MixingMatrix_mix (my sound.get(), you); his textgrid = Data_copy (my textgrid.get()); his numberOfChannels = your numberOfRows; his channelNames = STRVECclone (your rowLabels.get()); his channelNames = newSTRVECcopy (your rowLabels.get()); return him; } Loading EEG/ERP.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ void ERP_drawChannel_number (ERP me, Graphics graphics, integer channelNumber, d */ Graphics_setInner (graphics); Graphics_setWindow (graphics, tmin, tmax, vmin, vmax); Graphics_function (graphics, my z [channelNumber], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); Graphics_function (graphics, & my z [channelNumber] [0], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); Graphics_unsetInner (graphics); if (garnish) { Graphics_drawInnerBox (graphics); Loading EEG/ERPTier.cpp +13 −34 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ static autoERPTier EEG_PointProcess_to_ERPTier (EEG me, PointProcess events, dou Function_init (thee.get(), fromTime, toTime); thy numberOfChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); Melder_assert (thy numberOfChannels > 0); thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); integer numberOfEvents = events -> nt; double soundDuration = toTime - fromTime; double samplingPeriod = my sound -> dx; Loading Loading @@ -191,7 +191,7 @@ void ERPTier_subtractBaseline (ERPTier me, double tmin, double tmax) { ERPPoint event = my points.at [ievent]; for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double mean = Vector_getMean (event -> erp.get(), tmin, tmax, ichannel); double *channel = event -> erp -> z [ichannel]; VEC channel = event -> erp -> z.row (ichannel); for (integer isample = 1; isample <= numberOfSamples; isample ++) { channel [isample] -= mean; } Loading @@ -213,7 +213,7 @@ void ERPTier_rejectArtefacts (ERPTier me, double threshold) { double minimum = event -> erp -> z [1] [1]; double maximum = minimum; for (integer ichannel = 1; ichannel <= (numberOfChannels & ~ 15); ichannel ++) { double *channel = event -> erp -> z [ichannel]; constVEC channel = event -> erp -> z.row (ichannel); for (integer isample = 1; isample <= numberOfSamples; isample ++) { double value = channel [isample]; if (value < minimum) minimum = value; Loading @@ -233,19 +233,10 @@ autoERP ERPTier_extractERP (ERPTier me, integer eventNumber) { Melder_throw (U"No events."); ERPTier_checkEventNumber (me, eventNumber); ERPPoint event = my points.at [eventNumber]; integer numberOfChannels = event -> erp -> ny; Melder_assert (numberOfChannels == my numberOfChannels); integer numberOfSamples = event -> erp -> nx; Melder_assert (event -> erp -> ny == my numberOfChannels); autoERP thee = Thing_new (ERP); event -> erp -> structSound :: v_copy (thee.get()); for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *oldChannel = event -> erp -> z [ichannel]; double *newChannel = thy z [ichannel]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { newChannel [isample] = oldChannel [isample]; } } thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); return thee; } catch (MelderError) { Melder_throw (me, U": ERP not extracted."); Loading @@ -258,29 +249,17 @@ autoERP ERPTier_to_ERP_mean (ERPTier me) { if (numberOfEvents < 1) Melder_throw (U"No events."); ERPPoint firstEvent = my points.at [1]; integer numberOfChannels = firstEvent -> erp -> ny; integer numberOfSamples = firstEvent -> erp -> nx; Melder_assert (firstEvent -> erp -> ny == my numberOfChannels); autoERP mean = Thing_new (ERP); firstEvent -> erp -> structSound :: v_copy (mean.get()); Melder_assert (mean -> ny == my numberOfChannels); for (integer ievent = 2; ievent <= numberOfEvents; ievent ++) { ERPPoint event = my points.at [ievent]; for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *erpChannel = event -> erp -> z [ichannel]; double *meanChannel = mean -> z [ichannel]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { meanChannel [isample] += erpChannel [isample]; } } } double factor = 1.0 / numberOfEvents; for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *meanChannel = mean -> z [ichannel]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { meanChannel [isample] *= factor; Melder_assert (event -> erp -> ny == my numberOfChannels); mean -> z.all() += event -> erp -> z.all(); } } Melder_assert (mean -> ny == my numberOfChannels); mean -> channelNames = STRVECclone (my channelNames.get()); mean -> z.all() *= 1.0 / numberOfEvents; mean -> channelNames = newSTRVECcopy (my channelNames.get()); return mean; } catch (MelderError) { Melder_throw (me, U": mean not computed."); Loading @@ -297,7 +276,7 @@ autoERPTier ERPTier_extractEventsWhereColumn_number (ERPTier me, Table table, in autoERPTier thee = Thing_new (ERPTier); Function_init (thee.get(), my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); for (integer ievent = 1; ievent <= my points.size; ievent ++) { ERPPoint oldEvent = my points.at [ievent]; TableRow row = table -> rows.at [ievent]; Loading Loading @@ -326,7 +305,7 @@ autoERPTier ERPTier_extractEventsWhereColumn_string (ERPTier me, Table table, autoERPTier thee = Thing_new (ERPTier); Function_init (thee.get(), my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); for (integer ievent = 1; ievent <= my points.size; ievent ++) { ERPPoint oldEvent = my points.at [ievent]; TableRow row = table -> rows.at [ievent]; Loading EEG/ERPWindow.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ void ERP_drawScalp_garnish (Graphics graphics, double vmin, double vmax, enum kG } } Graphics_setColourScale (graphics, colourScale); Graphics_image (graphics, legend.at, 1, 2, 0.85, 0.98, 1, n, -0.8, +0.8, 0.0, 1.0); Graphics_image (graphics, legend.all(), 0.85, 0.98, -0.8, +0.8, 0.0, 1.0); Graphics_setColourScale (graphics, kGraphics_colourScale::GREY); Graphics_rectangle (graphics, 0.85, 0.98, -0.8, +0.8); Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_TOP); Loading Loading @@ -232,7 +232,7 @@ void ERP_drawScalp (ERP me, Graphics graphics, double tmin, double tmax, double } } } Graphics_image (graphics, image.at, 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, vmin, vmax); Graphics_image (graphics, image.all(), -1.0-0.5/n, 1.0+0.5/n, -1.0-0.5/n, 1.0+0.5/n, vmin, vmax); Graphics_setColourScale (graphics, kGraphics_colourScale::GREY); Graphics_setLineWidth (graphics, 2.0); /* Loading Loading @@ -357,7 +357,7 @@ void structERPWindow :: v_drawSelectionViewer () { } } Graphics_setColourScale (our graphics.get(), our p_scalp_colourScale); Graphics_image (our graphics.get(), image.at, 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum); Graphics_image (our graphics.get(), image.all(), -1.0-0.5/n, 1.0+0.5/n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum); Graphics_setColourScale (our graphics.get(), kGraphics_colourScale::GREY); Graphics_setLineWidth (our graphics.get(), 2.0); /* Loading Loading @@ -393,7 +393,8 @@ void structERPWindow :: v_drawSelectionViewer () { OPTIONMENU_ENUM_VARIABLE (kGraphics_colourScale, v_prefs_scalpColourSpace) void structERPWindow :: v_prefs_addFields (EditorCommand cmd) { OPTIONMENU_ENUM_FIELD (v_prefs_scalpColourSpace, U"Scalp colour space", kGraphics_colourScale, kGraphics_colourScale::BLUE_TO_RED) OPTIONMENU_ENUM_FIELD (kGraphics_colourScale, v_prefs_scalpColourSpace, U"Scalp colour space", kGraphics_colourScale::BLUE_TO_RED) } void structERPWindow :: v_prefs_setValues (EditorCommand cmd) { SET_ENUM (v_prefs_scalpColourSpace, kGraphics_colourScale, p_scalp_colourScale) Loading EEG/praat_EEG.cpp +18 −12 Original line number Diff line number Diff line Loading @@ -125,12 +125,13 @@ DO } FORM (MODIFY_EEG_removeTriggers, U"Remove triggers", nullptr) { OPTIONMENU_ENUM (removeEveryTriggerThat___, U"Remove every trigger that...", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, removeEveryTriggerThat___, U"Remove every trigger that...", kMelder_string::DEFAULT) SENTENCE (___theText, U"...the text", U"hi") OK DO MODIFY_EACH (EEG) EEG_removeTriggers (me, (kMelder_string) removeEveryTriggerThat___, ___theText); EEG_removeTriggers (me, removeEveryTriggerThat___, ___theText); MODIFY_EACH_END } Loading Loading @@ -266,27 +267,30 @@ DO FORM (NEW_EEG_to_ERPTier_triggers, U"To ERPTier (triggers)", nullptr) { REAL (fromTime, U"From time (s)", U"-0.11") REAL (toTime, U"To time (s)", U"0.39") OPTIONMENU_ENUM (getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string::DEFAULT) SENTENCE (theText, U"...the text", U"1") OK DO CONVERT_EACH (EEG) autoERPTier result = EEG_to_ERPTier_triggers (me, fromTime, toTime, (kMelder_string) getEveryEventWithATriggerThat, theText); autoERPTier result = EEG_to_ERPTier_triggers (me, fromTime, toTime, getEveryEventWithATriggerThat, theText); CONVERT_EACH_END (my name.get(), U"_trigger", theText) } FORM (NEW_EEG_to_ERPTier_triggers_preceded, U"To ERPTier (triggers, preceded)", nullptr) { REAL (fromTime, U"From time (s)", U"-0.11") REAL (toTime, U"To time (s)", U"0.39") OPTIONMENU_ENUM (getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string::DEFAULT) SENTENCE (text1, U"...the text", U"1") OPTIONMENU_ENUM (andIsPrecededByATriggerThat, U"and is preceded by a trigger that", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, andIsPrecededByATriggerThat, U"and is preceded by a trigger that", kMelder_string::DEFAULT) SENTENCE (text2, U" ...the text", U"4") OK DO CONVERT_EACH (EEG) autoERPTier result = EEG_to_ERPTier_triggers_preceded (me, fromTime, toTime, (kMelder_string) getEveryEventWithATriggerThat, text1, (kMelder_string) andIsPrecededByATriggerThat, text2); (kMelder_string) getEveryEventWithATriggerThat, text1, andIsPrecededByATriggerThat, text2); CONVERT_EACH_END (my name.get(), U"_trigger", text2) } Loading Loading @@ -422,7 +426,8 @@ FORM (GRAPHICS_ERP_drawScalp_colour, U"ERP: Draw scalp (colour)", nullptr) { REAL (toTime, U"right Time range", U"0.2") REAL (fromVoltage, U"left Voltage range (V)", U"10e-6") REAL (toVoltage, U"right Voltage range", U"-10e-6") RADIO_ENUM (colourScale, U"Colour scale", kGraphics_colourScale, BLUE_TO_RED) RADIO_ENUM (kGraphics_colourScale, colourScale, U"Colour scale", kGraphics_colourScale::BLUE_TO_RED) BOOLEAN (garnish, U"Garnish", true) OK DO Loading @@ -435,7 +440,8 @@ DO FORM (GRAPHICS_ERP_drawScalp_garnish, U"ERP: Draw scalp (garnish)", nullptr) { REAL (fromVoltage, U"left Voltage range (V)", U"10e-6") REAL (toVoltage, U"right Voltage range", U"-10e-6") RADIO_ENUM (colourScale, U"Colour scale", kGraphics_colourScale, BLUE_TO_RED) RADIO_ENUM (kGraphics_colourScale, colourScale, U"Colour scale", kGraphics_colourScale::BLUE_TO_RED) OK DO GRAPHICS_NONE Loading Loading @@ -704,7 +710,7 @@ DIRECT (NEW_ERPTier_to_ERP_mean) { FORM (NEW1_ERPTier_Table_extractEventsWhereColumn_number, U"Extract events where column (number)", nullptr) { WORD (extractAllEventsWhereColumn___, U"Extract all events where column...", U"") RADIO_ENUM (___is___, U"...is...", kMelder_number, DEFAULT) RADIO_ENUM (kMelder_number, ___is___, U"...is...", kMelder_number::DEFAULT) REAL (___theNumber, U"...the number", U"0.0") OK DO Loading @@ -716,13 +722,13 @@ DO FORM (NEW1_ERPTier_Table_extractEventsWhereColumn_text, U"Extract events where column (text)", nullptr) { WORD (extractAllEventsWhereColumn___, U"Extract all events where column...", U"") OPTIONMENU_ENUM (___, U"...", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, ___, U"...", kMelder_string::DEFAULT) SENTENCE (___theText, U"...the text", U"hi") OK DO CONVERT_TWO (ERPTier, Table) integer columnNumber = Table_getColumnIndexFromColumnLabel (you, extractAllEventsWhereColumn___); autoERPTier result = ERPTier_extractEventsWhereColumn_string (me, you, columnNumber, (kMelder_string) ___, ___theText); autoERPTier result = ERPTier_extractEventsWhereColumn_string (me, you, columnNumber, ___, ___theText); CONVERT_TWO_END (my name.get()) } Loading Loading
EEG/EEG.cpp +18 −24 Original line number Diff line number Diff line Loading @@ -409,18 +409,16 @@ autoEEG EEG_readFromBdfFile (MelderFile file) { } } static void detrend (double *a, integer numberOfSamples) { double firstValue = a [1], lastValue = a [numberOfSamples]; a [1] = a [numberOfSamples] = 0.0; for (integer isamp = 2; isamp < numberOfSamples; isamp ++) { a [isamp] -= ((isamp - 1.0) * lastValue + (numberOfSamples - isamp) * firstValue) / (numberOfSamples - 1); } static void detrend (VEC const& channel) { double firstValue = channel [1], lastValue = channel [channel.size]; channel [1] = channel [channel.size] = 0.0; for (integer isamp = 2; isamp < channel.size; isamp ++) channel [isamp] -= ((isamp - 1.0) * lastValue + (channel.size - isamp) * firstValue) / (channel.size - 1); } void EEG_detrend (EEG me) { for (integer ichan = 1; ichan <= my numberOfChannels - EEG_getNumberOfExtraSensors (me); ichan ++) { detrend (my sound -> z [ichan], my sound -> nx); } for (integer ichan = 1; ichan <= my numberOfChannels - EEG_getNumberOfExtraSensors (me); ichan ++) detrend (my sound -> z.row (ichan)); } void EEG_filter (EEG me, double lowFrequency, double lowWidth, double highFrequency, double highWidth, bool doNotch50Hz) { Loading @@ -441,7 +439,7 @@ void EEG_filter (EEG me, double lowFrequency, double lowWidth, double highFreque Spectrum_stopHannBand (spec.get(), 48.0, 52.0, 1.0); } autoSound him = Spectrum_to_Sound (spec.get()); NUMvector_copyElements (his z [1], my sound -> z [ichan], 1, my sound -> nx); NUMvector_copyElements (& his z [1] [0], & my sound -> z [ichan] [0], 1, my sound -> nx); } } catch (MelderError) { Melder_throw (me, U": not filtered."); Loading Loading @@ -496,25 +494,22 @@ void EEG_subtractMeanChannel (EEG me, integer fromChannel, integer toChannel) { const integer numberOfElectrodeChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); for (integer isamp = 1; isamp <= my sound -> nx; isamp ++) { double referenceValue = 0.0; for (integer ichan = fromChannel; ichan <= toChannel; ichan ++) { for (integer ichan = fromChannel; ichan <= toChannel; ichan ++) referenceValue += my sound -> z [ichan] [isamp]; } referenceValue /= (toChannel - fromChannel + 1); for (integer ichan = 1; ichan <= numberOfElectrodeChannels; ichan ++) { for (integer ichan = 1; ichan <= numberOfElectrodeChannels; ichan ++) my sound -> z [ichan] [isamp] -= referenceValue; } } } void EEG_setChannelToZero (EEG me, integer channelNumber) { try { if (channelNumber < 1 || channelNumber > my numberOfChannels) Melder_throw (U"No channel ", channelNumber, U"."); integer numberOfSamples = my sound -> nx; double *channel = my sound -> z [channelNumber]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { VEC channel = my sound -> z.row (channelNumber); for (integer isample = 1; isample <= numberOfSamples; isample ++) channel [isample] = 0.0; } } catch (MelderError) { Melder_throw (me, U": channel ", channelNumber, U" not set to zero."); } Loading Loading @@ -594,9 +589,8 @@ static void Sound_removeChannel (Sound me, integer channelNumber) { U"No channel ", channelNumber, U"."); Melder_require (my ny > 1, U"Cannot remove last remaining channel."); for (integer ichan = channelNumber; ichan < my ny; ichan ++) { NUMvector_copyElements (my z [ichan + 1], my z [ichan], 1, my nx); } for (integer ichan = channelNumber; ichan < my ny; ichan ++) NUMvector_copyElements (& my z [ichan + 1] [0], & my z [ichan] [0], 1, my nx); my ymax -= 1.0; my ny -= 1; } catch (MelderError) { Loading Loading @@ -636,7 +630,7 @@ autoEEG EEGs_concatenate (OrderedOf<structEEG>* me) { Melder_throw (U"Cannot concatenate zero EEG objects."); EEG first = my at [1]; integer numberOfChannels = first -> numberOfChannels; autostring32vector channelNames = STRVECclone (first -> channelNames.get()); autostring32vector channelNames = newSTRVECcopy (first -> channelNames.get()); for (integer ieeg = 2; ieeg <= my size; ieeg ++) { EEG other = my at [ieeg]; if (other -> numberOfChannels != numberOfChannels) Loading Loading @@ -671,7 +665,7 @@ autoEEG EEG_extractPart (EEG me, double tmin, double tmax, bool preserveTimes) { try { autoEEG thee = Thing_new (EEG); thy numberOfChannels = my numberOfChannels; thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); thy sound = Sound_extractPart (my sound.get(), tmin, tmax, kSound_windowShape::RECTANGULAR, 1.0, preserveTimes); thy textgrid = TextGrid_extractPart (my textgrid.get(), tmin, tmax, preserveTimes); thy xmin = thy textgrid -> xmin; Loading Loading @@ -723,7 +717,7 @@ autoEEG EEG_MixingMatrix_to_EEG_unmix (EEG me, MixingMatrix you) { his sound = Sound_MixingMatrix_unmix (my sound.get(), you); his textgrid = Data_copy (my textgrid.get()); his numberOfChannels = your numberOfColumns; his channelNames = STRVECclone (your columnLabels.get()); his channelNames = newSTRVECcopy (your columnLabels.get()); return him; } Loading @@ -741,7 +735,7 @@ autoEEG EEG_MixingMatrix_to_EEG_mix (EEG me, MixingMatrix you) { his sound = Sound_MixingMatrix_mix (my sound.get(), you); his textgrid = Data_copy (my textgrid.get()); his numberOfChannels = your numberOfRows; his channelNames = STRVECclone (your rowLabels.get()); his channelNames = newSTRVECcopy (your rowLabels.get()); return him; } Loading
EEG/ERP.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ void ERP_drawChannel_number (ERP me, Graphics graphics, integer channelNumber, d */ Graphics_setInner (graphics); Graphics_setWindow (graphics, tmin, tmax, vmin, vmax); Graphics_function (graphics, my z [channelNumber], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); Graphics_function (graphics, & my z [channelNumber] [0], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); Graphics_unsetInner (graphics); if (garnish) { Graphics_drawInnerBox (graphics); Loading
EEG/ERPTier.cpp +13 −34 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ static autoERPTier EEG_PointProcess_to_ERPTier (EEG me, PointProcess events, dou Function_init (thee.get(), fromTime, toTime); thy numberOfChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); Melder_assert (thy numberOfChannels > 0); thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); integer numberOfEvents = events -> nt; double soundDuration = toTime - fromTime; double samplingPeriod = my sound -> dx; Loading Loading @@ -191,7 +191,7 @@ void ERPTier_subtractBaseline (ERPTier me, double tmin, double tmax) { ERPPoint event = my points.at [ievent]; for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double mean = Vector_getMean (event -> erp.get(), tmin, tmax, ichannel); double *channel = event -> erp -> z [ichannel]; VEC channel = event -> erp -> z.row (ichannel); for (integer isample = 1; isample <= numberOfSamples; isample ++) { channel [isample] -= mean; } Loading @@ -213,7 +213,7 @@ void ERPTier_rejectArtefacts (ERPTier me, double threshold) { double minimum = event -> erp -> z [1] [1]; double maximum = minimum; for (integer ichannel = 1; ichannel <= (numberOfChannels & ~ 15); ichannel ++) { double *channel = event -> erp -> z [ichannel]; constVEC channel = event -> erp -> z.row (ichannel); for (integer isample = 1; isample <= numberOfSamples; isample ++) { double value = channel [isample]; if (value < minimum) minimum = value; Loading @@ -233,19 +233,10 @@ autoERP ERPTier_extractERP (ERPTier me, integer eventNumber) { Melder_throw (U"No events."); ERPTier_checkEventNumber (me, eventNumber); ERPPoint event = my points.at [eventNumber]; integer numberOfChannels = event -> erp -> ny; Melder_assert (numberOfChannels == my numberOfChannels); integer numberOfSamples = event -> erp -> nx; Melder_assert (event -> erp -> ny == my numberOfChannels); autoERP thee = Thing_new (ERP); event -> erp -> structSound :: v_copy (thee.get()); for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *oldChannel = event -> erp -> z [ichannel]; double *newChannel = thy z [ichannel]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { newChannel [isample] = oldChannel [isample]; } } thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); return thee; } catch (MelderError) { Melder_throw (me, U": ERP not extracted."); Loading @@ -258,29 +249,17 @@ autoERP ERPTier_to_ERP_mean (ERPTier me) { if (numberOfEvents < 1) Melder_throw (U"No events."); ERPPoint firstEvent = my points.at [1]; integer numberOfChannels = firstEvent -> erp -> ny; integer numberOfSamples = firstEvent -> erp -> nx; Melder_assert (firstEvent -> erp -> ny == my numberOfChannels); autoERP mean = Thing_new (ERP); firstEvent -> erp -> structSound :: v_copy (mean.get()); Melder_assert (mean -> ny == my numberOfChannels); for (integer ievent = 2; ievent <= numberOfEvents; ievent ++) { ERPPoint event = my points.at [ievent]; for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *erpChannel = event -> erp -> z [ichannel]; double *meanChannel = mean -> z [ichannel]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { meanChannel [isample] += erpChannel [isample]; } } } double factor = 1.0 / numberOfEvents; for (integer ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *meanChannel = mean -> z [ichannel]; for (integer isample = 1; isample <= numberOfSamples; isample ++) { meanChannel [isample] *= factor; Melder_assert (event -> erp -> ny == my numberOfChannels); mean -> z.all() += event -> erp -> z.all(); } } Melder_assert (mean -> ny == my numberOfChannels); mean -> channelNames = STRVECclone (my channelNames.get()); mean -> z.all() *= 1.0 / numberOfEvents; mean -> channelNames = newSTRVECcopy (my channelNames.get()); return mean; } catch (MelderError) { Melder_throw (me, U": mean not computed."); Loading @@ -297,7 +276,7 @@ autoERPTier ERPTier_extractEventsWhereColumn_number (ERPTier me, Table table, in autoERPTier thee = Thing_new (ERPTier); Function_init (thee.get(), my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); for (integer ievent = 1; ievent <= my points.size; ievent ++) { ERPPoint oldEvent = my points.at [ievent]; TableRow row = table -> rows.at [ievent]; Loading Loading @@ -326,7 +305,7 @@ autoERPTier ERPTier_extractEventsWhereColumn_string (ERPTier me, Table table, autoERPTier thee = Thing_new (ERPTier); Function_init (thee.get(), my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy channelNames = STRVECclone (my channelNames.get()); thy channelNames = newSTRVECcopy (my channelNames.get()); for (integer ievent = 1; ievent <= my points.size; ievent ++) { ERPPoint oldEvent = my points.at [ievent]; TableRow row = table -> rows.at [ievent]; Loading
EEG/ERPWindow.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -158,7 +158,7 @@ void ERP_drawScalp_garnish (Graphics graphics, double vmin, double vmax, enum kG } } Graphics_setColourScale (graphics, colourScale); Graphics_image (graphics, legend.at, 1, 2, 0.85, 0.98, 1, n, -0.8, +0.8, 0.0, 1.0); Graphics_image (graphics, legend.all(), 0.85, 0.98, -0.8, +0.8, 0.0, 1.0); Graphics_setColourScale (graphics, kGraphics_colourScale::GREY); Graphics_rectangle (graphics, 0.85, 0.98, -0.8, +0.8); Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_TOP); Loading Loading @@ -232,7 +232,7 @@ void ERP_drawScalp (ERP me, Graphics graphics, double tmin, double tmax, double } } } Graphics_image (graphics, image.at, 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, vmin, vmax); Graphics_image (graphics, image.all(), -1.0-0.5/n, 1.0+0.5/n, -1.0-0.5/n, 1.0+0.5/n, vmin, vmax); Graphics_setColourScale (graphics, kGraphics_colourScale::GREY); Graphics_setLineWidth (graphics, 2.0); /* Loading Loading @@ -357,7 +357,7 @@ void structERPWindow :: v_drawSelectionViewer () { } } Graphics_setColourScale (our graphics.get(), our p_scalp_colourScale); Graphics_image (our graphics.get(), image.at, 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum); Graphics_image (our graphics.get(), image.all(), -1.0-0.5/n, 1.0+0.5/n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum); Graphics_setColourScale (our graphics.get(), kGraphics_colourScale::GREY); Graphics_setLineWidth (our graphics.get(), 2.0); /* Loading Loading @@ -393,7 +393,8 @@ void structERPWindow :: v_drawSelectionViewer () { OPTIONMENU_ENUM_VARIABLE (kGraphics_colourScale, v_prefs_scalpColourSpace) void structERPWindow :: v_prefs_addFields (EditorCommand cmd) { OPTIONMENU_ENUM_FIELD (v_prefs_scalpColourSpace, U"Scalp colour space", kGraphics_colourScale, kGraphics_colourScale::BLUE_TO_RED) OPTIONMENU_ENUM_FIELD (kGraphics_colourScale, v_prefs_scalpColourSpace, U"Scalp colour space", kGraphics_colourScale::BLUE_TO_RED) } void structERPWindow :: v_prefs_setValues (EditorCommand cmd) { SET_ENUM (v_prefs_scalpColourSpace, kGraphics_colourScale, p_scalp_colourScale) Loading
EEG/praat_EEG.cpp +18 −12 Original line number Diff line number Diff line Loading @@ -125,12 +125,13 @@ DO } FORM (MODIFY_EEG_removeTriggers, U"Remove triggers", nullptr) { OPTIONMENU_ENUM (removeEveryTriggerThat___, U"Remove every trigger that...", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, removeEveryTriggerThat___, U"Remove every trigger that...", kMelder_string::DEFAULT) SENTENCE (___theText, U"...the text", U"hi") OK DO MODIFY_EACH (EEG) EEG_removeTriggers (me, (kMelder_string) removeEveryTriggerThat___, ___theText); EEG_removeTriggers (me, removeEveryTriggerThat___, ___theText); MODIFY_EACH_END } Loading Loading @@ -266,27 +267,30 @@ DO FORM (NEW_EEG_to_ERPTier_triggers, U"To ERPTier (triggers)", nullptr) { REAL (fromTime, U"From time (s)", U"-0.11") REAL (toTime, U"To time (s)", U"0.39") OPTIONMENU_ENUM (getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string::DEFAULT) SENTENCE (theText, U"...the text", U"1") OK DO CONVERT_EACH (EEG) autoERPTier result = EEG_to_ERPTier_triggers (me, fromTime, toTime, (kMelder_string) getEveryEventWithATriggerThat, theText); autoERPTier result = EEG_to_ERPTier_triggers (me, fromTime, toTime, getEveryEventWithATriggerThat, theText); CONVERT_EACH_END (my name.get(), U"_trigger", theText) } FORM (NEW_EEG_to_ERPTier_triggers_preceded, U"To ERPTier (triggers, preceded)", nullptr) { REAL (fromTime, U"From time (s)", U"-0.11") REAL (toTime, U"To time (s)", U"0.39") OPTIONMENU_ENUM (getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, getEveryEventWithATriggerThat, U"Get every event with a trigger that", kMelder_string::DEFAULT) SENTENCE (text1, U"...the text", U"1") OPTIONMENU_ENUM (andIsPrecededByATriggerThat, U"and is preceded by a trigger that", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, andIsPrecededByATriggerThat, U"and is preceded by a trigger that", kMelder_string::DEFAULT) SENTENCE (text2, U" ...the text", U"4") OK DO CONVERT_EACH (EEG) autoERPTier result = EEG_to_ERPTier_triggers_preceded (me, fromTime, toTime, (kMelder_string) getEveryEventWithATriggerThat, text1, (kMelder_string) andIsPrecededByATriggerThat, text2); (kMelder_string) getEveryEventWithATriggerThat, text1, andIsPrecededByATriggerThat, text2); CONVERT_EACH_END (my name.get(), U"_trigger", text2) } Loading Loading @@ -422,7 +426,8 @@ FORM (GRAPHICS_ERP_drawScalp_colour, U"ERP: Draw scalp (colour)", nullptr) { REAL (toTime, U"right Time range", U"0.2") REAL (fromVoltage, U"left Voltage range (V)", U"10e-6") REAL (toVoltage, U"right Voltage range", U"-10e-6") RADIO_ENUM (colourScale, U"Colour scale", kGraphics_colourScale, BLUE_TO_RED) RADIO_ENUM (kGraphics_colourScale, colourScale, U"Colour scale", kGraphics_colourScale::BLUE_TO_RED) BOOLEAN (garnish, U"Garnish", true) OK DO Loading @@ -435,7 +440,8 @@ DO FORM (GRAPHICS_ERP_drawScalp_garnish, U"ERP: Draw scalp (garnish)", nullptr) { REAL (fromVoltage, U"left Voltage range (V)", U"10e-6") REAL (toVoltage, U"right Voltage range", U"-10e-6") RADIO_ENUM (colourScale, U"Colour scale", kGraphics_colourScale, BLUE_TO_RED) RADIO_ENUM (kGraphics_colourScale, colourScale, U"Colour scale", kGraphics_colourScale::BLUE_TO_RED) OK DO GRAPHICS_NONE Loading Loading @@ -704,7 +710,7 @@ DIRECT (NEW_ERPTier_to_ERP_mean) { FORM (NEW1_ERPTier_Table_extractEventsWhereColumn_number, U"Extract events where column (number)", nullptr) { WORD (extractAllEventsWhereColumn___, U"Extract all events where column...", U"") RADIO_ENUM (___is___, U"...is...", kMelder_number, DEFAULT) RADIO_ENUM (kMelder_number, ___is___, U"...is...", kMelder_number::DEFAULT) REAL (___theNumber, U"...the number", U"0.0") OK DO Loading @@ -716,13 +722,13 @@ DO FORM (NEW1_ERPTier_Table_extractEventsWhereColumn_text, U"Extract events where column (text)", nullptr) { WORD (extractAllEventsWhereColumn___, U"Extract all events where column...", U"") OPTIONMENU_ENUM (___, U"...", kMelder_string, DEFAULT) OPTIONMENU_ENUM (kMelder_string, ___, U"...", kMelder_string::DEFAULT) SENTENCE (___theText, U"...the text", U"hi") OK DO CONVERT_TWO (ERPTier, Table) integer columnNumber = Table_getColumnIndexFromColumnLabel (you, extractAllEventsWhereColumn___); autoERPTier result = ERPTier_extractEventsWhereColumn_string (me, you, columnNumber, (kMelder_string) ___, ___theText); autoERPTier result = ERPTier_extractEventsWhereColumn_string (me, you, columnNumber, ___, ___theText); CONVERT_TWO_END (my name.get()) } Loading