cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Browse apps to extend the software in the new JMP Marketplace
Choose Language Hide Translation Bar
Yngeinstn
Level IV

One-Dimensional Phase Unwrapping Problem

Where to begin? I originally asked for help (see link below) on how to make a blanket 360 degree flip based on a spec value however looking into a bit more thoroughly that won't work because the phase is wrapped. There is a process to unwrap the phase to a continuous form.

 

The process is as follows: (using Radian Values)

1) Start with the second sample from the left in the wrapped phase signal.

2) Calculate the difference between the current sample and its directly adjacent left-hand neighbour.

3) If the difference between the two is larger than +π, then subtract 2π from this sample and also from all the samples to the right of it.

4) If the difference between the two is smaller than -π, then add 2π to this sample and also to all the samples to the right of it.

5) Have all the samples been processed? If No then go back to step 2. If Yes then stop

 

I am looking for some assistance in performing this operation and have attached a sample data table for reference.

In this data table I need to unwrap by :RowCol, :channel, :teststate and refstate.

 

Thanks in advance

// You can plot the data according to the scripts below
// This is what i think is a wrapped phase

_dt = Current Data Table();

gb = _dt << Graph Builder(
	Size( 1326, 1002 ),
	Show Control Panel( 0 ),
	Show Legend( 0 ),
	Variables( X( :index ), Y( :radians ), Overlay( :RowCol_PartNo_Ch ) ),
	Elements( Line( X, Y, Legend( 8 ) ) ),
	Local Data Filter(
		Add Filter(
			columns( :teststate, :refstate, :channel, :RowCol ),
			Where( :teststate == 11 ),
			Where( :refstate == 1 ),
			Where( :channel == {"0", "1", "2", "3"} ),
			Where( :RowCol == "r3c1sr3sc1" ),
			Display( :channel, N Items( 4 ) ),
			Display( :RowCol, N Items( 15 ), Find( Set Text( "" ) ) )
		)
	),
	SendToReport(
		Dispatch(
			{},
			"index",
			ScaleBox,
			{Min( 4.3125 ), Max( 22.6875 ), Inc( 1 ), Minor Ticks( 4 )}
		)
	)
);

// This is what i think is a normal (continuous form)
_dt = Current Data Table();

gb = _dt << Graph Builder(
	Size( 1326, 1002 ),
	Show Control Panel( 0 ),
	Show Legend( 0 ),
	Variables( X( :index ), Y( :radians ), Overlay( :RowCol_PartNo_Ch ) ),
	Elements( Line( X, Y, Legend( 8 ) ) ),
	Local Data Filter(
		Add Filter(
			columns( :teststate, :refstate, :channel, :RowCol ),
			Where( :teststate == 11 ),
			Where( :refstate == 1 ),
			Where( :channel == {"0", "1", "2", "3"} ),
			Where( :RowCol == "r3c1sr3sc0" ),
			Display( :channel, N Items( 4 ) ),
			Display( :RowCol, N Items( 15 ), Find( Set Text( "" ) ) )
		)
	),
	SendToReport(
		Dispatch(
			{},
			"index",
			ScaleBox,
			{Min( 4.3125 ), Max( 22.6875 ), Inc( 1 ), Minor Ticks( 4 )}
		)
	)
);


 

Changing column values based on the column spec limit 

1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

Re: One-Dimensional Phase Unwrapping Problem

Any idea what the correct result would look like? Something similar to this:

Wrapped phase:

jthi_0-1620586157168.png

 

Should this be changed?

jthi_2-1620586399504.png

 

Running this script will be fairly slow, but most likely it can be optimized to be faster (it also has an problem if last value is in wrong phase):

 

Names Default To Here(1);
dt = Current Data Table();

dt << New Column("supportindex", Character, "Nominal",
	<< Set Each Value(:rowcol || char(:channel)||char(:teststate)||char(:refstate))
);
dt << New Column("radians_cont", Numeric, "Continuous");

Summarize(dt, uniqValues = by(:supportIndex));

For(i = 1, i <= N Items(uniqValues), i++,
	valIndex = Loc(Column(dt, "supportIndex") << get as matrix, uniqValues[i]);
	m = Column(dt, "radians")[valIndex];
	deduction = 0;
	nr = N Items(m);
	For(k = 2, k <= nr - 1, k++,
		rad_dif = m[k - 1] - m[k];
		If(rad_dif  > pi(), deduction = 2*pi(),
		   rad_dif < -1*pi(), deduction = -2*pi(),
		   deduction = 0;
		);
		m[k::nr] = m[k::nr] + deduction;
	);
	dt[valIndex, "radians_cont"] = m;
);

dt << Delete Columns("supportindex");

