IDL for loop overwrites data - idl-programming-language

I have a problem with my for-loops in IDL.
for sl=0,2 do begin ; number of hours
for t=90,90 do begin ; timesteps each hour
for rad_num = 0, 3 do begin ; number of radars
for ibin = 0, 333 do begin ; distance to radar
for iray = 0, 359 do begin ; angle
if finite(input(ibin,iray,rad_num)) eq 1 then begin
bin = bin_index(ibin,iray,rad_num)
ray = ray_index(ibin,iray,rad_num) ; necessary because of different grids
array(sl,t,ray,bin)=array(sl,t,ray,bin)+ input(ibin,iray,rad_num)
array_N(sl,t,ray,bin) = array_N(sl,t,ray,bin) + 1.
endif
endfor
endfor
endfor
endfor
endfor
array = array / array_N
When I stopped the program after the first sl-loop-step, I get the following:
print, array[0,90,315,49]
44.0.673
But when I don't stop the program, I get this:
print, array[0,90,315,49]
-NaN
It seems, that my program overwrites the data of the previous loop-step. When I make a scatter-plot, I also have the points of the last loop-step only...
Do you see my mistake?
Thanks a lot!
kiki

You don't assign to dwd in the code you show (and the code won't compile as-is because of the enddo's -- I assume you had to rewrite the code instead of copy-and-past for some reason?).

Related

IDL two step graph

I'm struggling with setting a y(x) condition that varies with x range. As an example below, the code wants to plot y=x between x=0 and x=5.1; otherwise y=2x.
Upon compilation, the code spits out the following: Expression must be a scalar or 1 element array in this context:
In other words don't know how to assign an array variable 'x' into if statement.
Thank you all for your help in advance.
PRO test
x = findgen(101.0,start=0)/10.0 ; 0.0 start, 10.0 end increment of 0.1
print,x
if x lt 5.1 then begin
y = 1.0 * x ;
endif else begin
y = 2.0* x
endelse
graph1=plot(x,y,thick=2,NAME=first,/CURRENT, $
linestyle = 0, ytitle=' y',xtitle='x' ) ; O
END
The problem is the test in your IF statement. Use WHERE instead to do something like the following.
y = x ;; need to initialize variable
low = WHERE(x lt 5.1,lw,COMPLEMENT=upp,NCOMPLEMENT=up)
IF (lw[0] GT 0) THEN y[low] = x[low] ;; technically don't need this line
IF (up[0] GT 0) THEN y[upp] = 2e0*x[upp]

skip missing values in a for loop

