The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum for Programming
 Forum for Origin C
 Storing cursor positions
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

hendrikdecooman

Albania
Posts

Posted - 02/03/2006 :  10:17:19 AM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Origin Version (Select Help-->About Origin): v7.O552
Operating System: Windows

Hi anyone out there,

in the research I'm doing it' s sometimes necessary to process a lot of spectra. Processing involves amongst others something like finding the peak positions. Although it is not always possible to automize these procedure without losing data, I would like to have some form of automatisation: what I want to be able to do is storing the coordinates of the cursor position at a certain key navigation, so that I can take a quick scan and select visually. People before me just typed over the coordinates in excell, which is nerveracking.
It would be even better if I could place and remove markers and then store al the marker's positions in a spreadsheetfile.

Now, I already succeeded in implementing a code that stores cursorpositions in Labview but I find it to be not that userfriendly. Today was the first time I realised that origin allows programming too. And I find origin to be quite userfriendly (for my purposes anyway).
Labview also has the disadvantage that because of the visual programming concept some very elementary things can get quite complicated.
So before I start I would like to know:
Is Origin fit for the things I want to do?
And if so, I can imagine someone somewhere must have made a program that does exactly this. In that case, please let me know!

Thanks in advance,

Hendrik

Mike Buess

USA
3037 Posts

Posted - 02/03/2006 :  11:10:39 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Hendrik,

It's easy to obtain cursor positions and store them in a worksheet, text label, Results log or file (among other places). It's also easy to create vertical, horizontal or oblique markers for visual reference. In fact, you could probably automate the entire peak picking process with a little effort. If you click the Search button at the top of this page and enter "peaks" you'll find many examples.

Marking and labelling tools are available in OriginLab's File Exchange...
http://www.originlab.com/FileExchange/details.aspx?fid=53
http://www.originlab.com/FileExchange/details.aspx?fid=47

More examples are available here...
http://www.originlab.com/index.aspx?s=8&lm=243

Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/03/2006 11:12:11 AM
Go to Top of Page

hendrikdecooman

Albania
Posts

Posted - 02/10/2006 :  09:26:08 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Mike,

really really thank you for the answer. I found a programme that stores cursorpositions. The code is listed below.
It works BUT:
1/ I have to give in advance the numbe of dat points I will select and this is very unpractical because this is not known in advance
2/ I don't know how I can make the program store these datapoints in an ASCII file, instead of displaying them in the script window.

The last part I should be able to solve if I just spend some time learnig the syntax of Origin C, I guess.
As to the first part, I don't know how to do this. I don't get what LabTalk does etcetera. I thought Origin C is like C with 'special features for Origin applications' but this code seems strange to me.
Is there some kind of tutorial for Origin C?

As to your remark that it's probably possible to automize a great deal of the processing: I tend to disagree. It's inherent to my kind of spectra that using FFT filters, smooting etcetera, gets rid of some weak signals as well - often you need a trained eye and a lot of background knowledge to determine whether a certain very small bump is in fact a signal or just some noise. Admitted, for the stronger signals a peak picker is just as well (better) as (than) my mind and eyes, but for the study I'm doing for the moment I fear I am cursed to keep on inspecting visually... Believe me, I've spent quite some time trying to find a suited filter...

Anyway, I hope you can get my on the right track with Origin C - I think this is really the solution I was looking for...

Thanks in advance,

Hendrik




/*------------------------------------------------------------------------------*
* File Name: *
* Creation: *
* Purpose: OriginC Source C file *
* Copyright (c) ABCD Corp. 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 *
* All Rights Reserved *
* *
* Modification Log: *
*------------------------------------------------------------------------------*/


#include <origin.h>

// This example shows how to get x, y coordinates of points clicked by user
// on a graph layer.
// Number of points to be fetched is pased as parameter. Default is 2.
// So for 5 points, type this command in the script window:
// read_screen_points 5
//

