Текущая ситуация

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

Однако при анализе данных на компьютере вы ожидаете, что будете контролировать все переменные и сможете повторно запустить все, что вы сделали, одним нажатием кнопки. Правильно? Ну ... это сложно. Существует так много уровней программного обеспечения со сложными зависимостями, которые зависят от очень конкретных версий для работы, что очень сложно отслеживать все, и очень маловероятно, что старый код будет работать в новой среде (операционной системе и программном стеке).

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

Для получения более подробной информации я рекомендую проверить недавнюю запись в блоге К. Титуса Брауна об этой проблеме Как я научился перестать беспокоиться и полюбить приближающийся кризис архивируемости в научном программном обеспечении », а также забавную историческую перспективу того, как мы сюда попали, см. из выступления Джо Армстронга Мы в беспорядке.

Есть ли решение?

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

На уровне языка программирования

В настоящее время я использую менеджер пакетов каждого языка программирования, чтобы отслеживать конкретные версии используемых библиотек. В большинстве случаев лучшими инструментами (т.е. менее ошибочными) для установки библиотек для языка программирования являются те, которые использует язык (npm для JS, pip для Python и т. Д.). Итак, полагаясь на другой менеджер пакетов, который сделает эту работу (то есть на менеджер пакетов ОС), по моему опыту, вы получите больше проблем, чем оно того стоит. Однако иногда это может иметь недостатки для воспроизводимости (например, кризис левой панели в Node), и нам нужно быть осторожными.

По возможности мы должны включать исходный код наших зависимостей в наш проект и не полагаться на внешние источники. На таком языке, как R, управление версиями и создание моментальных снимков исходного кода зависимостей может быть затруднительным, но есть такие решения, как Packrat. В Node.JS вы можете легко управлять своими зависимостями с помощью package.jsonfile и npm shrinkwrap. В Python вы можете делать pip freeze > requirements.txt. Для обоих есть способы разместить свои собственные локальные репозитории.

На уровне операционной системы

Вместо того, чтобы полагаться на менеджер пакетов ОС (например, apt для Debian, rpm для Fedora) для отслеживания самих языков и всех других зависимостей (например, для некоторых языков требуются определенные версии Fortran, компилятор GCC и т. Д.), Я использую менеджер пакетов Nix. .

Nix - это функциональный менеджер пакетов, который обычно хранит пакеты в каталоге /nix. Каждый пакет имеет свой собственный уникальный подкаталог, например

/nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/

который является результатом хеширования графика зависимостей сборки пакета. Не волнуйтесь, вам не придется иметь дело непосредственно с этими путями, чтобы использовать установленные вами инструменты. Но это позволит вам выполнять детерминированные установки и использовать несколько версий одних и тех же инструментов без каких-либо конфликтов. И все зависимости изолированы внутри /nix, поэтому все, что вы устанавливаете, не будет зависеть от хост-системы (если у вас нет какой-либо зависимости на уровне ядра или прошивки, но у вас будет такая же проблема с контейнерами Docker).

Nix работает на Linux, Mac и bash последней предварительной версии Windows 10 Insiders.

Как связать все это на воспроизводимой бумаге

Поэтому для воспроизводимой среды используйте систему управления зависимостями каждого языка для модулей и библиотек. Затем используйте Nix для управления самими языками и любыми другими зависимостями уровня ОС. Но как сделать эксперимент / документ воспроизводимым? Как указать путь к результату, фигуре или сюжету? Вот тут-то и вступают в игру такие вещи, как интерактивные записные книжки (Jupyter / iPython, Beaker, nteract). В блогах есть множество сообщений о том, как их использовать. К сожалению, научная продукция по-прежнему в значительной степени зависит от статических документов (файлов PDF), а не от классных интерактивных самообновляющихся фигур. Так что в настоящее время для меня лучше всего использовать LaTeX (иногда Markdown) для набора текста и создания PDF-файла и KnitR для интеграции кода R, используемого для создания графиков в файле LaTeX. KnitR также позволяет вам встраивать другие языки в ваши бумажные файлы, такие как Python или JavaScript.

В следующем сообщении блога я покажу вам практический пример того, как это выглядит, следите за обновлениями!