I have a folder with 1000 tifs. I'd like to read 4 tifs, do some calculation and read the next 4 tifs. The problem is, that for example tif number 500 is missing. Now my current program stops right bevor tif number 500.
So my idea is that I check if the path exists with file_test and /directory and skip all missing values in the foor loop.
Directory: Set this keyword to return 1 (true) if File exists and is a directory. true =1, false = 0
for j = 0, 1102 do begin
PathEx = File_test(e:\Meteosat\Tiff\2016\06\17\MSG_201606170100_B4_L.tif', directory)
if PathEx = 1 then
B = READ_TIFF(e:\Meteosat\Tiff\2016\06\17\MSG_201606170100_B4_L.tif, GEOTIFF=tags)
if PathEx = 0 then
print, 'missing' and continue
end
I want to skip all missing paths. I don't know how to do this. I Also read something about
.CONTINUE
But I have no clue how this works too.
thank you!
pampi
I am not sure you are using the correct syntax. Your code should be something like the following:
FOR j=0L, 1102L DO BEGIN
PathEx = FILE_TEST('e:\Meteosat\Tiff\2016\06\17\MSG_201606170100_B4_L.tif', /DIRECTORY)
IF (PathEx[0] EQ 0) THEN CONTINUE ;; This will jump to the next index
b = READ_TIFF('e:\Meteosat\Tiff\2016\06\17\MSG_201606170100_B4_L.tif',GEOTIFF=tags)
ENDFOR
You should probably have a list of file names and then index those. Suppose you call them something like filenames and this is a [N]-element string array. Then you would do something like the following within the above loop:
file = filenames[j]
PathEx = FILE_TEST(file[0],/DIRECTORY)
IF (PathEx[0] EQ 0) THEN CONTINUE ;; This will jump to the next index
b = READ_TIFF(file[0],GEOTIFF=tags)
I should also mention that the variable b should either be an array or you should have an array defined outside the loop that you can store data into, otherwise all your operations within the FOR loop will be lost.

How to check for file updates after 5 min intervals with autoit?

I'm trying to get some sort of script working so It checks two files every 5 mins to check if they've updated/changed/been modified.
If file 1 has been updated/changed/been modified it should do one thing, if file 2 has been updated/changed/been modified it should close a certain program and launch a new program then change the programs title and move it to 0, 0 (top left of screen)
The part I don't know how to do is the checking the files to see if they've been updated/changed/been modified.
Could someone help me and point me in the right direction?
Thanks in advance :)
You are looking for FileGetTime, specifically with the option set to 0 (modified)
Code Example
Func Timecheck()
$file1_2 = FileGetTime("C:\file1.txt", 0, 1)
$file2_2 = FileGetTime("C:\file2.txt", 0, 1)
If $file1_1 == $file1_2 Then
; Do something here if file 1 isn't modified within 5ins
EndIf
If $file2_1 == $file2_2 Then
; Maybe WinClose?
WinClose("programhere")
; Maybe ProcessClose
ProcessClose("process.exe")
; Launch your program...
Run(...)
; Wait for process
ProcessWait("process.exe")
; Wait for Program...
WinWait("programhere")
WinSetTitle("programhere", "", "newprogramhere")
WinMove("newprogramheret", "", 0, 0, 800, 600, 1)
EndIf
$file1_1 = FileGetTime("C:\file1.txt", 0, 1)
$file2_1 = FileGetTime("C:\file2.txt", 0, 1)
EndFunc
; Initial Launch, grab current GetTime
$file1_1 = FileGetTime("C:\file1.txt", 0, 1)
$file2_1 = FileGetTime("C:\file2.txt", 0, 1)
While 1
Sleep(300000)
Timecheck()
WEnd
Reference: http://www.autoitscript.com/autoit3/docs/functions/FileGetTime.htm

How to read Base64 VLQ code?