void read_screen_points(int nPts = 2)
{
// Declare vectors to hold coordinates
vector vecX, vecY;
// Call function to get points
int iRet = get_screen_reader_points(nPts, vecX, vecY);
if( iRet < 0 )
printf("Function call to get screen points returned error: %d\n", iRet);

printf("User clicked on %d points\n", iRet);
if( 0 != iRet )
{
printf("X, Y coordinates of points are:\n");
for(int ii = 0; ii < iRet; ii++)
printf(" %d: X = %f, Y = %f\n", ii, vecX[ii], vecY[ii]);
}
}

// This static function handles calling LabTalk to get user to click on the screen.
// Parameters:
// nPts: no. of points that user should click
// vecX: vector to hold x coordinates of points, passed by reference
// vecX: vector to hold y coordinates of points, passed by reference
// Return:
// -1: no. of points inappropriate
// >=0: no. of points user actually clicked
static int get_screen_reader_points(int nPts, vector& vecX, vector& vecY)
{
// Return error if number of points not appropriate
// Arbitrary upper limit of 99 - change as desired
if( nPts < 1 || nPts > 99) return -1;

// Run the LabTalk section in this file to give user control to click points
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenPts,%d)", strThisFile, nPts);
LT_execute(strCMD);

// On return, the LabTalk variable tmp_scr_count has number of points user clicked + 1
double dCount;
LT_get_var("tmp_scr_count", &dCount);
int nCount = (int) (dCount - 1);
if( 0 == nCount ) return 0;

// Get values of x, y coordinates from LabTalk variables and delete the vars
vecX.SetSize(nCount);
vecY.SetSize(nCount);
string strX, strY;
double dX, dY;
for(int ii = 1; ii <= nCount; ii++)
{
strX.Format("tmp_scr_pos_x%d", ii);
strY.Format("tmp_scr_pos_y%d", ii);
LT_get_var(strX, &vecX[ii - 1]);
LT_get_var(strY, &vecY[ii - 1]);
strCMD.Format("del -v %s", strX);
LT_execute(strCMD);
strCMD.Format("del -v %s", strY);
LT_execute(strCMD);
}

// Delete the count LabTalk variable
LT_execute("del -v tmp_scr_count;");

// Return the number of points clicked by user
return nCount;
}

// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenPts]
// Number of points to get is passed as 1st parameter
// Select screen reader tool
dotool 2;

// Main loop to accept points
tmp_scr_count = 1;
def quittoolbox
{
// Check if user has clicked required number of points
if( 1 == tmp_scr_count )
done = 1;
if( %1 != tmp_scr_count )
return;
}

// Get points and store in temp string variables
def pointproc
{
tmp_scr_pos_x$(tmp_scr_count)=x;
tmp_scr_pos_y$(tmp_scr_count)=y;
if( tmp_scr_count >= %1 )
{
dotool 0;
// Set the variable to break the infinite loop
done = 1;
}
tmp_scr_count += 1;
}
// Set up an "infinite loop" so code waits for user to click points
for( done = 0; done == 0; )
{
// wait a while
sec -p 0.1;
}
#endif
////////////////////////////////////////////////////////////////////////////////////

Go to Top of Page

easwar

USA
1965 Posts

Posted - 02/10/2006 :  10:30:50 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:

The last part I should be able to solve if I just spend some time learnig the syntax of Origin C, I guess.
As to the first part, I don't know how to do this. I don't get what LabTalk does etcetera. I thought Origin C is like C with 'special features for Origin applications' but this code seems strange to me.
Is there some kind of tutorial for Origin C?



Hi Hendrik,

Origin C is ANSI C compatible for all the "usual" C things. In addition Origin C also has C++/C# features for accessing various Origin objects such as worksheet, graph etc using methods and properties. Take a look at the Programming Help file and the "Programming Guide" section in there for intro to these features.

