Как определить каждый исходный файл при объединении множества файлов netcdf с помощью ncrcat?

Я объединяю тысячи nc-файлов (результаты моделирования), чтобы мне было легче обрабатывать их в Matlab. Для этого я использую ncrcat. Файлы имеют разные размеры, и переменная времени не уникальна для файлов. Конкатенация работает хорошо и позволяет мне читать данные в Matlab намного быстрее, чем индивидуальное чтение файлов. Однако я хочу иметь возможность идентифицировать исходный NC-файл, из которого происходит каждая точка данных. Можно ли, скажем, добавить имя исходного файла в качестве дополнительной переменной, чтобы я мог отслеживать данные?


person Chris Coffey    schedule 10.06.2019    source источник


Ответы (2)


Самый простой способ: онлайн-индексирование

Прежде чем мы начнем, я бы использовал целочисленный индекс, а не имя файла для идентификации каждого запуска, так как с ним намного проще работать как для записи, так и для обработки в программе Matlab. Вместо простого монотонно увеличивающегося индекса идентификатор может иметь отношение к вашему запуску (или вы даже можете при необходимости написать несколько отдельных индексов (например, у вас может быть номер для разрешения, даты, версии модели и т. Д.).

Итак, очевидный способ сделать это, который я могу придумать, - это то, что каждая симуляция записывает индекс в файл, чтобы идентифицировать себя. то есть при первом запуске модели будет записана переменная

myrun=1

секунда

myrun=2

и так далее ... затем, когда вы катите файлы, данные можно очень легко однозначно идентифицировать с помощью этого индекса.

Обратите внимание: если ваши пространственные измерения не уникальны и количество временных шагов также меняется от запуска к запуску в зависимости от того, что вы пишете, ваш индекс должен быть функцией всех неуникальных измерений, например мирун (х, у, т). Если какое-либо из ваших измерений уникально для всех файлов, то это измерение является избыточным в индексе и может быть опущено.

Конечно, единственная проблема с этим решением заключается в том, что оно означает повторный запуск моделирования :-D, и вы можете говорить о дорогостоящей модели для запуска или о чьих-то запусках, которые вы не можете повторить. Если о повторном запуске не может быть и речи, вам нужно будет попробовать добавить индекс в автономном режиме ...

Автономное индексирование (проще, если сетки одинаковые, иначе сложнее)

ЕСЛИ размер вашего пространства был одинаковым для всех файлов, то это все еще простая задача, поскольку вы можете очень легко добавить индекс в автономном режиме для всех временных шагов в каждом файле, используя nco:

ncap2 -s 'myrun[$time]=array(X,0,$time)' infile.nc  outfile.nc

или если вы готовы перезаписать исходный файл (будьте осторожны!)

ncap2 -O -s 'myrun[$time]=array(X,0,$time)'

где X - номер серии. Это добавит переменную с новой переменной myrun, которая является функцией времени, а затем поместит X на каждом шаге. Когда вы объединяете, вы можете увидеть, какой срез данных был из какого конкретного прогона.

Кстати, второй ноль - это приращение, поскольку оно установлено на ноль, число X будет записано для всех временных шагов в данном файле (в противном случае, если бы оно было равно 1, индекс увеличивался бы на единицу на каждом временном шаге - это может быть полезно в некоторых случаях (например, вы можете использовать два индекса: один с нулевым приращением для идентификации цикла, а второй - с приращением единицы, чтобы легко сказать, к какому шагу X-го прогона принадлежит срез данных).

Если ваши файлы тоже относятся к разным доменам, то, возможно, вы захотите поместить их в общую сетку, прежде чем делать это ... Я думаю, что для этого

cdo enlarge 

может помочь, см. этот пост: https://code.mpimet.mpg.de/boards/2/topics/1459.

person Adrian Tompkins    schedule 11.06.2019
comment
Во-первых, спасибо за такой исчерпывающий ответ. Очень признателен. В моем случае повторный запуск обходится слишком дорого. Но я рассмотрю этот подход в следующий раз. Однако пространственный домен во всех файлах идентичен, поэтому ваше второе решение выглядит так, как будто оно будет работать. Сегодня вечером я попробую, доложу о своем успехе и подтвердю ваш ответ. - person Chris Coffey; 11.06.2019

Я согласен с тем, что индекс будет проще, чем имя файла. Я бы просто добавил к приведенному выше ответу, что команду добавления уникального индекса X с измерением времени для каждого входного файла можно упростить до

ncap2 -s 'myrun[$time]=X' in.nc out.nc
person Charlie Zender    schedule 11.06.2019
comment
Спасибо, Чарли, мне кажется, я всегда нахожу способы чрезмерно усложнить использование NCO ;-) - person Adrian Tompkins; 12.06.2019
comment
привет Чарли, быстрое разъяснение вашего ответа, если я хочу установить X как переменную bash, например $ x, то одинарные кавычки не будут работать, поскольку они переводятся буквально. Если я использую двойные кавычки: ncap2 -s myrun [$ time] = $ {x} in.nc out.nc, бит $ time прерывается, т.е. я могу добавить постоянную метку, но не в зависимости от измерения времени. Есть идеи, как это обойти? - person Adrian Tompkins; 29.07.2019
comment
Привет, Адриан, Да, попробуйте ncap2 -s myrun [\ $ time] = $ {x} in.nc out.nc - person Charlie Zender; 07.08.2019