It is surprising how far you can get with a single formula column:
dt << new column("Motif ID", nominal, formula(Col Cumulative Sum(
Row() > 6 & Summation( i = 1, 6, Abs( Lag( :power, i ) ) ) == 0 & :power != 0
)));
However, there is still some cleanup to do... this approach creates a "0" group ID, which is the leading data, and does not cut off the last motif where we'd like. The "6" in the summation is because I designate a new group if at least 6 consecutive zeros are encountered prior to a power change.
There are of course many other ways to do this that are more sophisticated, involving comparisons to the background floors, attacks/decays, etc... but if a simple approach like this one works, great.
The script below incorporates this idea, but cleans up the dataset, as well. Ideally the values in the last few lines would be parameterized.
names default to here(1);
dt = current data table();
dtSub = dt << subset(selected rows(0), selected columns(0));
//create ID column
dtSub << new column("Motif ID", nominal, formula(Col Cumulative Sum(
Row() > 6 & Summation( i = 1, 6, Abs( Lag( :power, i ) ) ) == 0 & :power != 0
)));
dtSub:MotifID << delete formula;
//the next 2 loops truncate the dataset, assuming it ends like the sample dataset ended.
for(i = nrow(dtSub), abs(dtSub:power[i] - dtSub:power[i-1]) < 20, i--,
dtSub << Delete Rows(i)
);
for(i = nrow(dtSub), abs(dtSub:power[i] - dtSub:power[i-1]) > 5, i--,
dtSub << Delete Rows(i)
);
//delete ID 0 group
dtSub << select where(:Motif ID == 0) << delete rows;
//delete 0 power rows, but not when they lie within a group
i = nrow(dtSub)-1;
while (i > 1,
if(dtSub:Motif ID[i] < dtSub:MotifID[i+1] & dtSub:power[i] == 0,
while( dtSub:power[i] == 0,
dtSub << delete rows(i--);
)
);
i--
);