Обо мне. Что-то типа CV.
Я увлекся компьютерами в 1993 году, началось все с игр на ZX-совместимом компьютере у друга, потом пробовал писать программы на Basic, затем в кодах/на ассемблере. Потом у меня появился компьютер "Львов ПК-01" на К580ВМ80А (аналог i8080), для которого игр было существенно меньше, чем для ZX, что стимулировало к низкоуровнему программированию. Затем в конце 1994 года мне купили/я собрал 286 с черно-белым монитором, там был QBasic, затем Pascal, затем C (и немного С++). Также я увлекался радиоэлектроникой, и после школы не мог выбрать между Матмехом УрГУ или Радиофаком УПИ, в итоге выбрал Физфак УрГУ, где защитил диссертацию в 2008 году.
Далее я работал сервисным инженером по разнообразному измерительному оборудованию, и стал, на мой взгляд, неплохим специалистом в том числе по спектральным методам (атомно-абсорбционные, атомно-эмиссионные (искровые, ИСП, тлеющего разряда), Фурье-, рентгенофлуоресцентые спектрометры), о которых сейчас пробую написать большой учебный курс.
18 лет преподавал на Физфаке УрГУ курсы Микропроцессорная техника, Информатика (Pascal/Delphi, для 1 курса), Вычислительные методы в теории конденсированного состояния, Стат.физика и даже Квантовая механика (для "вечерников").
Моим хобби была разработка Embedded устройств, с уклоном в измерительные и управляющие. Программировал микроконтроллеры, разрабатывал специализированные аналоговые схемы (малошумящие, высокоомные и пр.), участвовал и участвую в разработке искрового эмиссионного спектрометра.
В эпоху короновируса я работал с ИК-диапазоном 8-14 мкм, спроектировал (сам и с помощью) первое серийное устройство, строил модели, разрабатывал алгоритмы, делал измерительные установки и, в частности, изучал гауссовый шум :-) Было хорошо и интересно, фирма до сих пор для меня -- эталон отношения к сотрудникам.
Однако, при переходе в следующую эпоху, в феврале 2022 года, я решил вернуться в измерительные системы. Жизнь стала тяжелее.
Программирование сопровождает меня постоянно: я решаю свои задачи, преподавал учебные курсы, связанные с программированием, побудил некоторых студентов стать программистами, но почему-то сам пока не считаю себя программистом. Я считаю мои умения по диагностике, знания по физике/измерениям редкими/уникальными, но не могу их монетизировать, поэтому, видимо, придется мне все-таки становиться обычным, не самым лучшим, но программистом или ML-инженером.
Собственно, история
Итак, в одной южной, но близкой стране потребовалась моя помощь в настройке примерно двенадцатилетнего атомно-абсорбционного спектрометра азиатского производства.
Такой прибор я видел впервые (раньше работал с Shimadzu, Agilent/Varian, Thermo, Analytic Jena), но достаточно быстро разобрался. В целом, прибор жизнеспособный, но наткнулся я на ошибку в вычислениях. Суть примерно следующая: Прибор -- с этой точки зрения, -- спектрофотометр, измеряет оптическую плотность, абсорбцию ABS на заданной длине волны (там все еще чуть хитрее, но сейчас это несущественно). Мы подаем на вход растворы с заданной концентрацией CON элемента (например, марганца), и сопоставляем ABS с CON: строим график зависимости, который приближаем линейной или квадратичной функцией (методом наименьших квадратов).
Когда измеряем неизвестную пробу, ABS нам выдает прибор, и по графику вычисляем CON, которую принимаем за результат измерения. Всё, казалось бы, просто.
Если зависимость линейная, то все работает хорошо. Однако, при указании квадратичной зависимости можно пойти двумя путями, выбрав ABS(CON) или CON(ABS):
1) A1*ABS2+B1*ABS+C1 = CON
2) A2*CON2+B2*CON+C2 = ABS
В первом случае, концентрация в неизвестной пробе вычисляется сразу же как полином второй степени от абсорбции.
Во втором случае для вычисления концентрации нужно решать квадратное уравнение.
Специальные азиатские программисты почему-то пошли вторым способом. Более того, им из-за чего-то настолько не нравятся отрицательные результаты концентрации (даже самые минимальные), что они отбрасывают этот (отрицательный) корень, и выбирают положительный. Соответственно, подача чистой воды(Sample2) на вход приводит к результату не (примерно 0), а существенно выше верхней калибровочной точки (например, 2.7572 при графике от 0.0 до 1.0). Который в графическом представлении соответствует второму пересечению параболой оси ОХ.
Что же делать? Правильный ответ -- обратиться к фирме-производителю. Только их программисты могут исправить эту ошибку. Я получил обновленную версию программы. Логично ведь, что я не один такой "умный" нашел эту ошибку? Приборов произведено некоторое количество, штук 100, а может, 1000 или даже 10000 (за 12-то лет), и эта ошибка явно у кого-то еще проявилась, и просто обязана быть исправлена? А оказалось, что нет, так и не исправлена. Говорят, более свежей версии программы нет.
Я обращался только через представителя, но пока даже по необходимым запчастям предложения нет, а вопросы по П/О, говорят, вообще часто игнорируются. Причем я слышал это не только про данного, а вообще про особенности работы с производителями "оттуда".
Далее буду писать иносказательно, на всякий случай. Скорее всего, этого вообще не было на самом деле, и это все только чей-то сон. Все детали придуманы, совпадения случайны.
Оказалось, что каким-то "непонятным" образом стали видны внутренности устройства программы, и после их изучения локализовалось место ошибки:
case FittngMethod.Square:
if (crCurveAbs.ParamB * crCurveAbs.ParamB - 4.0 * (crCurveAbs.ParamA * (crCurveAbs.ParamC - avgAbs)) < 0.0)
return 0.0;
double num1 = Math.Sqrt(crCurveAbs.ParamB * crCurveAbs.ParamB - 4.0 * (crCurveAbs.ParamA * (crCurveAbs.ParamC - avgAbs)));
double num2 = (0.0 - crCurveAbs.ParamB - num1) / (2.0 * crCurveAbs.ParamA);
double num3 = (0.0 - crCurveAbs.ParamB + num1) / (2.0 * crCurveAbs.ParamA);
double num4 = 0.0;
if (num2 < 0.0 && num3 < 0.0)
num4 = 0.0;
else if (num2 < 0.0)
num4 = num3;
else if (num3 < 0.0)
num4 = num2;
else if (crCurveAbs.ParamA < 0.0)
{
if (num2 < num3)
num4 = num2;
else if (num3 < num2)
num4 = num3;
}
else if (num2 < num3)
num4 = num2;
else if (num3 < num2)
num4 = num3;
return num4;
Узнаёте школьную формулу решения квадратного уравнения? Так вот, ее здесь просто не должно быть, нужно просто правильно выбирать оси.
Как решение, поменялись оси на графике местами и исправилась формула вычисления концентрации, убралась вся эта мишура (строки 8-23) с отбрасыванием отрицательных значений. И все заработало как положено!
Изменился смысл, размерности и значения коэффициентов полинома. Вычисленное значение стало положительным, но на самом деле и небольшие отрицательные не станут неправильно большими, как раньше. Проблемная ветка программы стала выглядеть так:
case FittingMethod.Square: // DONE: fixed
return corCurveAbs.ParamA * avgAbs * avgAbs +
corCurveAbs.ParamB * avgAbs +
corCurveAbs.ParamC;
Были найдены еще другие странные ошибки, например, при выборе меди программа не позволяла создавать "метод", выдавая какую-то непонятную ошибку. Понимание устройства программы позволило "задебажить" эту проблему и понять ее смысл.
Еще нашелся выход в сервисный режим. Он, правда, оказался полностью не локализованным:
Но теперь решилась и эта проблема. Был написан скрипт на python, который извлекает китайские строки и создает из них plain-text файл, затем файл перевелся при помощи translate.google.com, и скорректировался (в том числе, чтобы английские строки уместились на место иероглифов, пришлось сокращать некоторые слова). Строки вставились на места. Наверное, существует более удобный способ перевода, но все сделалось "по быстрому". Да, достаточно криво, но хотя бы что-то стало читаемым.
Еще раз подчеркну: все вышеописанное -- это фантастика, изображения, наверное, сгенерированы "искусанным интеллектом", вероятность всех таких совпадений очень мала (если, например, программа была бы написана на С++ или Delphi, то ee "реверсить" было бы сложнее). Задача сервис-инженера -- заменять крупные блоки, делать настройки программы и оборудования в соответствии с утвержденной производителем методикой.
Компонентный ремонт и исправление программного обеспечения -- фантастика, скорее даже не научная.
Вышеописанный сон привел к лучшему пониманию C#, пониманию чужого большого проекта, решению практической задачи (люди могут полноценно работать на приборе).
Производитель, конечно, должен быть заинтересован, чтобы его оборудование работало как можно лучше, чтобы пользователи рекомендовали приобретение его своим коллегам. Я мог бы дописать их программу, внести туда аналитические подходы, ставшие классическими (например, многократное дозирование пробы в графитовую кювету с целью концентрирования / увеличения чувствительности / снижения предела обнаружения, или другие "фишки", патенты на которые закончились) но это будет означать, что я своими умениями выведу азиатского производителя на приличный мировой уровень. С другой стороны, Shimadzu, Agilent, Thermo, Analytic Jena, (Bruker, Perkin Elmer) не сподобились предложить мне работу, зачем их жалеть? Посоветуйте, по возможности, что делать.
Автор: YDR