cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Register for our Discovery Summit 2024 conference, Oct. 21-24, where you’ll learn, connect, and be inspired.
Choose Language Hide Translation Bar
ChrisLooi
Level III

How to Automate Analysis for Cyclic Data

Dear JMP Community,

 

I have an oven that cycle the temperature continuously (from Hot to Cold, then from Cold to Hot and repeat.....).

The oven provide recording of the temperature vs time.

 

If we plot Temperature @ Yaxis , Time @Xaxis, we get the attached graph.

 

We need compute what is the rate of temperature change within specific range of temperature (in this case between 0dgC and 130dgC).

 

For example:

The Green Pinned Information is referring to a Ramp Down (from 130dgc to 0dgc).

With the respective time then we can calculate the rate temp change (130 divided by the time difference).

 

The Purple Pinned Information is referring to the Ramp Up (from 0dgC to 130dgc).

Then we do the same to compute the rate of temp change.

 

The Green (Ramp Down) and Purple (Ramp Up) = 1 cycle

 

In this case, we need to compute for all the ramp up and down for the whole several cycles here.

Actually, for example purposes we only show several cycles, but in actual there are hundreds of cycle.

 

My question is how do we compute the ramp up and ramp down for each cycle and store it in another data table?

Of course, one can do manually but this is too tedious.

Any automated way or "more simplified" way we can do this?

 

I attach the data.

The Oven only record 2 columns of data (Time and Temp). There is no data for Cycle (1st Cycle, 2nd Cycle...etc).

 

Sorry for the long mail & thanks for any advise.

 

B.r,

Chris

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
SDF1
Super User

Re: How to Automate Analysis for Cyclic Data

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

View solution in original post

3 REPLIES 3
jthi
Super User

Re: How to Automate Analysis for Cyclic Data

You can do this for example by utilizing formulas. You could start by adding state column

jthi_0-1727801182462.png

If(
	0 < :Temp Profile < 130 & Dif(:Temp Profile) < 0, curstate = "Down Ramp",
	0 < :Temp Profile < 130 & Dif(:Temp Profile) > 0, curstate = "Ramp Up",
	curstate = "No Ramp"
)

From there you can then add more calculations.

-Jarmo
SDF1
Super User

Re: How to Automate Analysis for Cyclic Data

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

ChrisLooi
Level III

Re: How to Automate Analysis for Cyclic Data

Thanks to jthi and SDF1 for the help. Appreciate it.