Spatially Subsetting Images in batch mode using IDL and ENVI - subset

I would like to spatially subset LANDSAT photos in ENVI using an IDL program. I have over 150 images that I would like to subset, so I'd like to run the program in batch mode (with no interaction). I know how to do it manually, but what command would I use to spatially subset the image via lat/long coordinates in IDL code?

Here is some inspiration, for a single file.
You can do the same for a large number of files by building up
a list of filenames and looping over it.
; define the image to be opened (could be in a loop), I believe it can also be a tif, img...
img_file='path/to/image.hdr'
envi_open_file,img_file,r_fid=fid
if (fid eq -1) then begin
print, 'Error when opening file ',img_file
return
endif
; let's define some coordinates
XMap=[-70.0580916, -70.5006694]
YMap=[-32.6030694, -32.9797194]
; now convert coordinates into pixel position:
; the transformation function uses the image geographic information:
ENVI_CONVERT_FILE_COORDINATES, FID, XF, YF, XMap, YMap
; we must consider integer. Think twice here, maybe you need to floor() or ceil()
XF=ROUND(XF)
YF=ROUND(YF)
; read the image
envi_file_query, fid, DIMS=DIMS, NB=NB, NL=NL, NS=NS
pos = lindgen(nb)
; and store it in an array
image=fltarr(NS, NL, NB)
; read each band sequentially
FOR i=0, NB-1 DO BEGIN
image[*,*,i]= envi_get_data(fid=fid, dims=dims, pos=pos[i])
endfor
; simply crop the data with array-indexing function
imagen= image[XF[0]:XF[1],YF[0]:YF[1]]
nl2=YF[1]-YF[0]
ns2=XF[1]-XF[0]
; read mapinfo to save it in the final file
map_info=envi_get_map_info(fid=fid)
envi_write_envi_file, imagen, data_type=4, $
descrip = 'cropped', $
map_info = map_info, $
nl=nl2, ns=ns2, nb=nb, r_fid=r_fid, $
OUT_NAME = 'path/to/cropped.hdr'

Related

Adding/multiplying heatmaps in gnuplot

