Background: Testing
As many of you know, we at Geon Technologies have a large body of work using REDHAWK SDR and its Eclipse -based IDE. We also use the FileWriter Component enough that we released our FEI_FileReader Component to then pull RF snapshots back into REDHAWK using the FEI Interfaces spec. It’s a powerful set of capabilities that help us setup container-based unit tests that can scale up to the system-level, all in REDHAWK.
But what if you what if you want to analyze data from REDHAWK in a different tool like MATLAB or Octave? Once again, the FileWriter Component and IDE can both help with getting data into files in either raw BULKIO or X-Midas BLUE -formatted files.
But then what? That’s the issue I ran into because we wanted to take our REDHAWK -based implementations of original MATLAB models and compare the results. After some searching around, I was unable to find an already-prepared BLUE/Platiunum -file format parser for MATLAB that would let me bring snapshots into MATLAB, so, I wrote one.
X-Midas Blue Reader
You can find the source code here.
The goal of this little project is to read all of the header and extended header information from snapshots into MATLAB. I would then take those snapshots and develop analysis tools to help us vet our snapshots against the original MATLAB models at each stage in an algorithm.
The XMidasBlueReader takes the file you want it to manage as the constructor argument:
my_blue = XMidasBlueReader('path/to/data/file');
Header Control Block (HCB)
So what about the header control block? Here’s an example output of a 500KHz bandwidth snapshot captured from an RTL pointed at the FRS band.
% BLUE type 1000 (vector data)
rf_frs.hcb.type
ans =
1000
% Complex, Float
rf_frs.hcb.format
ans =
'CF'
% SRI information (xdelta = 1/500e3), Time
rf_frs.hcb.adjunct
ans =
struct with fields:
xstart: 0
xdelta: 2.0000e-06
xunits: 1
Extended Header
The REDHAWK FileWriter Component stores your SRI’s keywords map as a list in the extended header. The XMidasBlueReader imports those as well. In this case, my RTL was pointed in the 462 MHz range of FRS:
rf_frs.ext_header(1)
ans =
struct with fields:
lkey: 24
lext: 16
ltag: 7
type: 'D'
value: 462643750
tag: 'CHAN_RF'
For those not familiar with the format, the lkey
, lext
, and ltag
members are length information describing the key in bytes; you can likely ignore those if the type
, tag
, and value
seem sane. The type
is the same description as found in the hcf.format(2)
position (in this case, double). The tag
is your SRI keyword name, and of course the value
is the value. Again in this case, it’s pointed at the center of the 462 MHz-oriented FRS channels.
Data
Naturally, snapshots can be extremely large even over short periods of time — often much larger than the default allowed matrix size in MATLAB if you tried to read the entire file at the same time. For example, even this short ~30 second snapshot at 500 Ksps complex float was approximately 96 MB. Recognizing that each complex (2) float (4 bytes) sample is 2×4 bytes, we would need a vector of length ~12 million to get all samples at once.
For me, I have no intention of crunching 12 million samples at once, but I may want the option to bring in a few hundred thousand of them, right?
For reading, use read(num_samples)
and rewind(num_samples)
. The hcb.format
field is what defines a sample. For complex-formatted data, it will return a row vector already in complex format, shown here:
cplx_frs = rf_frs.read(8)'
ans =
0.0745 + 0.2000i
-0.0118 + 0.1373i
-0.1059 - 0.0588i
-0.1059 - 0.0667i
0.0118 - 0.1137i
0.1686 + 0.0196i
0.1137 + 0.0275i
0.0510 + 0.0510i
Also from the format
information is the number of bytes being read per sample which translates to advancing the internal read pointer to prevent reading off the edge of the file. To reset that pointer, use resetRead
. You can check if you’re at the start or end of the data buffer using the begin
and end
methods.
Example Application
Below is a screenshot example application I put together for our team using MATLAB’s App Designer tooling (which is really good, by the way).
The signal in the screenshot is the result of analyzing the FRS signal used in the above examples. The whole application brings in the two different file streams from REDHAWK: spectral analysis output vs. the original signal. Functionality-wise, it provides Next and Previous playback functionality so that the engineers can step through the analysis vs. the characteristics it is identifying.
Conclusion
We hope you all find the XMidasBlueReader as useful as we are! For us, it’s an easy way to “tap” REDHAWK-based algorithms in our Waveforms, and feed the data back through the original model.
If you have ideas for features, or find bugs, please submit issues and/or pull requests against the repository. And of course if you’re interested in any of the above capabilities, please don’t hesitate to contact us.