Work function endlessly loops and when I set WORK_DONE as -1, no output is shown - gnuradio

I'm currently trying to implement my own source block on GNURADIO. What this source block does is takes the values of 4 arguments (titled Value1,Value2,Value3 and Value4) and converts them to binary values with varying lengths. For example, Value1 is converted into a binary value with a length of 11 bits, whilst Value2 is converted into a binary value with a length of 16 bits etc. The conversion of these values work.
The issue I'm having is that I am unable to output these converted values onto a vector sink. when the work function returns (len(output[0]),when I execute the code using QA code. I end up with an endless loop, which when interrupted, outputs an extremely large vector with values of "0L".
Now from reading similar questions, I understand that as my block is set as a source, it will send out data as long as the vector sink has enough room in its input buffer. Therefore I set the return value to be -1 to force the flow graph to stop. This gives me an empty value "()" in the Vector sink.
The code is shown below:
import numpy
import time
import sys
import random
import os
from gnuget import *
from gnuradio import gr
from gnuradio import blocks
from gnuradio.blocks.blocks_swig1 import vector_source_b
class ConvertVariables(gr.sync_block):
"""
docstring for block ConvertVariables
"""
def __init__(self,Value1,Value2,Value3,Value4):
self.value1 = Value1
self.value2 = Value2
self.value3 = Value3
self.value4 = Value4
gr.sync_block.__init__(self,
name="ConvertVariables",
in_sig=None,
out_sig=[(numpy.byte)])
def work(self, input_items, output_items):
out = output_items[0]
self.value1_R = getvalue1(self.value1)
self.value2_R = getvalue2(self.value2)
self.value3_R = getvalue3(self.value3)
self.value4_R = getvalue4(self.value4)
self.value1_B = bytearray(self.value1_R,'utf-8')
self.value2_B = bytearray(self.value2_R,'utf-8')
self.value3_B = bytearray(self.value3_R,'utf-8')
self.value4_B = bytearray(self.value4_R,'utf-8')
print(type(self.value1_B))
print(type(self.value2_B))
print(type(self.value3_B))
print(type(self.value4_B))
print(len(output_items),"output_items")
self.out[:] = [self.value1_B,self.value2_B,self.value3_B,self.value4_B]
print(len(output_items[0]))
return (len(output_items[0]))
So ideally when the arguments(2034,5000,50,5) are sent. The expected result in the vector sink is
('11111110010','0001001110001000','110010','0101')
However what appears instead is either
(0L,0L,0L,0L)
(The length of the vector is not consistent, if I set the return value of work to len(output[0]), the terminal windows fills with 0L)
or
()
This only occurs if the return value of work is set to -1

Related

Octave strread can't return parsed results to an array (?)

