Скрипты MATLAB для запуска на бэкэнде Flask: конвертер matlab в .py? - PullRequest
0 голосов
/ 08 мая 2019

У меня есть бэкэнд Flask, который получает данные xml спереди, которые я затем анализирую сзади, чтобы передать их ряду предварительно предоставленных сценариев MATLAB. Моя проблема как архитектурная, так и функциональная:

(1) я хотел бы знать, как подключить несколько взаимозависимых сценариев MATLAB к серверу Flask, чтобы эти сценарии могли обрабатывать запросы POST к серверу (будь то промежуточное программное обеспечение между matlab и python или matlab) custom util)

(2) и как динамически изменить каталог, из которого мой основной скрипт MATLAB импортирует файл, который он должен анализировать, учитывая, что это входящий запрос,

Stack рекомендует множество вещей, чаще всего это библиотека SMOP для преобразования MATLAB в python великими победителями, но, похоже, это не подходит для сценариев данной сложности: их примерно 5 млн. реализованы файлы зависимостей и не все необходимые классы

Моя копия компилятора приложений Matlab также не имеет опции "пакет python".

Вот пример кода MATLAB : это один файл пакета с подкаталогами (вы можете увидеть зависимости, импортированные из относительного пути). Он принимает один файл .m5 в качестве входных данных. Как можно реализовать что-то подобное на сервере?

% calculate the VCG ECG CAD Score form the 12 lead ECG
%
% input path to file
% output size 1 by 1

function [Score] = Calculate_VCG_CAD_Score_From12LeadECGTemplate(TwelveLeadECGFilePath, VCG_transform)

% testing
Testing = 1;

% addpaths
root = 'M:\Some Dingy Ass School in Europe\Datenbank';
addpath([root,'\Software\Matlab']);
addpath([root,'\Software\Matlab\Transforms']);
addpath([root,'\Cleverly Editted Out Projectname\ProgrammCode\Gui']);

% warnings
war1 = 'no file name given';
war2 = 'Undefined transform. Averdson is used';

if nargin < 1
    warning(war1)
    TwelveLeadECGFilePath = [root,'\Cleverly Editted Out Projectname\Daten\ECG\CS200Ex_BaselVIII_2703_3212\MPS_2703_2703_20140228_082204000.xml']
    warning(war2)
    VCG_transform = 'Averdson';
end
if nargin == 1
    warning(war2)
    VCG_transform = 'Averdson';
end
if nargin > 2
    warning('too many inputs will be ignored');
end

% select transform
switch(VCG_transform)
    case {'Averdson'} 
        transform = 'Averdson';
    otherwise
        warning(war2)
        transform = 'Averdson';
end

cebrisDataReader(TwelveLeadECGFilePath);

% read in ECG file (XML, Templates)
% evtl. Funktion machen
%xDoc = xmlread(TwelveLeadECGFilePath);
%xRoot = xDoc.getDocumentElement;
%schema = char(xRoot.getAttribute('xsi:noNamespaceSchemaLocation'))
%allListitems = xDoc.getElementsByTagName('listitem')

% test case
TwelveLeadECGTemplateRest = [1 2 3 4 5 6 7 8 9 10 11 12; 13 14 15 16 17 18 19 20 21 22 23 24; 25 26 27 28 29 30 31 32 33 34 35 36];
TwelveLeadECGTemplateRest = [1 2 3 4 5 6 7 6 5 4 3 2; 
                             2 4 6 8 10 12 14 12 10 8 6 4; 
                             3 6 8 10 12 14 16 14 12 10 8 6;
                             2 4 6 8 10 12 14 12 10 8 6 4; 
                             1 2 3 4 5 6 7 6 5 4 3 2];

% Fall 1 keine CAD
TwelveLeadECGTemplateMaxLoad = TwelveLeadECGTemplateRest;
figure(2);clf
subplot(2,1,1); hold on
plot(TwelveLeadECGTemplateRest(:,1),'b-');
plot(TwelveLeadECGTemplateRest(:,2),'g-');
plot(TwelveLeadECGTemplateRest(:,3),'r-');
subplot(2,1,2); hold on
plot(TwelveLeadECGTemplateMaxLoad(:,1),'b-');
plot(TwelveLeadECGTemplateMaxLoad(:,2),'g-');
plot(TwelveLeadECGTemplateMaxLoad(:,3),'r-');
%figure(3);clf
%plot3(TwelveLeadECGTemplateRest(1,:),TwelveLeadECGTemplateRest(2,:),TwelveLeadECGTemplateRest(3,:),'b-');
%hold on
%plot3(TwelveLeadECGTemplateMaxLoad(1,:),TwelveLeadECGTemplateMaxLoad(2,:),TwelveLeadECGTemplateMaxLoad(3,:),'r-');