Certain operations such as picking points off a screen are not currently available in Origin C. This is where the LabTalk scripting part comes in, because such things are possible from LabTalk. So basically in the code example you posted, a LabTalk script section is being called to deal with the screen clicking part.

The LabTalk script can be in a separate disk file (.OGS file) and sections from the script could be then called in Origin C. However, if convenient, the script can also be simply placed at the end of the OC file with an ifdef which then the OC compiler ignores, but the LabTalk interpreter can understand and run.

Here is a modified OC code, with embedded LabTalk, that gets arbitrary number of screen clicks from user. The X, Y values for the clicked points get put into a worksheet. This worksheet is hidden by default and you can change in the code. The wks can be seen in Project Explorer and you can double-click to open.

You could then look up wks and ascii export etc in help files and add code to export the contents of the worksheet to an ascii file as desired.

Easwar
OriginLab



void get_screen_clicks()
{
// Create a new worksheet to hold the x, y values
Worksheet wks;
wks.Create("Origin", CREATE_HIDDEN);
// Delete all cols - template may have different setup than needed
while( wks.DeleteCol(0) );
// Add two cols to hold x,y values of clicked points
wks.AddCol("PointX");
wks.AddCol("PointY");
wks.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
string strWksName = wks.GetPage().GetName();

// Now call LabTalk code to accept points till user clicks Esc key
SetDataDisplayText("Double-click for Points, Esc to quit");
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenClicks, %s)", strThisFile, strWksName);
LT_execute(strCMD);

// Back from LabTalk call - report to user
printf("X, Y of clicked points saved in worksheet: %s\n", strWksName);
}

// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenClicks]
%a=%1_PointX;
%b=%1_PointY;
//create picked_b -c 10;
for(done=0,waiting=0,idx=1;done==0; ) {
sec -p .1;
if(waiting==0)
{
dotool 2;
def pointproc
{
%a[idx]=x;
%b[idx]=y;
idx++;
}
def quittoolbox
{
done=1;
dotool 0;
}
waiting=1;
}
}
#endif







Edited by - easwar on 02/10/2006 10:35:19 AM
Go to Top of Page

hendrikdecooman

Albania
Posts

Posted - 02/10/2006 :  7:39:20 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Thanks very much!!
Now to get full functionality it's necessary for me to be able to zoom in and out etcetera without having to stop the program.
And it would be very (very) handy to get a marker at each point I've clicked, just to make it easier to keep track of what I'm doing.
I hope I'll get round to learning how to do it myself in the near future but considering the time pressure for the moment, all help is more than welcome!

Thanks in advance

A very happy Hendrik
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/11/2006 :  09:32:33 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
The code below is a variation of Easwar's code that saves the name of the output worksheet between program sessions. If the wks exists the next time you run it you are asked if you want to start a new wks or append to existing. That way you can stop, zoom and continue. The LabTalk script draws a vertical red line at X of selected point.
static string strWksName; // save worksheet name between sessions

void get_screen_clicks()
{
Worksheet wks;
wks.Attach(strWksName);
if( wks )
{
if( MessageBox( GetWindow(), "Start a new output worksheet?", "Attention!" ,
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 ) == IDYES )
wks.Detach();
}
if( !wks )
{
wks.Create("Origin", CREATE_HIDDEN);
// Delete all cols - template may have different setup than needed
while( wks.DeleteCol(0) );
// Add two cols to hold x,y values of clicked points
wks.AddCol("PointX");
wks.AddCol("PointY");
wks.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
strWksName = wks.GetPage().GetName();
}

// Now call LabTalk code to accept points till user clicks Esc key
SetDataDisplayText("Double-click for Points, Esc to quit");
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenClicks, %s)", strThisFile, strWksName);
LT_execute(strCMD);
// Back from LabTalk call - report to user
Dataset dd(wks,0);
printf("X, Y of %d points saved in worksheet: %s\n", dd.GetSize(), strWksName);
}

// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenClicks]
//%a=%1_PointX;
//%b=%1_PointY;
for(done=0,waiting=0,idx=%1!wks.maxrows+1;done==0; ) {
sec -p .1;
if(waiting==0)
{
dotool 2;
def pointproc
{
// draw vertical line at x value
draw -l -v x;
// find its name
doc -e G {break};
// color it red
%B.color=color(red);
%1_PointX[idx]=x;
%1_PointY[idx]=y;
idx++;
}
def quittoolbox
{
done=1;
dotool 0;
}
waiting=1;
}
}


Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/11/2006 10:47:56 AM
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/12/2006 :  12:11:38 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Unfortunately, the vertical lines created by the last script do not rescale when you change the display range. The following version merely plots the selected points with red X's whose positions will be preserved when rescaling the graph. The markers are shown only while the function is running. If you prefer permanent markers just delete or comment out gl.RemovePlot(dp);. The sort command at the end of the LabTalk section sorts the output worksheet in ascending order of its X values which might be useful if you want to export the results to file.
static string strWksName; // save worksheet name between sessions

void get_screen_clicks()
{
Worksheet wks(strWksName);
if( wks )
{
if( MessageBox( GetWindow(), "Start a new output worksheet?", "Attention!" ,
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 ) == IDYES )
wks.Detach();
}
if( !wks )
{
wks.Create("Origin", CREATE_HIDDEN);
// Delete all cols - template may have different setup than needed
while( wks.DeleteCol(0) );
// Add two cols to hold x,y values of clicked points
wks.AddCol("PointX");
wks.AddCol("PointY");
wks.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
strWksName = wks.GetPage().GetName();
}

// Plot selected points as markers
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(strWksName + "_PointY");
if( !dp )
{
Curve cv(wks,1);
gl.AddPlot(cv, IDM_PLOT_SCATTER);
dp = gl.DataPlots(strWksName + "_PointY");
dp.Curve.Symbol.Shape.nVal = 13; // symbol = X
dp.Curve.Symbol.Size.nVal = 9; // symbol size = 9
dp.Curve.Symbol.EdgeColor.nVal = 1; // symbol color = red
}

// Now call LabTalk code to accept points till user clicks Esc key
SetDataDisplayText("Double-click for Points, Esc to quit");
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenClicks, %s)", strThisFile, strWksName);
LT_execute(strCMD);

gl.RemovePlot(dp); // Remove markers

// Back from LabTalk call - report to user
Dataset dd(wks,0);
printf("X, Y of %d points saved in worksheet: %s\n", dd.GetSize(), strWksName);
}

// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenClicks]
for(done=0,waiting=0,idx=%1!wks.maxrows+1;done==0; ) {
sec -p .1;
if(waiting==0)
{
dotool 2;
def pointproc
{
%1_PointX[idx]=x;
%1_PointY[idx]=y;
idx++;
}
def quittoolbox
{
done=1;
dotool 0;
}
waiting=1;
}
}
sort -w %1 %1_PointX;
#endif


Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/12/2006 12:19:30 PM
Go to Top of Page

hendrikdecooman

Albania
Posts

Posted - 02/12/2006 :  12:35:58 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
With the risk of sounding repetitive: THANKS!
However, I've got some remarks again (of course :-) )

1/ When the program is running, Origin is using all of my laptop's CPU (which is not desirable).
This was not the case in the previous version (of Easwar). I thought that the cause should lie in the

sec -p .1;

part, but this hasn't changed since the last version. How can I fix this problem?

2/ It's already a big help that I can zoom in and out without having to open a new dataworksheet, so the following question is of less importance (more out of curiosity): isn't is possible to 'tell' origin that he shouldn't stop running the program, unless when then user presses 'escape'?

3/ This is more important. Most of the time I have a lot of spectra in one single graph, so that vertical markes lines can get quite confusing. Because I almost always normalize the spectra, a smaller marker (of, for instance, 0.25 height) at the peak positions, would be much better.

