前言
从6月14号开始至今,我在武汉物数所待了6个多月,也着实体验了一把研究所的氛围。当初鉴于找工作的需要,想做个地方学习敲代码,就让老师安排去了研究所,也说不清楚当初做这个决定是否正确。
当然,到了一个新的地方,确实涨了不少见识。原本听着高大上的研究所原来是这么一回事儿,那些听着深奥的专业术语,多听两边也就习以为常。内心好些遗憾的是我呆了半年多时间,也就真是打了个杂,敲了几行代码,却没有去学一些和磁共振相关的稍微核心一点的东西。
磁共振
我所在的项目组从事的是核磁共振仪器的设计制造工作,而我参与的是辅助其他人工作的工具软件调试和开发工作。一个十足的边缘人物,干的就是搬砖的活,不需要什么磁共振相关的知识,随便一个会敲代码的都能干。当然也接触了一些相关的名词,在此就做个记录。
处于外磁场中的原子核,受到与质子进动频率相同的射频信号激发,会发生核磁共振的现象。当撤掉射频信号的时候,共振的原子核会释放刚刚吸收到的射频能量,恢复原来的状态。通过分析释放出的射频能量,可以分析原子核的分布。由于在医学研究中,生物体中成分最多的是水,水中又有两个氢,所以研究分析主要以氢核为主。通过分析氢核在生物体内的分布,就可以了解水的分布和含量。而生物体内不同组织和器官的水含量和分布在健康和病变下有不同的范围,由此来研究磁共振信号和生物状态的关系。
对于氢原子,不同的外磁场强度对应不同的进动频率,也就对应不同频率的发射和接收脉冲。为了区分出三维空间中生物体的不同位置,就要使得生物体所处于的三维空间每个点的磁场强度都不同,这样接受到的信号才能区分不同的部位。所以外磁场是在一个维度上的渐变的磁场和两个垂直线圈产生的渐变磁场的叠加,三个维度的磁场可以分别控制。
射频信号的发送、采集以及控制操作不是仅仅通过手工操作完成的,对于不同的研究对像,要采集不同的信号,都要编写合适的脉冲序列来实现。在脉冲序列中包括各种信号的发送、控制及采样等步骤。我打杂期间所做的工作就主要是修改脉冲序列编辑器,这个编辑器是用来脉冲序列语句的,并可以观察对应序列的脉冲波形。我没能参加脉冲序列的编写,所做的不过是修改程序中前人留下的坑和添加某些小功能罢了。在此期间我做的主要有语法分析器的设计和实现,脉冲序列文本和脉冲序列图形的对应显示,信号的3D显示器设计和实现。
Qt
实习期间的大部分工作都是基于Qt的程序设计。而我本人去研究所的目的就是去接触实际的编程机会,可以说是得偿所愿吧。在此过程中不敢说学到了什么编程经验,但是有了这一段经历,当再一次看到一大串长长的代码时,就显得不那么困难了。
Qt是一个跨平台的C++图形界面框架,有一堆封装好的图形界面函数,通过简单的语句就能实现好看的界面。另外,还可以利用Qt Designer工具,用拖拽空间的方式,快速进行界面的设计,有利于快速开发。
ANTRL4
有个学习关于编译原理的机会,是我在研究所里的最大收获。由于磁共振仪器里面脉冲序列的编写涉及到领域特定语言DSL,就需要为这种领域特定语言设计相应的编译器前端,实现基本的语法分析功能。
编译原理涉及到的内容很多,有词法分析、语法分析、语义分析、中间代码生成、代码优化以及目标代码生成等环节。将与源代码有关而与目标机器无关的部分称为编译器前端,包括词法分析、语法分析、语义分析以及目标代码优化;剩下的部分用来实现目标代码的部分称为编译器后端。ANTLR这个框架可以自动高效地生成编译器前端,根据用户定义的语法文件自动生成词法分析器和语法分析器。
ANTLR这个框架虽然是由Java语言编写的,但是编写脉冲序列的语法文件需要用ANTLR的语法规则来写,并且最终生成的语法文件可以转化成各种目标语言的代码,因为主项目的程序是基于C++开发的,所以在编写完脉冲序列语法文件后,用ANTLR框架生成C++的源代码文件,这样主项目的程序就可以调用这个语法分析器来实现对脉冲序列的分析了。
ANTRL4语法规则
利用ANTRL编写语法分析器,其本质是书写几个领域特定语言的语法规则文件。最简单的话,就是写一个词法规则文件和一个语法规则文件,文件的后缀名是g4。下面举一个简单的例子来了解基本的词法规则和语法规则文件。
词法文件举例
|
|
在源代码文件中出现的所有符号,必须在词法规则文件的定义里面能找到;并且有重复定义的词,比如某些关键字的定义被包含在变量的模式里面,那么就需要把关键字的定义写在变量定义的前面。
语法文件举例
|
|
语法文件的设计遵从自顶向下的方法。首先,一个语法文件是由一堆的语句和文件结束符构成的,这相当于是语法分析的启始规则,然后从上往下,把启始规则中的每一成分都进行递归地分解,直到不能再分解为止。例如上述的语法文件中,语句分为申明语句和赋值语句,申明语句又是由多个词法构成的,其中的’INT’、’ID’、’EQUAL’和’COLON’都已经是基本的词法单元了,不能再分,只有‘value_expression’可以再分,分为几种情况,可以是加减操作,符号操作,以及是基本的数字词法。在最后一条语法规则‘value_expression’中,词法被迭代调用了,这时候就需要注意了,需要把优先级高的规则放在前面,优先级低的放在后面。通过这样的迭代操作,可以把这个数值表达式分解成基本的数字符号加减形式,这时候语法不可再分,分析结束。
总结
现在看来,出去见识一下还是值得的,待在学校里自习,不如在外面学习。虽然从回头的角度来看,利用这段打杂时间学习编程技术以便于找工作的目的没有实现,甚至在本来需要花时间在找工作的情况下有些浪费时间,但是我还是觉得出去找了一圈是值得的,认识了几个学校外的人,学习了一些其他领域的知识,看过了一些别人的学习工作日常。