I'm trying to understand how css source map works. I've created a very simple scss file.
#navbar {
color: black;
}
When I compile the above scss, I get the following map file.
{
"version": "3",
"mappings": "AAAA,OAAQ;EACP,KAAK,EAAE,KAAK",
"sources": ["test.scss"],
"file": "test.css"
}
when I decode "mappings", I get the following values.
0) [0,0,0,0], [7,0,0,8]
1) [2,0,1,-7], [5,0,0,5], [2,0,0,2], [5,0,0,5]
What are those values?
I found an example at http://www.thecssninja.com/javascript/source-mapping, under the section "Base64 VLQ and keeping the source map small".
The above diagram AAgBC once processed further would return 0, 0, 32, 16, 1 – the 32 being the continuation bit that helps build the following value of 16. B purely decoded in Base64 is 1. So the important values that are used are 0, 0, 16, 1. This then lets us know that line 1 (lines are kept count by the semi colons) column 0 of the generated file maps to file 0 (array of files 0 is foo.js), line 16 at column 1.
Even after reading the answers, explanations were still not so clear to me. Here is an explanation in plain english in case it helps someone:
something like ;;AAAA,IAAM,WAAW,SAAX;... means <line0 info>;<line1 info>;...
so for ;;AAAA;IAAM,WAAW,SAAX;..., line 0 and line 1 doesn't have any important info (empty spaces etc.)
then for line 2 we have AAAA,IAAM,WAAW,SAAX
we convert each of these groups to binary using the base64 character mapping:
BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
so we basically find the index in this BASE64_ALPHABET above, and convert the index to 6-bit binary (6 bit because we use base64). eg. index of A is 0, so in 6 bit binary its 000000. so AAAA would be 000000 000000 000000 000000
then if we do this with IAAM we get: 001000 000000 000000 001100.
then this bit representation is the VLQ encoded version of 4 numbers. we start from the left block, remove the sign and continuation bit, keep the bits. and continue adding it bits while continuation bit is 1.
eg. 001000 is (cont)0100(sign)
so cont = 0 (no other block will be added to this number)
sign=0 (its positive)
bits = 0100 --> so it is 4 in decimal
-- note that we only remove sign bit for the first time. so if we had
101000 001000
we would say
0100 (cont=1, sign=0) 01000 (cont=0)
so we would have had +010001000 = 136
when we keep doing this, we will get these 4 numbers (continuation bit should be 0 exactly 4 times).
AAAA would map to (0,0,0,0)
IAAM would map to (4,0,0,6)
WAAW would map to (11,0,0,11)
...
now, each of these mean relative numbers. so we correct those:
AAAA actually points to: (0,0,0,0)
IAAM actually points to: (0+4, 0+0, 0+0, 0+6) = (4,0,0,6)
WAAW actually points to: (4+11, 0+0, 0+0, 6+11) = (15,0,0,17) // we added it where IAAAM was actually pointing to
...
so numbers (n1, n2, n3, n4) here stand for
n1: column in generated code
n2: corresponding source file index in "sources" array of sourceMapping output
n3: line number in original code
n4: column number in original code
we already knew which line this referred to from the beginning. so using the information we have above, we learned:
AAAA: line 2, column 1 of generated code points to sources[0], line 0, column 0
IAAM: line 2, column 4 of generated code points to sources[0], line 0, column 6
WAAW: line 2, column 15 of generated code points to sources[0], line 0, column 17
...
two good sources about this:
more on VLQ encoding
more on how to interpret/decode
Despite the examples I could find, I took me quite a while to understand how the coding / decoding really works. So I thought I'd learn best by trying to make something myself in a very explicit, step by step way. I started out with the explanation of VLQ at this blog,
I use the following Python functor to generate sourcemaps for Transcrypt.
The code is simple and I think gives good insight in how the coding/decoding works in principle.
To achieve speed despite its simplicity, it caches the first 256 numbers, which are used most often in generating a v3 sourcemap.
import math
class GetBase64Vlq:
def __init__ (self):
self.nBits32 = 5
self.encoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
self.prefabSize = 256
self.prefab = [self (i, True) for i in range (self.prefabSize)]
def __call__ (self, anInteger, init = False):
if not init and 0 < anInteger < self.prefabSize:
return self.prefab [anInteger]
else:
signed = bin (abs (anInteger)) [2 : ] + ('1' if anInteger < 0 else '0')
nChunks = math.ceil (len (signed) / float (self.nBits32))
padded = (self.nBits32 * '0' + signed) [-nChunks * self.nBits32 : ]
chunks = [('1' if iChunk else '0') + padded [iChunk * self.nBits32 : (iChunk + 1) * self.nBits32] for iChunk in range (nChunks - 1, -1, -1)]
return ''.join ([self.encoding [int (chunk, 2)] for chunk in chunks])
getBase64Vlq = GetBase64Vlq ()
Example of use:
while (True):
print (getBase64Vlq (int (input ('Give number:'))))

Pascal. Recursive function to count amount of odd numbers in the sequence

I need to write recursive function to count amount of odd numbers in the sequence
Here my initial code:
program OddNumbers;
{$APPTYPE CONSOLE}
uses
SysUtils;
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2=0)) then
begin
count:= count + 1;
GetOddNumbersAmount:=count;
end;
i:=i+1;
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i);
end;
var X: array[1..10] of integer;
i,amount: integer;
begin
writeln('Enter your sequence:');
for i:=1 to 10 do
read(X[i]);
amount:= GetOddNumbersAmount(X, 0, 1);
writeln('Amount of odd numbers: ', amount);
readln;
readln;
end.
When i type the sequence and press "enter", program closed without any errors and i can't see the result.
Also, i think my function isn't correct.
Can someone help with that code?
UPD:
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2<>0)) then
count:= count + 1;
if(i = 10) then
GetOddNumbersAmount:=count
else
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i+1);
end;
You don't provide an end of recursion, i.e., you always call your function GetOddNumbersAmount again, and your program never terminates. Thus, you get an array index error (or a stack overflow) and your program crashes.
Please note, that every recursion need a case where it terminates, i.e. does not call itself. In your case, it should return if there are no elements in the array left.
In addition, you are counting the even numbers, not the odd ones.
You passed a static array to a dynamic so the index get confused:
Allocat the array with
SetLength(X,10)
allocates an array of 10 integers, indexed 0 to 9.
Dynamic arrays are always integer-indexed, always starting from 0!
SetLength(X,10)
for it:=0 to 9 do begin
X[it]:= random(100);
And second if you know the length a loop has more advantages:
function GetEvenNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
for i:= 0 to length(X)-1 do
if((x[i] <> 0) and (x[i] mod 2=0)) then begin
inc(count);
//write(inttostr(X[i-1])+ ' ') :debug
end;
result:=count;
end;

Resources