{"action":"created","comment":{"url":"https://api.github.com/repos/idaholab/raven/pulls/comments/182632495","pull_request_review_id":113465691,"id":182632495,"diff_hunk":"@@ -0,0 +1,961 @@\n+\"\"\"\n+Created on July 25th, 2017\n+@author: rouxpn\n+\"\"\"\n+from __future__ import division, print_function, unicode_literals, absolute_import\n+import warnings\n+warnings.simplefilter('default',DeprecationWarning)\n+import os\n+import re\n+import csv\n+import xml.etree.ElementTree as ET\n+from decimal import Decimal\n+\n+class phisicsdata():\n+  \"\"\"\n+    This class parses the PHISICS output of interest. The output of interest are printed in the a csv file.\n+  \"\"\"\n+  def __init__(self, phisicsDataDict):\n+    \"\"\"\n+      Reads the PHISICS output.\n+      @ In, phisicsDataDict, dictionary, dictionary of variables passed by the interface\n+      @ Out, None\n+    \"\"\"\n+    self.phisicsRelap = phisicsDataDict['phiRel']               # boolean: True means PHISICS RELAP coupled, False means PHISICS standalone\n+    self.printSpatialRR = phisicsDataDict['printSpatialRR']     # boolean: True means spatial RR are printed, False means spatial RR are not printed\n+    self.printSpatialFlux = phisicsDataDict['printSpatialFlux'] # boolean: True means spatial fluxes are printed, False means spatial fluxes are not printed\n+    self.workingDir = phisicsDataDict['workingDir']             # string: working directory\n+    self.mrtauOutputFileMPI = []\n+    instantDict = {}\n+    mrtauDict = {}\n+    markerList = ['Fission matrices of','Scattering matrices of','Multigroup solver ended!']\n+\n+    self.instantOutputFileMPI,self.mrtauOutputFileMPI = self.fileOutName(phisicsDataDict)\n+    mrtauOutput = [self.mrtauOutputFileMPI,phisicsDataDict['mrtauFileNameDict']['decay_heat']]\n+    cpuTime = self.getCPUtime(phisicsDataDict['numberOfMPI'])\n+    if self.phisicsRelap is False:\n+      instantOutput = ['Dpl_INSTANT_'+phisicsDataDict['jobTitle']+'_flux_mat.csv', 'scaled_xs.xml']\n+    if self.phisicsRelap is True:\n+      instantOutput = ['PHISICS_RELAP5_'+phisicsDataDict['jobTitle']+'_flux_sub.csv','PHISICS_RELAP5_'+phisicsDataDict['jobTitle']+'_power_dens_sub.csv','scaled_xs.xml']\n+\n+    self.materialsDict = self.locateMaterialInFile(phisicsDataDict['numberOfMPI'])\n+    self.perturbationNumber = self.getPertNumber()\n+    self.cleanUp(phisicsDataDict['jobTitle'])\n+    self.getNumberOfGroups()\n+    self.getNumberOfRegions()\n+    if phisicsDataDict['mrtauStandAlone'] == False:   # MRTAU/INSTANT are coupled\n+      mrtauTimeSteps = self.getMrtauInstantTimeSteps()\n+      instantTimeSteps = self.getInstantTimeSteps(instantOutput[0])\n+      xsLabelList, xsList = self.getAbsoluteXS(instantOutput[1])\n+    if phisicsDataDict['mrtauStandAlone'] == True:    # MRTAU is standalone mode\n+      mrtauTimeSteps = self.getMrtauTimeSteps()\n+      self.getMrtauIsotopeList()\n+\n+    for timeStepIndex in xrange (0,len(mrtauTimeSteps)):\n+      if phisicsDataDict['mrtauStandAlone'] == False:\n+        keff, errorKeff = self.getKeff()\n+        reactionRateInfoMPI = self.getReactionRates(phisicsDataDict['numberOfMPI'])\n+        reactionRateInfo = self.summedDictValues(reactionRateInfoMPI,'reactionRates',self.numberingRR)\n+        if self.printSpatialRR is True:\n+          fissionMatrixInfoMPI = self.getMatrix(markerList[0],markerList[1],'FissionMatrix',phisicsDataDict['numberOfMPI'])\n+          fissionMatrixInfo = self.summedDictValues(fissionMatrixInfoMPI,'FissionMatrix',self.matrixNumbering)\n+        else:\n+          fissionMatrixInfo = {}\n+        if self.printSpatialFlux is True:\n+          if self.phisicsRelap is False:\n+            fluxLabelList, fluxList, matFluxLabelList, matFluxList = self.getFluxInfo(instantOutput[0])\n+          if self.phisicsRelap is True:\n+            fluxLabelList, fluxList = self.getFluxInfoPhiRel(instantOutput[0])\n+            powerDensLabelList, powerDensList = self.getFluxInfoPhiRel(instantOutput[1])\n+        if self.printSpatialFlux is False:\n+          fluxLabelList = ['fluxLabel']\n+          fluxList = [0.0000E+00]\n+          matFluxLabelList = ['matFluxLabelList']\n+          matFluxList = [0.0000E+00]\n+          powerDensLabelList = ['powerDensLabelList']\n+          powerDensList = [0.0000E+00]\n+        depLabelList, depList, timeStepList, matList = self.getDepInfo(timeStepIndex, mrtauTimeSteps, phisicsDataDict['numberOfMPI'])\n+        decayLabelList, decayList = self.getDecayHeat(timeStepIndex,mrtauTimeSteps)\n+        instantDict['keff'] = keff\n+        instantDict['errorKeff'] = errorKeff\n+        instantDict['reactionRateInfo'] = reactionRateInfo\n+        instantDict['fissionMatrixInfo'] = fissionMatrixInfo\n+        instantDict['workingDir'] = self.workingDir\n+        instantDict['fluxLabelList'] = fluxLabelList\n+        instantDict['fluxList'] = fluxList\n+        instantDict['depLabelList'] = depLabelList\n+        instantDict['depList'] = depList\n+        instantDict['timeStepList'] = timeStepList\n+        instantDict['decayLabelList'] = decayLabelList\n+        instantDict['decayList'] = decayList\n+        instantDict['timeStepIndex'] = timeStepIndex\n+        instantDict['mrtauTimeSteps'] = mrtauTimeSteps\n+        instantDict['xsLabelList'] = xsLabelList\n+        instantDict['xsList'] = xsList\n+        instantDict['cpuTime'] = cpuTime\n+        if self.phisicsRelap is True:\n+          instantDict['powerDensList'] = powerDensList\n+          instantDict['powerDensLabelList'] = powerDensLabelList\n+        if self.phisicsRelap is False:\n+          instantDict['matFluxLabelList'] = matFluxLabelList\n+          instantDict['matFluxList'] = matFluxList\n+        self.writeCSV(instantDict,timeStepIndex,mrtauTimeSteps,phisicsDataDict['jobTitle'])\n+\n+      if phisicsDataDict['mrtauStandAlone'] == True:\n+        decayHeatMrtau = self.getDecayHeatMrtau(timeStepIndex, mrtauTimeSteps)\n+        depList = self.getDepInfoMrtau(timeStepIndex, mrtauTimeSteps)\n+        mrtauDict['workingDir'] = self.workingDir\n+        mrtauDict['decayHeatMrtau'] = decayHeatMrtau\n+        mrtauDict['depList'] = depList\n+        mrtauDict['timeStepIndex'] = timeStepIndex\n+        mrtauDict['mrtauTimeSteps'] = mrtauTimeSteps\n+        self.writeMrtauCSV(mrtauDict)\n+  \n+  def summedListValues(self,list):\n+    \"\"\"\n+      Sums up values from a given list.\n+      @ In, list, list of intergers or floats\n+      @ Out, sum, integer or float, sum of the values given in input\n+    \"\"\"\n+    sum = 0\n+    for i in xrange (0,len(list)):\n+      sum = sum + float(list[i])\n+    return sum\n+  \n+  def summedDictValues(self,dict,typeOfParameter,parameterList):\n+    \"\"\"\n+      Sums up the values from a given dictionary.\n+      @ In, dict, dictionary, nested dictionaries of intergers or floats\n+      @ In, typeOfParameter, string, either 'reactionRates' or 'FissionMatrix'\n+      @ In, parameterList, list, list of the parameters parsed\n+      @ Out, summedDict, dict, dictionary of integer or float\n+    \"\"\"\n+    summedDict = self.declareDict(typeOfParameter,parameterList)\n+    if self.printSpatialRR is False:\n+      for parameter,mpi in dict.iteritems():\n+        sum = 0\n+        for mpi,value in mpi.iteritems():\n+          sum = '%.15E' % Decimal(float(sum) + float(value))\n+        summedDict[parameter] = sum\n+    if self.printSpatialRR is True:\n+      for group,region in dict.iteritems():\n+        for region,parameter in region.iteritems():\n+          for parameter,mpi in parameter.iteritems():\n+            sum = 0\n+            for mpi,value in mpi.iteritems():\n+              sum = '%.15E' % Decimal(float(sum) + float(value))\n+            summedDict[group][region][parameter] = sum\n+    return summedDict\n+      \n+  def fileOutName(self,phisicsDataDict):\n+    \"\"\"\n+      Puts in a list the INSTANT output file names based on the number of MPI.\n+      The format is title.o-MPI\n+      @ In, phisicsDataDict, dictionary, dictionary of variables passed by the interface\n+      @ Out, instantOutputFileMPI, list, list of INSTANT output file names\n+      @ Out, mrtauOutputFileMPI, list, list of MRTAU output file names\n+    \"\"\"\n+    instantMPI = []\n+    mrtauMPI = []\n+    for mpi in xrange (0,phisicsDataDict['numberOfMPI']):\n+      mrtauMPI.append(os.path.join(self.workingDir,phisicsDataDict['mrtauFileNameDict']['atoms_csv'].split('.')[0]+'-'+str(mpi)+'.csv')) # MRTAU files (numbers.csv)\n+      if self.phisicsRelap is False:    # INSTANT files, no coupling with RELAP\n+          instantMPI.append(phisicsDataDict['instantOutput']+'-'+str(mpi))\n+      if self.phisicsRelap is True:     # INSTANT files, coupling with RELAP\n+        if mpi == 0:\n+          pass\n+        else:\n+          instantMPI.append('INSTout-'+str(mpi))\n+    return instantMPI, mrtauMPI\n+   \n+  def cleanUp(self,jobTitle):\n+    \"\"\"\n+      Removes the file that RAVEN reads for postprocessing.\n+      @ In, jobTitle, string, job title name\n+      @ Out, None\n+    \"\"\"\n+    csvOutput = os.path.join(self.workingDir, jobTitle+'-'+self.perturbationNumber+'.csv')\n+    if os.path.isfile(csvOutput):\n+      os.remove(csvOutput)\n+    with open (csvOutput,'wb'):\n+      pass\n+    \n+  def getAbsoluteXS(self,xsOutput):\n+    \"\"\"\n+      Parses the absolute cross section output generated by PHISICS.\n+      @ In, xsOutput, string, filename of the XML file containing the absolute perturbed XS\n+      @ Out, labelList, list of the XS labels\n+      @ Out, valueList, list of the XS\n+    \"\"\"\n+    labelList = []\n+    valueList = []\n+    tree = ET.parse(os.path.join(self.workingDir,xsOutput))\n+    root = tree.getroot()\n+    for materialXML in root.getiterator('library'):\n+      for isotopeXML in materialXML.getiterator('isotope'):\n+        reactionList = [j.tag for j in isotopeXML]\n+        for k in xrange (0, len(reactionList)):\n+          for groupXML in isotopeXML.getiterator(reactionList[k]):\n+            individualGroup = [x.strip() for x in groupXML.attrib.get('g').split(',')]\n+            individualGroupValues = [y.strip() for y in groupXML.text.split(',')]\n+            for position in xrange(0,len(individualGroup)):\n+              labelList.append(materialXML.attrib.get('lib_name')+'|'+isotopeXML.attrib.get('id')+'|'+reactionList[k]+'|'+individualGroup[position])\n+              valueList.append(individualGroupValues[position])\n+    return labelList, valueList\n+    \n+  def removeSpaces(self,line):\n+    \"\"\"\n+      Removes the spaces.\n+      @ In, line, string\n+      @ Out, line, string, same line without the blank spaces\n+    \"\"\"\n+    line = re.sub(r' ',r'',line)\n+    return line\n+    \n+  def getNumberOfGroups(self):\n+    \"\"\"\n+      Gives the number of energy groups used in the PHISICS simulations.\n+      @ In, None \n+      @ Out, None \n+    \"\"\"\n+    self.Ngroups = 0\n+    with open(os.path.join(self.workingDir,self.instantOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'Number of elements of group', line):\n+          self.Ngroups = line.split()[-3]  # pick the last occurence (last group), which is also the number of groups\n+        if re.search(r'Number of element  types', line):\n+          break\n+  \n+  def getNumberOfRegions(self):\n+    \"\"\"\n+      Gives the number of spatial regions used in the PHISICS simulations.\n+      @ Out, None\n+    \"\"\"\n+    flagStart = 0\n+    count = 0\n+    subdomainList = []\n+    with open(os.path.join(self.workingDir,self.instantOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'Subdomain volumes',line):\n+          flagStart = 1\n+        if re.search(r'Balance report for the primal solution', line):\n+          flagStart = 2\n+        if flagStart == 1:\n+          stringIsNumber = self.isNumber(line.split())\n+          if stringIsNumber is True:\n+            count = count + 1\n+            subdomainList.append(line.split()[0])\n+        if flagStart == 2:\n+          break\n+    self.Nregions = count\n+    return\n+  \n+  def getPertNumber(self):\n+    \"\"\"\n+      Gets the current perturbation number.\n+      @ In, None\n+      @ Out, pertNumber, string, perturbation number in a string format\n+    \"\"\"\n+    splitWorkDir = self.workingDir.split('/')\n+    pertNumber = splitWorkDir[-1]\n+    return pertNumber\n+  \n+  def removeTheZeroTimeStep(self,timeSteps):\n+    \"\"\"\n+      Removes the first time step, t=0, to make the number of time steps match with the number of time steps in INSTANT.\n+      @ In, timeSteps, list, list of the time steps in MRTAU\n+      @ Out, timeSteps, list, time steps in MRTAU withtout the first time step\n+    \"\"\"\n+    timeSteps.pop(0)\n+    return timeSteps\n+    \n+  def getMrtauInstantTimeSteps(self):\n+    \"\"\"\n+      Gets the time steps in the coupled MRTAU/INSTANT output.\n+      @ In, None\n+      @ Out, timeSteps, list\n+    \"\"\"\n+    count = 0\n+    timeSteps = []\n+    with open(os.path.join(self.workingDir,self.mrtauOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'Material',line):\n+          count = count + 1\n+        if count == 1:\n+          stringIsFloatNumber = self.isFloatNumber(line.split(','))\n+          if stringIsFloatNumber is True:\n+            timeSteps.append(line.split(',')[0])\n+        if count > 1:\n+          break\n+    timeSteps = self.removeTheZeroTimeStep(timeSteps)\n+    return timeSteps\n+    \n+  def getMrtauTimeSteps(self):\n+    \"\"\"\n+      Gets the time steps in the MRTAU standalone output.\n+      @ In, None\n+      @ Out, timeSteps, list, list of time steps\n+    \"\"\"\n+    timeSteps = []\n+    with open(os.path.join(self.workingDir,self.mrtauOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        stringIsFloatNumber = self.isFloatNumber(line.split(','))\n+        if stringIsFloatNumber is True:\n+          timeSteps.append(line.split(',')[0])\n+    return timeSteps\n+    \n+  def getMrtauIsotopeList(self,mrtauCSVOutput):\n+    \"\"\"\n+      Gets the isotope in the MRTAU standalone output.\n+      @ In, mrtauCSVOutput, string, MRTAU file name\n+      @ Out, None\n+    \"\"\"\n+    self.isotopeListMrtau = []\n+    with open(os.path.join(self.workingDir,self.mrtauOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'TIME',line):\n+          line = re.sub(r'TIME\\s+\\(days\\)',r'',line)\n+          line = re.sub(r' ',r'',line)\n+          line = re.sub(r'\\n',r'',line)\n+          self.isotopeListMrtau = filter(None,line.split(','))\n+          break\n+    \n+  def getInstantTimeSteps(self,input):\n+    \"\"\"\n+      Gets the time steps in the INSTANT output.\n+      @ In, input, string, input file name\n+      @ Out, timeSteps, list, list of time steps\n+    \"\"\"\n+    count = 0\n+    timeSteps = []\n+    with open(os.path.join(self.workingDir,input), 'r') as outfile:\n+      for line in outfile :\n+        if re.search(r'PHISICS',line):\n+          timeSteps.append(line.split(',')[line.split(',').index('Time') + 1])\n+    return timeSteps\n+\n+  def reduceDigits(self,mrtauTimeSteps):\n+    \"\"\"\n+      Reduces the number of digits in the MRTAU time steps.\n+      @ In, mrtauTimeSteps, list\n+      @ Out, timeSteps, list, list of time steps\n+    \"\"\"\n+    timeSteps = []\n+    for i in xrange (0, len(mrtauTimeSteps)):\n+      timeSteps.append('%.6E' % (float(mrtauTimeSteps[i])))\n+    return timeSteps\n+  \n+  def findUnits(self,line):\n+    \"\"\"\n+      Returns the units in which the time steps are printed in the INSTANT output\n+      @ In, line, string, line containing the units\n+      @ Out, units, string\n+    \"\"\" \n+    units = line.split(' ')[-3]\n+    return units\n+  \n+  def getKeff (self):\n+    \"\"\"\n+      Gets the multiplication factor.\n+      @ In, None\n+      @ Out, keff, string, floating number under string format of keff\n+      @ Out, errorKeff, string, floating number under string format of errorKeff\n+    \"\"\"\n+    self.units = None\n+    keff = []\n+    with open(os.path.join(self.workingDir,self.instantOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'Time Input Type', line):\n+          self.units = self.findUnits(line)\n+        if re.search(r'k-effective at the last', line) :\n+          keff = [line.split()[-1]]\n+        if re.search(r'error for the eigenvalue', line) :\n+            errorKeff = [line.split()[-1]]\n+    return keff, errorKeff\n+\n+  def isNumber(self,line):\n+    \"\"\"\n+      Checks if a string is an integer.\n+      @ In, line, list, list of strings\n+      @ Out, isNumber, Boolean, True if integer, False otherwise\n+    \"\"\"\n+    if line != []:\n+      try:\n+        int(line[0])\n+        return True\n+      except ValueError:\n+        return False\n+        \n+  def isFloatNumber(self,line):\n+    \"\"\"\n+      Checks if a string is a float number.\n+      @ In, line, list, list of strings\n+      @ Out, isFloatNumber, Boolean, True if float, False otherwise\n+    \"\"\"\n+    if line != []:\n+      try:\n+        float(line[0])\n+        return True\n+      except ValueError:\n+        return False\n+   \n+  def convertInDays(self,instantTimeSteps):\n+    \"\"\"\n+      Converts the INSTANT time steps (seconds) into days.\n+      @ In, instantTimeSteps, list\n+      @ Out, timeSteps, list\n+    \"\"\"\n+    timeSteps = []\n+    for i in xrange (0, len(instantTimeSteps)):\n+      timeSteps.append('%.6E' % (float(instantTimeSteps[i]) / (24 * 60 * 60)))\n+    return timeSteps\n+   \n+  def declareDict(self,typeOfParameters,numbering):\n+    \"\"\"\n+      Declares the reaction rate dictionary.\n+      @ In, typeOfparameter, string, either 'reaction rate' or 'FissionMatrix', to select which matrix is to be parsed\n+      @ In, numbering, dict, Column number (key) parameter number (value)\n+      @ Out, dict, dictionary, dictionary with reaction rate keys, and empty values\n+    \"\"\"\n+    dict = {}\n+    if self.printSpatialRR is True:\n+      for i in xrange (1,int(self.Ngroups) + 1):\n+        dict[str(i)] = {}\n+        for j in xrange (1,int(self.Nregions) + 1):\n+          dict[str(i)][str(j)] = {}\n+          for k in xrange (0, len(numbering)):\n+            if numbering.keys()[k] == 'Group':\n+              pass\n+            else:\n+              dict[str(i)][str(j)][numbering.keys()[k]] = {}\n+    if self.printSpatialRR is False:\n+      for k in xrange (0, len(numbering)):\n+        if numbering.keys()[k] == 'Group':\n+          pass\n+        else:\n+          dict[numbering.keys()[k]] = {}\n+    if typeOfParameters == 'reactionRates':   # Puts the reaction rate labels in a list\n+      self.paramList = []\n+      for key in numbering.iterkeys():\n+        self.paramList.append(key)\n+        \n+    if typeOfParameters == 'FissionMatrix':   # Puts the fission matrix labels in a list\n+      self.matrixList = []\n+      for key in numbering.iterkeys():\n+        self.matrixList.append(key)\n+    return dict\n+        \n+  def getReactionRates(self,numberOfMPI):\n+    \"\"\"\n+      Gets the reactions rates, power for each group in PHISICS\n+      @ In, None\n+      @ Out, ReactionRateDict, dictionary, dictionary containing the reaction rate info\n+    \"\"\"\n+    flagStart = 0\n+    count = 0\n+    countTimeStep = 0\n+    for mpi in xrange (0,numberOfMPI): # parse all the segmented files\n+      with open(os.path.join(self.workingDir,self.instantOutputFileMPI[mpi]), 'r') as outfile:\n+        for line in outfile:\n+          if re.search(r'averaged flux\\s+power', line):\n+            if mpi == 0:\n+              self.numberingRR = self.mapColumns(line,count)\n+              reactionRateDict = self.declareDict('reactionRates',self.numberingRR)\n+            flagStart = 1\n+            countTimeStep = countTimeStep + 1\n+          if re.search(r'Fission matrices of all',line):\n+            flagStart = 2\n+          if flagStart == 1:\n+            if self.printSpatialRR is True:  # if the spatial reaction rates are printed\n+              if re.search(r'\\w+\\s+\\w+',line):\n+                line = re.sub(r'[\\|]',' ',line)\n+                line = line.split()\n+                stringIsNumber = self.isNumber(line)\n+                if stringIsNumber == True :\n+                  for i in xrange (0,len(self.numberingRR)):\n+                    groupNum  = line[0]\n+                    regionNum = line[1]\n+                    if self.paramList[i] == 'Group':\n+                      pass\n+                    else:\n+                      reactionRateDict[groupNum][regionNum][self.paramList[i]][mpi] = line[self.numberingRR.get(self.paramList[i])]\n+            if self.printSpatialRR is False:  # if the spatial reaction rates are not printed\n+              if re.search(r'Total',line):\n+                line = line.split()\n+                for i in xrange (0,len(self.numberingRR)):\n+                  if self.paramList[i] == 'Group' or self.paramList[i] == 'Region':\n+                    pass\n+                  else:                \n+                    reactionRateDict[self.paramList[i]][mpi] = line[self.numberingRR.get(self.paramList[i])]\n+    if reactionRateDict != {}:\n+      return reactionRateDict\n+    \n+  def getMatrix(self,startStringFlag,endStringFlag,typeOfMatrix,numberOfMPI):\n+    \"\"\"\n+      Gets the fission matrix or scattering matrix in the PHISICS output.\n+      @ In, startStringFlag, string, string marker.\n+      @ In, endStringFlag, string, string marker.\n+      @ In, typeOfMatrix, string, allows to choose between fission matrix parsing or scattering matrix parsing\n+      @ In, numberOfMPI, interger, number of MPI user-defined\n+      @ Out, matrixDict, dictionary\n+    \"\"\"\n+    flagStart = 0\n+    count = 0\n+    countTimeStep = 0\n+    matrixDict = {}\n+    for mpi in xrange (0,numberOfMPI): # parse all the segmented files\n+      with open(os.path.join(self.workingDir,self.instantOutputFileMPI[mpi]), 'r') as outfile:\n+        for line in outfile:\n+          if re.search(startStringFlag, line):\n+            flagStart = 1\n+            countTimeStep = countTimeStep + 1\n+          if re.search(endStringFlag,line):\n+            flagStart = 2\n+          if flagStart == 1:\n+            if re.search(r'\\s+1\\s+2\\s+3\\s+4',line):\n+              line = re.sub(r'[\\|]',' ',line)\n+              self.matrixNumbering = self.mapColumns(line,count)\n+              if mpi == 0: # declare the dictionary only at the first iteration\n+                matrixDict = self.declareDict(typeOfMatrix,self.matrixNumbering)\n+            if re.search(r'Region\\:\\s+\\d',line):\n+              regionNumber = line.split()[-1]\n+            if re.search(r'\\d+.\\d+E',line):\n+              line = re.sub(r'[\\|]',' ',line)\n+              line = line.split()\n+              for i in xrange (1,len(self.matrixNumbering) + 1):\n+                print mpi\n+                matrixDict[line[0]][str(regionNumber)][str(i)][str(mpi)] = line[self.matrixNumbering.get(str(i)) + 1]  \n+    return matrixDict\n+  \n+  def mapColumns(self,line,count):\n+    \"\"\"\n+      Allocates a column number relative to the reaction rates.\n+      @ In, line, string\n+      @ In, count, interger, counts the column position\n+      @ Out, numbering, dictionary, key: reaction rate name, value: column number\n+    \"\"\"\n+    numbering = {}\n+    line = re.sub(r'averaged',r'',line)\n+    line = re.sub(r'fis. ',r'',line)\n+    line = re.sub(r'[\\|]',' ',line)\n+    parameterNames = line.split()\n+    for i in xrange(len(parameterNames)):\n+      numbering[parameterNames[i]] = count\n+      count = count + 1\n+    return numbering\n+\n+  def locateXYandGroups(self,IDlist):\n+    \"\"\"\n+      Locates what the position number of the x, y, z coordinates and the first energy group are in the INSTANT csv output file. \n+      @ In, IDlist, list, list of all the parameter in the csv output\n+      @ Out, xPositionInList, interger, position of the parameter x in the list\n+      @ Out, yPositionInList, interger, position of the parameter y in the list\n+      @ Out, zPositionInList, interger, position of the parameter z in the list\n+      @ Out, firstGroupPositionInList, interger, position of the first energy parameter\n+    \"\"\"\n+    xPositionInList = 0\n+    yPositionInList = 0\n+    zPositionInList = 0\n+    firstGroupPositionInList = 0\n+    for i in xrange (0,len(IDlist)):\n+      if IDlist[i] == 'X':\n+        xPositionInList = i\n+      if IDlist[i] == 'Y':\n+        yPositionInList = i\n+      if IDlist[i] == 'Z':\n+        zPositionInList = i\n+      if IDlist[i] == '1':\n+        group1PositionInList = i\n+        break\n+    return xPositionInList, yPositionInList, zPositionInList, group1PositionInList\n+    \n+  def getFluxInfo(self,input):\n+    \"\"\"\n+      Reads the INSTANT csv file to get the flux info relative to each region and each group.\n+      The flux info are also provided for each material.\n+      @ In, input, string, file name\n+      @ Out, fluxLabelList, list, labels relative to flux\n+      @ Out, fluxList, list, flux values\n+      @ Out, matFluxLabelList, list, labels relative to material flux\n+      @ Out, matFluxList, list, material flux values\n+    \"\"\"\n+    IDlist = []\n+    fluxLabelList = []\n+    fluxList = []\n+    matFluxLabelList = []\n+    matFluxList = []\n+    flagFlux = 0\n+    countTimeStep = 0\n+    with open(os.path.join(self.workingDir,input), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'PHISICS',line):\n+          flagFlux = 0\n+          countTimeStep = countTimeStep + 1\n+        if re.search(r'FLUX BY CELLS',line):\n+          flagFlux = 1\n+        if re.search(r'FLUX BY MATERIAL',line):\n+          flagFlux = 2\n+        if re.search(r'FLUX BY SUBDOMAIN',line):\n+          flagFlux = 3\n+        \n+        if flagFlux == 1:\n+          if re.search(r'ID\\s+,\\s+ID',line):\n+            line = re.sub(r' ',r'',line)\n+            IDlist = line.split(',')\n+            xPosition, yPosition, zPosition, group1Position = self.locateXYandGroups(IDlist)\n+            IDlist.remove('\\n')\n+          stringIsNumber = self.isNumber(line.split(','))\n+          if stringIsNumber is True:\n+            line = re.sub(r' ',r'',line)\n+            line = re.sub(r'\\n',r'',line)\n+            for g in xrange (1,int(self.Ngroups) + 1):\n+              if countTimeStep == 1: # the labels are the same for each time step\n+                fluxLabelList.append('flux'+'|'+'cell'+line.split(',')[0]+'|'+'gr'+str(g))\n+              fluxList.append(line.split(',')[group1Position + g - 1])\n+              \n+        if flagFlux == 2:\n+          stringIsNumber = self.isNumber(line.split(','))\n+          if stringIsNumber is True:\n+            line = re.sub(r' ',r'',line)\n+            line = re.sub(r'\\n',r'',line)\n+            for g in xrange (1,int(self.Ngroups) + 1):\n+              if countTimeStep == 1:\n+                matFluxLabelList.append('flux'+'|'+'mat'+line.split(',')[0]+'|'+'gr'+str(g))\n+              matFluxList.append(line.split(',')[g])\n+    return fluxLabelList, fluxList, matFluxLabelList, matFluxList\n+ \n+  def getFluxInfoPhiRel(self,input):\n+    \"\"\"\n+      Gets the flux info by cell and material if the PHISICS/RELAP coupled version is used.\n+      @ In, input, string, csv output\n+      @ Out, labelList, list, list of labels\n+      @ Out, varList, list, lidt of values relative to the labels\n+    \"\"\"\n+    IDlist = []\n+    labelList = []\n+    varList = []\n+    flagFlux = 0\n+    countTimeStep = 0\n+    with open(os.path.join(self.workingDir,input), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'PHISICS',line):\n+          flagFlux = 0\n+          countTimeStep = countTimeStep + 1\n+        if re.search(r'FLUX BY CELLS',line):\n+          flagFlux = 1\n+        if re.search(r'POWER DENSITY BY CELLS',line):\n+          flagFlux = 2\n+        if re.search(r'FLUX BY SUBDOMAIN',line):\n+          flagFlux = 3\n+        \n+        if flagFlux == 1:\n+          if re.search(r'ID\\s+,\\s+ID',line):\n+            line = re.sub(r' ',r'',line)\n+            IDlist = line.split(',')\n+            xPosition, yPosition, zPosition, group1Position = self.locateXYandGroups(IDlist)\n+            IDlist.remove('\\n')\n+          stringIsNumber = self.isNumber(line.split(','))\n+          if stringIsNumber is True:\n+            line = re.sub(r' ',r'',line)\n+            line = re.sub(r'\\n',r'',line)\n+            for g in xrange (1,int(self.Ngroups) + 1):\n+              if countTimeStep == 1: # the labels are the same for each time step\n+                labelList.append('flux'+'|'+'cell'+line.split(',')[0]+'|'+'gr'+str(g))\n+              varList.append(line.split(',')[group1Position + g - 1])\n+              \n+        if flagFlux == 2:\n+          stringIsNumber = self.isNumber(line.split(','))\n+          if stringIsNumber is True:\n+            line = re.sub(r' ',r'',line)\n+            line = re.sub(r'\\n',r'',line)\n+            for g in xrange (1,int(self.Ngroups) + 1):\n+              if countTimeStep == 1:\n+                labelList.append('flux'+'|'+'mat'+line.split(',')[0]+'|'+'gr'+str(g))\n+              varList.append(line.split(',')[g])\n+    return labelList, varList\n+    \n+  def getMaterialList(self,line,matList):\n+    \"\"\"\n+    Returns a list of all the problem materials.\n+    @ In, line, list\n+    @ In, matList, list\n+    @ Out, matList, list (appends additional material)\n+    \"\"\"\n+    matList.append(line[1])\n+    return matList\n+ \n+  def getDepInfo(self,timeStepIndex,matchedTimeSteps,numberOfMPI):\n+    \"\"\"\n+      Reads the INSTANT csv file to get the material density info relative to depletion.\n+      @ In, timeStepIndex, integer, timestep number\n+      @ In, matchedTimeSteps, list, list of time steps considered\n+      @ In, numberOfMPI, interger, number of MPI used\n+      @ Out, depLabelList, list, list of labels relative to depletion\n+      @ Out, depList, list, list of values relative to depletion\n+    \"\"\"\n+    materialList = []\n+    depLabelList = []\n+    depList = []\n+    timeStepList = []\n+    matList = []\n+    for mpi in xrange(0,numberOfMPI):\n+      with open(os.path.join(self.workingDir,self.mrtauOutputFileMPI[mpi]), 'r') as outfile:\n+        for line in outfile:\n+          line = self.removeSpaces(line)\n+          if re.search(r'TIME',line):\n+            line = re.sub(r'\\n',r'',line)\n+            self.isotopeList = line.split(',')\n+          if re.search(r'Material',line):\n+            materialList = line.split(',')\n+            matList = self.getMaterialList(line.split(','), matList)\n+          stringIsFloatNumber = self.isFloatNumber(line.split(','))\n+          if stringIsFloatNumber is True:\n+            line = re.sub(r'\\n',r'',line)\n+            if (float(line.split(',')[0]) == float(matchedTimeSteps[timeStepIndex])):\n+              for i in xrange (1,len(self.isotopeList)):\n+                timeStepList.append(line.split(',')[0])\n+                depLabelList.append('dep'+'|'+materialList[1]+'|'+self.isotopeList[i])\n+                depList.append(line.split(',')[i])\n+    return depLabelList, depList, timeStepList, matList\n+  \n+  def getDepInfoMrtau(self,timeStepIndex,matchedTimeSteps):\n+    \"\"\"\n+      Reads the MRTAU csv file to get the material density info relative to depletion.\n+      @ In, timeStepIndex, integer, timestep number\n+      @ In, matchedTimeSteps, list, list of time steps considered\n+      @ Out, depLabelList, depList\n+    \"\"\"\n+    depList = []\n+    with open(os.path.join(self.workingDir,self.mrtauOutputFileMPI[0]), 'r') as outfile:\n+      for line in outfile:\n+        line = self.removeSpaces(line)\n+        stringIsFloatNumber = self.isFloatNumber(line.split(','))\n+        if stringIsFloatNumber is True:\n+          if (float(line.split(',')[0]) == float(matchedTimeSteps[timeStepIndex])):\n+            line = re.sub(r'\\n',r'',line)\n+            for i in xrange (0,len(self.isotopeListMrtau)):\n+              depList.append(line.split(',')[i+1])\n+    return depList\n+    \n+  def findDecayHeat(self,line):\n+    \"\"\"\n+      Determines whether the decay heat is printed.\n+      @ In, line, string\n+      @ Out, findDecayHeat, boolean, True if decay heat is printed, false otherwise\n+      @ Out, DecayHeatUnits, string\n+    \"\"\"\n+    DecayHeatUnits = None\n+    isDecayHeatPrinted = line.split(' ')[-2]\n+    if isDecayHeatPrinted == 'YES':\n+      DecayHeatUnits =  line.split(' ')[-1]\n+      return True, DecayHeatUnits\n+    else:\n+      return False, DecayHeatUnits\n+  \n+  def numberOfMediaUsed(self,mpi,numberOfMPI):\n+    \"\"\"\n+      Finds the number of media used in a given INSTANT output.\n+      @ In, mpi, integer, MPI number considered\n+      @ In, numberOfMPI, integer, total number of MPI user-selected\n+      @ Out, mediaUsed, integer, number of media treated in one INSTANT MPI output\n+    \"\"\"\n+    count = 0\n+    if self.phisicsRelap is True and mpi >= numberOfMPI - 1:\n+      pass\n+    else:\n+      with open(os.path.join(self.workingDir, self.instantOutputFileMPI[mpi])) as outfile:\n+        for line in outfile:\n+          if re.search(r'Medium\\s+\\d+\\s+used',line):\n+            count = count + 1\n+    return count\n+\n+  def getCPUtime(self,numberOfMPI):\n+    \"\"\"\n+      Gets the PHISICS CPU time.\n+      @ In, numberOfMPI, interger, number of MPI user-selected\n+      @ Out, cpuTime, list, cpu time (string) in a list\n+    \"\"\"\n+    cpuTimes = []\n+    for mpi in xrange (0,numberOfMPI):\n+      with open(os.path.join(self.workingDir,self.instantOutputFileMPI[mpi])) as outfile:\n+        for line in outfile:\n+          if re.search(r'CPU\\s+time\\s+\\(min\\)',line) and self.phisicsRelap is False:\n+            cpuTimes.append(line.strip().split(' ')[-1])\n+          if self.phisicsRelap is True:\n+            return 'na'\n+    cpuTime = self.summedListValues(cpuTimes)\n+    return [cpuTime]\n+          \n+  def locateMaterialInFile(self,numberOfMPI):\n+    \"\"\"\n+      Finds the material names in a given INSTANT output file.\n+      @ In, numberOfMPI, integer, number of MPI user-selected\n+      @ Out, materialsDict, dictionary, dictionary listing the media treated in a given mpi output.\n+              format: {MPI-0:{1:fuel1_1, 2:fuel1_5, 3:{fuel1_7}}, MPI-2:{1:fuel1_2, 2:fuel1_3, 3:fuel1_4, 4:fuel1_6}}\n+    \"\"\"\n+    materialsDict = {}\n+    for mpi in xrange(0,numberOfMPI):\n+      count = 0\n+      materialsDict['MPI-'+str(mpi)] = {}\n+      mediaUsed = self.numberOfMediaUsed(mpi,numberOfMPI)\n+      if self.phisicsRelap is True and mpi >= numberOfMPI - 1 : pass\n+      else:\n+        with open(os.path.join(self.workingDir, self.instantOutputFileMPI[mpi])) as outfile:\n+          for line in outfile:\n+            if re.search(r'Density spatial moment',line):\n+              count = count + 1\n+              matLine = filter(None, line.split(' '))\n+              materialsDict['MPI-'+str(mpi)][count] = matLine[matLine.index('Material') + 1]\n+              if count == mediaUsed:\n+                break\n+    return materialsDict\n+   \n+  def getDecayHeat(self,timeStepIndex,matchedTimeSteps):\n+    \"\"\"\n+      Reads the main output file to get the decay heat.\n+      @ In, timeStepIndex, integer, number of the timestep considered\n+      @ In, matchedTimeSteps, list, list of time steps considered\n+      @ Out, decayLabelList, list, list of the decay labels (under the format fuel|isotope)\n+      @ Out, decayList, list, list of the decay heat values\n+    \"\"\"\n+    materialList = []\n+    decayLabelList = []\n+    decayList = []\n+    timeStepList = []\n+    for mpi in xrange(0,len(self.instantOutputFileMPI)):\n+      decayFlag = 0 \n+      breakFlag = 0 \n+      matLineFlag = 0 \n+      materialCounter = 0\n+      with open(os.path.join(self.workingDir, self.instantOutputFileMPI[mpi])) as outfile:\n+        for line in outfile:\n+          if re.search(r'Decay Heat computed',line) and mpi == 0:\n+            self.isDecayHeatPrinted, self.decayHeatUnits = self.findDecayHeat(line)\n+            if self.isDecayHeatPrinted is False:\n+              decayLabelList = ['decayHeat']\n+              decayList = 0\n+              return  decayLabelList,decayList\n+          if re.search(r'INDIVIDUAL DECAY HEAT BLOCK',line):\n+            decayFlag = 1\n+            materialCounter = materialCounter + 1\n+          if re.search(r'CUMULATIVE DECAY HEAT BLOCK',line):\n+            decayFlag = 0\n+          if re.search(r'BURNUP OUTPUT',line):\n+            breakFlag = 1\n+          if decayFlag == 1 and breakFlag == 0:\n+            line = re.sub(r'\\n',r'',line)\n+            decayLine = filter(None, line.split(' '))\n+            if decayLine != []:\n+              stringIsFloatNumber = self.isFloatNumber(decayLine)\n+            if stringIsFloatNumber is True and decayLine != []:\n+              if (float(decayLine[0]) == float(matchedTimeSteps[timeStepIndex])):\n+                for i in xrange (1,len(self.isotopeList)):\n+                  decayLabelList.append('decay'+'|'+self.materialsDict['MPI-'+str(mpi)][materialCounter]+'|'+self.isotopeList[i])\n+                  decayList.append(decayLine[i])\n+          if breakFlag == 1:\n+            break\n+    return decayLabelList, decayList\n+      \n+  def getDecayHeatMrtau(self,timeStepIndex,matchedTimeSteps):\n+    \"\"\"\n+      Gets the decay heat from the standalone MRTAU output.\n+      @ In, timeStepIndex, integer, timestep number\n+      @ In, matchedTimeSteps, list, list of time steps considered\n+      @ Out, decayListMrtau, list, list of the decay values from MRTAU\n+    \"\"\"\n+    decayFlag = 0\n+    breakFlag = 0\n+    self.decayLabelListMrtau = []\n+    self.numDensityLabelListMrtau = []\n+    decayListMrtau = []\n+    with open(os.path.join(self.workingDir,self.mrtauCSVOutputMPI), 'r') as outfile:\n+      for line in outfile:\n+        if re.search(r'INDIVIDUAL DECAY HEAT BLOCK',line):\n+          decayFlag = 1\n+        if re.search(r'CUMULATIVE DECAY HEAT BLOCK',line):\n+          breakFlag = 1\n+        if decayFlag == 1 and breakFlag == 0:\n+          line = re.sub(r'\\n',r'',line)\n+          decayLine = filter(None, line.split(' '))\n+          if decayLine != []: stringIsFloatNumber = self.isFloatNumber(decayLine)\n+          if stringIsFloatNumber is True and decayLine != []:\n+            if (float(decayLine[0]) == float(matchedTimeSteps[timeStepIndex])):\n+              for i in xrange (0,len(self.isotopeListMrtau)):\n+                if int(self.perturbationNumber) == 1:\n+                  self.numDensityLabelListMrtau.append('numDensity'+'|'+self.isotopeListMrtau[i])\n+                  self.decayLabelListMrtau.append('decay'+'|'+self.isotopeListMrtau[i])\n+                decayListMrtau.append(decayLine[i+1])\n+          if breakFlag == 1:\n+            break\n+    return decayListMrtau\n+  \n+  def getRRlist(self,instantDict):\n+    \"\"\"\n+      Puts the reaction rate labels and the reaction rate values in a list.\n+      @ In, instantDict, dictionary\n+      @ Out, rrNames, list, list of parameter labels that are in the reaction rate matrix\n+      @ Out, rrValues, list, values relative to the labels, within the reaction rate matrix\n+    \"\"\"\n+    rrNames = []\n+    rrValues = []\n+    if self.printSpatialRR is True:\n+      for i in xrange(0,len(self.paramList)):\n+        for j in xrange(1,int(self.Ngroups) + 1):\n+          for k in xrange(1, int(self.Nregions) + 1):\n+            if self.paramList[i] == 'Group':\n+              pass\n+            else:\n+              rrNames.append(self.paramList[i]+'|gr'+str(j)+'|reg'+str(k))\n+              rrValues.append(instantDict.get('reactionRateInfo').get(str(j)).get(str(k)).get(self.paramList[i]))\n+    if self.printSpatialRR is False:\n+      for i in xrange(0,len(self.paramList)):\n+        if self.paramList[i]   == 'Group':\n+          pass\n+        elif self.paramList[i] == 'Region':\n+          pass\n+        else:\n+          rrNames.append(self.paramList[i]+'|Total')\n+          rrValues.append(instantDict.get('reactionRateInfo').get(self.paramList[i]))\n+    if 'Group' in rrNames:\n+      rrNames.remove('Group')\n+    return rrNames, rrValues\n+    \n+  def writeCSV(self,instantDict,timeStepIndex,matchedTimeSteps,jobTitle):\n+    \"\"\"\n+      Prints the INSTANT/MRTAU data in csv files.\n+      @ In, InstantDict, dictionary, contains all the values collected from INSTANT output\n+      @ In, timeStepIndex, integer, timestep number\n+      @ In, matchedTimeSteps, list, list of time steps considered\n+      @ In, jobTitle, string, job title parsed from INSTANT input\n+      @ Out, None\n+      \n+    \"\"\"\n+    if self.paramList != []:\n+      rrNames, rrValues = self.getRRlist(instantDict)\n+      csvOutput = os.path.join(instantDict.get('workingDir'),jobTitle+'-'+self.perturbationNumber+'.csv')\n+      if self.phisicsRelap is False:\n+        with open(csvOutput, 'a+') as f:\n+          instantWriter = csv.writer(f, delimiter=',',quotechar=',', quoting=csv.QUOTE_MINIMAL)\n+          if timeStepIndex == 0:\n+            instantWriter.writerow(['timeMrTau'] + ['keff'] + ['errorKeff'] + rrNames + instantDict.get('fluxLabelList') + instantDict.get('matFluxLabelList') + instantDict.get('depLabelList') + instantDict.get('decayLabelList') + instantDict.get('xsLabelList') + ['cpuTime'])","path":"framework/CodeInterfaces/PHISICS/phisicsdata.py","position":null,"original_position":940,"commit_id":"70a33a7af4fe4e451a0f9d237a3798e79b89104b","original_commit_id":"8eeea000284e32d993de9d866e8e07d1605b33f1","user":{"login":"alfoa","id":9202671,"avatar_url":"https://avatars0.githubusercontent.com/u/9202671?v=4","gravatar_id":"","url":"https://api.github.com/users/alfoa","html_url":"https://github.com/alfoa","followers_url":"https://api.github.com/users/alfoa/followers","following_url":"https://api.github.com/users/alfoa/following{/other_user}","gists_url":"https://api.github.com/users/alfoa/gists{/gist_id}","starred_url":"https://api.github.com/users/alfoa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alfoa/subscriptions","organizations_url":"https://api.github.com/users/alfoa/orgs","repos_url":"https://api.github.com/users/alfoa/repos","events_url":"https://api.github.com/users/alfoa/events{/privacy}","received_events_url":"https://api.github.com/users/alfoa/received_events","type":"User","site_admin":false},"body":"Yes","created_at":"2018-04-19T04:46:33Z","updated_at":"2018-04-19T04:46:33Z","html_url":"https://github.com/idaholab/raven/pull/510#discussion_r182632495","pull_request_url":"https://api.github.com/repos/idaholab/raven/pulls/510","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/idaholab/raven/pulls/comments/182632495"},"html":{"href":"https://github.com/idaholab/raven/pull/510#discussion_r182632495"},"pull_request":{"href":"https://api.github.com/repos/idaholab/raven/pulls/510"}},"in_reply_to_id":180789384},"pull_request":{"url":"https://api.github.com/repos/idaholab/raven/pulls/510","id":162415522,"html_url":"https://github.com/idaholab/raven/pull/510","diff_url":"https://github.com/idaholab/raven/pull/510.diff","patch_url":"https://github.com/idaholab/raven/pull/510.patch","issue_url":"https://api.github.com/repos/idaholab/raven/issues/510","number":510,"state":"open","locked":false,"title":"WIP: Alfoa/rouxpn/phisics interface","user":{"login":"rouxpn","id":30636482,"avatar_url":"https://avatars3.githubusercontent.com/u/30636482?v=4","gravatar_id":"","url":"https://api.github.com/users/rouxpn","html_url":"https://github.com/rouxpn","followers_url":"https://api.github.com/users/rouxpn/followers","following_url":"https://api.github.com/users/rouxpn/following{/other_user}","gists_url":"https://api.github.com/users/rouxpn/gists{/gist_id}","starred_url":"https://api.github.com/users/rouxpn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rouxpn/subscriptions","organizations_url":"https://api.github.com/users/rouxpn/orgs","repos_url":"https://api.github.com/users/rouxpn/repos","events_url":"https://api.github.com/users/rouxpn/events{/privacy}","received_events_url":"https://api.github.com/users/rouxpn/received_events","type":"User","site_admin":false},"body":"--------\r\nPull Request Description\r\n--------\r\n##### What issue does this change request address? (Use \"#\" before the issue to link it, i.e., #42.)\r\n\r\n\r\n##### What are the significant changes in functionality due to this change request?\r\n\r\n\r\n----------------\r\nFor Change Control Board: Change Request Review\r\n----------------\r\nThe following review must be completed by an authorized member of the Change Control Board.\r\n- [ ] 1. Review all computer code.\r\n- [ ] 2. If any changes occur to the input syntax, there must be an accompanying change to the user manual and xsd schema. If the input syntax change deprecates existing input files, a conversion script needs to be added (see Conversion Scripts).\r\n- [ ] 3. Make sure the Python code and commenting standards are respected (camelBack, etc.) - See on the [wiki](https://github.com/idaholab/raven/wiki/RAVEN-Code-Standards#python) for details.\r\n- [ ] 4. Automated Tests should pass, including run_tests, pylint, manual building and xsd tests. If there are changes to Simulation.py or JobHandler.py the qsub tests must pass.\r\n- [ ] 5. If significant functionality is added, there must  be tests added to check this. Tests should cover all possible options.  Multiple short tests are preferred over one large test. If new development on the internal JobHandler parallel system is performed, a cluster test must be added setting, in <RunInfo> XML block, the node ```<internalParallel>``` to True.\r\n- [ ] 6. If the change modifies or adds a requirement or a requirement based test case, the Change Control Board's Chair or designee also needs to approve the change.  The requirements and the requirements test shall be in sync.\r\n- [ ] 7. The merge request must reference an issue.  If the issue is closed, the issue close checklist shall be done.\r\n- [ ] 8. If an analytic test is changed/added is the the analytic documentation updated/added?\r\n","created_at":"2018-01-11T15:53:25Z","updated_at":"2018-04-19T04:46:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"18159b69e4e3c10acffd5c7b71e18187b0bd9007","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/idaholab/raven/pulls/510/commits","review_comments_url":"https://api.github.com/repos/idaholab/raven/pulls/510/comments","review_comment_url":"https://api.github.com/repos/idaholab/raven/pulls/comments{/number}","comments_url":"https://api.github.com/repos/idaholab/raven/issues/510/comments","statuses_url":"https://api.github.com/repos/idaholab/raven/statuses/70a33a7af4fe4e451a0f9d237a3798e79b89104b","head":{"label":"alfoa:alfoa/rouxpn/phisics_interface","ref":"alfoa/rouxpn/phisics_interface","sha":"70a33a7af4fe4e451a0f9d237a3798e79b89104b","user":{"login":"alfoa","id":9202671,"avatar_url":"https://avatars0.githubusercontent.com/u/9202671?v=4","gravatar_id":"","url":"https://api.github.com/users/alfoa","html_url":"https://github.com/alfoa","followers_url":"https://api.github.com/users/alfoa/followers","following_url":"https://api.github.com/users/alfoa/following{/other_user}","gists_url":"https://api.github.com/users/alfoa/gists{/gist_id}","starred_url":"https://api.github.com/users/alfoa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alfoa/subscriptions","organizations_url":"https://api.github.com/users/alfoa/orgs","repos_url":"https://api.github.com/users/alfoa/repos","events_url":"https://api.github.com/users/alfoa/events{/privacy}","received_events_url":"https://api.github.com/users/alfoa/received_events","type":"User","site_admin":false},"repo":{"id":88065586,"name":"raven","full_name":"alfoa/raven","owner":{"login":"alfoa","id":9202671,"avatar_url":"https://avatars0.githubusercontent.com/u/9202671?v=4","gravatar_id":"","url":"https://api.github.com/users/alfoa","html_url":"https://github.com/alfoa","followers_url":"https://api.github.com/users/alfoa/followers","following_url":"https://api.github.com/users/alfoa/following{/other_user}","gists_url":"https://api.github.com/users/alfoa/gists{/gist_id}","starred_url":"https://api.github.com/users/alfoa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alfoa/subscriptions","organizations_url":"https://api.github.com/users/alfoa/orgs","repos_url":"https://api.github.com/users/alfoa/repos","events_url":"https://api.github.com/users/alfoa/events{/privacy}","received_events_url":"https://api.github.com/users/alfoa/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/alfoa/raven","description":"RAVEN is a flexible and multi-purpose probabilistic risk analysis, uncertainty quantification, parameter optimization and data knowledge-discovering framework.","fork":true,"url":"https://api.github.com/repos/alfoa/raven","forks_url":"https://api.github.com/repos/alfoa/raven/forks","keys_url":"https://api.github.com/repos/alfoa/raven/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alfoa/raven/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alfoa/raven/teams","hooks_url":"https://api.github.com/repos/alfoa/raven/hooks","issue_events_url":"https://api.github.com/repos/alfoa/raven/issues/events{/number}","events_url":"https://api.github.com/repos/alfoa/raven/events","assignees_url":"https://api.github.com/repos/alfoa/raven/assignees{/user}","branches_url":"https://api.github.com/repos/alfoa/raven/branches{/branch}","tags_url":"https://api.github.com/repos/alfoa/raven/tags","blobs_url":"https://api.github.com/repos/alfoa/raven/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alfoa/raven/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alfoa/raven/git/refs{/sha}","trees_url":"https://api.github.com/repos/alfoa/raven/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alfoa/raven/statuses/{sha}","languages_url":"https://api.github.com/repos/alfoa/raven/languages","stargazers_url":"https://api.github.com/repos/alfoa/raven/stargazers","contributors_url":"https://api.github.com/repos/alfoa/raven/contributors","subscribers_url":"https://api.github.com/repos/alfoa/raven/subscribers","subscription_url":"https://api.github.com/repos/alfoa/raven/subscription","commits_url":"https://api.github.com/repos/alfoa/raven/commits{/sha}","git_commits_url":"https://api.github.com/repos/alfoa/raven/git/commits{/sha}","comments_url":"https://api.github.com/repos/alfoa/raven/comments{/number}","issue_comment_url":"https://api.github.com/repos/alfoa/raven/issues/comments{/number}","contents_url":"https://api.github.com/repos/alfoa/raven/contents/{+path}","compare_url":"https://api.github.com/repos/alfoa/raven/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alfoa/raven/merges","archive_url":"https://api.github.com/repos/alfoa/raven/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alfoa/raven/downloads","issues_url":"https://api.github.com/repos/alfoa/raven/issues{/number}","pulls_url":"https://api.github.com/repos/alfoa/raven/pulls{/number}","milestones_url":"https://api.github.com/repos/alfoa/raven/milestones{/number}","notifications_url":"https://api.github.com/repos/alfoa/raven/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alfoa/raven/labels{/name}","releases_url":"https://api.github.com/repos/alfoa/raven/releases{/id}","deployments_url":"https://api.github.com/repos/alfoa/raven/deployments","created_at":"2017-04-12T15:08:36Z","updated_at":"2018-04-10T17:03:30Z","pushed_at":"2018-04-18T23:41:22Z","git_url":"git://github.com/alfoa/raven.git","ssh_url":"git@github.com:alfoa/raven.git","clone_url":"https://github.com/alfoa/raven.git","svn_url":"https://github.com/alfoa/raven","homepage":"https://raven.inl.gov/","size":459812,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":1,"open_issues":1,"watchers":0,"default_branch":"devel"}},"base":{"label":"idaholab:devel","ref":"devel","sha":"fbee9e3def3c1ee576d1af85f3258cc816ceaaaf","user":{"login":"idaholab","id":3855370,"avatar_url":"https://avatars0.githubusercontent.com/u/3855370?v=4","gravatar_id":"","url":"https://api.github.com/users/idaholab","html_url":"https://github.com/idaholab","followers_url":"https://api.github.com/users/idaholab/followers","following_url":"https://api.github.com/users/idaholab/following{/other_user}","gists_url":"https://api.github.com/users/idaholab/gists{/gist_id}","starred_url":"https://api.github.com/users/idaholab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/idaholab/subscriptions","organizations_url":"https://api.github.com/users/idaholab/orgs","repos_url":"https://api.github.com/users/idaholab/repos","events_url":"https://api.github.com/users/idaholab/events{/privacy}","received_events_url":"https://api.github.com/users/idaholab/received_events","type":"Organization","site_admin":false},"repo":{"id":85989537,"name":"raven","full_name":"idaholab/raven","owner":{"login":"idaholab","id":3855370,"avatar_url":"https://avatars0.githubusercontent.com/u/3855370?v=4","gravatar_id":"","url":"https://api.github.com/users/idaholab","html_url":"https://github.com/idaholab","followers_url":"https://api.github.com/users/idaholab/followers","following_url":"https://api.github.com/users/idaholab/following{/other_user}","gists_url":"https://api.github.com/users/idaholab/gists{/gist_id}","starred_url":"https://api.github.com/users/idaholab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/idaholab/subscriptions","organizations_url":"https://api.github.com/users/idaholab/orgs","repos_url":"https://api.github.com/users/idaholab/repos","events_url":"https://api.github.com/users/idaholab/events{/privacy}","received_events_url":"https://api.github.com/users/idaholab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/idaholab/raven","description":"RAVEN is a flexible and multi-purpose probabilistic risk analysis, uncertainty quantification, parameter optimization and data knowledge-discovering framework.","fork":false,"url":"https://api.github.com/repos/idaholab/raven","forks_url":"https://api.github.com/repos/idaholab/raven/forks","keys_url":"https://api.github.com/repos/idaholab/raven/keys{/key_id}","collaborators_url":"https://api.github.com/repos/idaholab/raven/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/idaholab/raven/teams","hooks_url":"https://api.github.com/repos/idaholab/raven/hooks","issue_events_url":"https://api.github.com/repos/idaholab/raven/issues/events{/number}","events_url":"https://api.github.com/repos/idaholab/raven/events","assignees_url":"https://api.github.com/repos/idaholab/raven/assignees{/user}","branches_url":"https://api.github.com/repos/idaholab/raven/branches{/branch}","tags_url":"https://api.github.com/repos/idaholab/raven/tags","blobs_url":"https://api.github.com/repos/idaholab/raven/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/idaholab/raven/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/idaholab/raven/git/refs{/sha}","trees_url":"https://api.github.com/repos/idaholab/raven/git/trees{/sha}","statuses_url":"https://api.github.com/repos/idaholab/raven/statuses/{sha}","languages_url":"https://api.github.com/repos/idaholab/raven/languages","stargazers_url":"https://api.github.com/repos/idaholab/raven/stargazers","contributors_url":"https://api.github.com/repos/idaholab/raven/contributors","subscribers_url":"https://api.github.com/repos/idaholab/raven/subscribers","subscription_url":"https://api.github.com/repos/idaholab/raven/subscription","commits_url":"https://api.github.com/repos/idaholab/raven/commits{/sha}","git_commits_url":"https://api.github.com/repos/idaholab/raven/git/commits{/sha}","comments_url":"https://api.github.com/repos/idaholab/raven/comments{/number}","issue_comment_url":"https://api.github.com/repos/idaholab/raven/issues/comments{/number}","contents_url":"https://api.github.com/repos/idaholab/raven/contents/{+path}","compare_url":"https://api.github.com/repos/idaholab/raven/compare/{base}...{head}","merges_url":"https://api.github.com/repos/idaholab/raven/merges","archive_url":"https://api.github.com/repos/idaholab/raven/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/idaholab/raven/downloads","issues_url":"https://api.github.com/repos/idaholab/raven/issues{/number}","pulls_url":"https://api.github.com/repos/idaholab/raven/pulls{/number}","milestones_url":"https://api.github.com/repos/idaholab/raven/milestones{/number}","notifications_url":"https://api.github.com/repos/idaholab/raven/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/idaholab/raven/labels{/name}","releases_url":"https://api.github.com/repos/idaholab/raven/releases{/id}","deployments_url":"https://api.github.com/repos/idaholab/raven/deployments","created_at":"2017-03-23T19:29:27Z","updated_at":"2018-03-15T19:21:25Z","pushed_at":"2018-04-18T23:41:25Z","git_url":"git://github.com/idaholab/raven.git","ssh_url":"git@github.com:idaholab/raven.git","clone_url":"https://github.com/idaholab/raven.git","svn_url":"https://github.com/idaholab/raven","homepage":"https://raven.inl.gov/","size":513155,"stargazers_count":26,"watchers_count":26,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":24,"mirror_url":null,"archived":false,"open_issues_count":186,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":24,"open_issues":186,"watchers":26,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/idaholab/raven/pulls/510"},"html":{"href":"https://github.com/idaholab/raven/pull/510"},"issue":{"href":"https://api.github.com/repos/idaholab/raven/issues/510"},"comments":{"href":"https://api.github.com/repos/idaholab/raven/issues/510/comments"},"review_comments":{"href":"https://api.github.com/repos/idaholab/raven/pulls/510/comments"},"review_comment":{"href":"https://api.github.com/repos/idaholab/raven/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/idaholab/raven/pulls/510/commits"},"statuses":{"href":"https://api.github.com/repos/idaholab/raven/statuses/70a33a7af4fe4e451a0f9d237a3798e79b89104b"}},"author_association":"NONE"}}
{"actor":{"display_login":"alfoa"}}