I cannot express enough how much I appreciate your and Eiswar's help, really. It's a world of difference for me!

A very grateful Hendrik
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/12/2006 :  1:15:02 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
1/ When the program is running, Origin is using all of my laptop's CPU (which is not desirable).
This was not the case in the previous version (of Easwar).
I get 50% CPU usage with both mine and Easwar's version. No reason for them to be different that I can see.
quote:
isn't is possible to 'tell' origin that he shouldn't stop running the program, unless when then user presses 'escape'?
Afraid not. (At least that I know of.)
quote:
Most of the time I have a lot of spectra in one single graph, so that vertical markes lines can get quite confusing. Because I almost always normalize the spectra, a smaller marker (of, for instance, 0.25 height) at the peak positions, would be much better.
You might try the code I posted earlier this morning. (BTW, that was the code I tested against Easwar's under your first point.) If you prefer a vertical bar symbol to X change dp.Curve.Symbol.Shape.nVal to 16. You can adjust its height by changing dp.Curve.Symbol.Size.nVal.

Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/12/2006 1:34:37 PM
Go to Top of Page

hendrikdecooman

Albania
Posts

Posted - 02/13/2006 :  05:50:34 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Mike,

thanks once more. However, when compiling, following error messages (amongst others, but I think these are the real problem) appear:

C:\Program Files\OriginLab\OriginPro7\OriginC\evenbetterer.c(5) :Error, data member not found:Curve
C:\Program Files\OriginLab\OriginPro7\OriginC\evenbetterer.c(34) :Error, Variable "dp.Curve.Symbol.Shape.nVal" not declared

Do I need to import a special package or something?

Hendrik
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/13/2006 :  08:09:32 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Sorry, that code requires 7.5. This works in 7.0 SR4...
static string strWksName; // save worksheet name between sessions
void get_screen_clicks()
{
Worksheet wks(strWksName);
if( wks )
{
if( MessageBox( GetWindow(), "Start a new output worksheet?", "Attention!" ,
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 ) == IDYES )
wks.Detach();
}
if( !wks )
{
wks.Create("Origin", CREATE_HIDDEN);
// Delete all cols - template may have different setup than needed
while( wks.DeleteCol(0) );
// Add two cols to hold x,y values of clicked points
wks.AddCol("PointX");
wks.AddCol("PointY");
wks.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
strWksName = wks.GetPage().GetName();
}

// Plot selected points as markers
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(strWksName + "_PointY");
if( !dp )
{
Curve cv(wks,1);
gl.AddPlot(cv, IDM_PLOT_SCATTER);
gl.LT_execute("set " + strWksName + "_PointY" + " -k 7"); // symbol = X, (10 for |)
gl.LT_execute("set " + strWksName + "_PointY" + " -c color(red)"); // color = red
gl.LT_execute("set " + strWksName + "_PointY" + " -z 12"); // size = 12
}

// Now call LabTalk code to accept points till user clicks Esc key
SetDataDisplayText("Double-click for Points, Esc to quit");
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenClicks, %s)", strThisFile, strWksName);
LT_execute(strCMD);

gl.LT_execute("lay -e " + strWksName + "_PointY"); // remove markers

// Back from LabTalk call - report to user
Dataset dd(wks,0);
printf("X, Y of %d points saved in worksheet: %s\n", dd.GetSize(), strWksName);
}
// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenClicks]
for(done=0,waiting=0,idx=%1!wks.maxrows+1;done==0; ) {
sec -p .1;
if(waiting==0)
{
dotool 2;
def pointproc
{
%1_PointX[idx]=x;
%1_PointY[idx]=y;
idx++;
}
def quittoolbox
{
done=1;
dotool 0;
}
waiting=1;
}
}
sort -w %1 %1_PointX;
#endif


Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/13/2006 08:18:22 AM
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/13/2006 :  11:23:35 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Something else that may or may not be useful... You can restrict peak selections to actual data point positions by using the Data Reader tool rather than Screen Reader tool. Replace dotool 2 with dotool 3 near top of the LabTalk section.