Is it possible with gnuplot to perform an operation on data (adding/multiplying) from two data files to generate a heatmap with the result of the operation ?
Ex: I have two files each with 4 columns, where
Col1: X coordinate
Col2: Y coordiante
Col3: Value
Col4: Uncertainty
I want to multiply the columns 3 of each file.
I wondered if something similar exists/would work in gnuplot, like ...
splot 'first.dat' using 1:2:(v=$3), 'second.dat' using 1:2:(v*$3)
I have been able to do this with two columns from the same file
splot 'first.dat' using 1:2:($3*$4)
A very similar question has already been answered:
gnuplot plot data from two files
In your case it will look like that:
splot "<paste first.dat second.dat" u 1:2:($3*$6)
Note that all columns from both files are present, therefore you have to "skip" the ones from the second file.
The OP apparently runs Linux or MacOS. #Eldrad's nice and short solution won't work with Windows. Of course, you can install additional programs like gnuwin, awk, etc...
A platform independent and gnuplot-only (bit more complicated) solution is the following.
You load the files 1:1 into datablocks and print these datablocks into a new datablock by appending each line. Assumption is of course that the two files have the same number of lines.
Code:
### plot data from different files combined with mathematical operation
# platform independent gnuplot-only solution
reset session
Windows = GPVAL_SYSNAME[:7] eq "Windows" ? 1 : 0 # otherwise Linux or MacOS
FILE = "first.dat"
Data = "$Data1"
if (Windows) { load '< echo '.Data.' ^<^<EOD & type "'.FILE.'"' }
else { load '< echo "\'.Data.' <<EOD" & cat "'.FILE.'"' }
FILE = "second.dat"
Data = "$Data2"
if (Windows) { load '< echo '.Data.' ^<^<EOD & type "'.FILE.'"' }
else { load '< echo "\'.Data.' <<EOD" & cat "'.FILE.'"' }
set print $Data
do for [i=1:|$Data1|] {
print $Data1[i][1:strlen($Data1[i])-1]."\t".$Data2[i]
}
set print
splot $Data u 1:2:($3*$6)
### end of code

Minimal self-compiling to .pdf Rmarkdown file

I need to compose a simple rmarkdown file, with text, code and the results of executed code included in a resulting PDF file. I would prefer if the source file is executable and self sifficient, voiding the need for a makefile.
This is the best I have been able to achieve, and it is far from good:
#!/usr/bin/env Rscript
library(knitr)
pandoc('hw_ch4.rmd', format='latex')
# TODO: how to NOT print the above commands to the resulting .pdf?
# TODO: how to avoid putting everyting from here on in ""s?
# TODO: how to avoid mentioning the file name above?
# TODO: how to render special symbols, such as tilde, miu, sigma?
# Unicode character (U+3BC) not set up for use with LaTeX.
# See the inputenc package documentation for explanation.
# nano hw_ch4.rmd && ./hw_ch4.rmd && evince hw_ch4.pdf
"
4E1. In the model definition below, which line is the likelihood?
A: y_i is the likelihood, based on the expectation and deviation.
4M1. For the model definition below, simulate observed heights from the prior (not the posterior).
A:
```{r}
points <- 10
rnorm(points, mean=rnorm(points, 0, 10), sd=runif(points, 0, 10))
```
4M3. Translate the map model formula below into a mathematical model definition.
A:
```{r}
flist <- alist(
y tilda dnorm( mu , sigma ),
miu tilda dnorm( 0 , 10 ),
sigma tilda dunif( 0 , 10 )
)
```
"
Result:
What I eventually came to use is the following header. At first it sounded neat, but later I realized
+ is indeed easy to compile in one step
- this is code duplication
- mixing executable script and presentation data in one file is a security risk.
Code:
#!/usr/bin/env Rscript
#<!---
library(rmarkdown)
argv <- commandArgs(trailingOnly=FALSE)
fname <- sub("--file=", "", argv[grep("--file=", argv)])
render(fname, output_format="pdf_document")
quit(status=0)
#-->
---
title:
author:
date: "compiled on: `r Sys.time()`"
---
The quit() line is supposed to guarantee that the rest of the file is treated as data. The <!--- and --> comments are to render the executable code as comments in the data interpretation. They are, in turn, hidden by the #s from the shell.

How can I save input to a file?

I use gforth running on linux boxes.
For one of my mini-applications I want to register a formatted text output from a few different user inputs.
Here is the INPUT$ I use:
: INPUT$
pad swap accept pad swap ;
I think this is correct. I tested it this way:
cr ." enter something : " 4 INPUT$ CR
enter something : toto
ok
cr ." enter something : " 8 INPUT$ CR
enter something : titi
ok
.S <4> 140296186274576 4 140296186274576 4 ok
My file definition:
256 Constant max-line
Create line-buffer max-line 2 + allot
//prepare file for Write permissions :
s" foo.out" w/o create-file throw Value fd-out
: close-output ( -- ) fd-out close-file throw ;
The end goal is to build very small files as:
data1;data2;data3
data4;data5;data6
where each data is the user input (asked 3times to insert text & a second wave of 3 inputs)
I did not find documentation about how I can use text inputs to build my file.
How can I call my stack data to copy them to the text file format? (using type will only echo texts to my terminal)
I think you are looking for the Forth write-file and write-line words, which are documented here: https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/General-files.html
write-file ( c-addr u fileid -– ior )
write-line ( c-addr u fileid –- ior )
Pass the address and length of your text buffer, and the file ID (fd-out in your example) to write text to the file. The ior result will be zero on success.

R simplify heatmap to pdf

I want to plot a simplified heatmap that is not so difficult to edit with the scalar vector graphics program I am using (inkscape). The original heatmap as produced below contains lots of rectangles, and I wonder if they could be merged together in the different sectors to simplify the output pdf file:
nentries=100000
ci=rainbow(nentries)
set.seed=1
mean=10
## Generate some data (4 factors)
i = data.frame(
a=round(abs(rnorm(nentries,mean-2))),
b=round(abs(rnorm(nentries,mean-1))),
c=round(abs(rnorm(nentries,mean+1))),
d=round(abs(rnorm(nentries,mean+2)))
)
minvalue = 10
# Discretise values to 1 or 0
m0 = matrix(as.numeric(i>minvalue),nrow=nrow(i))
# Remove rows with all zeros
m = m0[rowSums(m0)>0,]
# Reorder with 1,1,1,1 on top
ms =m[order(as.vector(m %*% matrix(2^((ncol(m)-1):0),ncol=1)), decreasing=TRUE),]
rowci = rainbow(nrow(ms))
colci = rainbow(ncol(ms))
colnames(ms)=LETTERS[1:4]
limits=c(which(!duplicated(ms)),nrow(ms))
l=length(limits)
toname=round((limits[-l]+ limits[-1])/2)
freq=(limits[-1]-limits[-l])/nrow(ms)
rn=rep("", nrow(ms))
for(i in toname) rn[i]=paste(colnames(ms)[which(ms[i,]==1)],collapse="")
rn[toname]=paste(rn[toname], ": ", sprintf( "%.5f", freq ), "%")
heatmap(ms,
Rowv=NA,
labRow=rn,
keep.dendro = FALSE,
col=c("black","red"),
RowSideColors=rowci,
ColSideColors=colci,
)
dev.copy2pdf(file="/tmp/file.pdf")
Why don't you try RSvgDevice? Using it you could save your image as svg file, which is much convenient to Inkscape than pdf
I use the Cairo package for producing svg. It's incredibly easy. Here is a much simpler plot than the one you have in your example:
require(Cairo)
CairoSVG(file = "tmp.svg", width = 6, height = 6)
plot(1:10)
dev.off()
Upon opening in Inkscape, you can ungroup the elements and edit as you like.
Example (point moved, swirl added):
I don't think we (the internet) are being clear enough on this one.
Let me just start off with a successful export example
png("heatmap.png") #Ruby dev's think of this as kind of like opening a `File.open("asdfsd") do |f|` block
heatmap(sample_matrix, Rowv=NA, Colv=NA, col=terrain.colors(256), scale="column", margins=c(5,10))
dev.off()
The dev.off() bit, in my mind, reminds me of an end call to a ruby block or method, in that, the last line of the "nested" or enclosed (between png() and dev.off()) code's output is what gets dumped into the png file.
For example, if you ran this code:
png("heatmap4.png")
heatmap(sample_matrix, Rowv=NA, Colv=NA, col=terrain.colors(32), scale="column", margins=c(5,15))
heatmap(sample_matrix, Rowv=NA, Colv=NA, col=greenred(32), scale="column", margins=c(5,15))
dev.off()
it would output the 2nd (greenred color scheme, I just tested it) heatmap to the heatmap4.png file, just like how a ruby method returns its last line by default

plotting 3D bar graph in matlab or excel

I need to plot a 3D bar graph in matlab or excel. I am going to use some dates in x-axis, time in y-axis and some amount on the z-axis. Each record in csv file looks like ...
18-Apr, 21, 139.45
I am not sure how to do this right. can anyone help me please. I tried using pivort chart of excel. however, i could not manipulate the axis and use appropriate space between each tick.
thanks
kaisar
Since the question is lacking details, let me illustrate with an example.
Consider the following code:
%# read file contents: date,time,value
fid = fopen('data.csv','rt');
C = textscan(fid, '%s %s %f', 'Delimiter',',');
fclose(fid);
%# correctly reshape the data, and extract x/y labels
num = 5;
d = reshape(C{1},num,[]); d = d(1,:);
t = reshape(C{2},num,[]); t = t(:,1);
Z = reshape(C{3},num,[]);
%# plot 3D bars
bar3(Z)
xlabel('date'), ylabel('time'), zlabel('value')
set(gca, 'XTickLabel',d, 'YTickLabel',t)
I ran on the following data file:
data.csv
18-Apr,00:00,0.85535
18-Apr,03:00,0.38287
18-Apr,06:00,0.084649
18-Apr,09:00,0.73387
18-Apr,12:00,0.33199
19-Apr,00:00,0.83975
19-Apr,03:00,0.37172
19-Apr,06:00,0.82822
19-Apr,09:00,0.17652
19-Apr,12:00,0.12952
20-Apr,00:00,0.87988
20-Apr,03:00,0.044079
20-Apr,06:00,0.68672
20-Apr,09:00,0.73377
20-Apr,12:00,0.43717
21-Apr,00:00,0.37984
21-Apr,03:00,0.97966
21-Apr,06:00,0.39899
21-Apr,09:00,0.44019
21-Apr,12:00,0.15681
22-Apr,00:00,0.32603
22-Apr,03:00,0.31406
22-Apr,06:00,0.8945
22-Apr,09:00,0.24702
22-Apr,12:00,0.31068
23-Apr,00:00,0.40887
23-Apr,03:00,0.70801
23-Apr,06:00,0.14364
23-Apr,09:00,0.87132
23-Apr,12:00,0.083156
24-Apr,00:00,0.46174
24-Apr,03:00,0.030389
24-Apr,06:00,0.7532
24-Apr,09:00,0.70004
24-Apr,12:00,0.21451
25-Apr,00:00,0.6799
25-Apr,03:00,0.55729
25-Apr,06:00,0.85068
25-Apr,09:00,0.55857
25-Apr,12:00,0.90177
26-Apr,00:00,0.41952
26-Apr,03:00,0.35813
26-Apr,06:00,0.48899
26-Apr,09:00,0.25596
26-Apr,12:00,0.92917
27-Apr,00:00,0.46676
27-Apr,03:00,0.25401
27-Apr,06:00,0.43122
27-Apr,09:00,0.70253
27-Apr,12:00,0.40233
Use MATLAB's CSV reading functions (or write your own) and then use bar3 to display the data.

Resources