1 00:00:00,480 --> 00:00:04,160 Hello and welcome to the  third video of this series.   2 00:00:04,160 --> 00:00:08,240 In this video, I want to talk about the  GROOPS parser and how it can make your life   3 00:00:08,800 --> 00:00:14,720 easier and how it can make your GROOPS scripts  more flexible. I've prepared a short script. I'll   4 00:00:14,720 --> 00:00:21,040 talk about it in a second, but the purpose of the  script is to compare kinematic orbits to dynamic   5 00:00:21,040 --> 00:00:27,840 orbits of a satellite and visualize this in a  plot. The result should look something like this.   6 00:00:29,760 --> 00:00:34,960 So we have along, cross, and radial axes. The  kinematic orbits, which are noisy, are compared   7 00:00:36,240 --> 00:00:42,240 to a dynamic orbit, which is relatively  smooth. For this we have some data. We   8 00:00:42,240 --> 00:00:48,400 have kinematic orbits and reduced-dynamic orbits  for four different satellites: GRACE-1, GRACE-2,   9 00:00:48,400 --> 00:00:58,720 Sentinel-1A, and TerraSAR-Xe, each for one week.  Both kinematic and reduced-dynamic orbits. So if   10 00:00:58,720 --> 00:01:03,920 we start with our script – I'll go quickly through  it – it's very simple. We do not have any global   11 00:01:03,920 --> 00:01:11,120 variables so far. First of all, we remove a "tmp"  directory in case it already exists. The next step   12 00:01:11,120 --> 00:01:17,280 is to recreate this "tmp" directory and also  create the "plots" directory. And then the   13 00:01:17,280 --> 00:01:25,520 first real step in the script is to synchronize  our kinematic orbit and our dynamic orbit so we   14 00:01:25,520 --> 00:01:31,200 ensure that both contain the same epochs, which  is necessary because the kinematic orbit might   15 00:01:31,200 --> 00:01:36,800 contain some gaps while the reduced dynamic orbit  does not contain gaps. And as you can see here,   16 00:01:38,240 --> 00:01:47,280 I've selected GRACE-1 for 2015-01-01 and the same  here, I have selected the reduced dynamic orbit.   17 00:01:49,760 --> 00:01:55,600 Both orbits are then written to their  respective files which only contain synchronized   18 00:01:56,160 --> 00:02:02,400 epochs, so epochs that are part of both files.  The next step is "InstrumentMultiplyAdd", where   19 00:02:03,520 --> 00:02:05,520 the two temporary files we just wrote   20 00:02:07,360 --> 00:02:12,320 – the dynamic orbit is subtracted from the  kinematic orbit – and the result is written to   21 00:02:13,120 --> 00:02:23,520 "orbitDiff.txt". Finally, we want to visualize  the orbit in a local orbit system so we simulate   22 00:02:23,520 --> 00:02:28,880 a star camera file based on the dynamic  orbit and we rotate the differences from the   23 00:02:29,920 --> 00:02:36,320 celestial reference frame to the local orbit  reference frame. And finally, we plot the result.   24 00:02:37,840 --> 00:02:43,360 We have three layers, one for each each  component, so along, cross, and radial.   25 00:02:45,360 --> 00:02:54,160 As you can see, we read the orbit file here and  "valueX" is "data0", which is the modified Julian   26 00:02:54,160 --> 00:02:59,840 date (MJD). The value of "data1" is the first  value, which is the along-track value. We multiply   27 00:02:59,840 --> 00:03:05,120 times 100 to convert it to centimeters  and add five centimeters to shift it   28 00:03:08,000 --> 00:03:15,440 in the plot. That's basically it. We also said  as the "axisX" we use a "time" axis where we can   29 00:03:15,440 --> 00:03:24,880 define the tick spacing and so on. At the end, we  end up with this plot, where we have along shifted   30 00:03:24,880 --> 00:03:34,960 by +5, radial shifted by -5, and the values in  centimeters, and a time axis. So far so good.   31 00:03:36,640 --> 00:03:46,080 As you could see, I just used here the orbits  from GRACE-1. So now what if we wanted to   32 00:03:47,360 --> 00:03:53,680 visualize the orbit for GRACE-2? We could, of  course, change it here to 2 and also here to 2   33 00:03:54,560 --> 00:04:00,240 and run the script and it would work fine.  But that's already a bit inconvenient. So   34 00:04:01,440 --> 00:04:06,480 what we can do in GROOPS is we can create a  global variable – let's call it "satellite"   35 00:04:07,600 --> 00:04:13,840 – we will give it a type "string" and 36 00:04:15,520 --> 00:04:22,720 just define it as "GRACE-2". And instead of  having GRACE-2 here, we can now replace this with   37 00:04:23,920 --> 00:04:27,840 the variable "{satellite}". Same here. 38 00:04:31,440 --> 00:04:38,960 And now, when I run the script, "{satellite}" will  be replaced by "GRACE-2". Another location where   39 00:04:38,960 --> 00:04:45,520 we can put it is, for example, in the title. We  can say, okay, we're going to have the name of   40 00:04:45,520 --> 00:04:51,920 the satellite in the title and also, maybe, in  the file name. So let's say the file name should   41 00:04:53,840 --> 00:04:57,520 be "{satellite}_orbitDiff.png".  And if we now run this... 42 00:05:00,720 --> 00:05:08,160 Goes by pretty quickly. And now we have a  file not only called "orbitDiff.png" but   43 00:05:08,160 --> 00:05:11,920 "GRACE-2_orbitDiff.png" and also it contains  GRACE-2 in there and, as you can see,   44 00:05:11,920 --> 00:05:18,560 it's different to GRACE-1. The original one  was GRACE-1. So it's already pretty convenient.   45 00:05:20,960 --> 00:05:29,680 As I mentioned in the beginning, we also have data  for one week but here it's basically hard-coded to   46 00:05:29,680 --> 00:05:40,320 use 2015-01-01. We can also circumvent this  by creating a global variable – let's call   47 00:05:40,320 --> 00:05:51,440 it "time" and it's from type "time" – and we can  just say, okay, we want to visualize 2015-01-02,   48 00:05:55,920 --> 00:06:03,760 let's say. As you can see, the modified Julian  date (MJD) value is this. And I can now replace   49 00:06:03,760 --> 00:06:10,640 the date here with the variable "time", but you  have to be careful here. If I just use "{time}",   50 00:06:11,200 --> 00:06:18,480 it would use "57024" as the value, because that's  the value which represents the time. But of course   51 00:06:18,480 --> 00:06:23,760 the file name does not contain the modified  Julian date but it contains the actual date.   52 00:06:23,760 --> 00:06:28,960 Here we can use another feature of our  parser: We can specify a format. We could do 53 00:06:31,133 --> 00:06:41,520 "{time:%Y-%m-%d}" or as an  alternative we can just use   54 00:06:43,500 --> 00:06:50,880 "{time:%D}" for date, which will parse  the date in the ISO format, as shown here.   55 00:06:52,320 --> 00:07:02,400 We can do the same here. We can replace it and,  again, this will be – when I run the script – this   56 00:07:02,400 --> 00:07:15,840 will be replaced. What you can also do is add the  date to the file name and if I now run this... 57 00:07:17,840 --> 00:07:21,920 I should have another plot – exactly  – I have now this plot which is called   58 00:07:21,920 --> 00:07:30,560 "GRACE-2_orbitDiff_2015-01-02.png". And as  you can see, again, this is different than   59 00:07:30,560 --> 00:07:37,600 2015-01-01 we plotted before. Now it's  easy for me to just plot, for example, 60 00:07:40,080 --> 00:07:47,280 "TerraSAR-X" instead of "GRACE-" and  2015-01-07. So if I run this now... 61 00:07:50,560 --> 00:07:59,440 Done, and now I have a figure or plot  "TerraSAR-X_orbitDiff_2015-01-07.png". So,   62 00:07:59,440 --> 00:08:09,440 yeah, that's pretty handy! Another thing I want  to show you is – let's add another layer – and   63 00:08:10,640 --> 00:08:13,680 we'll use the same input file "orbitDiff.txt",   64 00:08:15,200 --> 00:08:23,760 but instead of – what we now want to do is we  want to highlight outliers in our time series.   65 00:08:27,760 --> 00:08:33,120 Let's define an outlier by the total  difference being larger than five centimeters.   66 00:08:33,120 --> 00:08:47,200 So I can first compute the total difference  which would be "sqrt(data1^2+data2^2+data3^2)". 67 00:08:48,720 --> 00:08:58,400 And let's say this should be – or, rather, let's  now add a condition, so you can write if this   68 00:08:59,760 --> 00:09:07,600 distance is larger – let's multiply it by  100, so let's do it in centimeters – if   69 00:09:07,600 --> 00:09:20,600 this is larger than five centimeters, then  at a "valueY" of 10 – or then use a "valueY"   70 00:09:20,640 --> 00:09:28,080 of 10, otherwise use "nan" (not a  number). And what we want to happen is   71 00:09:28,080 --> 00:09:37,520 we want to have a symbol – let's pick a black  diamond – at the value of 10 on the Y-axis if   72 00:09:39,360 --> 00:09:45,760 the total distance between the kinematic and  the reduced dynamic orbit is larger than 5   73 00:09:45,760 --> 00:09:51,680 centimeters. Otherwise we use the value "nan",  which is this function. So what you can see here   74 00:09:51,680 --> 00:09:58,640 is that the parser can interpret mathematical  expressions. There are quite a few of them:   75 00:10:00,560 --> 00:10:06,640 from square root to other mathematical  operations, comparisons, and also   76 00:10:06,640 --> 00:10:15,040 specific functions. We can take a look at the  GROOPS documentation. If you go to Parser,   77 00:10:15,040 --> 00:10:21,760 there's a list of the mathematical expressions  that are supported: logical expressions, functions   78 00:10:21,760 --> 00:10:27,600 with multiple arguments and so on. And there's  also the text parser, you can see we earlier used   79 00:10:28,933 --> 00:10:37,280 "%Y-%m-%d" but also "%D" for the date.  So here, there's an explanation of   80 00:10:39,760 --> 00:10:50,160 these parser options you have. Okay, and if we now  run it again, we should hopefully end up with –   81 00:10:52,160 --> 00:10:58,400 yeah, see, so now in our TerraSAR-X figure we  have black diamonds at the locations where the   82 00:10:59,040 --> 00:11:04,000 total difference between the kinematic orbit  and the reduced-dynamic orbit is larger than 5   83 00:11:04,000 --> 00:11:09,280 centimeters. Of course, there are many more  options you can use or many more functions you   84 00:11:09,280 --> 00:11:15,360 can use with the GROOPS parser, but in principle  it's super handy to simplify the script, make it   85 00:11:15,360 --> 00:11:19,440 more flexible, use the same script for different  satellites, for different dates and so on.   86 00:11:20,640 --> 00:11:26,400 In the next video we will use this  because we will then extend our script   87 00:11:26,400 --> 00:11:32,880 to include loops and conditions and there,  again, these expressions and the parser will   88 00:11:33,680 --> 00:11:38,640 be very convenient. So until the  next video, see you. Bye bye!