gb = dt << Graph Builder(
	Size(1326, 1002),
	Show Control Panel(0),
	Show Legend(0),
	Variables(X(:index), Y(:radians), Y(:radians_cont), Overlay(:RowCol_PartNo_Ch)),
	Elements(Position(1, 1), Line(X, Y, Legend(11))),
	Elements(Position(1, 2), Line(X, Y, Legend(12))),
	Local Data Filter(
		Add Filter(
			columns(:teststate, :refstate, :channel, :RowCol),
			Where(:teststate == 11),
			Where(:refstate == 1),
			Where(:channel == {"0", "1", "2", "3"}),
			Where(:RowCol == "r3c1sr3sc1"),
			Display(:channel, N Items(4), Size(178, 68)),
			Display(:RowCol, N Items(15), Size(161, 255), Find(Set Text("")))
		)
	),
	SendToReport(
		Dispatch(
			{},
			"index",
			ScaleBox,
			{Min(4.3125), Max(22.6875), Inc(1), Minor Ticks(4)}
		)
	)
);

Issue with last sample:

jthi_1-1620586324314.png

 

-Jarmo

View solution in original post

3 REPLIES 3
jthi
Super User

Re: One-Dimensional Phase Unwrapping Problem

Any idea what the correct result would look like? Something similar to this:

Wrapped phase:

jthi_0-1620586157168.png

 

Should this be changed?

jthi_2-1620586399504.png

 

Running this script will be fairly slow, but most likely it can be optimized to be faster (it also has an problem if last value is in wrong phase):

 

Names Default To Here(1);
dt = Current Data Table();

dt << New Column("supportindex", Character, "Nominal",
	<< Set Each Value(:rowcol || char(:channel)||char(:teststate)||char(:refstate))
);
dt << New Column("radians_cont", Numeric, "Continuous");

Summarize(dt, uniqValues = by(:supportIndex));

For(i = 1, i <= N Items(uniqValues), i++,
	valIndex = Loc(Column(dt, "supportIndex") << get as matrix, uniqValues[i]);
	m = Column(dt, "radians")[valIndex];
	deduction = 0;
	nr = N Items(m);
	For(k = 2, k <= nr - 1, k++,
		rad_dif = m[k - 1] - m[k];
		If(rad_dif  > pi(), deduction = 2*pi(),
		   rad_dif < -1*pi(), deduction = -2*pi(),
		   deduction = 0;
		);
		m[k::nr] = m[k::nr] + deduction;
	);
	dt[valIndex, "radians_cont"] = m;
);

dt << Delete Columns("supportindex");

gb = dt << Graph Builder(
	Size(1326, 1002),
	Show Control Panel(0),
	Show Legend(0),
	Variables(X(:index), Y(:radians), Y(:radians_cont), Overlay(:RowCol_PartNo_Ch)),
	Elements(Position(1, 1), Line(X, Y, Legend(11))),
	Elements(Position(1, 2), Line(X, Y, Legend(12))),
	Local Data Filter(
		Add Filter(
			columns(:teststate, :refstate, :channel, :RowCol),
			Where(:teststate == 11),
			Where(:refstate == 1),
			Where(:channel == {"0", "1", "2", "3"}),
			Where(:RowCol == "r3c1sr3sc1"),
			Display(:channel, N Items(4), Size(178, 68)),
			Display(:RowCol, N Items(15), Size(161, 255), Find(Set Text("")))
		)
	),
	SendToReport(
		Dispatch(
			{},
			"index",
			ScaleBox,
			{Min(4.3125), Max(22.6875), Inc(1), Minor Ticks(4)}
		)
	)
);

Issue with last sample:

jthi_1-1620586324314.png

 

-Jarmo
Yngeinstn
Level IV

Re: One-Dimensional Phase Unwrapping Problem

This is great work @jthi.

 

(picture 1): I would think that as long as the curve holds the same shape of the parts / channel that didn't have the wrapped phase, it is correct. I will verify with the test folks.

(picture 2): I think that blue line (channel 0) is dead but the other 3 channels had a tremendous number of wrapped phases and your script worked it out.

(picture 3): I can live with that for now as we are screening at two (2) middle indices and not the last.

 

As for optimization of the script, I wouldn't even know where to begin. Maybe someone could chime in on this thread with suggestions.

 

Again, this is great and can't thank you enough for the help. Because we were arbitrarily unwrapping the phase there is potential of screening out good parts. Not sure if we were sending bad parts until i can dig into it some more.

Yngeinstn
Level IV

Re: One-Dimensional Phase Unwrapping Problem

I am looking back at the script and applying it to another set of data and I don't think we are quite there yet. i am going to have to think a bit on this one. It's close...