;+ ; ; @todo seb ; ;- ; le format netcdf et IDL nous permet d''aller lire uniquement la partie de ; tableau qui nous interesse. ; ; attention, qd il y a un shift il faut faire attention a ce que ; l''on fait et en particulier arriver a positionner la boite ; specifiee par firstx:lastx par rapport au tableau contenu dans ; le fichier netCDF. ; pour s''y reperer voici un petit dessin ; ; dans le repere 0:jpi, avec le zoom definit par firstx:lastx ; ; 0 j key-1 key i jpi-1 ; |......|........| |-----------|----------------| ; ; si on veut savoir comment c''etait avant le shift: ; ; 0 i-key jpi-key-1 jpi-key jpi-key+j jpi-1 ; |--------|--------------| |........|..........| ; ; avant que l''on ajuste au zoom definit par ixminmesh,ixmaxmesh c''etait: ; ; 0 ixmin i-key jpi-key-1 jpi-key jpi-key+j jpi-1 jpidta ; +ixmin +ixmin +ixmin +ixmin +ixmin ; |,,,,|--------|--------------| |........|..........|,,,,,,,,,,,| ; ; après il suffit de remplacer i et j par firstx ou lastx qd on ; ne fait pas de stride. ; ; When using stride, things are getting more complicated.... ; ; 1) when must replace firstx by firstx*key_stride[0] and ; lastx by lastx*key_stride[0] ; 2) we must use jpitotal instead of jpi ; 3) finding the position of the offset in the right side part is ; tricky. look at this illustration of stride = 4 ... ; 0 j key-1 key i jpi-1 ; +...+..|+...+...+ |--+---+---+|--+---+---+---+-| ; ; 0 i-key jpi-key-1 jpi-key jpi-key+j jpi-1 ; |--+---+---+|--+---+---+---+-| +...+..|+...+...+ ; in the ........ part, it is easy the first point is number 0 but in ; the --------- part the first point is number 3... The position of ; the first point in the is given by: ; (key_stride[0]-1)-((key-1) MOD key_stride[0]) ; 4) last point...by default, the number of element read by IDL when ; using stride is given by n_elements/stride. However, we must read: ; (n_elements+stride-1)/stride or (n_elements-1)/key_stride+1 ; for example: for n_elements between 10 and 12, with a stride of 3, ; we must read 4 points instead of 3...: +--+--+--+-- ; This problem as an easy solution by using the keyword count with ; the appropriate value! ; key_shift = long(testvar(var = key_shift)) ; IF n_elements(key_yreverse) EQ 0 THEN key_yreverse = 0 IF keyword_set(key_yreverse) THEN BEGIN tmp = jpj-1-firsty firsty = jpj-1-lasty lasty = tmp ENDIF ; IF n_elements(key_zreverse) EQ 0 THEN key_zreverse = 0 IF keyword_set(key_zreverse) THEN BEGIN tmp = jpk-1-firstz firstz = jpk-1-lastz lastz = tmp ENDIF ; IF (key_gridtype EQ 'c_u' OR key_gridtype EQ 'c_f' OR key_gridtype EQ 'c_ff') $ AND (vargrid EQ 'U' OR vargrid EQ 'F') THEN BEGIN IF keyword_set(key_periodic) THEN BEGIN key_shift = key_shift-1 ENDIF ELSE BEGIN firstx = firstx+1 lastx = lastx+1 ENDELSE ENDIF IF (key_gridtype EQ 'c_v' OR key_gridtype EQ 'c_f' OR key_gridtype EQ 'c_ff') $ AND (vargrid EQ 'V' OR vargrid EQ 'F') THEN BEGIN firsty = firsty+1 lasty = lasty+1 ENDIF ; ixmin = ixminmesh-ixmindta iymin = iyminmesh-iymindta izmin = izminmesh-izmindta jpitotal = long(ixmaxmesh-ixminmesh+1) key = long(key_shift MOD jpitotal) if key LT 0 then key = key+jpitotal ; case 1 OF ;...................................................................... ;...................................................................... varinq.ndims eq 2:BEGIN ;xy array ;...................................................................... ;...................................................................... case 1 OF ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) EQ 3:BEGIN ; on ne shift pas et il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx+ixmin,firsty+iymin] $ ,count=[nx,ny] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) NE 3:BEGIN ; on ne shift pas mais il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx*key_stride[0]+ixmin $ ,firsty*key_stride[1]+iymin] $ ,count=[nx,ny], stride = key_stride[0:1] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) EQ 3:BEGIN ; on shift mais il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 of ; --------- part, we can directly extract the array in one piece firstx GE key:BEGIN ncdf_varget,cdfid,name,res,offset=[ixmin-key+firstx $ ,firsty+iymin] $ ,count=[nx,ny] END ; ......... part, we can directly extract the array in one piece lastx LE key-1:BEGIN ncdf_varget,cdfid,name,res,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin] $ ,count=[nx,ny] END ELSE:BEGIN ; we have to extract the array in 2 pieces... ; ......... part, first part... ncdf_varget,cdfid,name,tab1,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin] $ ,count=[key-1-firstx+1,ny] ; --------- part, second part... ncdf_varget,cdfid,name,tab2,offset=[ixmin,firsty+iymin] $ ,count=[lastx-key+1,ny] res = [temporary(tab1), temporary(tab2)] END ENDCASE END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) NE 3:BEGIN ; on shift et il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 OF ; case sur la facon de fire le champ ; --------- part, we can directly extract the array in one piece firstx*key_stride[0] GE key:BEGIN ncdf_varget,cdfid,name,res,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ +(firstx-((key-1)/key_stride[0]+1))*key_stride[0] $ ,firsty*key_stride[1]+iymin] $ ,count=[nx,ny], stride = key_stride[0:1] END ; ......... part, we can directly extract the array in one piece lastx*key_stride[0] LE key-1:BEGIN ncdf_varget,cdfid,name,res,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin] $ ,count=[nx,ny], stride = key_stride[0:1] END ELSE:BEGIN ; we have to extract the array in 2 pieces... ; ......... part, first part... ncdf_varget,cdfid,name,tab1,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin] $ ,count=[(key-firstx*key_stride[0]-1)/key_stride[0]+1,ny] $ , stride = key_stride[0:1] ; --------- part, second part... ncdf_varget,cdfid,name,tab2,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ , firsty*key_stride[1]+iymin] $ ,count=[nx-(key-firstx*key_stride[0]-1)/key_stride[0]-1,ny] $ , stride = key_stride[0:1] ; in one unique array... res = [temporary(tab1), temporary(tab2)] END ENDCASE ; case sur la facon de fire le champ END ENDCASE ; differentes possibilites de key_shift et key_performance END ;...................................................................... ;...................................................................... varinq.ndims eq 3 AND (where(varinq.dim EQ inq.recdim))[0] EQ -1:BEGIN ;xyz array ;...................................................................... ;...................................................................... case 1 of ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) EQ 3:BEGIN ; on ne shift pas et il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx+ixmin,firsty+iymin,firstz+izmin] $ ,count=[nx,ny,nz] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) NE 3:BEGIN ; on ne shift pas mais il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx*key_stride[0]+ixmin $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin] $ ,count=[nx,ny,nz], stride = key_stride END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) EQ 3:BEGIN ; on shift mais il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 of firstx GE key:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[ixmin-key+firstx $ ,firsty+iymin $ ,firstz+izmin] $ ,count=[nx,ny,nz] END lastx LE key-1:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin $ ,firstz+izmin] $ ,count=[nx,ny,nz] END ELSE:BEGIN ; Le tableau est separe en 2 morceaux... ncdf_varget,cdfid,name,tab1,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin $ ,firstz+izmin] $ ,count=[key-1-firstx+1,ny,nz] ncdf_varget,cdfid,name,tab2,offset=[ixmin $ ,firsty+iymin $ ,firstz+izmin] $ ,count=[lastx-key+1,ny,nz] res = [temporary(tab1), temporary(tab2)] END ENDCASE END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) NE 3:BEGIN ; on shift et il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 OF ; case sur la facon de fire le champ firstx*key_stride[0] GE key:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ +(firstx-((key-1)/key_stride[0]+1))*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin] $ ,count=[nx,ny,nz], stride = key_stride END lastx*key_stride[0] LE key-1:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin] $ ,count=[nx,ny,nz], stride = key_stride END ELSE:BEGIN ; le tableau est separe en 2 morceaux... ncdf_varget,cdfid,name,tab1,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin] $ ,count=[(key-firstx*key_stride[0]-1)/key_stride[0]+1,ny,nz] $ , stride = key_stride ; 2eme bout... ncdf_varget,cdfid,name,tab2,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin] $ ,count=[nx-(key-firstx*key_stride[0]-1)/key_stride[0]-1,ny,nz] $ , stride = key_stride ; on recolle le tout res = [temporary(tab1), temporary(tab2)] END ENDCASE ; case sur la facon de fire le champ END ENDCASE ; differentes possibilites de key_shift et key_performance END ;...................................................................... ;...................................................................... varinq.ndims eq 3 AND (where(varinq.dim EQ inq.recdim))[0] NE -1:BEGIN ;xyt array ;...................................................................... ;...................................................................... case 1 of ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) EQ 3:BEGIN ; on ne shift pas et il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx+ixmin $ ,firsty+iymin $ ,firsttps] $ ,count=[nx,ny,jpt] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) NE 3:BEGIN ; on ne shift pas mais il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx*key_stride[0]+ixmin $ ,firsty*key_stride[1]+iymin $ ,firsttps] $ ,count=[nx,ny,jpt], stride = [key_stride[0:1], 1] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) EQ 3:BEGIN ; on shift mais il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 of ; --------- part, we can directly extract the array in one piece firstx GE key:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[ixmin-key+firstx $ ,firsty+iymin $ ,firsttps] $ ,count=[nx,ny,jpt] END ; ......... part, we can directly extract the array in one piece lastx LE key-1:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin $ ,firsttps] $ ,count=[nx,ny,jpt] END ELSE:BEGIN ; Le tableau est separe en 2 morceaux... ; ......... part, first part... ncdf_varget,cdfid,name,tab1,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin $ ,firsttps] $ ,count=[key-1-firstx+1,ny,jpt] ; --------- part, second part... ncdf_varget,cdfid,name,tab2,offset=[ixmin $ ,firsty+iymin $ ,firsttps] $ ,count=[lastx-key+1,ny,jpt] res = [temporary(tab1), temporary(tab2)] END ENDCASE END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) NE 3:BEGIN ; on shift et il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, ; --------- part, we can directly extract the array in one piece case 1 OF ; case sur la facon de fire le champ firstx*key_stride[0] GE key:BEGIN ncdf_varget,cdfid,name,res,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ +( firstx-((key-1)/key_stride[0]+1) )*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firsttps] $ ,count=[nx,ny,jpt], stride = [key_stride[0:1], 1] END ; ......... part, we can directly extract the array in one piece lastx*key_stride[0] LE key-1:BEGIN ncdf_varget,cdfid,name,res,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firsttps] $ ,count=[nx,ny,jpt], stride = [key_stride[0:1], 1] END ELSE:BEGIN ; ......... part, first part... ncdf_varget,cdfid,name,tab1,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firsttps] $ ,count=[(key-firstx*key_stride[0]-1)/key_stride[0]+1,ny,jpt] $ , stride = [key_stride[0:1], 1] ; --------- part, second part... ncdf_varget,cdfid,name,tab2,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ , firsty*key_stride[1]+iymin $ ,firsttps] $ ,count=[nx-(key-firstx*key_stride[0]-1)/key_stride[0]-1,ny,jpt] $ , stride = [key_stride[0:1], 1] ; on recolle le tout res = [temporary(tab1), temporary(tab2)] END ENDCASE ; case sur la facon de fire le champ END endcase END ;...................................................................... ;...................................................................... varinq.ndims eq 4:BEGIN ;xyzt array ;...................................................................... ;...................................................................... case 1 of ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) EQ 3:BEGIN ; on ne shift pas et il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx+ixmin $ ,firsty+iymin $ ,firstz+izmin $ ,firsttps] $ ,count=[nx,ny,nz,jpt] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) EQ 0 AND total(key_stride) NE 3:BEGIN ; on ne shift pas mais il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, ncdf_varget,cdfid,name,res,offset=[firstx*key_stride[0]+ixmin $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin $ ,firsttps] $ ,count=[nx,ny,nz,jpt], stride = [key_stride, 1] END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) EQ 3:BEGIN ; on shift mais il n''y a pas de stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 of firstx GE key:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[ixmin-key+firstx $ ,firsty+iymin $ ,firstz+izmin $ ,firsttps] $ ,count=[nx,ny,nz,jpt] END lastx LE key-1:BEGIN ; on peut tout couper d''un coup ncdf_varget,cdfid,name,res,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin $ ,firstz+izmin $ ,firsttps] $ ,count=[nx,ny,nz,jpt] END ELSE:BEGIN ; Le tableau est separe en 2 morceaux... ncdf_varget,cdfid,name,tab1,offset=[jpi-key+ixmin+firstx $ ,firsty+iymin $ ,firstz+izmin $ ,firsttps] $ ,count=[key-1-firstx+1,ny,nz,jpt] ncdf_varget,cdfid,name,tab2,offset=[ixmin $ ,firsty+iymin $ ,firstz+izmin $ ,firsttps] $ ,count=[lastx-key+1,ny,nz,jpt] res = [temporary(tab1), temporary(tab2)] END ENDCASE END ;,,,,,,,,,,,,,,,,,,,,,,,, keyword_set(key_shift) NE 0 AND total(key_stride) NE 3:BEGIN ; on shift et il y a un stride ;,,,,,,,,,,,,,,,,,,,,,,,, case 1 OF ; case sur la facon de fire le champ firstx*key_stride[0] GE key:BEGIN ; on peut tout coupe d''un coup ncdf_varget,cdfid,name,res,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ +(firstx-((key-1)/key_stride[0]+1))*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin $ ,firsttps] $ ,count=[nx,ny,nz,jpt], stride = [key_stride, 1] END lastx*key_stride[0] LE key-1:BEGIN ; on peut tout coupe d''un coup ncdf_varget,cdfid,name,res,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin $ ,firsttps] $ ,count=[nx,ny,nz,jpt], stride = [key_stride, 1] END ELSE:BEGIN ; le tableau est separe en 2 morceaux... ncdf_varget,cdfid,name,tab1,offset=[jpitotal-key+ixmin+firstx*key_stride[0] $ ,firsty*key_stride[1]+iymin $ ,firstz*key_stride[2]+izmin $ ,firsttps] $ ,count=[(key-firstx*key_stride[0]-1)/key_stride[0]+1,ny,nz,jpt] $ , stride = [key_stride, 1] ; 2eme bout... ncdf_varget,cdfid,name,tab2,offset=[ixmin $ +(key_stride[0]-1)-((key-1) MOD key_stride[0]) $ , firsty*key_stride[1]+iymin $ , firstz*key_stride[2]+izmin $ , firsttps] $ ,count=[nx-(key-firstx*key_stride[0]-1)/key_stride[0]-1,ny,nz,jpt] $ , stride = [key_stride, 1] ; on recolle le tout res = [temporary(tab1), temporary(tab2)] END ENDCASE ; case sur la facon de fire le champ END endcase END ENDCASE ; we apply reverse IF keyword_set(key_yreverse) AND ny NE 1 THEN BEGIN IF varinq.ndims - ((where(varinq.dim EQ inq.recdim))[0] NE -1) EQ 2 THEN $ res = reverse(reform(res, nx, ny, jpt, /overwrite), 2) $ ELSE res = reverse(reform(res, nx, ny, nz, jpt, /overwrite), 2) ENDIF if keyword_set(key_zreverse) AND nz NE 1 $ AND varinq.ndims - ((where(varinq.dim EQ inq.recdim))[0] NE -1) EQ 3 THEN $ res = reverse(reform(res, nx, ny, nz, jpt, /overwrite), 3) ; IF (key_gridtype EQ 'c_u' OR key_gridtype EQ 'c_f') AND keyword_set(key_periodic) $ AND (strupcase(vargrid) EQ 'U' OR strupcase(vargrid) EQ 'F') THEN key_shift = key_shift+1