...You might also find the Scroll and Zoom Toolbar useful for navigating your data.
http://www.originlab.com/fileexchange/details.aspx?fid=89

Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/13/2006 12:48:16 PM
Go to Top of Page

hendrikdecooman

Albania
Posts

Posted - 02/22/2006 :  11:43:49 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Mike (and everyone else),

I must thank you once again for the program. It works like a charm.
However, I've still got problems/questions:

1/ First of all, I reversed the X and Y positions (for our purposes it's better), but he aplies this to the markers as well. I thought this should be easy to solve, but I'm having troubles with the help functions (I posted a question about this on the Origin Forum) and thus...

2/ Then, I would like to have the data sorted, in first instance according to X (this is the Y-coordinate on the graph) and then accoring to the Y-values (X on the graph). Now the Y values are rounded to the nearest integer (this is easier for my purposes). In other words: things like

26 43.76
42 22.21
26 16.43
42 25.34

should become

26 16.43
26 43.76
42 22.21
42 25.34

It seemed logical that, at the end of the code

sort -w %1 %1_PointY;
sort -w %1 %1_PointX;


would do exactly this, but it seems to have the same effect as

sort -w %1 %1_PointX;

and thus returns

26 16.43
26 43.76
42 25.34
42 22.21

How should I go about it then?

Thanks in advance,

Hendrik


Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 02/22/2006 :  1:06:34 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Hendrik,

1/ So you want two plots: PointY versus PointX (markers) and PointX versus PointY (separate graph). In Origin 7.0 a column cannot be used as both X and Y so you must duplicate the columns for the second plot.

2/ The sort object allows for primary and secondary sort orders.

Both points are addressed below. Columns Height(X2) and Position(Y2) are created and sorted but not plotted.
static string strWksName; // save worksheet name between sessions
void get_screen_clicks()
{
Worksheet wks(strWksName);
if( wks )
{
if( MessageBox( GetWindow(), "Start a new output worksheet?", "Attention!" ,
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 ) == IDYES )
wks.Detach();
}
if( !wks )
{
wks.Create("Origin", CREATE_HIDDEN);
// Delete all cols - template may have different setup than needed
while( wks.DeleteCol(0) );
// Add two cols to hold x,y values of clicked points
wks.AddCol("PointX");
wks.AddCol("PointY");
wks.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
wks.AddCol("Height");
wks.AddCol("Position");
wks.Columns(2).SetType(OKDATAOBJ_DESIGNATION_X);
strWksName = wks.GetPage().GetName();
}

// Plot selected points as markers
GraphLayer gl = Project.ActiveLayer();
DataPlot dp = gl.DataPlots(strWksName + "_PointY");
if( !dp )
{
Curve cv(wks,1);
gl.AddPlot(cv, IDM_PLOT_SCATTER);
gl.LT_execute("set " + strWksName + "_PointY" + " -k 7"); // symbol = X, (10 for |)
gl.LT_execute("set " + strWksName + "_PointY" + " -c color(red)"); // color = red
gl.LT_execute("set " + strWksName + "_PointY" + " -z 12"); // size = 12
}

// Now call LabTalk code to accept points till user clicks Esc key
SetDataDisplayText("Double-click for Points, Esc to quit");
string strThisFile = __FILE__;
string strCMD;
strCMD.Format("run.section(%s,GetScreenClicks, %s)", strThisFile, strWksName);
LT_execute(strCMD);

//gl.LT_execute("lay -e " + strWksName + "_PointY");

// Back from LabTalk call - report to user
printf("X, Y of points saved in worksheet: %s\n", strWksName);
}
// This section of LabTalk will be ignored by compiler since it is contained within an ifdef block.
// The section of script within this block can then be successfully called by a run.section LabTalk command.
#ifdef LABTALK
[GetScreenClicks]
for(done=0,waiting=0,idx=%1!wks.maxrows+1;done==0; ) {
sec -p 0.1;
if(waiting==0)
{
dotool 2;
def pointproc
{
%1_PointX[idx]=x;
%1_PointY[idx]=y;
idx++;
};
def quittoolbox
{
done=1;
dotool 0;
};
waiting=1;
};
};
%1_Height = int(%1_PointY);
%1_Position = %1_PointX;
sort.wksname$ = %1;
sort.c1 = 3;
sort.c2 = 4;
sort.r1 = 1;
sort.r2 = %1!wks.maxrows;
sort.cname1$ = A: Height;
sort.cname2$ = A: Position;
sort.wks();
#endif


Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 02/22/2006 2:01:37 PM
Go to Top of Page

hendrikdecooman

Albania
Posts

Posted - 02/23/2006 :  03:49:18 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Once again,
you're the man!

Thanks,

Hendrik
Go to Top of Page

kanderlee

Taiwan
Posts

Posted - 11/01/2007 :  03:54:09 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi, Mike,

I used the lastest code you had post on this topic, but there were some error messages after linking.
D:\Docs\Origin Programing\Get Screen Clicks.c(52) :Origin C Function Runtime Error, unknown error
D:\Docs\Origin Programing\Get Screen Clicks.c(52) :Origin C Function Runtime Error, unknown error
D:\Docs\Origin Programing\Get Screen Clicks.c(27) :Origin C Function Runtime Error, unknown error

This code worked fine even though there were some error messages appearing.

If I use this code in multilayer graphpage, the cross marks would appear at some strange positions.

Can I use data reader in this code instead of screen reader?

And what code should be added if I want to put the window's name when I click a point? Thank you.
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 11/01/2007 :  08:53:41 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Can I use data reader in this code instead of screen reader?
Replace dotool 2 with dotool 3.

quote:
And what code should be added if I want to put the window's name when I click a point?
Where do you want to put it?

Mike Buess
Origin WebRing Member
Go to Top of Page

kanderlee

Taiwan
Posts

Posted - 11/01/2007 :  9:26:46 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
I want to put the window's (or dataset's) name in the same worksheet (which stores X & Y position, etc.)