In Octave, I am reading very large text files from disk and parsing them. The function textread() does just what I want except for the way it is implemented. Looking at the source, textread.m pulls the entire text file into memory before attempting to parse lines. If the text file is large, it fills all my free RAM (16 GB) with text and then starts saving back to disk (virtual memory), before parsing. If I wait long enough, textread() will complete, but it takes almost forever.
Notice that after parsing into a matrix of floating point values, the same data fit into memory quite easily. So I'm using textread() in an intermediate zone, where there is enough memory for the floats, but not enough memory for the same data as text.
All of that is preparation for my question, which is about strread(). The data in my text files looks like this
0.0647148 -2.0072535 0.5644875 8.6954257
0.1294296 -8.4689583 0.6567095 144.3090450
0.1941444 -9.2658037 -1.0228742 173.8027785
0.2588593 -6.5483359 -1.5767574 90.7337329
0.3235741 -0.7646807 -0.5320896 1.7357120
... and so on. There are no header lines or comments in the file.
I wrote a function that reads the file line by line, and notice the two ways I'm attempting to use strread() to parse a line of data.
function dest = readPowerSpectrumFile(filename, dest)
% read enough lines to fill destination array
[rows, cols] = size(dest);
fid = fopen(filename, 'r');
for line = 1 : rows
lstr = fgetl(fid);
% this line works, but is very brittle
[dest(line, 1), dest(line, 2), dest(line, 3), dest(line, 4)] = strread(lstr, "%f %f %f %f");
% This line doesn't work. Or anything similar I can think of.
% dest(line, 1:4) = strread(lstr, "%f %f %f %f");
endfor
fclose(fid);
endfunction
Is there an elegant way of having strread return parsed values to an array? Otherwise I'll have to write a new function any time I change the number of columns.
Thanks
Your described format is a matrix with floating point values. In this case you can just use load
d = load ("yourfile");
which is much faster than any other function. You can have a look at the used implementation in libinterp/corefcn/ls-mat-ascii.cc: read_mat_ascii_data
If you feed fprintf more values than are in its format specification, it will reapply the print statement until it's used them up:
>> fprintf("%d %d \n", 1:6)
1 2
3 4
5 6
It appears this also works with strread. If you specify only one value to read, but there are multiple on the current line, it will keep reading them and add them to a column vector. All we need to do is to assign those values to the correct row of dest:
function dest = readPowerSpectrumFile(filename, dest)
% read enough lines to fill destination array
[rows, cols] = size(dest);
fid = fopen(filename, 'r');
for line = 1 : rows
lstr = fgetl(fid);
% read all values from current line into column vector
% and store values into row of dest
dest(line,:) = strread(lstr, "%f");
% this will also work since values are assumed to be numeric by default:
% dest(line,:) = strread(lstr);
endfor
fclose(fid);
endfunction
Output:
readPowerSpectrumFile(filename, zeros(5,4))
ans =
6.4715e-02 -2.0073e+00 5.6449e-01 8.6954e+00
1.2943e-01 -8.4690e+00 6.5671e-01 1.4431e+02
1.9414e-01 -9.2658e+00 -1.0229e+00 1.7380e+02
2.5886e-01 -6.5483e+00 -1.5768e+00 9.0734e+01
3.2357e-01 -7.6468e-01 -5.3209e-01 1.7357e+00

Strange numbers in the output from Netcdf in Fortran

