要在Flask后端上运行的MATLAB脚本:从matlab到.py转换器?

时间:2019-05-08 13:29:43

标签: python matlab flask

我有一个Flask后端,该后端从前端接收xml数据,然后在后端进行解析,以提供给许多预先提供的MATLAB脚本。我的问题既涉及架构又涉及功能:

(1)我想知道如何将多个相互依赖的MATLAB脚本连接到Flask服务器上,以使这些脚本可以在对服务器的POST请求上进行操作(可能是matlab与python或matlab之间的某种中间件自定义实用程序)

(2)以及如何动态更改主MATLAB脚本从其导入文件的目录,假设该文件是传入请求,则该文件应进行分析,

Stack推荐了各种各样的方法,最常见的是由伟大的victorlei用来将MATLAB转换为python的SMOP库,但是对于给定复杂性的脚本来说,这似乎没有用处:大约5 .m值得依赖的文件,并不是所有需要的类都实现了

我的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 :(得分:0)

为什么不直接在MATLAB中使用XML数据? xml2struct是一种很棒/快速的MEX函数,用于将XML文件转换为MATLAB结构。我在自己的计算机上安装了non-MEX version of this in the File Exchange by Wouter Foukena,其运行速度比C ++ MEX慢130倍。

或者如果我读错了,而您需要在MATLAB中阅读JSON而不是XML(我读了您的文章,因为您的过程以XML读取并输出JSON),请尝试jsonlab。它的输出有些不同(单元/数组而不是struct),但仍易于使用。