Advertisement
shinemic

VASP XML 文件解析案例

Mar 27th, 2022 (edited)
915
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JSON 6.33 KB | None | 0 0
  1. {
  2.  "cells": [
  3.   {
  4.    "cell_type": "markdown",
  5.    "id": "ec5091c9",
  6.    "metadata": {},
  7.    "source": [
  8.     "# VASP XML 文件解析案例"
  9.    ]
  10.   },
  11.   {
  12.    "cell_type": "markdown",
  13.    "id": "61270d81",
  14.    "metadata": {},
  15.    "source": [
  16.     "*注:本实验中所用到的数据文本行数为 23597933*"
  17.    ]
  18.   },
  19.   {
  20.    "cell_type": "markdown",
  21.    "id": "df7e3535",
  22.    "metadata": {},
  23.    "source": [
  24.     "## 场景一:提取 band set 节点部分 r 值并对应相加"
  25.    ]
  26.   },
  27.   {
  28.    "cell_type": "markdown",
  29.    "id": "383ca44e",
  30.    "metadata": {},
  31.    "source": [
  32.     "### 方法 1.1:Perl\n",
  33.     "\n",
  34.     "代码:`calc_add_2_4.pl`\n",
  35.     "\n",
  36.     "---\n",
  37.     "```Perl\n",
  38.     "if (/<set comment=\"band /) {\n",
  39.     "    while (<>) {\n",
  40.     "        push @r, [split(\" \", $1)] if @r<=3 && m{<r>\\s*(.*?)\\s*</r>};\n",
  41.     "        if (m{</set>}) {\n",
  42.     "            print join \" \", map { sprintf \"%.4f\", $r[1][$_] + $r[3][$_] } 0..$#{$r[0]};\n",
  43.     "            undef @r;\n",
  44.     "            last;\n",
  45.     "        };\n",
  46.     "    }\n",
  47.     "}\n",
  48.     "```\n",
  49.     "---\n",
  50.     "\n",
  51.     "执行:\n",
  52.     "\n",
  53.     "---\n",
  54.     "```Bash\n",
  55.     "perl -lnf calc_add_2_4.pl vasprun_large.xml > out_pl_calc_add_2_4.txt\n",
  56.     "```\n",
  57.     "---\n",
  58.     "\n",
  59.     "耗时:10秒"
  60.    ]
  61.   },
  62.   {
  63.    "cell_type": "markdown",
  64.    "id": "2cccabcf",
  65.    "metadata": {},
  66.    "source": [
  67.     "## 场景二:band set 节点下所有 r 值对应相加"
  68.    ]
  69.   },
  70.   {
  71.    "cell_type": "markdown",
  72.    "id": "0205dcf4",
  73.    "metadata": {},
  74.    "source": [
  75.     "### 方法 2.1:Perl + List::Util\n",
  76.     "\n",
  77.     "代码:`calc_sum.pl`\n",
  78.     "\n",
  79.     "---\n",
  80.     "```Perl\n",
  81.     "if (/<set comment=\"band /) {\n",
  82.     "    while (<>) {\n",
  83.     "        push @r, [split(\" \", $1)] if m{<r>\\s*(.*?)\\s*</r>};\n",
  84.     "        if (m{</set>}) {\n",
  85.     "            print join \" \", map {\n",
  86.     "                    $j = $_;\n",
  87.     "                    sprintf \"%.4f\", sum( map { $r[$_][$j] } 0..$#r )\n",
  88.     "                } 0..$#{$r[0]};\n",
  89.     "            undef @r;\n",
  90.     "            last;\n",
  91.     "        }\n",
  92.     "    }\n",
  93.     "}\n",
  94.     "```\n",
  95.     "---\n",
  96.     "\n",
  97.     "执行:\n",
  98.     "\n",
  99.     "---\n",
  100.     "```Bash\n",
  101.     "perl -MList::Util=sum -lnf calc_sum.pl vasprun_large.xml > out_pl_calc_sum.txt\n",
  102.     "```\n",
  103.     "---\n",
  104.     "\n",
  105.     "耗时:3分10秒"
  106.    ]
  107.   },
  108.   {
  109.    "cell_type": "markdown",
  110.    "id": "f9c57121",
  111.    "metadata": {},
  112.    "source": [
  113.     "### 方法 2.2:Perl + 逐步循环\n",
  114.     "\n",
  115.     "代码:`calc_add.pl`\n",
  116.     "\n",
  117.     "---\n",
  118.     "```Perl\n",
  119.     "if (/<set comment=\"band /) {\n",
  120.     "    @r = ();\n",
  121.     "    while (<>) {\n",
  122.     "        if (m{<r>\\s*(.*?)\\s*</r>}) {\n",
  123.     "            @d = split(\" \", $1);\n",
  124.     "            if (@r) {\n",
  125.     "                $r[$_] += $d[$_] for 0 .. $#r;\n",
  126.     "            } else {\n",
  127.     "                @r = @d;\n",
  128.     "            }\n",
  129.     "        } else {\n",
  130.     "            print join \" \", map { sprintf \"%.4f\", $_ } @r;\n",
  131.     "            last;\n",
  132.     "        }\n",
  133.     "    }\n",
  134.     "}\n",
  135.     "```\n",
  136.     "---\n",
  137.     "\n",
  138.     "执行:\n",
  139.     "\n",
  140.     "---\n",
  141.     "```Bash\n",
  142.     "perl -lnf calc_add.pl vasprun_large.xml > out_pl_calc_add.txt\n",
  143.     "```\n",
  144.     "---\n",
  145.     "\n",
  146.     "耗时:2分44秒"
  147.    ]
  148.   },
  149.   {
  150.    "cell_type": "markdown",
  151.    "id": "86efffbc",
  152.    "metadata": {},
  153.    "source": [
  154.     "### 方法 2.3:XQuery(basex 实现)\n",
  155.     "\n",
  156.     "代码:`xq_sum.xqy`\n",
  157.     "\n",
  158.     "---\n",
  159.     "```XQuery\n",
  160.     "for $band-set in //set[starts-with(@comment, \"band \")]\n",
  161.     "return\n",
  162.     "    for $raw-record in $band-set\n",
  163.     "    let $rcount    := count($raw-record/r),\n",
  164.     "        $data-line := for-each($raw-record/r, function($r) {\n",
  165.     "            for-each(tokenize(normalize-space($r), \"\\s+\"), xs:decimal(?))\n",
  166.     "        }),\n",
  167.     "        $vcount    := count($data-line) idiv $rcount\n",
  168.     "    return string-join(for-each(1 to $vcount, function($iv) {\n",
  169.     "        format-number(sum(for-each(1 to $rcount, function($ir) {\n",
  170.     "            $data-line[$vcount * ($ir - 1) + $iv]\n",
  171.     "                })), \"0.0000\")\n",
  172.     "            }), \" \"\n",
  173.     "        )\n",
  174.     "```\n",
  175.     "---\n",
  176.     "\n",
  177.     "执行:\n",
  178.     "\n",
  179.     "---\n",
  180.     "```Bash\n",
  181.     "basex -i vasprun_large.xml xq_sum.xqy > out_basex_xq_sum.txt\n",
  182.     "```\n",
  183.     "---\n",
  184.     "\n",
  185.     "耗时:2分39秒\n",
  186.     "\n",
  187.     "**注:** 上述写法生成的文件尾(EOF)将不包含回车符 `\\n`,利用 `wc -l` 统计行数将比上述方法少 1 行。"
  188.    ]
  189.   },
  190.   {
  191.    "cell_type": "markdown",
  192.    "id": "4b203335",
  193.    "metadata": {},
  194.    "source": [
  195.     "### 方法 2.4:Python + lxml\n",
  196.     "\n",
  197.     "代码:`lxml_query.py`\n",
  198.     "\n",
  199.     "---\n",
  200.     "```Python\n",
  201.     "import sys\n",
  202.     "from lxml import etree\n",
  203.     "\n",
  204.     "tree = etree.parse(sys.argv[1])\n",
  205.     "for spin in tree.xpath('//set[starts-with(@comment, \"band \")]]'):\n",
  206.     "    for kpoint in spin.findall(\"set\"):\n",
  207.     "        for band in kpoint.xpath('.//set[starts-with(@comment, \"band \")]'):\n",
  208.     "            print(\" \".join(map(lambda xs: format(sum(xs), \".4f\"),\n",
  209.     "                               zip(*map(lambda line: map(float,\n",
  210.     "                                   line.strip().split()),\n",
  211.     "                                   band.xpath(\".//r/text()\"))))))\n",
  212.     "```\n",
  213.     "---\n",
  214.     "\n",
  215.     "执行:\n",
  216.     "\n",
  217.     "---\n",
  218.     "```Bash\n",
  219.     "python lxml_query.py vasprun_large.xml > out_python_lxml.txt\n",
  220.     "```\n",
  221.     "---\n",
  222.     "\n",
  223.     "结果:超出内存最大限制"
  224.    ]
  225.   }
  226.  ],
  227.  "metadata": {
  228.   "kernelspec": {
  229.    "display_name": "Python 3 (ipykernel)",
  230.    "language": "python",
  231.    "name": "python3"
  232.   },
  233.   "language_info": {
  234.    "codemirror_mode": {
  235.     "name": "ipython",
  236.     "version": 3
  237.    },
  238.    "file_extension": ".py",
  239.    "mimetype": "text/x-python",
  240.    "name": "python",
  241.    "nbconvert_exporter": "python",
  242.    "pygments_lexer": "ipython3",
  243.    "version": "3.8.12"
  244.   }
  245.  },
  246.  "nbformat": 4,
  247.  "nbformat_minor": 5
  248. }
  249.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement