Hi @ChrisLooi ,

Along with what @jthi was thinking, I wanted to add some more JSL that could help to automate it for the hundreds (thousands?) of cycles that you might be dealing with. Below is some code that should work for the entire data set, although it was tested for just the one you provided (thank you, doing that really helps a lot!). I didn't comment the code, but if there's any part that doesn't make sense, let me know and I'll explain what it does.

```
Names Default To Here( 1 );
dt = Current Data Table();
dt << New Column( "State",
"Character",
"Nominal",
Formula(
If(
0 <= :Temp Profile < 130 & Dif( :Temp Profile ) < 0, "Ramp down",
0 <= :Temp Profile < 130 & Dif( :Temp Profile ) > 0, "Ramp up",
"No Ramp"
)
)
);
dt << New Column( "Cycle No", "Numeric", "Ordinal" );
dt << New Column( "Phase", "Character", "Nominal" );
l = 1;
:"Cycle No"n[1] = 1;
For( i = 2, i <= N Rows( dt ) - 1, i++,
If(
(:State[i] == :State[i - 1]), :"Cycle No"n[i] = l,
((:State[i] != :State[i - 1]) & (:State[i] == "Ramp down" & :State[i - 1] == "No Ramp")),
:"Cycle No"n[i] = l;
:Phase[i] = "Start";,
((:State[i] != :State[i - 1]) & (:State[i] == "No Ramp" & :State[i - 1] == "Ramp down")),
:"Cycle No"n[i] = l;
:Phase[i - 1] = "End";,
((:State[i] != :State[i - 1]) & (:State[i] == "Ramp up" & :State[i - 1] == "No Ramp")),
:"Cycle No"n[i] = l;
:Phase[i] = "Start";,
((:State[i] != :State[i - 1]) & (:State[i] == "No Ramp" & :State[i - 1] == "Ramp up")),
:Phase[i - 1] = "End";
l++;
:"Cycle No"n[i] = l;
)
);
:"Cycle No"n[N Row( dt )] = l;
dt << Row Selection( Select Where( :Phase == "Start" ) );
dt << Row Selection( Select Where( :Phase == "End" ), Current Selection( "Extend" ) );
dtsubset = dt << Subset( Selected Rows( 1 ), Selected columns only( 0 ), Suppress Formula Eval( 1 ) );
dt << Clear Select;
dt_results = dtsubset << Summary(
Group( :State, :Cycle No ),
Mean( :Time ),
Mean( :Temp Profile ),
Subgroup( :Phase ),
Freq( "None" ),
Weight( "None" ),
statistics column name format( "column" ),
Link to original data table( 0 )
);
Close( dtsubset, no save );
dt_results << New Column( "Temp Rate Change (°C/sec)",
"Numeric",
"Continuous",
Formula( (:"Temp Profile, End"n - :"Temp Profile, Start"n) / (:"Time, End"n - :"Time, Start"n) )
);
dt_results << Sort( By( :Cycle No, :"Time, End"n, :State ), Order( Ascending, Ascending, Ascending ), Replace Table, Suppress Formula Eval( 0 ) );
dt_results << Delete Columns( :"N Rows"n );
```

You can of course make it more flexible by adding in the ability to change the temp range of interest (here, it's hard-coded as 0 and 130), but that also ads some more complexity.

Anyway, hope this helps!

DS