Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

psmeca: Make the last few columns of input optional #2018

Merged
merged 14 commits into from
Nov 15, 2019
Merged

Conversation

seisman
Copy link
Member

@seisman seisman commented Nov 9, 2019

Fixes #2016.

Copy link
Member

@PaulWessel PaulWessel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment before the Set_Columns line to remind us:
/* Because psmeca reads optional columns we cannot insist records are all the same, hence VAR below */

@seisman
Copy link
Member Author

seisman commented Nov 9, 2019

I have a few failing tests locally. Need to check them

@PaulWessel
Copy link
Member

OK, let me know.

@seisman
Copy link
Member Author

seisman commented Nov 9, 2019

@PaulWessel This one doesn't work. It seems the last column "10km" is read as a float value "10.0" instead of a string.

gmt psmeca -R239/240/34/35.2 -JX8c -Baf -Sa2c << END > test2.ps
239.384 34.556 12.   180     18   -88  5 0 0 10km
END

@PaulWessel
Copy link
Member

I may be able to fix that since "km" is not a valid unit, but I can imagine some users thinking that any string can be used for that title, and if they give 00101 then we will read that as 101 and not as a string. This is the problem of allowing variable record lengths with or without a string at the end...

@seisman
Copy link
Member Author

seisman commented Nov 9, 2019

I may have a working solution. We can still use GMT_COL_FIX but only read Ctrl->S.n_cols - 2 columns (i.e. the required columns). Then the remaining columns if any are saved in In->text.
Then use sscanf(In->text, "%lf %lf %[^\n]s\n", &xynew[ix], &xynew[iy], event_title); to read the newX, newY and title from In->text. Do you think it's a good way?

@PaulWessel
Copy link
Member

