遥感数据处理系列
一些项目及科研中遇到的小需求,一方面记录自己的学习历程,另一方面帮助大家学习。
ArcPy批量计算栅格数据平均值
GLDAS数据下载及处理(NC转TIF)
ArcGIS批量裁剪栅格数据
前言
遥感常用的IDL语言?如何节约数据处理的计算时间?如何跑满CPU充分利用PC算力?那么,一个NB的批处理脚本派上了用场!祭出IDL~
在使用IDL跑模型时发现:即使是一个费时的工作,但其对CPU和内存的使用仅占了约10%,这是因为线性逻辑循环导致的顺序数据处理。那么,并行计算,不就可以跑满CPU和内存条了吗?一个多线程或是多进程的思路浮现脑海,跃然电脑上~
一、IDL多进程
1. 原理简介
IDL多进程主要使用其IDL_IDLBridge函数。
IDL处理数据时仅在一个进程进行,不利于充分利用PC的CPU算力。那么在异步计算是可以考虑使用多进程来加速数据处理,IDL_IDLBridge可以在一个IDL进程正在等待的同时完成更多的处理。
函数使用:
compile_opt idl2
obridge = obj_new('IDL_IDLBridge')
childprofile1='Full path to your IDL file'
obridge->Execute,'.compile "'+childprofile1+'"'
obridge->Execute,'IDL file name',/NOWAIT
常用参数简介:
compile_opt:给IDL编译器一些改变编译过程的默认信息(不用管它)
obj_new():初始化一个IDL_IDLBridge对象,控制对应IDL子进程
Execute:执行IDL子进程中的IDL命令
/NOWAIT:异步操作是通过NOWAIT关键字指定的,用于异步执行耗时命令
基本逻辑如图所示:
简述为:
创建IDL_IDLBridge对象 -> 通过Execute方法开启IDL子进程
2. 代码
代码实例:
pro MultiProcesses
;开启3个进程同时处理数据
compile_opt idl2
obridge1 = obj_new('IDL_IDLBridge')
childprofile1='F:\Mekong_MultiRun\mekong_2010.pro'
obridge1->Execute,'.compile "'+childprofile1+'"'
obridge1->Execute,'mekong_2010',/NOWAIT
obridge2 = obj_new('IDL_IDLBridge')
childprofile2='F:\Mekong_MultiRun\mekong_2011.pro'
obridge2->Execute,'.compile "'+childprofile2+'"'
obridge2->Execute,'mekong_2011',/NOWAIT
obridge3 = obj_new('IDL_IDLBridge')
childprofile3='F:\Mekong_MultiRun\mekong_2012.pro'
obridge3->Execute,'.compile "'+childprofile3+'"'
obridge3->Execute,'np_mekong_2012',/NOWAIT
END
上例可实现对Mekong_MultiRun文件夹下的三个IDL文件的同时执行,及开启三个子进程同时处理数据。
子进程代码实例:
pro Mekong_2010
;子进程1
; 以下代码目的为:说明子进程文件格式与常规代码相同
;计算植被指数NDVI
;算整个文件夹
compile_opt strictarr
COMPILE_OPT idl2
envi, /restore_base_save_files
envi_batch_init, log_file='batch.txt',/NO_STATUS_WINDOW
dir1='F:\MODIS09-17\500m\b1\2010' ;输入路径,红波段。 直接写文件夹的路径。文件夹内存放 红波段 数据
dir2='F:\MODIS09-17\500m\b2\2010' ;输入路径,近红外波段。 存放 近红外波段 数据的文件夹路径
out_dir='F:\MODIS09-17\500m\NDVI\2010' ;输出路径
files1=file_search(dir1,'*.tif')
files2=file_search(dir2,'*.tif')
for i=0,n_elements(files1)-1 do begin
ENVI_OPEN_FILE, files1[i], r_fid=fid, /no_realize
ENVI_FILE_QUERY, fid, nl=nl, ns=ns,dims=dims,nb=nb
mapinfo=envi_get_map_info(fid=fid)
mapinfo1=mapinfo
file1=ENVI_GET_DATA(fid=fid,dims=dims,pos=0)
low_row=N_elements(file1[0,*]);获取行数
low_col=N_elements(file1[*,0]);获取列数
ndvi=make_array(low_col,low_row,value=0.0)
ENVI_OPEN_FILE, files2[i], r_fid=fid, /no_realize
ENVI_FILE_QUERY, fid, nl=nl, ns=ns,dims=dims,nb=nb
file2=ENVI_GET_DATA(fid=fid,dims=dims,pos=0)
for a=0,low_col-1 do begin;获取列数
for b=0,low_row-1 do begin;获取行数,应该是先列后行
if file1[a,b] LE 0 || file2[a,b] LE 0 then begin
ndvi[a,b]=-2
endif else begin
if (double(file2[a,b])+double(file1[a,b])) eq 0 then begin
ndvi[a,b]=-2
endif else begin
ndvi[a,b]=(double(file2[a,b])-double(file1[a,b]))/(double(file2[a,b])+double(file1[a,b]))
endelse
endelse
endfor
endfor
outfile8=out_dir+'\'+strmid(file_basename(files1[i]),0,25)+'.NDVI.tif' ;16 25
ENVI_WRITE_ENVI_FILE,ndvi,r_fid=fid,map_info=MapInfo1,out_name=outfile8
endfor
END
子进程的具体内容与平时的IDL文件相同,不用刻意讲究语法,但要注意该方法适用于异步场景,多个子进程之间尽量不要共用文件,以免造成进程阻塞。
3. 查看进程
进程启动后,在IDL中无法直接看到是否运行,需要到 “任务管理器 -> 性能 -> 打开资源监视器”查看进程,运行实例如下图所示:
总结
ArcPy牛皮!毕业万岁!中期快乐!
常规的数据处理用不到本文方法,但是,费时的操作可就是IDL多进程真香喽~
后记
写博客的初衷是分享我的一些经验,同时也方便自己在其他电脑上进行数据处理。帮了很多人,但评论区小伙伴也有遇到问题的,那么:知识付费,我的时间和经验正好可以解决你的问题。