I'm fairly new to Fortran and try reading in 3D (80000*100*10) single precision NetCDF data (however I'd just read it 2D like (80000,100,1st)). I would need to convert them into double precision for some further code not shown below.
The .nc-File which I create to check if the reading/writing works does contain only "0" if I use real single precision for all NF90-functions as well as the variable 'values'.
It does contain mostly "0" and several weird numbers which don't seem to relate in a conceivable way to the input data if I use double precision (code shown below). At least I get any output in my nc file this way.
I don't get any compiling errors {nor error codes in 'STATUS' if I check for specific lines after NF90 functions. Update: That was mistaken}. Input_test.nc gets created exactly as expected regarding dimensions, but not regarding the actual values.
My code is:
PROGRAM read
Implicit None
INCLUDE 'netcdf.inc'
INTEGER :: NCID, horstart, verstart, horlen, verlen, horcount, vercount, STATUS, STATUS2
REAL(kind=8), DIMENSION(80000,100) :: values
horstart = 1
verstart = 1
horcount = 80000 !!(tried to use this instead of horlen, doesn't change anything)
vercount = 100 !!(tried to use this instead of verlen, doesn't change)
varname = 'pres'
!! get input data
STATUS = NF90_OPEN('my_valid_path/file.nc', 0, NCID)
STATUS = NF90_INQ_DIMID(NCID, 'ncells', horid)
STATUS = NF90_INQ_DIMID(NCID, 'height', verid)
STATUS = NF90_INQ_DIMLEN(NCID,horid,horlen)
STATUS = NF90_INQ_DIMLEN(NCID,verid,verlen)
STATUS = NF90_INQ_VARID(NCID,varname,varid)
STATUS = NF90_GET_VARA_DOUBLE(NCID,varid,[horstart,verstart,1],[horlen,verlen,1],values)
STATUS = NF90_CLOSE(NCID)
STATUS = NF90_CREATE ('some_path/input_test.nc', 0, ncid);
STATUS = NF90_DEF_DIM (ncid, 'hor',horcount, dimhor)
STATUS = NF90_DEF_DIM (ncid, 'ver',vercount, dimver)
STATUS = NF90_DEF_DIM (ncid, '1d',1, dimcode)
STATUS = NF90_DEF_VAR(ncid,'pres',NF90_DOUBLE,2,[dimhor,dimver],pres_id)
STATUS = NF90_DEF_VAR(ncid,'status',NF90_INT,1,dimcode,stat_id)
STATUS = NF90_ENDDEF(ncid)
STATUS = NF90_PUT_VARA_DOUBLE(ncid,pres_id,[horstart,verstart],[horcount,vercount],values)
STATUS = NF90_PUT_VARA_INT(ncid,stat_id,1,1,STATUS2)
STATUS = NF90_CLOSE(ncid)
The nc file I read from doesn't contain any zeroes, not even in the 3rd dimension. The Output file however does contain a lot zeroes, it is not empty though.
Example input: 0,095213220 0,099325478 0,10358732 0,10800611 0,11259078 0,11734842 0,12228279 0,12740466 0,13271827 0,13822863 0,14394356
Example output: 0 0 0 0 0 0,000493943283800036 0,000594558776356280 0,000234268474741839 2,88491937681101e-05 2,09666131608306e-16 7,30948746534081e-20
I'm probably doing something stupid, but I went temporarily out of ideas what to check for.
UPDATE: Thoroughly checking the error codes saved in STATUS did give a non-zero match at NF90_GET_VARA_DOUBLE/(also REAL). Getting back to this tomorrow.
With error handler I came to the conclusion that the above code works. The errors eventually came from a spelling mistake of the variables I tried to read from.

Google Spreadsheet Python API read specific column

I have 2 questions regarding google spreadsheet's api using python. My google spreadsheet is as follows:
a b1 23 4 5 6
When I run the script below I only get
root#darkbox:~/google_py# python test.py
1
2
3
4
I only want to get column 1 so i want to see
1
3
5
my second issue here is considering there is a space between the rows my script is not getting the second part (it should be 5 in this case)
How can I get the specified column and ignore white spaces?
#!/usr/bin/env python
import gdata.docs
import gdata.docs.service
import gdata.spreadsheet.service
import re, os
email = 'xxxx#gmail.com'
password = 'passw0rd'
spreadsheet_key = '14cT5KKKWzup1jK0vc-TyZt6BBwSIyazZz0sA_x0M1Bg' # key param
worksheet_id = 'od6' # default
#doc_name = 'python_test'
def main():
client = gdata.spreadsheet.service.SpreadsheetsService()
client.debug = False
client.email = email
client.password = password
client.source = 'test client'
client.ProgrammaticLogin()
q = gdata.spreadsheet.service.DocumentQuery()
feed = client.GetSpreadsheetsFeed(query=q)
feed = client.GetWorksheetsFeed(spreadsheet_key)
rows = client.GetListFeed(spreadsheet_key,worksheet_id).entry
for row in rows:
for key in row.custom:
print "%s" % (row.custom[key].text)
return
if __name__ == '__main__':
main()
To ignore white spaces:
Suggest you switch to CellFeed - I think list feed stops reading when it hits whitespace. Sorry, I forget the fine details. But I dropped List feed and switched to cellfeed a long time ago.

Error Handling with Live Data Matlab

I am using a live data API that is returning the next arriving trains. I plan on giving the user the next 5 trains arriving. If there are less than 5 trains arriving, how you handle that? I am having trouble thinking of a way, I was thinking a way with if statements but don't know how I would set them up.
time1Depart = dataReturnedFromLiveAPI{1,1}.orig_departure_time;
time2Depart = dataReturnedFromLiveAPI{1,2}.orig_departure_time;
time3Depart = dataReturnedFromLiveAPI{1,3}.orig_departure_time;
time4Depart = dataReturnedFromLiveAPI{1,4}.orig_departure_time;
time5Depart = dataReturnedFromLiveAPI{1,5}.orig_departure_time;
time1Arrival = dataReturnedFromLiveAPI{1,1}.orig_arrival_time;
time2Arrival = dataReturnedFromLiveAPI{1,2}.orig_arrival_time;
time3Arrival = dataReturnedFromLiveAPI{1,3}.orig_arrival_time;
time4Arrival = dataReturnedFromLiveAPI{1,4}.orig_arrival_time;
time5Arrival = dataReturnedFromLiveAPI{1,5}.orig_arrival_time;
The code right now uses a matrix that goes from 1:numoftrains but I am using just the first five.
It's a bad practice to assign individual value to a separate variable. Better if you pass all related values to a vector or cell array depending on class of orig_departure_time and orig_arrival_time.
It looks like dataReturnedFromLiveAPI is a cell array of structures. Then you can do:
timeDepart = cellfun(#(x), x.orig_departure_time, ...
dataReturnedFromLiveAPI(1,1:min(5,size(dataReturnedFromLiveAPI,2))), ...
'UniformOutput',0 );
timeArrival = cellfun(#(x), x.orig_arrival_time, ...
dataReturnedFromLiveAPI(1,1:min(5,size(dataReturnedFromLiveAPI,2))), ...
'UniformOutput',0 );
Then you how to access the values one by one as
time1Depart = timeDepart{1};
If orig_departure_time and orig_arrival_time are numeric scalars, you can use ...'UniformOutput',1.... You will get output as a vector and can get single values with timeDepart(1).

Anim Plot Updating

I am trying to find maximum values of a sinusoidal and show it in a subplot. And trying to update it like an animation. But the subplot of the maximum values gives all zero values. When I print the array it is not zeroes. I think it is not updating y values. I couldn't figure out the reason. Any help would be kindly appreciated.
I will put my code it is executable:
from pylab import *
import time
ion()
fs = 1e6
Ts = 1/fs
SNR=10
sinfreq=2*pi*1e5
pack= 512
t = Ts*arange(0,pack)
f = fs*(arange(0,pack)-pack/2)/pack
max_y = zeros (len(t))
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
subplot(211)
line1, = plot(y)
subplot(212)
line2, = plot(max_y)
for i1 in arange(1,1000):
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
line1.set_ydata(y)
mk=0
for mk in range(0,len(y)):
if y[mk] > max_y[mk]:
max_y[mk] = y[mk]
print max_y
line2.set_ydata(max_y)
draw()
waitforbuttonpress(timeout=0.5)
You've forgotten an indent in the second for loop.
That should actually give you an IndentationError, so I don't understand how you can say that the program is executable (in fact, I edited your entry to remove the left-over "enter code here" statement; if you had checked and copy-pasted your entry, you'd probably found both mistakes).
But, are you sure you don't want simply
max_y[:] = max(y)
instead of that for loop?
Ok I have found the solution incidentally, I don't know the reason but I update my max_y plot any other value firstly then do my real update, then the plot shows my changes. Other than this it is not showing. I try with different for loops they are ploting with one update but for my loop it wanted to update twice.
I have also add set_ylim to see better the limits. I put stars to places that I have changed. I am putting the new code also. I wish it will help people that have the same problem.
from pylab import *
import time
ion()
fs = 1e6
Ts = 1/fs
SNR=10
sinfreq=2*pi*1e5
pack= 512
t = Ts*arange(0,pack)
f = fs*(arange(0,pack)-pack/2)/pack
max_y = zeros (len(t))
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
subplot(211)
line1, = plot(y)
sub2=subplot(212) #****
line2, = plot(max_y)
for i1 in arange(1,1000):
y=sin(sinfreq*t)
y=y+randn(size(y))/sqrt(10^(SNR/10)*2)
line1.set_ydata(y)
mk=0
for mk in range(0,len(y)):
if y[mk] > max_y[mk]:
max_y[mk] = y[mk]
#print max_y
line2.set_ydata(zeros(len(max_y)))#****
line2.set_ydata(max_y)
sub2.set_ylim(min(max_y),max(max_y)) #****
draw()
waitforbuttonpress(timeout=0.5)