2017-01-05 9 views
0

필자의 두뇌 티저에 대해 필자는 문서 및 메일 링리스트 아카이브를 잠시 검색했으며이 집계를 처리하는 데 필요한 단계를 맞추는 데 어려움을 겪고 있습니다. 여기서Java NetCDF : 기존 파일 집계 : 시간 차원을 찾을 수 없음 문제

CFSR 1시간 데이터 파일의 데이터 : http://rda.ucar.edu/datasets/ds094.0/

cdas_20161215_0000_f00000_G4.grib2 
cdas_20161215_0000_f00100_G4 
cdas_20161215_0000_f00200_G4 
cdas_20161215_0000_f00300_G4 
etc... 

시간당 파일 2 개 시간 기준없이 설정 범위와, 다른 하나를 선언한다.

cdas_20161215_0000_f00300_G4.grib2 
double time(time=1); 
    :units = "Hour since 2016-12-15T00:00:00Z"; 
    :standard_name = "time"; 
    :long_name = "GRIB forecast or observation time"; 
    :calendar = "proleptic_gregorian"; 
    :bounds = "time_bounds"; 
double time_bounds(time=1, 2); 
    :units = "Hour since 2016-12-15T00:00:00Z"; 
    :long_name = "bounds for time"; 
double time1(time1=1); 
    :units = "Hour since 2016-12-15T00:00:00Z"; 
    :standard_name = "time"; 
    :long_name = "GRIB forecast or observation time"; 
    :calendar = "proleptic_gregorian"; 

문제는 내가 각 데이터 세트 생성을 단계별로 할 때, 서로 다른 시간마다 파일이 2 시간 차원 이름에 대한 이름을 바꿀 것입니다. 따라서 AggregationExisting은 특정 파일에 대해 '시간'이라는 차원 이름을 찾을 수 없습니다. 0300 파일의 u-component_of_wind_isobaric 변수에 대신 time1로 선언 되었기 때문입니다.

코드 나 전화 해요 :

List<String> variableNames = Arrays.asList("u-component_of_wind_isobaric","u-component_of_wind_height_above_ground","v-component_of_wind_isobaric","v-component_of_wind_height_above_ground","Pressure_reduced_to_MSL_msl","Geopotential_height_isobaric"); 
NetcdfDataset netcdfDataset = new NetcdfDataset(); 
//here i'm trying to aggregate on a dimension called 'time' 
AggregationExisting aggregationExisting = new AggregationExisting(netcdfDataset, "time", null); 
aggregationExisting.addDatasetScan(null, 
        "/cfsr-gribs/201612/", 
        "G4.grib2", 
        null, 
        null, 
        NetcdfDataset.getDefaultEnhanceMode(), 
        "false", 
        null); 
aggregationExisting.persistWrite(); 
aggregationExisting.finish(new CancelTaskImpl()); 
GridDataset gridDataset = new GridDataset(netcdfDataset); 
writer.setRedefineMode(true); 
CFGridWriter2.writeFile(gridDataset, variableNames, gridDataset.getBoundingBox(), null, 1, null, null, 1, true, writer); 

시간 차원 이름 문제는이 개 파일에 예시 :

//cdas_20161215_0000_f00300_G4.grib2 

float u-component_of_wind_isobaric(time1=1, isobaric3=37, lat=361, lon=720); 
    :long_name = "u-component of wind @ Isobaric surface"; 
    :units = "m/s"; 
    :abbreviation = "UGRD"; 
    :missing_value = NaNf; // float 
    :grid_mapping = "LatLon_Projection"; 
    :coordinates = "reftime time1 isobaric3 lat lon "; 
    :Grib_Variable_Id = "VAR_0-2-2_L100"; 
    :Grib2_Parameter = 0, 2, 2; // int 
    :Grib2_Parameter_Discipline = "Meteorological products"; 
    :Grib2_Parameter_Category = "Momentum"; 
    :Grib2_Parameter_Name = "u-component of wind"; 
    :Grib2_Level_Type = "Isobaric surface"; 
    :Grib2_Generating_Process_Type = "Forecast"; 


//cdas_20161215_0000_f00200_G4.grib2 

float u-component_of_wind_isobaric(time=1, isobaric3=37, lat=361, lon=720); 
    :long_name = "u-component of wind @ Isobaric surface"; 
    :units = "m/s"; 
    :abbreviation = "UGRD"; 
    :missing_value = NaNf; // float 
    :grid_mapping = "LatLon_Projection"; 
    :coordinates = "reftime time isobaric3 lat lon "; 
    :Grib_Variable_Id = "VAR_0-2-2_L100"; 
    :Grib2_Parameter = 0, 2, 2; // int 
    :Grib2_Parameter_Discipline = "Meteorological products"; 
    :Grib2_Parameter_Category = "Momentum"; 
    :Grib2_Parameter_Name = "u-component of wind"; 
    :Grib2_Level_Type = "Isobaric surface"; 
    :Grib2_Generating_Process_Type = "Forecast"; 

