Repository: CORE-GATECH-GROUP/serpent-tools
Pull request #52 (2017-12-07 21:14:11)

Fixes 51 - depmtx reader now parsers using regular expressions
More robust depmtx reader now uses regular expressions to obtain time, isotopics, zai, and decay matrix. The reference file has been modified by eliminating white space to demonstrate the flexibility of the new reader

Signed-off-by: Andrew Johnson <drewej@protonmail.com>


Patch:
diff --git a/serpentTools/parsers/__init__.py b/serpentTools/parsers/__init__.py
index 62a91b8..9ffb242 100644
--- a/serpentTools/parsers/__init__.py
+++ b/serpentTools/parsers/__init__.py
@@ -14,7 +14,7 @@ except ImportError:
     HAS_SCIPY = False
     csc_matrix = array
 
-from serpentTools.messages import warning, SerpentToolsException, info
+from serpentTools.messages import warning, SerpentToolsException, info, debug
 from serpentTools.parsers.depletion import DepletionReader
 from serpentTools.parsers.branching import BranchingReader
 from serpentTools.parsers.detector import DetectorReader
@@ -170,44 +170,88 @@ def depmtx(fileP):
     """
     if not path.exists(fileP):
         raise IOError('Cannot find depeletion matrix file {}'.format(fileP))
+
+    tRegex = re.compile(r't\s+=\s+([\d\.E\+-]+)')
+    nDensRegex = re.compile(r'N\d\(\s*([\d]+).*=\s+([\d\.E\+-]+)')
+    # matches index and quantity for N0 and N1 vectors
+    zaiRegex = re.compile(r'ZAI\(\s*[\d]+\).*=\s+(-?\d+)')
+    # matches index and name for ZAI vector
+    matrixRegex = re.compile(r'A\(\s*(\d+),\s*(\d+)\)\s+=\s+([\dE\.\+-]+)')
+    # matrix row, column, and decay constant for A matrix
+    failMsg = 'File {} is ill-formed for depmtx reader\nLine: '.format(fileP)
+
     if not HAS_SCIPY:
         warning('Decay matrix will be returned as full matrix')
+
     with open(fileP) as f:
-        t = float(f.readline().split()[-1][:-1])
         line = f.readline()
-        numIso = 0
-        n0Storage = {}
-        while line[0] == 'N':
-            numIso += 1
-            vals = line.split()
-            indx = int(vals[1][:-1])
-            ndens = float(vals[4][:-1])
-            n0Storage[indx - 1] = ndens
-            line = f.readline()
+        tMatch = re.match(tRegex, line)
+        if not tMatch:
+            raise SerpentToolsException(failMsg + line)
+        t = float(tMatch.groups()[0])
+        line = f.readline()
+
+        nMatch = re.match(nDensRegex, line)
+        if not nMatch:
+            raise SerpentToolsException(failMsg + line)
+
+        n0Storage, line, numIso = _parseIsoBlock(f, {}, nMatch, line, nDensRegex)
+        debug('Found {} isotopes for file {}'.format(numIso, fileP))
         n0 = empty((numIso, 1), dtype=longfloat)
-        for indx, v in n0Storage.items():
+        for indx, v in six.iteritems(n0Storage):
             n0[indx] = v
+
         zai = []
-        while line[0] == 'Z':
-            zai.append(line[12:-2])
+        zMatch = re.match(zaiRegex, line)
+        if not zMatch:
+            raise SerpentToolsException(failMsg + line)
+        while zMatch:
+            zai.append(zMatch.groups()[0])
             line = f.readline()
+            zMatch = re.match(zaiRegex, line)
+
+        if len(zai) != n0.size:
+            debug('Stopping at line -' + line)
+            raise SerpentToolsException(
+                'Did not obtain equal isotopes in ZAI vector [{}] as in N0 '
+                'vector [{}]'.format(len(zai), n0.size)
+            )
 
         line = f.readline()
+        aMatch = re.match(matrixRegex, line)
+        if not aMatch:
+            raise SerpentToolsException(failMsg + line)
+
         a = zeros((numIso, numIso), dtype=longfloat)
 
-        while line[0] == 'A':
-            vals = line.split()
-            pos = [int(xx[:-1]) for xx in vals[1:3]]
-            c = float(vals[-1][:-1])
-            a[pos[0] - 1, pos[1] - 1] = c
+        while aMatch:
+            row, col, const = aMatch.groups()
+            a[int(row) - 1, int(col) - 1] = float(const)
             line = f.readline()
+            aMatch = re.match(matrixRegex, line)
+
         n1 = empty_like(n0)
-        while line and line[0] == 'N':
-            vals = line.split()
-            indx = int(vals[1][:-1])
-            ndens = float(vals[4][:-1])
-            n1[indx - 1] = ndens
-            indx += 1
-            line = f.readline()
+        nMatch = re.match(nDensRegex, line)
+        n1, line, items = _parseIsoBlock(f, n1, nMatch, line, nDensRegex)
+        if items != numIso:
+            debug('Stopping at line -' + line)
+            raise SerpentToolsException(
+                'Did not obtain equal isotopes in N1 vector [{}] as in N0 '
+                'vector [{}]'.format(items, numIso)
+            )
 
         return t, n0, array(zai), csc_matrix(a) if HAS_SCIPY else a, n1
+
+
+def _parseIsoBlock(stream, storage, match, line, regex):
+    """Read through the N0, N1 block and add data to storage"""
+    items = 0
+    while match:
+        items += 1
+        vals = match.groups()
+        indx = int(vals[0])
+        ndens = float(vals[1])
+        storage[indx - 1] = ndens
+        line = stream.readline()
+        match = re.match(regex, line)
+    return storage, line, items


Test patch:
diff --git a/serpentTools/tests/depmtx_ref.m b/serpentTools/tests/depmtx_ref.m
index d45b200..b9ce572 100644
--- a/serpentTools/tests/depmtx_ref.m
+++ b/serpentTools/tests/depmtx_ref.m
@@ -62,17 +62,17 @@ N0( 60, 1) =  2.969194385985983930184572976430E-04; % 64155.09c
 N0( 61, 1) =  4.137300906148564500451614289744E-04; % 64156.09c
 N0( 62, 1) =  3.147461344099014199891806153886E-04; % 64157.09c
 N0( 63, 1) =  4.982967128670550598437682943143E-04; % 64158.09c
-N0( 64, 1) =  4.376379144643168764457208386176E-04; % 64160.09c
-N0( 65, 1) =  3.846796343279221003716384420470E-17; % 92232.09c
-N0( 66, 1) =  6.870389061970011623342495241181E-14; % 92233.09c
-N0( 67, 1) =  4.293077139753901466342252829511E-06; % 92234.09c
-N0( 68, 1) =  5.621565873446702577345690521327E-04; % 92235.09c
-N0( 69, 1) =  2.982886100926178976367134239832E-08; % 92236.09c
-N0( 70, 1) =  1.456340924238686170077029955405E-09; % 92237.09c
-N0( 71, 1) =  2.054873740352017655319549760407E-02; % 92238.09c
-N0( 72, 1) =  2.108367055387284252194156353166E-07; % 92239.09c
-N0( 73, 1) =  9.841801952371811001202615665146E-12; % 92240.09c
-N0( 74, 1) =  8.052266563002563381135156316475E-16; % 92241.09c
+N0(64, 1) =  4.376379144643168764457208386176E-04; % 64160.09c
+N0(65, 1) =  3.846796343279221003716384420470E-17; % 92232.09c
+N0(66, 1) =  6.870389061970011623342495241181E-14; % 92233.09c
+N0(67, 1) =  4.293077139753901466342252829511E-06; % 92234.09c
+N0(68, 1) =  5.621565873446702577345690521327E-04; % 92235.09c
+N0(69, 1) =  2.982886100926178976367134239832E-08; % 92236.09c
+N0(70, 1) =  1.456340924238686170077029955405E-09; % 92237.09c
+N0(71, 1) =  2.054873740352017655319549760407E-02; % 92238.09c
+N0(72, 1) =  2.108367055387284252194156353166E-07; % 92239.09c
+N0(73, 1) =  9.841801952371811001202615665146E-12; % 92240.09c
+N0(74, 1) =  8.052266563002563381135156316475E-16; % 92241.09c
 ZAI(  1) =  -1;
 ZAI(  2) =  10010;
 ZAI(  3) =  10020;
@@ -137,16 +137,16 @@ ZAI( 61) =  641560;
 ZAI( 62) =  641570;
 ZAI( 63) =  641580;
 ZAI( 64) =  641600;
-ZAI( 65) =  922320;
-ZAI( 66) =  922330;
-ZAI( 67) =  922340;
-ZAI( 68) =  922350;
-ZAI( 69) =  922360;
-ZAI( 70) =  922370;
-ZAI( 71) =  922380;
-ZAI( 72) =  922390;
-ZAI( 73) =  922400;
-ZAI( 74) =  922410;
+ZAI(65) =  922320;
+ZAI(66) =  922330;
+ZAI(67) =  922340;
+ZAI(68) =  922350;
+ZAI(69) =  922360;
+ZAI(70) =  922370;
+ZAI(71) =  922380;
+ZAI(72) =  922390;
+ZAI(73) =  922400;
+ZAI(74) =  922410;
 A = zeros(74, 74);
 A(   2,    2) = -1.500972704886488647503396416401E-12;
 A(   3,    2) = 1.500972704886488647503396416401E-12;
@@ -217,21 +217,21 @@ A(   1,   14) = 1.827132525888282652302896141169E-14;
 A(   2,   14) = 2.378724053264884450808088179421E-15;
 A(   3,   14) = 5.183681977466946621358812768637E-15;
 A(   4,   14) = 7.619080216058905058171000709915E-16;
-A(   6,   14) = 7.037312249475287147070996612611E-15;
-A(  11,   14) = 5.252196453045032161842091874674E-16;
-A(  13,   14) = 2.217131669901318917009967768153E-15;
-A(  14,   14) = -2.101367657408864964229926989358E-14;
-A(   1,   15) = 8.570932120853159136901615022104E-13;
-A(   2,   15) = 3.080381178417307535111101251503E-15;
+A(   6,  14) = 7.037312249475287147070996612611E-15;
+A(  11,  14) = 5.252196453045032161842091874674E-16;
+A(  13,  14) = 2.217131669901318917009967768153E-15;
+A(  14,  14) = -2.101367657408864964229926989358E-14;
+A(   1,  15) = 8.570932120853159136901615022104E-13;
+A(   2,  15) = 3.080381178417307535111101251503E-15;
 A(   3,   15) = 3.741022109942490275208240840694E-16;
 A(   4,   15) = 2.923239320951553699926835366345E-19;
 A(   6,   15) = 8.575279555696124562506859942928E-13;
 A(   9,   15) = 2.589029117482364333048791046002E-19;
-A(  12,   15) = 3.457587050434703755795592414333E-15;
-A(  13,   15) = 2.923239320951553699926835366345E-19;
-A(  14,   15) = 4.310477586852700503741058186465E-16;
-A(  15,   15) = -8.618590132475917017133608793804E-13;
-A(  16,   15) = 8.764620759605992455404938964010E-16;
+A(12, 15) = 3.457587050434703755795592414333E-15;
+A(13, 15) = 2.923239320951553699926835366345E-19;
+A(14, 15) = 4.310477586852700503741058186465E-16;
+A(15, 15) = -8.618590132475917017133608793804E-13;
+A(16, 15) = 8.764620759605992455404938964010E-16;
 A(   1,   16) = 1.420902914001124036507064261957E-11;
 A(   2,   16) = 1.502923411625723554478874384614E-15;
 A(   3,   16) = 4.018372490694978767381065749261E-16;
@@ -274,12 +274,12 @@ A(  20,   21) = 1.228968710025427074978484912429E-13;
 A(  21,   21) = -4.232924313427396862641505382048E-12;
 A(  22,   21) = 4.109186296073746496872745676487E-12;
 A(   1,   22) = 5.593267786682229780536312515193E-16;
-A(   2,   22) = 3.482618908468127649589892849026E-16;
-A(   3,   22) = 9.424053975799679433694594432756E-17;
-A(   4,   22) = 9.002651336774979851328395459195E-17;
-A(   5,   22) = 1.933571976251112710305592512234E-21;
-A(   6,   22) = 8.183462171786277170035897091567E-15;
-A(  17,   22) = 8.156666270662590258576244014207E-15;
+A(  2,   22) = 3.482618908468127649589892849026E-16;
+A(  3,   22) = 9.424053975799679433694594432756E-17;
+A(  4,   22) = 9.002651336774979851328395459195E-17;
+A(  5,   22) = 1.933571976251112710305592512234E-21;
+A(  6,   22) = 8.183462171786277170035897091567E-15;
+A( 17,   22) = 8.156666270662590258576244014207E-15;
 A(  20,   22) = 2.558095116485318870667450798224E-16;
 A(  21,   22) = 2.075508164338980887834071370303E-12;
 A(  22,   22) = -1.299005199107565347260968109059E-09;
@@ -793,18 +793,18 @@ N1(  9, 1) = 5.060433619751555762802705303744E-16;
 N1( 10, 1) = 6.199995212679281789456900943579E-34;
 N1( 11, 1) = 1.335014790831673510318193071082E-22;
 N1( 12, 1) = 6.757838821356679698956935594852E-12;
-N1( 13, 1) = 5.713456007267241150663798047094E-16;
-N1( 14, 1) = 8.424809681243940884598693412579E-13;
-N1( 15, 1) = 4.524295397652929040521740944314E-02;
-N1( 16, 1) = 1.713040787324974953168783041711E-12;
-N1( 17, 1) = 2.086936986944467839395658928337E-51;
-N1( 18, 1) = 2.424636326168540090075386101336E-50;
-N1( 19, 1) = 1.788687165347957167596924255025E-55;
-N1( 20, 1) = 9.101155945340115955547690599875E-50;
-N1( 21, 1) = 6.420431240825689197411479778674E-44;
-N1( 22, 1) = 1.771525301076316113494595647878E-42;
-N1( 23, 1) = 3.478551600249355163617301435932E-40;
-N1( 24, 1) = 9.521324405439976863171889655991E-40;
+N1(13, 1) = 5.713456007267241150663798047094E-16;
+N1(14, 1) = 8.424809681243940884598693412579E-13;
+N1(15, 1) = 4.524295397652929040521740944314E-02;
+N1(16, 1) = 1.713040787324974953168783041711E-12;
+N1(17, 1) = 2.086936986944467839395658928337E-51;
+N1(18, 1) = 2.424636326168540090075386101336E-50;
+N1(19, 1) = 1.788687165347957167596924255025E-55;
+N1(20, 1) = 9.101155945340115955547690599875E-50;
+N1(21, 1) = 6.420431240825689197411479778674E-44;
+N1(22, 1) = 1.771525301076316113494595647878E-42;
+N1(23, 1) = 3.478551600249355163617301435932E-40;
+N1(24, 1) = 9.521324405439976863171889655991E-40;
 N1( 25, 1) = 7.149865641067108751677561296294E-39;
 N1( 26, 1) = 1.744718381888471945301365449911E-55;
 N1( 27, 1) = 1.185006777468723203330033141583E-51;
diff --git a/serpentTools/tests/test_parserLevelRead.py b/serpentTools/tests/test_parserLevelRead.py
index 5296b27..60843fe 100644
--- a/serpentTools/tests/test_parserLevelRead.py
+++ b/serpentTools/tests/test_parserLevelRead.py
@@ -31,7 +31,7 @@ class DepmtxTester(unittest.TestCase):
         N = self.numIso
         self.assertTupleEqual(self.n0.shape, (N, 1), 'initial isotpics')
         self.assertTupleEqual(self.decMat.shape, (N, N), 'decay matrix')
-        self.assertTupleEqual(self.zai.shape, (N,), 'zai vector')
+        self.assertTupleEqual(self.zai.shape, (N, ), 'zai vector')
         self.assertTupleEqual(self.n1.shape, (N, 1), 'final isotopics')
 
     def test_correctSlices(self):