Yes we can do that. In fact, in my longer posting earlier I was about to write that scheme but decided to see if the VAR would be enough. But it cannot tell the trailing text. I am adding a minor improvement to the parsing (it will check if the trailing chars after the last digit or single period in a string is more than one or (if one) does not match a known unit, then it is deemed text. But as mentioned this will not catch strings that look like numbers. So you suggestion is more foolproof. I will still commit my fix since it applies in general and will not parse 10km as a number.

@PaulWessel
Copy link
Member

If you want to try the above, note that you will need to do this:

n_scanned = scanf (In->text, "%s %s %[^\n]s\n", Xstring, Ystring, event_title); 
if (n_scanned >= 2) { /* Got new x,y coordinates */
    if (ix == GMT_X) {
       gmt_scanf_arg (GMT, Xstring, GMT_IS_LON, false, &xynew[GMT_X]);
       gmt_scanf_arg (GMT, Ystring, GMT_IS_LAT,  false, &xynew[GMTY]);
   }
    else {
       gmt_scanf_arg (GMT, Ystring, GMT_IS_LON, false, &xynew[GMT_Y]);
       gmt_scanf_arg (GMT, Xstring, GMT_IS_LAT,  false, &xynew[GMT_X]);
    }
}

To handle proper parsing of 135:45W etc.

@PaulWessel
Copy link
Member

If you want to take a first crack at this then I can help with any pesky details.

@seisman
Copy link
Member Author

seisman commented Nov 9, 2019

OK. I'll look into it later.

@PaulWessel
Copy link
Member

Maybe something like this?. This assumes you may give an event title but not new x,y

if (In->text) {	/* Must examine the trailing text */
	n_scanned = scanf (In->text, "%s %s %[^\n]s\n", Xstring, Ystring, event_title);
	if (n_scanned >= 2) { /* Got new x,y coordinates and possibly event title */
		if (ix == GMT_X) {	/* Expect lon lat */
			gmt_scanf_arg (GMT, Xstring, GMT_IS_LON, false, &xynew[GMT_X]);
			gmt_scanf_arg (GMT, Ystring, GMT_IS_LAT,  false, &xynew[GMTY]);
		}
		else {	/* Expect lat lon */
			gmt_scanf_arg (GMT, Ystring, GMT_IS_LON, false, &xynew[GMT_Y]);
			gmt_scanf_arg (GMT, Xstring, GMT_IS_LAT,  false, &xynew[GMT_X]);
		}
		if (n_scanned == 2)	/* Got no title */
			event_title[0] = '\0';
	}
	else if (n_scanned == 1)	/* Only got event title */
		strncpy (event_title, In->text, GMT_BUFSIZ-1);
	else	/* Got no title */
		event_title[0] = '\0';
}

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

@PaulWessel I followed your first solution, as the second one doesn't work if event title contains several whitespaces (e.g. Right lateral strike, Right and lateral will be read as the newX and newY).

I also added a test to check psmeca with different input columns. Now all tests pass.

@PaulWessel
Copy link
Member

How do you handle the difference between

lon lat title

and

A longer title

both will give n_scanned 3, no?

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

I don't have a clever way to handle that, so I assume the newX and newY must be given if event title is needed. It's also consistent with older GMT4 or GMT5 behavior.

@PaulWessel
Copy link
Member

OK, I guess a clever solution would check if the resulting xynew coordinates are NaNs or not, and if they both are then change event_title to be the whole trailing text, e.g.

if (gmt_M_is_dnan (xynew[GMT_X]) and gmt_M_is_dnan (xynew[GMT_Y]))
	strncpy (event_title, In->text, GMT_BUFSIZ-1);

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

For a title like "10 km", gmt_scanf_arg returns 10.0000 and 0.000, not NaN. Why?

@PaulWessel
Copy link
Member

Odd, this is what I was fixing with #2020 and it caught the 10km title from before.

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

A title "Strike slip" also gives me 0.0 and 0.0, not NaN.

@PaulWessel
Copy link
Member

I have trouble switching to this branch - it complains about conflicts etc... I would approve and then try your case with 3 word title?

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

Try these commands?

# delete your local  meca-varcolumns branch
git branch -D meca-varcolumns
# switch to this branch
git checkout meca-varcolumns

@PaulWessel
Copy link
Member

OK now. Sorry, was in middle of building the full docs. Please give me a command or two that fails so I can debug.

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

gmt psmeca -R239/240/34/35 -JX4c -Ba0 -Sa1c > meca.ps << EOF
239.384 34.556 12.   180     18   -88  5 10 km
EOF

The title is "10 km".

@PaulWessel
Copy link
Member

The FIX cols set 9 cols, and your data record has 9 including the title. isn't the title in addition to the required cols? IF 10 km is the title then there should be 6 cols only?

@PaulWessel
Copy link
Member

Probably never mind. Xcode does not wipe and rebuild the supplements when the source changes, so I need to rebuild the whole thing. Your code seems to do 6 but my debugger says 9...

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

@PaulWessel Your fix works well except that newX and newY need to be reset to 0.0 if they're NaN.

I've made the fix and updated the test script.

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

I still have a question. If -: is used, the first two columns are "lat lon". What about the newX and newY columns? I expect to give "newY newX", but the script below doesn't work:

gmt psmeca -R239/240/34/35 -JX8c -Baf -Sa1c -C1p -: -pdf meca << EOF
34.556 239.384 12.   180     18   -88  5 34.8 239.8 10 km
EOF

I have to give "newX newY". i.e. This works:

gmt psmeca -R239/240/34/35 -JX8c -Baf -Sa1c -C1p -: -pdf meca << EOF
34.556 239.384 12.   180     18   -88  5 239.8 34.8  10 km
EOF

@PaulWessel
Copy link
Member

It should by lat lon in both places I think. I suggest we change the if test on ix to be

if (GMT->current.setting.io_lonlat_toggle[GMT_IN]) {

else
<do the first situation where X is X

which is cleaner than the ix stuff.

@PaulWessel
Copy link
Member

Also, the checking of xynew versus zero is no good. The day may come when you want to give 0,0 as the new coordinates and then you cannot. Please do this instead:

Initialize the xynew array to GMT->session.d_NaN
Remove the reassignment of xynew back to zero
Change the test near L768 to use the gmt_M_is_dnan macro

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

I made the change aa7fa4b to fix the issue with -:. Please help check if it's correct.

Also, the checking of xynew versus zero is no good. The day may come when you want to give 0,0 as the new coordinates and then you cannot. Please do this instead:

Initialize the xynew array to GMT->session.d_NaN
Remove the reassignment of xynew back to zero
Change the test near L768 to use the gmt_M_is_dnan macro

I agree, but it's used for a long time, and I have seen many scripts using 0 0 as newX and newY.

@PaulWessel
Copy link
Member

Looks good to me.

@PaulWessel
Copy link
Member

You mean people will place 0 0 when they use -C but don't want another placement instead of not giving the coordinates? Maybe we could handle it under compatibility and say this will break in GMT 7 and warn if we get 0,0 instead of NaN NaN until then?

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

You mean people will place 0 0 when they use -C but don't want another placement instead of not giving the coordinates?

Yes, this is exactly what the GMT4 manpage says:

Entries in these columns are necessary with the -C option. 
Using 0,0 in columns 8 and 9 will plot the beach ball at the longitude, latitude 
given in columns 1 and 2. The −: option will interchange the order of columns (1,2) and (8,9).

@PaulWessel
Copy link
Member

Of, a simpler time when NaNs were just bread eaten by Indians...
I think we can now handle just leaving those coordinates off entirely. Alternatively accept NaN NaN to mean no new location. And then until GMT 7 warn about 0,0. The test on zero is not good and GMT-like...

@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

Just realize that it's a bad idea to allow "title"-only input.

The Global CMT project (the most used focal mechanism solution data source) returns:

-176.96 -29.25 48 7.68 0.09 -7.77 1.39 4.52 -3.26 26 X Y 010176A       

Our current implementation gives
image
It means breaking many people's results.

@PaulWessel
Copy link
Member

PaulWessel commented Nov 10, 2019 via email

PaulWessel and others added 3 commits November 9, 2019 20:50
The Global CMT project (the most used focal mechanism solution data source) returns records like
-176.96 -29.25 48 7.68 0.09 -7.77 1.39 4.52 -3.26 26 X Y 010176A
@seisman
Copy link
Member Author

seisman commented Nov 10, 2019

@carltape This PR fixes the psmeca input issue reported in #2016. It would be good if you can give it a try.

In the new implementation, the new coordinates and event_title are optional. For example, -Sa now can accept following input formats:

  • longitude latitude depth strike dip rake mag
  • longitude latitude depth strike dip rake mag newX newY
  • longitude latitude depth strike dip rake mag event_title
  • longitude latitude depth strike dip rake mag newX newY event_title

@seisman seisman added this to the 6.0.1 milestone Nov 10, 2019
@carltape
Copy link

@seisman I installed this branch and confirm that it resolves the issue you were working on: psmeca allows variable number of columns, as before. Thank you!

In the process of wider testing, I found a lingering issue with psmeca. I will reopen #661

@seisman seisman merged commit 0fa52fb into 6.0 Nov 15, 2019
@seisman seisman deleted the meca-varcolumns branch November 15, 2019 16:29
@seisman
Copy link
Member Author

seisman commented Nov 15, 2019

@carltape Thanks for your reports and tests! This PS has been merged into 6.0 branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants