DAC 流处理 框架#

---
创建日期: 2023-06-18
想法日期: 2022-12-09
---
一种流处理框架的实现方式。

前言:

这篇原名叫做《一种 文本交互式 的 流处理 框架》,构想的是另一种流处理方式(类似函数提示词式的)。 在搜寻方案的时候,慢慢有了“Context”的想法,然后就成了DAC。 所以也不知道那个“文本交互式”的还会不会再出现。

另外,本篇内容大量重复《模块化分析平台》那两篇。本篇在先,只是被“微服务”气的,才先完成了那两篇。


我做了好几个数据分析程序,从A公司的rdsp,到Z公司的LDM、ATC、PCH、RDV。 还是感觉需要交互式的、定制化的分析。 (如果我们有高级的软件可以使用,比如TestLab、nCode,或许就没这么多事了。)

以SV为例,我们采集的数据进来,需要一些截取、滤波。 然后做FFT计算,得到的结果可能做幅值分析,可能做相位分析。 幅值提取,坎贝尔,还有瀑布图,甚至模态分析。

每一个数据都是一个节点(data node),比如时域数据、频域数据、提取的峰值表格等。 节点包含得到这个数据使用的参数。

不同的节点有不同的处理方式(action),比如可视化、递进分析。 有些处理方式需要不同的节点共同完成,比如坎贝尔需要频域数据加上转速信息。

我们有这些需求:

  • 要能作为项目保存、加载

  • 一个分析能够作为模板,快速建立新的分析(批量处理)

  • (定义参数作为标准分析)

  • 能够做交互的分析,反复修改参数查看结果变化(修改上游参数,有可能会影响到下游分析)

现有方式#

分析过程中使用不同的工具、处理方式,本质上没有区别,都是数据的流动、处理与展示。

手动方式

我们可以把数据只按照数值阵列的方式一一处理,比如 l1_c1_td = load(l1_c1_fpath); l1_c1_fd = fft(l1_c1_td, c1_sr)。 然后显示,只是需要手动定义一个又一个的变量,数据太多的时候,需要保存到硬盘;或者把数据共享给下游分析。

其实我们现在就是这样做的,可能有些处理方式是一个独立的程序,程序内部有它自己的流动,最后保存一个结果。 在这个处理程序的前方,是预处理:截取、除噪等。在这个处理程序的后方,是下游处理程序,或者当前结果的可视化。

公司内部的 MATLAB S&V 程序也可归为此类。

Jupyter

使用 Jupyter/LiveScript 和使用脚本本质上也是一样的,只是比较有顺序,把处理过程保存了下来。

不过遇到步骤比较多,比如33%、66%、100%,需要重复执行的情况,要么需要反复复制粘贴,要么把修改原本的cell再覆盖执行。

不仅会遇到很多的变量(如果要区分开每个分析),还需要记忆哪些库的哪些处理方式,使用曲线挺高的。

图形编程

我做的工具,一种比较常用的方式是树状分支结构的。 比如 LDM 中,每个部件有多少贴片的齿,每个齿有多少应变片。 基本上每个分析都和其子节点有关系, 当然分析方法比较固定。

因为树状关系并不能表达所有的情况(如前述,一个处理方式需要不同的节点)。 而 RDV,有不同的分析策略:比如单独看一个通道;一个部件附属的所有通道;一个部件附属的两个指定通道等等。 以及不同载荷下的结果协同分析。

这种比较高的自由度需求,多少会想到如下的使用场景。

[节点之间自由连线]

我之前并不喜欢图形编程,感觉不灵活,不方便查看代码本身。 要用图形编程做自定义,不好修改。

到现在反而想做一些类似图形编程的东西,不过不是作为编程(输出通用程序),而是作为一个分析平台。 这个平台可以通过自定义不同的节点(数据类型)和不同的处理方式(交互可视化、分析方法、出具报告)等来扩展。

只是可能图形化的表示需要额外的工作,并且不容易编辑(版本对比控制),所以更倾向于一种基于文本的命令(交互式处理)。 (慢慢的不就成了一门预定义函数的脚本工具?)

在 rdsp 的时候(?),我想把所有的分析放到一起,新的处理模块可以由其它几个组合而成, 像是SV_Standard = Trunc + FFT + Integrate, LabVIEW不是就有这种功能?

基于Python的节点编辑器

已经有许许多多的商业解决方案,问题是定制化没那么容易。 对我来说,最熟悉的当然是Python,看看哪些库能提供个框架。

我做了一番搜索,找到几个基于Python的项目:

确实挺惊艳的,至少在拖拽节点功能上能用(比如做个人员关系链接)。 也可以用Python自定义编程。

PDM

再想想,似乎也不是所有的分析都适合于做成模块,比如 PCH Log,就是动态添加的,而且也需要动态交互。 (也即是没有哪一种方案能完美兼容各种需求)

一方面内在的信息沟通逻辑各异,另一方面每个工具都各有成型,重头改造费时费力。

PDM多少有流式分析的共性,那就是复用已有工具,将不同的输入输出连接起来,更像是 Workbench。 当然,每个(工具)模块对外的显示模型就比较单一了,细节分析则要进入独立的工具。

流式分析#

不同的方式各有优势:

  • 函数库式的,设计很简洁,只用关系数据及处理方式本身。 不过如果变量多了以后,似乎就不容易靠一次进行了。

  • 节点式的,分析过程很清晰,数据层级如何一目了然。 但是比较固定,如果想要交叉分析,似乎就不容易呈现。 而且也不能有太多层级。

  • 独立程序连接的方式,各模块有自由度,不受限制的交互。 不过要定义输入输出,才能完成上下游交流,而这个信息的交换会比较单一。

  • 流式分析比较自由,甚至每个节点可以单独打开。 不过如果要批量处理,似乎得连很多线的样子。 吃面条了。

元素设计#

因为有自由度的需要,最终偏向流式分析,不过同时还有不同工作方式的需求。 在一个环境中希望分析流程如此,在另一个环境中另一种流程。 而且还要对相似的条件(不同的载荷),做同样的分析。

基础元素#

处理方式 (action)

如前述,处理方式(行为指令)有不同的情境:

  • 对数据进行处理,节点入,新节点出

  • 可视化的交互行为(甚至在交互完成后进行计算)

  • ……

其实处理方式就是一个个函数,定义了接口的函数。

为了便于知道每个处理方式的输入,需要对参数进行探测,然后将探测结果作为提示。 (其实就是把手动输入的函数名和参数,变成快速输入或者提示)

存储节点 (data node)

本质式数据、信息流动,所以需要有各种数据格式,进入处理节点。

环境空间 (context)

环境空间,指的是,比如不同的载荷,不同时间的采集数据。 需要来回切换的内容。

每个环境空间可能有相似的子分析,可以快速的创建新环境、以及切换。

首先,有些信息是共享的,全局变量。 例如传感器的布置、部件信息,这些对于一次实验来说是固定的,没有必要在不同的环境空间建立对象。 (或者说是在一个默认的环境空间定义)

对于处理的结果数据(action的输出),不同的环境空间需要不同的存储节点,因为输入(时间数据)都不一样。

除此之外,action需要在每个环境空间中独立存储吗? 出于快速分析的目的(也就是不必为了每个载荷再创建一次分析),不想修改action参数。 但是有的时候,比如不同载荷下的 CheckLevel 是不一样的,如果这个信息固定在 action 中,分析有可能出错。 但是如果每个 action 也要为不同的环境空间创建,信息又太多了,而且不方便action的管理。

一种方式是,为每个这种随环境空间变化的数值创建一个 数据节点wrapper。 那么action就可以大家共用,action内部去寻找各自环境空间的变量(数据节点)。 不过每次都需要创建wrapper,似乎又太麻烦了,不如直接修改action直接。

action如何既是模板又是变体? 是不是有些情况下,又希望某个环境空间特殊需要的分析方式。

交互控件#

编辑器

编辑器其实是不愿意定制GUI配置的妥协。

数据节点(data node)需要由基础参数创建,而处理方式(action)也有编辑的需求。 于是二者都成了“可编辑节点”,修改的方式使用YAML来表达。 如此就不要去做控件了。

容器

容器包含各种处理实例、过程中产生的节点数据。

此外,因为YAML配置只有文本,可是实际处理需要传入节点对象。 容器还需要找到所需要的数据,作为参数传给处理节点。

其他#

除了基础元素,还有些特性可以方便处理,或者提升速度。

计算缓存

假设原始数据不变,处理方式不变,参数也不变,那结果应该是一样的。 就没必要每次都再计算一遍。

把各个过程中的依赖哈希一下,确保计算方式唯一,保存结果。 如果需要的计算已经存在了,就可以直接读取。

后话#

应用、扩展

想要扩展框架到各种分析需求,不想扩展需要了解很复杂的结构,即使脱离主程序也能被调用,只是提供最简单的功能。

  • 可序列化、反序列化节点

  • 处理方式

    • 可视化交互基类

    • 处理基类

当模块、参数变多后

这时就和大软件一样了吧,提供了许多的功能,用户却找不到自己想要的。 不过这个是个小框架,所以可以很容易自己定制。

核心

核心依然是数据的流动,信息的处理与呈现。

真·后话

这篇写得有点混乱,没头没尾的。 写的时候DAC还只是设想,现在DAC已经有雏形在了。 好像一开始是自由的联想,可是慢慢我已经知道现状了,还要假装不知道的样子。 这时,已有的内容就反而成了一种束缚,不愿再多谈。

我也只是想结束这个话题,减少一个代办事项。

历程回顾#

一旦回顾起来,就发现似乎这么多年,什么也没做成。 每每看到当初的想法只进行到一点点,没继续下去,现在再也看不懂了。

一路上想法都有变化,又一路上都没什么大的差异。 不知何时又放弃,不知何时又重启。

那个当下的时候,觉得其他人做的都是什么玩意,看看我的“伟大作品”,他们定会有如醍醐灌顶! 而这个当下,我再看到以前的时候,不禁叫到这都做的什么玩意!

最早在A公司实验室,没怎么处理数据,天天对着别扭的VB采集软件。 后来去测试团队,跟着跑现场测数据。 没有什么趁手的分析工具,似乎只有数采自带的。

想用MATLAB做分析,却没有License。 好像开始还是用的SciLab,记不清是什么原因了,并没有完全使用。

而后渐渐开始用起Python来。 (早在那之前就想学Python,在电纸书上放了一本手册,一直没看过) 慢慢开始构建图形界面,最初还不是用的原生PyQt,而是GuiData,因为它自带了一些控件。 却始终不得绑定的精髓,别扭的用着。

对了,最开始用Python的时候,库还不容易安装,不少pypi都没有wheel,需要自己编译。 就会更倾向于发行版而不是纯Python解释器。 搜着搜着就用起了WinPython,也是因为这个才选择的GuiData吧。 (没用选择Anaconda因为封装太密了,自定义似乎不方便。WinPython则是提供了带环境变量的命令行) (后来才发现原来我大学的时候还下载保存过PythonXY,WinPython前身,然而从没有用过)

那个时候VSCode刚出来不久,我赶巧用上了,还算个老用户哩。

当时除了振动,还有位移、气隙什么的。 从那时起就想要一个能够自定义多种分析、不同数据类型、批量处理、处理模板、能保存读取的工具。 弄了一个rdsp。

也还记得在现场等待的时候,拿出笔记本写代码的情景,想着,我要和其他人不一样!

然而似乎气隙的那个模块都没有弄完整,并行的振动处理模块也不是很顺利。 再之后就换工作了,找工作的时候硬着头皮说自己开发了个数据处理框架,好像也没人在意。

在新的工作上,感觉又从头开始了一遍,不过速度比上次快。 所幸在新公司,MATLAB是有的,而且也还有基于MATLAB开发的工具。

看到在不同项目下,看到同事放着的各种分析(简单出出图啦)脚本,都会多留心,保存下来看看。 实在太乱了,而且都是针对当时项目修改的,不能通用。 稍微写得好的脚本,也有一些问题,还是我来吧。 (当时真的看到那么乱放的脚本,各种各样的,不能复现,非常抓狂。然而现在看看自己写的,并没有好到哪里去,好多依赖都失效了吧,不知以后抓狂了谁)

通常作为非程序员的工程师,还使用的MATLAB,一个通病是把数据和用户界面绑定。 要添加功能很困难,添加个if复制一大段代码然后再逐一修改。 或者调用脚本进行批量处理,根本不可能。 (而后说要面向对象,然后,然后使用了AppDesigner,接着把数据绑定到窗体对象上,就是面向对象了……)

我的设计思路,依然是简单把数据和界面分离,以及支持脚本分析。 数据设计首先考虑能用脚本执行,再用界面去调用这些操作。 不过往往设计到一半就没耐心地开始界面设计了。

而后做了几个定制性质的程序,慢慢又遇到了需要自由度的需求。 也不想再每分析方法都做个新程序。 本来DAC也是一个定制的程序,只是做着做着就觉得好像可以把各种处理方法都做成模块加入进来。 好像又回到了多年前,不过这次应该会能有些结果。(不会再多年后不知道自己写的是啥,就已经心满意足了 TnT )