I've tried to use %C in pointproc.

def pointproc
{
%1_PointX[idx]=x;
%1_PointY[idx]=y;
%1_DataLabel[idx]=%C;
idx++;
};

But an error message showed in Origin:


Is %C not the dataset's name? Why can't I use it?

And can this code work at multilayer ploting graphpage?

Thank you for your help. ^_^

quote:
quote:
And what code should be added if I want to put the window's name when I click a point?
Where do you want to put it?


Edited by - kanderlee on 11/02/2007 04:49:25 AM
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 11/02/2007 :  04:19:05 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
I want to put the window's (or dataset's) name in the same worksheet (which stores X & Y position, etc.)
Still not clear and it's been a long time since I wrote this script. Graph window name is gl.GetPage().GetName() and dataset name is strWksName + "_PointY". To assign string to the wks window label use wks.GetPage().Label = string.

quote:
Can this code work at multilayer ploting graphpage?
Looks like it works on the active layer of any graph window, single- or multi-layer.

Mike Buess
Origin WebRing Member
Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 11/02/2007 :  04:55:14 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
quote:
Is %C not the dataset's name? Why can't I use it?


To assign a string to a cell you must use $...

%1_DataLabel[idx]$=%C;

Mike Buess
Origin WebRing Member

Edited by - Mike Buess on 11/02/2007 04:58:02 AM
Go to Top of Page

kanderlee

Taiwan
Posts

Posted - 11/05/2007 :  02:20:46 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Wow...

My problem is solved by your rapid indication!

Thank you very^n much....^_^
Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000