;+ ; ; @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 ; |,,,,|--------|--------------| |........|..........|,,,,,,,,,,,| ; ; apres 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... Ihe 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 appropiate value! ; 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 ;...................................................................... ;...................................................................... varcontient.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], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ; --------- part, second part... ncdf_varget,cdfid,name,tab2,offset=[ixmin,firsty+iymin] $ ,count=[lastx-key+1,ny], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ; --------- 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], _extra = ex ; 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 ;...................................................................... ;...................................................................... varcontient.ndims eq 3 AND (where(varcontient.dim EQ contient.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], _extra = ex 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, _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ncdf_varget,cdfid,name,tab2,offset=[ixmin $ ,firsty+iymin $ ,firstz+izmin] $ ,count=[lastx-key+1,ny,nz], _extra = ex 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, _extra = ex 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, _extra = ex 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, _extra = ex ; 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, _extra = ex ; 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 ;...................................................................... ;...................................................................... varcontient.ndims eq 3 AND (where(varcontient.dim EQ contient.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], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ; --------- part, second part... ncdf_varget,cdfid,name,tab2,offset=[ixmin $ ,firsty+iymin $ ,firsttps] $ ,count=[lastx-key+1,ny,jpt], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ; --------- 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], _extra = ex ; on recolle le tout res = [temporary(tab1), temporary(tab2)] END ENDCASE ; case sur la facon de fire le champ END endcase END ;...................................................................... ;...................................................................... varcontient.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], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ncdf_varget,cdfid,name,tab2,offset=[ixmin $ ,firsty+iymin $ ,firstz+izmin $ ,firsttps] $ ,count=[lastx-key+1,ny,nz,jpt], _extra = ex 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], _extra = ex 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], _extra = ex 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], _extra = ex ; 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], _extra = ex ; on recolle le tout res = [temporary(tab1), temporary(tab2)] END ENDCASE ; case sur la facon de fire le champ END endcase END endcase