이 그래서 몇 가지 전처리 도구를 물색하고있어 처음 netCDF의 라이브러리 사용하는 것입니다 이 데이터 세트를 병합하여이 특이한 점을 얻으십시오. 모든 변수를 같은 시간 차원으로 이동하고 이름을 바꿀 수 있습니까? 내가 놓친 예제에 대한 링크조차 도움이 될 것입니다. 그렇지 않으면 수동으로 치수를 스탬핑하고 readDataSlice()를 사용하여 데이터를 수동으로 새 병합 파일에 복사하는 방법을 살펴볼 것입니다.

답변

1

자바가 아닌 도구를 사용하는 경우에는 NCO을 확인하는 것이 좋습니다.

먼저 wgrib2 유틸리티 (예 : here) 또는 ncl_convert2nc을 사용하여 grib에서 netcdf로 변환해야합니다.

두 번째로 해당 netcdf 파일을 반복하는 간단한 스크립트를 개발하고 time1이 차원 이름으로 존재하는지 확인하고, 그렇다면 time으로 이름을 변경하십시오. ,

ncrename -d time1,time file.nc file.nc 

셋째 (이제 모든 파일에 존재한다) time 레코드 차원 있는지 확인하십시오 : NCO의 ncrename 도구는이 작업을 수행 할 수 있습니다.

ncrcat cdas*.nc all_files.nc 

참고 : 기록 (time) 크기에 따라 파일을 연결하는 NCO의 ncrcat를 사용, 마지막으로

ncks --mk_rec_dmn time file.nc 

: 그렇지 않은 경우의 너무 NCO의 ncks 도구를 사용하여 만들어 보자 당신이 필요 없어 위의 줄에 와일드 카드를 사용하면 연결하려는 파일 목록을 포함시킬 수 있습니다.

ncrcat cdas_20161215_0000_f00000_G4.nc cdas_20161215_0000_f00100_G4.nc all_files.nc 
+0

감사합니다! 이것은 Java 파이프 라인에있을 것이므로 Netcdf-Java 접근법을 고수해야했습니다. –

0

그래서 Grib2가 현재 AggregationExisting에서 작동하지 않는 다른 짐승 인 Ucar로부터 응답을 받았습니다. 그들의 THREDDS 서버 제품은 Grib2 파일을위한 기능을 가지고 있으므로 몇 가지 다른 클래스가 있습니다. GribCollectionImmutable.

여기에 그들이 나를 위해 큰 일을이 방법에 권장 내용은 다음과 같습니다 응답에 대한

 List<String> variableNames = Arrays.asList("u-component_of_wind_isobaric","u-component_of_wind_height_above_ground","v-component_of_wind_isobaric","v-component_of_wind_height_above_ground","Pressure_reduced_to_MSL_msl","Geopotential_height_isobaric"); 
     FeatureCollectionType fcType = FeatureCollectionType.GRIB2; 
     Path outputPath = Paths.get("/cfsr/Netcdf4/201612/Cfsr_201612_Monthly.nc"); 
     String dataDir = "/cfsr-gribs/201612/"; 
     String spec = dataDir + ".*grib2$"; 
     String timePartition = "file"; 
     String dateFormatMark = null; 
     String olderThan = null; 
     Element innerNcml = null; 
     String path = dataDir; 
     String name = "cfsr"; 
     String collectionName = "cfsrCollection"; 

     //find and configure the folder as a grib collection 
     FeatureCollectionConfig fcc = new FeatureCollectionConfig(name, path, fcType, spec, 
       collectionName, dateFormatMark, olderThan, timePartition, innerNcml); 

     try (GribCollectionImmutable gc = GribCdmIndex.openGribCollection(fcc, null, log)) { 
      //had to breakpoint and see the dataset typenames to choose 'TP', could be different for each dataset 
      GribCollectionImmutable.Dataset ds = gc.getDatasetByTypeName("TP"); 
      String fullCollectionIndexFilePath = dataDir + name + ".ncx3"; 
      // now we open the collection index file, which catalogs all of the grib 
      // records in your collection 
      NetcdfDataset ncd = gc.getNetcdfDataset(ds, ds.getGroup(0), fullCollectionIndexFilePath, 
        fcc, null, log); 
      try (NetcdfFileWriter writer = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf4, 
        outputPath.toString(), new Nc4ChunkingDefault())) { 
       GridDataset gridDataset = new GridDataset(ncd); 
       for (String variableName : variableNames) { 
        GeoGrid grid = gridDataset.findGridByShortName(variableName); 
        //Check that the time dimension is the length you'd expect 
        log.info(String.format("Found grid for : %s = %s, with dimension length %s", variableName, grid != null, grid != null ? grid.getDimension(0).getLength() : 0)); 
       } 
       writer.setRedefineMode(true); 
       //write the aggregated variables to my output file 
       CFGridWriter2.writeFile(gridDataset, variableNames, gridDataset.getBoundingBox(), null, 1, null, null, 1, true, writer); 
      } catch (Exception exc) { 
       exc.printStackTrace(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     }