% calculate VCG from 12 leadd ECG
if Testing
    TwelveLeadECGTemplateRest = [1 1 1 1 1 1 1 1 1 1 1 1; 
                                 2 2 2 2 2 2 2 2 2 2 2 2; 
                                 3 3 3 3 3 3 3 3 3 3 3 3;
                                 4 4 4 4 4 4 4 4 4 4 4 4; 
                                 5 5 5 5 5 5 5 5 5 5 5 5];
end
[VCG_rest] = TwelveLeadECGToVCG(TwelveLeadECGTemplateRest, transform);
[VCG_MaxLoad] = TwelveLeadECGToVCG(TwelveLeadECGTemplateMaxLoad, transform);
if Testing
    VCG_rest
end

% calculate area from 
if Testing
    VCG_rest = [0 0 1 2 3 2 1;
                0 1 2 2 0 2 -1;
                0 1 2 3 4 2 1];
    VCG_rest = VCG_rest'
    VCG_MaxLoad = [0 0.5 1 2 3 2 1;
                   0 0.5 1 2 0 2 -1;
                   0 0.5 1 3 4 2 1];
    VCG_MaxLoad = VCG_MaxLoad'
end
VCGAreaRest = CalculateVCGScore(VCG_rest);
VCGAreaMaxLoad = CalculateVCGScore(VCG_MaxLoad);
if Testing
    VCGAreaRest
    VCGAreaMaxLoad
end

figure(4);clf
subplot(2,1,1)
hold on
plot(VCGAreaRest,'b-');
plot(VCGAreaMaxLoad,'r-');
subplot(2,1,2)
plot(VCGAreaRest-VCGAreaMaxLoad,'k-');

figure(5);clf
plot3(VCG_rest(1,:),VCG_rest(2,:),VCG_rest(3,:),'b-');
hold on
plot3(VCG_MaxLoad(1,:),VCG_MaxLoad(2,:),VCG_MaxLoad(3,:),'r-');

end

% locally defined functions

function [VCGarea] = CalculateVCGScore(VCGTemplate)

    LengthOfTemplate = size(VCGTemplate,1);
    area = 0;
    VCGarea = [];
    for n = 2: LengthOfTemplate
        % cumulative
        area = area + 0.5*norm(cross(VCGTemplate(n,:), VCGTemplate(n-1,:))); 
        % partly areas
        area = 0.5*norm(cross(VCGTemplate(n,:), VCGTemplate(n-1,:))); 

        % store
        VCGarea(n-1,:) = area;
    end
    % close loop (first and last element should be null as (0,0,0) for n=0
    VCGarea(LengthOfTemplate,:) = norm(cross(VCGTemplate(LengthOfTemplate,:), VCGTemplate(1,:)));
end

Внутренний сервер - это стандартная Flask, я думаю, на данном этапе он будет рассматриваться как RESTful API, но я только выбрал концепцию на прошлой неделе, так что не уверен. Голые кости сейчас выглядят так:

from flask_restful import Resource, Api
from flask_cors import CORS
from flask import jsonify
import requests, os, json, xmltodict
app = Flask(__name__)
api = Api(app)
CORS(app)
#VCG scripts are under Software/Matlab/Transfroms

@app.route('/api/upload', methods = ['POST'])
def upload_file():
    file = request.files['file']    
    contents = xmltodict.parse(file)
    # xmltodict is XML to JSON parser
    print(">> The XML contents. <<<\n")
    return jsonify(contents)

if __name__ == '__main__':
    app.run(debug=False)

# ----> Matlab to Python Scripts
# ---->Upload File parser

Я был бы рад услышать любые предложения! Заранее спасибо.

1 Ответ

0 голосов
/ 08 мая 2019

Почему бы не работать с данными XML непосредственно в MATLAB? xml2struct - это удивительная / быстрая функция MEX для преобразования XML-файлов в структуры MATLAB.Существует версия не-MEX этого в File Exchange от Wouter Foukena , которую я установил на своей машине, так как она работает примерно в 130 раз медленнее, чем C ++ MEX.

Или, если я прочитал это неправильно и вам нужно читать JSON, а не XML в MATLAB (я читаю ваш пост, поскольку ваш процесс читает в XML и выводит JSON), попробуйте jsonlab .Его вывод немного отличается (ячейки / массивы вместо struct), но с ним легко работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...