HIMAWARIのアジア・オセアニア広域データです。3000×3000格子で、本ページの共通例として使用します。
衛星コレクション
タブを切り替えると、観測領域、格子、時間間隔、命名規則、収録データが衛星ごとに切り替わります。
まず見る:HIMAWARIデータの全体像
以下の地図を構成する一つひとつの格子に日射量などの数値が入り、その値が .bin ファイルへ順番に格納されています。各格子の緯度・経度は、データ本体と同じ配列形状を持つ別の lat / lng ファイルで与えられます。ファイル名と対応関係は「緯度・経度ファイル」を参照してください。
日本域。3001×2521格子の1 kmデータです。
衛星の2.5分間隔スキャンに対応する日本域データです。
アジア・オセアニア広域データ
fld.4km:東経85度から西経155度、北緯60度から南緯60度、3000×3000格子。緯度・経度の対応付け:この格子を解析するときは、データ本体と同じ配列形状を持つ lat / lng ファイルを組み合わせて使用します。対応するファイル名と読み方は「緯度・経度ファイル」を参照してください。
fld.4km の地表面下向き日射量クイックルック。右側に要素コード、観測時刻、単位、表示範囲、格子数、色の読み方を示します。日本域データ
msm.1km と2.5分毎の jp01.1km~jp04.1km に共通する領域です。東経120–150度、北緯47.6–22.4度、3001×2521格子。緯度・経度の対応付け:msm.1km と jp01.1km~jp04.1km は共通の日本域格子です。データ本体と同じ配列形状を持つ lat / lng ファイルを組み合わせて使用します。詳しくは「緯度・経度ファイル」を参照してください。
msm.1km の地表面下向き日射量クイックルック。3001×2521格子のデータが10分毎に作成されます。
jp01.1km のクイックルックを代表例として表示しています。右側では、jp01~jp04 が同じ基準時刻から0分、2.5分、5分、7.5分に対応することを説明しています。まず見る:METEOSAT-IODCデータの全体像
インド洋域を対象とするコレクションです。0.03°格子、4000×4000格子、15分間隔で、ファイル名の領域・解像度表記は fld.3km です。各格子の緯度・経度は、対応する lat / lng ファイルで与えられます。ファイル名と対応関係は「緯度・経度ファイル」を参照してください。
4000×4000格子。格子中心は北緯59.985度から南緯59.985度、西経17.485度から東経102.485度です。
fld.3km:西経17.5度から東経102.5度、北緯60度から南緯60度、4000×4000格子。緯度・経度の対応付け:この格子を解析するときは、データ本体と同じ配列形状を持つMETEOSAT-IODC用の lat / lng ファイルを組み合わせて使用します。対応するファイル名と読み方は「緯度・経度ファイル」を参照してください。
fld.3km の地表面下向き日射量クイックルック。右側に要素コード、観測時刻、単位、表示範囲、格子数、色の読み方を示します。HIMAWARIMETEOSAT-IODC:まず日射量を読む
最も利用者の多い日射量を代表例として、データの意味から読み出しまでを順に説明します。
HIMAWARIコレクション — 3000×3000格子のアジア・オセアニア広域を共通例として説明し、その後に日本域と2.5分間隔の日本域を示します。
METEOSAT-IODCコレクション — 4000×4000格子のインド洋域 fld.3km を共通例として説明します。
日射量データ
地表面下向き日射量(全天日射量)
地表面に到達する下向き短波放射。直達成分と散乱成分の合計です。
W/m²地表面直達日射量
太陽方向から直接地表面へ到達する短波放射成分です。
W/m²地表面散乱日射量
大気や雲による散乱を経て地表面へ到達する短波放射成分です。
W/m²大気上端下向き日射量
大気上端(TOA)における下向き短波放射です。
W/m²ファイル名の読み方
HIMAWARIでは、3000×3000格子のアジア・オセアニア広域4 km地表面下向き日射量を代表例にします。
METEOSAT-IODCでは、4000×4000格子のインド洋域3 km地表面下向き日射量を代表例にします。
YYYYMMDDHHMN(年・月・日・時・分)です。2023-07-13 02:00 UTC
地表面下向き日射量
アジア・オセアニア広域
YYYY=年、MM=月、DD=日、HH=時、MN=分(UTC)
日射量ファイルの例
202307130200.dwn.sw.flx.sfc.fld.4km.bin202307130200.dwn.sw.flx.sfc.tdir.fld.4km.bin202307130200.dwn.sw.flx.sfc.scat.fld.4km.bin202307130200.dwn.sw.flx.toa.fld.4km.bin同じファイル名に .png を付加した .bin.png は内容確認用のクイックルック画像です。数値解析には .bin を使用します。
2026-07-13 09:12 UTC
地表面下向き日射量
インド洋域
YYYY=年、MM=月、DD=日、HH=時、MN=分(UTC)
日射量ファイルの例
202607130912.dwn.sw.flx.sfc.fld.3km.bin202607130912.dwn.sw.flx.sfc.tdir.fld.3km.bin202607130912.dwn.sw.flx.sfc.scat.fld.3km.bin202607130912.dwn.sw.flx.toa.fld.3km.bin同じファイル名に .png を付加した .bin.png は内容確認用のクイックルック画像です。数値解析には .bin を使用します。
バイナリ形式と格納順序
202307130200.dwn.sw.flx.sfc.fld.4km.bin を例に、数値表現と二次元格子の格納方向を示します。
202607130912.dwn.sw.flx.sfc.fld.3km.bin を例に、数値表現と二次元格子の格納方向を示します。
fld.4km は3000×3000格子で、3000 × 3000 × 4 byte = 36,000,000 byte です。実際の fld.3km は4000×4000格子で、4000 × 4000 × 4 byte = 64,000,000 byte です。 index = row × NX + column緯度・経度ファイル
各領域には、データ格子と一対一に対応する緯度ファイル(lat)と経度ファイル(lng)があります。いずれもヘッダなし、Big-endian、IEEE 754 Float32(1値4 byte)です。データ本体と同じ形状・格納順序なので、同じ [row, column] にある lat、lng、データ値が同一格子点を表します。
| コレクション | 座標ファイル | 配列形状(row, column) | 格子中心座標 | 1ファイル |
|---|---|---|---|---|
| HIMAWARI アジア・オセアニア広域 | standard_3000x3000.lat.fld.4km.binstandard_3000x3000.lng.fld.4km.bin | 3000 × 3000 | 緯度:59.98 → −59.98° 経度:85.02 → 204.98°E 刻み:0.04° | 36,000,000 byte |
| HIMAWARI 日本域 | standard_2521x3001.lat.msm.1km.binstandard_2521x3001.lng.msm.1km.bin | 2521 × 3001 | 緯度:47.595 → 22.395°N 経度:119.995 → 149.995°E 刻み:0.01° | 30,262,084 byte |
| METEOSAT-IODC インド洋域 | standard_4000x4000.iodc.42.5.lat.fld.3km.binstandard_4000x4000.iodc.42.5.lng.fld.3km.bin | 4000 × 4000 | 緯度:59.985 → −59.985° 経度:342.515 → 102.485°E(360°で折返し) = 17.485°W → 102.485°E 刻み:0.03° | 64,000,000 byte |
上表の座標は領域境界ではなく格子中心です。配列は行優先で、各行を西から東へ読み、行は北から南へ進みます。
ピクセル観測時刻ファイル
ひまわり8号・9号では、衛星の走査により、同じ画像内でもピクセルごとに実際の観測時刻が異なります。この差を扱うため、日射量などのデータ本体と同じ格子配列を持つ観測時刻ファイルを収録しています。METEOSAT-IODCコレクションには、このファイルはありません。
| 項目 | 仕様 |
|---|---|
| 要素コード | grd.time.mjd.hms |
| 数値型 | IEEE 754 Float32(1値4 byte) |
| バイトオーダー | Big-endian |
| ヘッダ | なし |
| 格子形状・格納順序 | 対応するデータ本体および緯度・経度ファイルと同一 |
| 配布時の圧縮 | bzip2(.bz2)。展開後が .bin 本体 |
| 格子値の単位 | 日(1日=1.0、1秒=1/86400日) |
mjd.hms という名称ですが、各格子値は完全なMJDそのものではありません。ファイル名に示されたUTC日付の00:00を基準とする経過時間を、日単位で格納しています。
| 領域 | 時刻ファイル名 | 配列形状 | 展開後サイズ | 時間構成 |
|---|---|---|---|---|
| アジア・オセアニア広域 | …grd.time.mjd.hms.fld.4km.bin | 3000 × 3000 | 36,000,000 byte | 10分毎 |
| 日本域 | …grd.time.mjd.hms.msm.1km.bin | 2521 × 3001 | 30,262,084 byte | 10分毎 |
| 日本域・高頻度観測 | …grd.time.mjd.hms.jp01.1km.bin~ …jp04.1km.bin | 2521 × 3001 | 各30,262,084 byte | 10分の基準時刻ごとに4走査 (2.5分間隔) |
使用手順
bzip2 -dkなどで.bz2を展開します。- データ本体と同じ配列形状で、Big-endian Float32として時刻ファイルを読みます。
- データ値、
lat、lng、timeの同じ[row, column]を対応付けます。 - 上式により、そのピクセルの実観測時刻をUTCの年月日時分秒へ変換します。
上表の座標は領域境界ではなく格子中心です。配列は行優先で、各行を西から東へ読み、行は北から南へ進みます。経度は0–360度表記で格納され、西経側は342.515°E(=17.485°W)から始まり、0°を越えて102.485°Eまで続きます。
読み出しサンプル
202307130200.dwn.sw.flx.sfc.fld.4km.bin(3000×3000格子)を読むコードを言語別に追加します。
202607130912.dwn.sw.flx.sfc.fld.3km.bin(4000×4000格子)を読むコードを言語別に追加します。
掲載順は、大量データの継続処理に向く言語を先にしています。すべての例で、先頭ピクセルを [1][1] とし、データ、緯度、経度、時刻を同じ添字で対応付ける方針です。
Java:HIMAWARI fld.4km クリックしてソースを展開
HIMAWARI fld.4km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
/** AMATERASS HIMAWARI fld.4km 読み出し例。配列は意図的に1始まりとし、先頭ピクセルを [1][1] にします。 */
public final class AmaterassPickup {
private static final int NX = 3000;
private static final int NY = 3000;
private static final long EXPECTED_BYTES = (long) NX * NY * Float.BYTES;
public static void main(String[] args) throws IOException {
if (args.length != 6) {
System.err.println("Usage: java -Xmx512m AmaterassPickup DATA.bin LAT.bin LNG.bin TIME.bin LATITUDE LONGITUDE");
System.exit(1);
}
float[][] data = readGrid(Path.of(args[0]));
float[][] lat = readGrid(Path.of(args[1]));
float[][] lon = readGrid(Path.of(args[2]));
float[][] time = readGrid(Path.of(args[3]));
double targetLat = Double.parseDouble(args[4]);
double targetLon = normalizeLon(Double.parseDouble(args[5]));
Pixel p = nearest(lat, lon, targetLat, targetLon);
System.out.printf("pixel = [%d][%d]%n", p.row, p.column);
System.out.printf("latitude = %.6f deg%n", lat[p.row][p.column]);
System.out.printf("longitude = %.6f deg%n", lon[p.row][p.column]);
System.out.printf("solar flux = %.3f W/m^2%n", data[p.row][p.column]);
double elapsedSeconds = time[p.row][p.column] * 86400.0;
System.out.printf("elapsed UTC seconds from filename date 00:00 = %.3f%n", elapsedSeconds);
}
private static float[][] readGrid(Path file) throws IOException {
if (Files.size(file) != EXPECTED_BYTES) throw new IOException("Unexpected file size: " + file);
float[][] grid = new float[NY + 1][NX + 1]; // index 0 is unused
ByteBuffer bytes = ByteBuffer.allocateDirect(NX * Float.BYTES).order(ByteOrder.BIG_ENDIAN);
try (FileChannel channel = FileChannel.open(file, StandardOpenOption.READ)) {
for (int row = 1; row <= NY; row++) {
bytes.clear();
while (bytes.hasRemaining()) if (channel.read(bytes) < 0) throw new EOFException(file.toString());
bytes.flip();
FloatBuffer values = bytes.asFloatBuffer();
values.get(grid[row], 1, NX);
}
}
return grid;
}
private static Pixel nearest(float[][] lat, float[][] lon, double targetLat, double targetLon) {
int bestRow = 1, bestColumn = 1;
double best = Double.POSITIVE_INFINITY;
for (int row = 1; row <= NY; row++) for (int column = 1; column <= NX; column++) {
double dLat = lat[row][column] - targetLat;
double dLon = Math.abs(normalizeLon(lon[row][column]) - targetLon);
dLon = Math.min(dLon, 360.0 - dLon);
double d2 = dLat * dLat + dLon * dLon;
if (d2 < best) { best = d2; bestRow = row; bestColumn = column; }
}
return new Pixel(bestRow, bestColumn);
}
private static double normalizeLon(double lon) {
double value = lon % 360.0;
return value < 0.0 ? value + 360.0 : value;
}
private record Pixel(int row, int column) {}
}
Java:METEOSAT-IODC fld.3km クリックしてソースを展開
METEOSAT-IODC fld.3km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
/** AMATERASS METEOSAT-IODC fld.3km 読み出し例。配列は意図的に1始まりとし、先頭ピクセルを [1][1] にします。 */
public final class AmaterassPickupIodc {
private static final int NX = 4000;
private static final int NY = 4000;
private static final long EXPECTED_BYTES = (long) NX * NY * Float.BYTES;
public static void main(String[] args) throws IOException {
if (args.length != 5) {
System.err.println("Usage: java -Xmx512m AmaterassPickupIodc DATA.bin LAT.bin LNG.bin LATITUDE LONGITUDE");
System.exit(1);
}
float[][] data = readGrid(Path.of(args[0]));
float[][] lat = readGrid(Path.of(args[1]));
float[][] lon = readGrid(Path.of(args[2]));
double targetLat = Double.parseDouble(args[3]);
double targetLon = normalizeLon(Double.parseDouble(args[4]));
Pixel p = nearest(lat, lon, targetLat, targetLon);
System.out.printf("pixel = [%d][%d]%n", p.row, p.column);
System.out.printf("latitude = %.6f deg%n", lat[p.row][p.column]);
System.out.printf("longitude = %.6f deg%n", lon[p.row][p.column]);
System.out.printf("solar flux = %.3f W/m^2%n", data[p.row][p.column]);
}
private static float[][] readGrid(Path file) throws IOException {
if (Files.size(file) != EXPECTED_BYTES) throw new IOException("Unexpected file size: " + file);
float[][] grid = new float[NY + 1][NX + 1]; // index 0 is unused
ByteBuffer bytes = ByteBuffer.allocateDirect(NX * Float.BYTES).order(ByteOrder.BIG_ENDIAN);
try (FileChannel channel = FileChannel.open(file, StandardOpenOption.READ)) {
for (int row = 1; row <= NY; row++) {
bytes.clear();
while (bytes.hasRemaining()) if (channel.read(bytes) < 0) throw new EOFException(file.toString());
bytes.flip();
FloatBuffer values = bytes.asFloatBuffer();
values.get(grid[row], 1, NX);
}
}
return grid;
}
private static Pixel nearest(float[][] lat, float[][] lon, double targetLat, double targetLon) {
int bestRow = 1, bestColumn = 1;
double best = Double.POSITIVE_INFINITY;
for (int row = 1; row <= NY; row++) for (int column = 1; column <= NX; column++) {
double dLat = lat[row][column] - targetLat;
double dLon = Math.abs(normalizeLon(lon[row][column]) - targetLon);
dLon = Math.min(dLon, 360.0 - dLon);
double d2 = dLat * dLat + dLon * dLon;
if (d2 < best) { best = d2; bestRow = row; bestColumn = column; }
}
return new Pixel(bestRow, bestColumn);
}
private static double normalizeLon(double lon) {
double value = lon % 360.0;
return value < 0.0 ? value + 360.0 : value;
}
private record Pixel(int row, int column) {}
}
C:HIMAWARI fld.4km クリックしてソースを展開
HIMAWARI fld.4km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define NX 3000
#define NY 3000
typedef float (*Grid)[NX + 1];
/* 添字0は意図的に使わず、先頭ピクセルを grid[1][1] とします。 */
static int little_endian(void) { const uint16_t x = 1; return *(const uint8_t *)&x; }
static float swap_float(float value) {
union { float f; uint8_t b[4]; } in = { .f = value }, out;
out.b[0]=in.b[3]; out.b[1]=in.b[2]; out.b[2]=in.b[1]; out.b[3]=in.b[0];
return out.f;
}
static Grid read_grid(const char *name) {
FILE *fp = fopen(name, "rb");
Grid grid = calloc(NY + 1, sizeof *grid);
if (!fp || !grid) { perror(name); exit(EXIT_FAILURE); }
for (int row = 1; row <= NY; row++) {
if (fread(&grid[row][1], sizeof(float), NX, fp) != NX) { fprintf(stderr, "Short file: %s\n", name); exit(EXIT_FAILURE); }
if (little_endian()) for (int column = 1; column <= NX; column++) grid[row][column] = swap_float(grid[row][column]);
}
if (fgetc(fp) != EOF) { fprintf(stderr, "File is larger than expected: %s\n", name); exit(EXIT_FAILURE); }
fclose(fp); return grid;
}
static double norm_lon(double x) { x = fmod(x, 360.0); return x < 0 ? x + 360.0 : x; }
int main(int argc, char **argv) {
if (argc != 7) { fprintf(stderr, "Usage: %s DATA.bin LAT.bin LNG.bin TIME.bin LATITUDE LONGITUDE\n", argv[0]); return EXIT_FAILURE; }
Grid data = read_grid(argv[1]);
Grid lat = read_grid(argv[2]);
Grid lon = read_grid(argv[3]);
Grid time = read_grid(argv[4]);
double target_lat = strtod(argv[5], NULL), target_lon = norm_lon(strtod(argv[6], NULL));
int best_row = 1, best_column = 1; double best = HUGE_VAL;
for (int row = 1; row <= NY; row++) for (int column = 1; column <= NX; column++) {
double dlat = lat[row][column] - target_lat;
double dlon = fabs(norm_lon(lon[row][column]) - target_lon); dlon = fmin(dlon, 360.0 - dlon);
double d2 = dlat*dlat + dlon*dlon;
if (d2 < best) { best=d2; best_row=row; best_column=column; }
}
int row=best_row, column=best_column;
printf("pixel = [%d][%d]\n", row, column);
printf("latitude = %.6f deg\n", lat[row][column]);
printf("longitude = %.6f deg\n", lon[row][column]);
printf("solar flux = %.3f W/m^2\n", data[row][column]);
printf("elapsed UTC seconds from filename date 00:00 = %.3f\n", (double)time[row][column] * 86400.0);
free(data); free(lat); free(lon); free(time);
return EXIT_SUCCESS;
}
C:METEOSAT-IODC fld.3km クリックしてソースを展開
METEOSAT-IODC fld.3km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define NX 4000
#define NY 4000
typedef float (*Grid)[NX + 1];
/* 添字0は意図的に使わず、先頭ピクセルを grid[1][1] とします。 */
static int little_endian(void) { const uint16_t x = 1; return *(const uint8_t *)&x; }
static float swap_float(float value) {
union { float f; uint8_t b[4]; } in = { .f = value }, out;
out.b[0]=in.b[3]; out.b[1]=in.b[2]; out.b[2]=in.b[1]; out.b[3]=in.b[0];
return out.f;
}
static Grid read_grid(const char *name) {
FILE *fp = fopen(name, "rb");
Grid grid = calloc(NY + 1, sizeof *grid);
if (!fp || !grid) { perror(name); exit(EXIT_FAILURE); }
for (int row = 1; row <= NY; row++) {
if (fread(&grid[row][1], sizeof(float), NX, fp) != NX) { fprintf(stderr, "Short file: %s\n", name); exit(EXIT_FAILURE); }
if (little_endian()) for (int column = 1; column <= NX; column++) grid[row][column] = swap_float(grid[row][column]);
}
if (fgetc(fp) != EOF) { fprintf(stderr, "File is larger than expected: %s\n", name); exit(EXIT_FAILURE); }
fclose(fp); return grid;
}
static double norm_lon(double x) { x = fmod(x, 360.0); return x < 0 ? x + 360.0 : x; }
int main(int argc, char **argv) {
if (argc != 6) { fprintf(stderr, "Usage: %s DATA.bin LAT.bin LNG.bin LATITUDE LONGITUDE\n", argv[0]); return EXIT_FAILURE; }
Grid data = read_grid(argv[1]);
Grid lat = read_grid(argv[2]);
Grid lon = read_grid(argv[3]);
double target_lat = strtod(argv[4], NULL), target_lon = norm_lon(strtod(argv[5], NULL));
int best_row = 1, best_column = 1; double best = HUGE_VAL;
for (int row = 1; row <= NY; row++) for (int column = 1; column <= NX; column++) {
double dlat = lat[row][column] - target_lat;
double dlon = fabs(norm_lon(lon[row][column]) - target_lon); dlon = fmin(dlon, 360.0 - dlon);
double d2 = dlat*dlat + dlon*dlon;
if (d2 < best) { best=d2; best_row=row; best_column=column; }
}
int row=best_row, column=best_column;
printf("pixel = [%d][%d]\n", row, column);
printf("latitude = %.6f deg\n", lat[row][column]);
printf("longitude = %.6f deg\n", lon[row][column]);
printf("solar flux = %.3f W/m^2\n", data[row][column]);
free(data); free(lat); free(lon); return EXIT_SUCCESS;
}
Fortran:HIMAWARI fld.4km クリックしてソースを展開
HIMAWARI fld.4km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
program amaterass_pickup
use iso_fortran_env, only: real32, real64, error_unit
implicit none
integer, parameter :: NX=3000, NY=3000
real(real32), allocatable :: data(:,:), lat(:,:), lon(:,:), time
character(len=1024) :: arg(6)
integer :: i, row, col, best_row, best_col
real(real64) :: target_lat, target_lon, dlat, dlon, d2, best
! Fortran配列は自然に1始まりで、先頭ピクセルは (1,1) です。
if (command_argument_count() /= 6) error stop 'Invalid number of arguments'
do i=1,6; call get_command_argument(i,arg(i)); end do
allocate(data(NY,NX), lat(NY,NX), lon(NY,NX), time(NY,NX))
call read_grid(trim(arg(1)), data)
call read_grid(trim(arg(2)), lat)
call read_grid(trim(arg(3)), lon)
call read_grid(trim(arg(4)), time)
read(arg(5),*) target_lat; read(arg(6),*) target_lon
target_lon = modulo(target_lon,360.0_real64)
best=huge(best); best_row=1; best_col=1
do row=1,NY
do col=1,NX
dlat=real(lat(row,col),real64)-target_lat
dlon=abs(modulo(real(lon(row,col),real64),360.0_real64)-target_lon); dlon=min(dlon,360.0_real64-dlon)
d2=dlat*dlat+dlon*dlon
if (d2<best) then; best=d2; best_row=row; best_col=col; end if
end do
end do
print '(A,I0,A,I0,A)', 'pixel = [',best_row,'][',best_col,']'
print '(A,F12.6)', 'latitude = ',lat(best_row,best_col)
print '(A,F12.6)', 'longitude = ',lon(best_row,best_col)
print '(A,F12.3)', 'solar flux = ',data(best_row,best_col)
print '(A,F12.3)', 'elapsed UTC seconds from filename date 00:00 = ', real(time(best_row,best_col),real64)*86400.0_real64
contains
subroutine read_grid(name,grid)
character(len=*),intent(in)::name
real(real32),intent(out)::grid(NY,NX)
real(real32)::row_values(NX)
integer::u,r,stat
open(newunit=u,file=name,access='stream',form='unformatted',status='old',action='read',convert='big_endian')
do r=1,NY
read(u,iostat=stat) row_values
if(stat/=0) error stop 'Unexpected end of file'
grid(r,1:NX)=row_values
end do
close(u)
end subroutine
end program
Fortran:METEOSAT-IODC fld.3km クリックしてソースを展開
METEOSAT-IODC fld.3km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
program amaterass_pickup_iodc
use iso_fortran_env, only: real32, real64, error_unit
implicit none
integer, parameter :: NX=4000, NY=4000
real(real32), allocatable :: data(:,:), lat(:,:), lon(:,:)
character(len=1024) :: arg(5)
integer :: i, row, col, best_row, best_col
real(real64) :: target_lat, target_lon, dlat, dlon, d2, best
! Fortran配列は自然に1始まりで、先頭ピクセルは (1,1) です。
if (command_argument_count() /= 5) error stop 'Invalid number of arguments'
do i=1,5; call get_command_argument(i,arg(i)); end do
allocate(data(NY,NX), lat(NY,NX), lon(NY,NX))
call read_grid(trim(arg(1)), data)
call read_grid(trim(arg(2)), lat)
call read_grid(trim(arg(3)), lon)
read(arg(4),*) target_lat; read(arg(5),*) target_lon
target_lon = modulo(target_lon,360.0_real64)
best=huge(best); best_row=1; best_col=1
do row=1,NY
do col=1,NX
dlat=real(lat(row,col),real64)-target_lat
dlon=abs(modulo(real(lon(row,col),real64),360.0_real64)-target_lon); dlon=min(dlon,360.0_real64-dlon)
d2=dlat*dlat+dlon*dlon
if (d2<best) then; best=d2; best_row=row; best_col=col; end if
end do
end do
print '(A,I0,A,I0,A)', 'pixel = [',best_row,'][',best_col,']'
print '(A,F12.6)', 'latitude = ',lat(best_row,best_col)
print '(A,F12.6)', 'longitude = ',lon(best_row,best_col)
print '(A,F12.3)', 'solar flux = ',data(best_row,best_col)
contains
subroutine read_grid(name,grid)
character(len=*),intent(in)::name
real(real32),intent(out)::grid(NY,NX)
real(real32)::row_values(NX)
integer::u,r,stat
open(newunit=u,file=name,access='stream',form='unformatted',status='old',action='read',convert='big_endian')
do r=1,NY
read(u,iostat=stat) row_values
if(stat/=0) error stop 'Unexpected end of file'
grid(r,1:NX)=row_values
end do
close(u)
end subroutine
end program
Python:HIMAWARI fld.4km クリックしてソースを展開
HIMAWARI fld.4km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
from pathlib import Path
import sys
import numpy as np
NX, NY = 3000, 3000
def read_grid(path: Path) -> np.ndarray:
raw = np.fromfile(path, dtype=">f4")
if raw.size != NX * NY:
raise ValueError(f"unexpected size: {path} ({raw.size} values)")
grid = np.empty((NY + 1, NX + 1), dtype=np.float32)
grid[0, :] = np.nan; grid[:, 0] = np.nan
grid[1:, 1:] = raw.reshape(NY, NX)
return grid
def main() -> None:
# 添字0は意図的に使わず、先頭ピクセルを grid[1, 1] とします。
if len(sys.argv) != 7:
raise SystemExit("invalid number of arguments")
data = read_grid(Path(sys.argv[1]))
lat = read_grid(Path(sys.argv[2]))
lon = read_grid(Path(sys.argv[3]))
time = read_grid(Path(sys.argv[4]))
target_lat = float(sys.argv[5]); target_lon = float(sys.argv[6]) % 360.0
dlat = lat[1:, 1:] - target_lat
dlon = np.abs(np.mod(lon[1:, 1:], 360.0) - target_lon); dlon = np.minimum(dlon, 360.0 - dlon)
flat = int(np.nanargmin(dlat*dlat + dlon*dlon))
row0, col0 = np.unravel_index(flat, (NY, NX)); row, column = row0 + 1, col0 + 1
print(f"pixel = [{row}][{column}]")
print(f"latitude = {lat[row, column]:.6f} deg")
print(f"longitude = {lon[row, column]:.6f} deg")
print(f"solar flux = {data[row, column]:.3f} W/m^2")
print(f"elapsed UTC seconds from filename date 00:00 = {float(time[row, column]) * 86400.0:.3f}")
if __name__ == "__main__":
main()
Python:METEOSAT-IODC fld.3km クリックしてソースを展開
METEOSAT-IODC fld.3km専用。先頭ピクセルを1始まりで扱い、同じ添字でデータと座標を対応付けます。
from pathlib import Path
import sys
import numpy as np
NX, NY = 4000, 4000
def read_grid(path: Path) -> np.ndarray:
raw = np.fromfile(path, dtype=">f4")
if raw.size != NX * NY:
raise ValueError(f"unexpected size: {path} ({raw.size} values)")
grid = np.empty((NY + 1, NX + 1), dtype=np.float32)
grid[0, :] = np.nan; grid[:, 0] = np.nan
grid[1:, 1:] = raw.reshape(NY, NX)
return grid
def main() -> None:
# 添字0は意図的に使わず、先頭ピクセルを grid[1, 1] とします。
if len(sys.argv) != 6:
raise SystemExit("invalid number of arguments")
data = read_grid(Path(sys.argv[1]))
lat = read_grid(Path(sys.argv[2]))
lon = read_grid(Path(sys.argv[3]))
target_lat = float(sys.argv[4]); target_lon = float(sys.argv[5]) % 360.0
dlat = lat[1:, 1:] - target_lat
dlon = np.abs(np.mod(lon[1:, 1:], 360.0) - target_lon); dlon = np.minimum(dlon, 360.0 - dlon)
flat = int(np.nanargmin(dlat*dlat + dlon*dlon))
row0, col0 = np.unravel_index(flat, (NY, NX)); row, column = row0 + 1, col0 + 1
print(f"pixel = [{row}][{column}]")
print(f"latitude = {lat[row, column]:.6f} deg")
print(f"longitude = {lon[row, column]:.6f} deg")
print(f"solar flux = {data[row, column]:.3f} W/m^2")
if __name__ == "__main__":
main()
大量処理について: Python例はNumPyによる一括読み込みを前提にします。純粋なPythonのピクセル単位ループは避け、長期間・多数時刻の連続処理にはJava、C、Fortranを推奨します。
HIMAWARIMETEOSAT-IODC:その他のデータ
日射量に加えて収録されている派生データを、衛星コレクション別に示します。
派生データ・雲・地表気象
| 分類 | データ | 要素コード | 単位 |
|---|---|---|---|
| 太陽光発電 | 1 kWpあたりの推定太陽光発電出力 | unit.pvp.tc028.ac000.sfcunit.pvp.tc028.ac945.sfcunit.pvp.tc028.ac975.sfcunit.pvp.tc049.ac000.sfcunit.pvp.tc049.ac945.sfcunit.pvp.tc049.ac975.sfc | kW/kWp |
| 太陽光発電 | 発電量計算に使用する推定PVパネル温度 | noct | K |
| 雲 | 雲光学的厚さ(水雲仮定) | wtr.cld.tau | 無次元 |
| 雲 | 雲光学的厚さ(氷雲仮定) | ice.cld.tau | 無次元 |
| 雲 | 雲光学的厚さ(輝度温度に基づく雲相) | wi.cld.tau | 無次元 |
| 雲 | 雲頂高度 | wtr.cld.cth | km |
| 雲 | 雲頂気圧 | wtr.cld.ctp | hPa |
| 雲 | 雲頂温度 | wtr.cld.ctt | K |
| 雲 | 雲粒有効半径 | wtr.cld.eff | µm |
| 雲 | 雲水量 | wtr.cld.lwp | g/m² |
| 赤外差分 | 10.4 µm-12.3 µm 輝度温度差 | btd.tir1-tir3.tbb | K |
| 赤外差分 | 8.6 µm-11.2 µm 輝度温度差 | btd.tir9-tir2.tbb | K |
| 赤外差分 | 8.6 µm-12.3 µm 輝度温度差 | btd.tir9-tir3.tbb | K |
| 地表気象 | 地表面相対湿度 | rh.sfc | % |
| 地表気象 | 地表面気温 | tsfc | K |
| 地表気象 | 地表面風速 | wnd.spd.sfc | m/s |
日射量4種類、PV関連7種類、雲関連8種類、赤外輝度温度差3種類、地表気象3種類の計25種類です。地表気象3種類は fld.4km と msm.1km に、その他22種類は fld.4km、msm.1km、jp01.1km~jp04.1km に収録されています。
unit.pvp の読み方
unit.pvp は、1 kWpの太陽光発電設備を設置した場合の推定出力を表します。値が0.8なら、その時刻・格子において1 kWpの設備から約0.8 kW出力すると読みます。
unit.pvp.tc028.ac945.sfc = 温度係数 −0.28 %/°C、インバータ効率94.5%として計算した、1 kWpあたりの推定太陽光発電出力[kW/kWp]
tc049 は −0.49 %/°C、ac975 は97.5%、ac000 は100%の理想条件を表します。既存コード noct は、機器仕様値としてのNOCTではなく、各時刻・格子で発電量計算に使用する推定PVパネル温度[K]です。
太陽光発電出力
| 分類 | データ | 要素コード | 単位 |
|---|---|---|---|
| 太陽光発電 | 1 kWpあたりの推定太陽光発電出力 | unit.pvp.tc028.ac000.sfcunit.pvp.tc028.ac945.sfcunit.pvp.tc028.ac975.sfcunit.pvp.tc049.ac000.sfcunit.pvp.tc049.ac945.sfcunit.pvp.tc049.ac975.sfc | kW/kWp |
METEOSAT-IODCでは、日射量4種類に加え、温度係数2条件(tc028、tc049)とインバータ効率3条件(ac000、ac945、ac975)を組み合わせたPV出力6種類を収録しています。
unit.pvp の読み方
unit.pvp は1 kWpの太陽光発電設備を設置した場合の推定出力です。例えば値0.8は、その時刻・格子で約0.8 kW/kWpの出力を表します。
unit.pvp.tc028.ac945.sfc.fld.3km.bin = 温度係数−0.28 %/°C、インバータ効率94.5%として計算した、1 kWpあたりの推定太陽光発電出力