def KalmanFilterMRTI(**kwargs):
    """
  kalman filtered MRTI 
  """
    # import needed modules
    import petsc4py, numpy
    PetscOptions = sys.argv
    PetscOptions.append("-ksp_monitor")
    PetscOptions.append("-ksp_rtol")
    PetscOptions.append("1.0e-15")
    PetscOptions.append("-solver")
    #PetscOptions.append("petsc")
    PetscOptions.append("superlu_dist")
    PetscOptions.append("-log_summary")
    PetscOptions.append("-override_max")
    PetscOptions.append("-modelcov")
    PetscOptions.append(kwargs['cv']['modelcov'])
    #PetscOptions.append("-verify_inverse")
    #PetscOptions.append("-write_system_matrix")
    #PetscOptions.append("-ksp_inverse_pc")
    #PetscOptions.append("ilu")
    #PetscOptions.append("lu")
    # ROI info
    #PetscOptions.append("-nx")
    #PetscOptions.append("-35")
    #PetscOptions.append("-ny")
    #PetscOptions.append("-35")
    #PetscOptions.append("-ix")
    #PetscOptions.append("-125")
    #PetscOptions.append("-iy")
    #PetscOptions.append("-115")
    #PetscOptions.append("-help")
    petsc4py.init(PetscOptions)

    from petsc4py import PETSc

    # create stages for logging
    PredictionStage = PETSc.Log.Stage("Prediction")
    CorrectionStage = PETSc.Log.Stage("Correction")

    # break processors into separate communicators
    petscRank = PETSc.COMM_WORLD.getRank()
    petscSize = PETSc.COMM_WORLD.Get_size()
    sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize))

    # set shell context
    # TODO import vtk should be called after femLibrary ????
    # FIXME WHY IS THIS????
    import femLibrary
    # initialize libMesh data structures
    libMeshInit = femLibrary.PyLibMeshInit(PetscOptions, PETSc.COMM_WORLD)

    # store control variables
    getpot = femLibrary.PylibMeshGetPot(PetscOptions)
    #getpot.SetIniValue( "thermal_conductivity/k_0_probe","1.0e8")
    #getpot.SetIniValue( "thermal_conductivity/k_0_tumor","1.0e8")
    getpot.SetIniValue("perfusion/w_0_healthy", "9.0")
    # tumor = applicator
    getpot.SetIniValue("perfusion/w_0_tumor", "0.0")
    getpot.SetIniValue("optical/mu_a_healthy", "5.0e2")
    getpot.SetIniValue("optical/mu_s_healthy", "140.0e2")
    getpot.SetIniValue("optical/anfact", "0.88")
    # from Duck table 2.15
    getpot.SetIniValue("material/specific_heat", "3840.0")
    # set ambient temperature
    u_init = 37.0
    probe_init = 21.0
    probe_init = u_init
    getpot.SetIniValue("initial_condition/u_init", "%f" % u_init)
    getpot.SetIniValue("initial_condition/probe_init", "%f" % probe_init)
    getpot.SetIniValue("bc/u_dirichletid",
                       "1")  #apply dirichlet data on applicator domain
    # set probe domain for heating
    getpot.SetIniValue("probe/domain", "2")

    # root directory of data
    workDir = "/share/work/fuentes/data/biotex/090318_751642_treat/"
    workDir = "/data/fuentes/biotex/090318_751642_treat/"
    dataRoot = "%s/Processed/s1%02d%03d" % (workDir, kwargs['cv']['uniform'],
                                            kwargs['cv']['roi'])
    tmapRoot = "%s/Processed/s1%02d%03d" % (workDir, 0, 0)

    # load vtk modules to read imaging
    import vtk
    import vtk.util.numpy_support as vtkNumPy
    # read imaging data geometry that will be used to project FEM data onto
    #vtkReader = vtk.vtkXMLImageDataReader()
    vtkReader = vtk.vtkDataSetReader()
    vtkReader.SetFileName('%s/tmap.0000.vtk' % tmapRoot)
    vtkReader.Update()
    templateImage = vtkReader.GetOutput()
    dimensions = templateImage.GetDimensions()
    # dimensions should already be in meters
    spacing = [dx * 1.000 for dx in templateImage.GetSpacing()]
    origin = [x0 * 1.000 for x0 in templateImage.GetOrigin()]
    print spacing, origin, dimensions
    femImaging = femLibrary.PytttkImaging(getpot, dimensions, origin, spacing)

    image_roi = [[130, 155], [123, 148], [0, 0]]
    size_roi = [
        image_roi[0][1] - image_roi[0][0] + 1,
        image_roi[1][1] - image_roi[1][0] + 1,
        image_roi[2][1] - image_roi[2][0] + 1
    ]
    roiOrigin = [
        origin[0] + image_roi[0][0] * spacing[0],
        origin[1] + image_roi[1][0] * spacing[1],
        origin[2] + image_roi[2][0] * spacing[2]
    ]

    # create ROI template
    roi_array = numpy.zeros(dimensions, dtype=numpy.double, order='C')
    #roi_array[118:153,125:160] = 1.e4
    # TODO row/column major ordering never seems to work...
    # FIXME notice the indices are reversed to account to the transpose
    roi_array[image_roi[1][0]:image_roi[1][1] + 1,
              image_roi[0][0]:image_roi[0][1] + 1] = 1.e4
    roi_vec = PETSc.Vec().createWithArray(roi_array, comm=PETSc.COMM_SELF)

    # initialize FEM Mesh
    femMesh = femLibrary.PylibMeshMesh()
    RotationMatrix = [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]
    Translation = [0., 0., 0.]
    #Setup Affine Transformation for registration
    AffineTransform = vtk.vtkTransform()
    #AffineTransform.Translate( [0.050,0.080, origin[2]] )
    AffineTransform.Translate([0.051, 0.080, 0.0509])
    AffineTransform.RotateZ(29.0)
    AffineTransform.RotateY(86.0)
    #AffineTransform.RotateY( 90.0 )
    AffineTransform.RotateX(0.0)
    AffineTransform.Scale([1., 1., 1.])
    matrix = AffineTransform.GetConcatenatedTransform(0).GetMatrix()
    RotationMatrix = [[
        matrix.GetElement(0, 0),
        matrix.GetElement(0, 1),
        matrix.GetElement(0, 2)
    ],
                      [
                          matrix.GetElement(1, 0),
                          matrix.GetElement(1, 1),
                          matrix.GetElement(1, 2)
                      ],
                      [
                          matrix.GetElement(2, 0),
                          matrix.GetElement(2, 1),
                          matrix.GetElement(2, 2)
                      ]]
    Translation = [
        matrix.GetElement(0, 3),
        matrix.GetElement(1, 3),
        matrix.GetElement(2, 3)
    ]
    # set intial mesh
    #femMesh.SetupUnStructuredGrid( "%s/meshTemplate1.e" % workDir ,0,RotationMatrix, Translation  )
    femMesh.SetupUnStructuredGrid("%s/meshTemplate2.NoAppBoundary.e" % workDir,
                                  0, RotationMatrix, Translation)
    #femMesh.SetupUnStructuredGrid( "%s/meshTemplate2.WithAppBoundary.e" % workDir ,0,RotationMatrix, Translation  )
    #femMesh.SetupStructuredGrid( (60,60,2),
    #                             [.0216,.0825],[.0432,.104],[-.001,.001],[2,2,2,2,3,2])
    #femMesh.ReadFile("magnitudeROI.e")

    # add the data structures for the Background System Solve
    # set deltat, number of time steps, power profile, and add system
    acquisitionTime = 5.00
    deltat = acquisitionTime
    ntime = 128
    eqnSystems = femLibrary.PylibMeshEquationSystems(femMesh, getpot)
    getpot.SetIniPower(1,
                       [[17, 27, 39, 69, ntime], [0.0, 4.05, 0.0, 10.05, 0.0]])

    # instantiate Kalman class
    kalmanFilter = None
    if (kwargs['cv']['algebra'] == 0):
        kalmanFilter = femLibrary.PytttkDenseKalmanFilterMRTI(
            eqnSystems, deltat)
    elif (kwargs['cv']['algebra'] == 1):
        kalmanFilter = femLibrary.PytttkUncorrelatedKalmanFilterMRTI(
            eqnSystems, deltat)
    elif (kwargs['cv']['algebra'] == 2):
        kalmanFilter = femLibrary.PytttkSparseKalmanFilterMRTI(
            eqnSystems, deltat)
    else:
        raise RuntimeError("\n\n unknown linear algebra... ")
    kalmanFilter.systems["StateSystem"].AddStorageVectors(ntime)

    # add systems to plot covariance
    CovCol = [
        0, 1, 4, 5, 8, 10, 100, 101, 104, 150, 151, 154, 200, 201, 204, 250,
        251, 254, 300, 301, 304, 350, 351, 354, 400, 401, 404, 450, 451, 454,
        504, 505, 510, 900, 901, 904, 905, 908, 910, 1000, 1001, 1004, 1050,
        1051, 1054, 1100, 1101, 1104, 1150, 1151, 1154, 1200, 1201, 1204, 1250,
        1251, 1254, 1300, 1301, 1304, 1350, 1351, 1354, 1400, 1401, 1404, 1450,
        1451, 1454, 1500, 1501, 1504, 1550, 1551, 1554, 1600, 1601, 1604, 1650,
        1651, 1654, 1700, 1701, 1704, 1750, 1751, 1754, 1802, 1803, 1805, 1807,
        1832, 1835, 1836, 1839, 1908, 1911, 1946, 1949, 1984, 1987, 2022, 2025,
        2060, 2063, 2098, 2101, 2136, 2139, 2174, 2177, 2216, 2219, 2516, 2519,
        2520, 2523, 2592, 2595, 2630, 2633, 2668, 2671, 2706, 2709, 2744, 2747,
        2782, 2785, 2820, 2823, 2858, 2861, 2896, 2899, 2934, 2937, 2972, 2975,
        3010, 3013, 3048, 3051, 3086, 3089, 3124, 3127, 3162, 3165, 3201, 3203,
        3217, 3219, 3221, 3223, 3303, 3305, 3346, 3348, 3389, 3391, 3432, 3434,
        3475, 3477, 3518
    ]
    CovCol = [
        3520, 3561, 3563, 3604, 3606, 3649, 3653, 3991, 3993, 3995, 3997, 4077,
        4079, 4120, 4122, 4163, 4165, 4206, 4208, 4248, 4250, 4291, 4293, 4334,
        4336, 4377, 4379, 4420, 4422, 4463, 4465, 4506, 4508, 4549, 4551, 4592,
        4594, 4635, 4637, 4678, 4680, 4721, 4723, 4766, 4767, 4780, 4782, 4842,
        4873, 4904, 4935, 4966, 4997, 5028, 5059, 5092, 5338, 5340, 5400, 5431,
        5462, 5493, 5524, 5555, 5586, 5617, 5648, 5679, 5710, 5741, 5772, 5803,
        5834, 5865, 5897, 5904, 5905, 5906, 5907, 5908, 5909, 5910, 5911, 5912,
        5913, 5914, 5915, 5916, 5917, 5918, 5919, 5920, 5921, 5922, 5923, 5924,
        5925, 5926, 5927, 5928, 5929, 5930, 5931, 5932, 5933, 5934, 5935, 5936,
        5937, 5938, 5939, 5940, 5941, 5942, 5943, 5944, 5945, 5946, 5947, 5948,
        5949, 5950, 5951, 5952, 5953, 5954, 5955, 5956, 5957, 5958, 5959, 5960,
        5961, 5962, 5963, 5964, 5965, 5966, 5967, 5968, 5969, 5970, 5971, 5972,
        5973, 5974, 5975, 5976, 5977, 5978, 5979, 5980, 5981, 5982, 5983, 5984,
        5985, 5986, 5987, 5988, 5989, 5990, 5991, 5992, 5993, 5994, 5995, 5996,
        5997, 5998, 5999, 6000
    ]
    CovCol = [
        6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009, 6010, 6011, 6012,
        6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024,
        6025, 6026, 6027, 6028, 6029, 6030, 6031, 6032, 6033, 6034, 6035, 6036,
        6037, 6038, 6039, 6040, 6041, 6042, 6043, 6044, 6045, 6046, 6047, 6048,
        6049, 6050, 6051, 6052, 6053, 6054, 6055, 6056, 6057, 6058, 6059, 6060,
        6061, 6062, 6063, 6064, 6065, 6066, 6067, 6068, 6069, 6070, 6071, 6072,
        6073, 6074, 6075, 6076, 6077, 6078, 6079, 6080, 6081, 6082, 6083, 6084,
        6085, 6086, 6087, 6088, 6089, 6090, 6091, 6092, 6093, 6094, 6095, 6096,
        6097, 6098, 6099, 6100, 6101, 6102, 6103, 6104, 6105, 6106, 6107, 6108,
        6109, 6110, 6111, 6112, 6113, 6114, 6115, 6116, 6117, 6118, 6119, 6120,
        6121, 6122, 6123, 6124, 6125, 6126, 6127, 6128, 6129, 6130, 6131, 6132,
        6133, 6134, 6135, 6136, 6137, 6138, 6139, 6140, 6141, 6142, 6143, 6144,
        6145, 6146, 6147, 6148, 6149, 6150, 6151, 6152, 6153, 6154, 6155
    ]
    CovCol = [33, 187, 3469]
    CovCol = CovCol + [40, 69, 111, 222, 555, 654, 807, 911, 987, 5454]

    for column in CovCol:
        tmpCovSystem = eqnSystems.AddExplicitSystem("Cov%04d" % column)
        tmpCovSystem.AddFirstLagrangeVariable("col%04d" % column)

    preUpdateSystem = eqnSystems.AddExplicitSystem("preUpdate")
    preUpdateSystem.AddFirstLagrangeVariable("predict")
    preUpdateSystem.AddFirstLagrangeVariable("damage")
    preUpdateSystem.AddFirstLagrangeVariable("damderiv")

    roiSystem = eqnSystems.AddExplicitSystem("ROISystem")
    roiSystem.AddFirstLagrangeVariable("roi")

    # initialize libMesh data structures
    eqnSystems.init()

    # print info
    eqnSystems.PrintSelf()

    # project ROI
    femImaging.ProjectImagingToFEMMesh("ROISystem", 0.0, roi_vec, eqnSystems)

    # show interpolations range
    roi_vec.set(1.e4)
    femImaging.ProjectImagingToFEMMesh("MRTIMean", 0.0, roi_vec, eqnSystems)

    # choose system to create measurement from
    #numMeasurement = kalmanFilter.CreateMeasurementMapFromImaging("MRTIMean", 8 )
    #numMeasurement = kalmanFilter.CreateMeasurementMapFromImaging("ROISystem", 8 )

    MeasurementMapNodeSet = 7
    MeasurementMapNodeSet = 8
    FEMMeshIsImagingMesh = False
    if (FEMMeshIsImagingMesh):
        # create identity map if needed
        MeasurementMapNodeSet = 9
        numMeasurement = kalmanFilter.CreateIdentityMeasurementMap(
            MeasurementMapNodeSet)
        kalmanFilter.Setup(numMeasurement)
        kalmanFilter.CreateROINodeSetMeasurementMap(MeasurementMapNodeSet)
    else:  # default is unstructured FEM Mesh
        # initialize petsc data structures
        MeasurementMapNodeSet = 5  # use node set ID as the averaging number
        numMeasurement = size_roi[0] * size_roi[1] * size_roi[2]
        kalmanFilter.Setup(numMeasurement)
        kalmanFilter.CreateROIAverageMeasurementMap(
            image_roi, MeasurementMapNodeSet, [origin[0], origin[1], 0.0469],
            spacing)

    # get covariance diagonal and and covariance entries for plotting
    for column in CovCol:
        kalmanFilter.ExtractCoVarianceForPlotting("Cov%04d" % column, column)
    kalmanFilter.ExtractVarianceForPlotting("StateStdDev")

    # set output file
    MeshOutputFile = "fem_data%s%d.%04d.e" % (
        kalmanFilter.LinAlgebra, MeasurementMapNodeSet, kwargs['fileID'])

    # write IC
    exodusII_IO = femLibrary.PylibMeshExodusII_IO(femMesh)
    exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, 1, 0.0)

    # NOTE This is after IC write
    # error check that can recover a constant field
    roiVec = roiSystem.GetSolutionVector()
    roiVec.set(1000.0)
    imagetest = kalmanFilter.ProjectMeasurementMatrix(roiVec)

    # show transpose measurement matrix map
    kalmanFilter.MeasurementMatrixTranspose("ROISystem", 1.e3)

    # loop over time steps and solve
    #for timeID in range(35,70):
    for timeID in range(1, ntime):
        print "time step = ", timeID
        eqnSystems.UpdatePetscFEMSystemTimeStep("StateSystem", timeID)
        PredictionStage.push()  # log prediction stage
        # use model to predict the state and covariance
        kalmanFilter.StatePredict(timeID)
        kalmanFilter.CovariancePredict()
        PredictionStage.pop()  # log prediction stage

        # copy from state system
        preUpdateSystem.CopySolutionVector(kalmanFilter.systems["StateSystem"])

        CorrectionStage.push()  # log correction stage

        # read MRTI Data
        vtkTmapReader = vtk.vtkDataSetReader()
        vtkTmapReader.SetFileName('%s/tmap.%04d.vtk' % (tmapRoot, timeID))
        vtkTmapReader.Update()
        tmap_cells = vtkTmapReader.GetOutput().GetPointData()
        tmap_array = u_init + vtkNumPy.vtk_to_numpy(
            tmap_cells.GetArray('scalars'))
        tmap_vec = PETSc.Vec().createWithArray(tmap_array,
                                               comm=PETSc.COMM_SELF)
        femImaging.ProjectImagingToFEMMesh("MRTIMean", u_init, tmap_vec,
                                           eqnSystems)

        # read in SNR base uncertainty measurement
        measurementCov = 2.0 * 2.0
        vtkSTDReader = vtk.vtkDataSetReader()
        vtkSTDReader.SetFileName('%s/snruncert.%04d.vtk' % (dataRoot, timeID))
        vtkSTDReader.Update()
        std_cells = vtkSTDReader.GetOutput().GetPointData()
        snr_array = vtkNumPy.vtk_to_numpy(std_cells.GetArray('scalars'))
        snr_vec = PETSc.Vec().createWithArray(snr_array, comm=PETSc.COMM_SELF)
        femImaging.ProjectImagingToFEMMesh("MRTIStdDev", measurementCov,
                                           snr_vec, eqnSystems)

        # extract data to kalman data structures
        #mrtiSoln = kalmanFilter.systems["MRTIMean"].GetSolutionVector( )
        #mrtiROI = kalmanFilter.ProjectMeasurementMatrix("MRTIMean")
        mrtiROI = PETSc.Vec().createWithArray(
            tmap_array.reshape(dimensions)[image_roi[1][0]:image_roi[1][1] + 1,
                                           image_roi[0][0]:image_roi[0][1] +
                                           1],
            comm=PETSc.COMM_SELF)
        kalmanFilter.ExtractMeasurementData(mrtiROI, "MRTIStdDev")
        #kalmanFilter.systems["MRTIMean"].ApplyDirichletData()
        #kalmanFilter.systems["MRTIStdDev"].ApplyDirichletData()

        # save prefem to disk for dbg
        PreFEMsoln = eqnSystems.GetPetscFEMSystemSolnSubVector(
            "StateSystem", 0)
        predictFEM = kalmanFilter.ProjectMeasurementMatrix(PreFEMsoln)

        vtkPreFEMImage = ConvertNumpyVTKImage(predictFEM[...], "prefem",
                                              size_roi, spacing, roiOrigin)
        vtkPreFEMWriter = vtk.vtkXMLImageDataWriter()
        vtkPreFEMWriter.SetFileName(
            "prefemROI%d.%04d.%04d.vti" %
            (MeasurementMapNodeSet, kwargs['fileID'], timeID))
        vtkPreFEMWriter.SetInput(vtkPreFEMImage)
        vtkPreFEMWriter.Update()

        # save mrti to disk for compare
        vtkMRTImage = ConvertNumpyVTKImage(mrtiROI[...], "mrti", size_roi,
                                           spacing, roiOrigin)
        vtkMRTIWriter = vtk.vtkXMLImageDataWriter()
        vtkMRTIWriter.SetFileName(
            "mrtiROI%d.%04d.%04d.vti" %
            (MeasurementMapNodeSet, kwargs['fileID'], timeID))
        vtkMRTIWriter.SetInput(vtkMRTImage)
        vtkMRTIWriter.Update()

        # save stddev to disk for rms
        stddevROI = PETSc.Vec().createWithArray(
            snr_array.reshape(dimensions)[image_roi[1][0]:image_roi[1][1] + 1,
                                          image_roi[0][0]:image_roi[0][1] + 1],
            comm=PETSc.COMM_SELF)
        vtkstdDevImage = ConvertNumpyVTKImage(stddevROI[...], "stddev",
                                              size_roi, spacing, roiOrigin)
        vtkstdDevWriter = vtk.vtkXMLImageDataWriter()
        vtkstdDevWriter.SetFileName(
            "stddevROI%d.%04d.%04d.vti" %
            (MeasurementMapNodeSet, kwargs['fileID'], timeID))
        vtkstdDevWriter.SetInput(vtkstdDevImage)
        vtkstdDevWriter.Update()

        # set UpdatePrediction = False to study model propagation only
        UpdatePrediction = False
        UpdatePrediction = True
        if (UpdatePrediction):
            # update the state vector and covariance
            kalmanGainSolver = "petsc"
            kalmanGainSolver = "superlu_dist"
            kalmanFilter.StateUpdate(kalmanGainSolver)
            kalmanFilter.CovarianceUpdate()

        CorrectionStage.pop()  # log correction stage

        # save prefem to disk for dbg
        UpdateFEMsoln = eqnSystems.GetPetscFEMSystemSolnSubVector(
            "StateSystem", 0)
        updateFEM = kalmanFilter.ProjectMeasurementMatrix(UpdateFEMsoln)

        vtkUpdateFEMImage = ConvertNumpyVTKImage(updateFEM[...], "updatefem",
                                                 size_roi, spacing, roiOrigin)
        vtkUpdateFEMWriter = vtk.vtkXMLImageDataWriter()
        vtkUpdateFEMWriter.SetFileName(
            "updatefemROI%d.%04d.%04d.vti" %
            (MeasurementMapNodeSet, kwargs['fileID'], timeID))
        vtkUpdateFEMWriter.SetInput(vtkUpdateFEMImage)
        vtkUpdateFEMWriter.Update()

        # get covariance diagonal and and covariance entries for plotting
        for column in CovCol:
            kalmanFilter.ExtractCoVarianceForPlotting("Cov%04d" % column,
                                                      column)
        kalmanFilter.ExtractVarianceForPlotting("StateStdDev")

        # compute l2 norm of difference
        print femLibrary.WeightedL2Norm(kalmanFilter.systems["StateSystem"],
                                        "u0", kalmanFilter.systems["MRTIMean"],
                                        "u0*",
                                        kalmanFilter.systems["MRTIStdDev"],
                                        "du0*")
        print femLibrary.WeightedL2Norm(kalmanFilter.systems["StateSystem"],
                                        "u0", kalmanFilter.systems["MRTIMean"],
                                        "u0*",
                                        kalmanFilter.systems["StateStdDev"],
                                        "du0")
        #eqnSystems.StoreTransientSystemTimeStep("StateSystem",timeID )
        exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, timeID + 1,
                                  timeID * deltat)
    retval = dict([])
    retval['fns'] = [0.0]
    retval['rank'] = petscRank
    return (retval)
def pennesModeling(**kwargs):
    """
  treatment planning model 
  """
    # import needed modules
    import petsc4py, numpy, sys
    PetscOptions = sys.argv
    PetscOptions.append("-ksp_monitor")
    PetscOptions.append("-ksp_rtol")
    PetscOptions.append("1.0e-15")
    #PetscOptions.append("-idb")
    petsc4py.init(PetscOptions)

    from petsc4py import PETSc

    # break processors into separate communicators
    petscRank = PETSc.COMM_WORLD.getRank()
    petscSize = PETSc.COMM_WORLD.Get_size()
    sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize))

    # set shell context
    import femLibrary
    # initialize libMesh data structures
    libMeshInit = femLibrary.PyLibMeshInit(PetscOptions, PETSc.COMM_WORLD)

    # the original configuration ini file should be stored
    config = kwargs['config_parser']

    # store control variables
    getpot = femLibrary.PylibMeshGetPot(PetscOptions)

    # copy all values from the input file
    for section in config.sections():
        for name, value in config.items(section):
            #print "%s/%s" % (section,name) , value
            getpot.SetIniValue("%s/%s" % (section, name), value)

    # nodeset 1 will be treated as dirichlet
    dirichletID = 1
    getpot.SetIniValue("bc/u_dirichlet", '%d' % dirichletID)

    # set tissue lookup tables
    k_0Table = {
        "default": config.getfloat("thermal_conductivity", "k_0_healthy"),
        "vessel": config.getfloat("thermal_conductivity", "k_0_healthy"),
        "grey": config.getfloat("thermal_conductivity", "k_0_grey"),
        "white": config.getfloat("thermal_conductivity", "k_0_white"),
        "csf": config.getfloat("thermal_conductivity", "k_0_csf"),
        "tumor": config.getfloat("thermal_conductivity", "k_0_tumor")
    }
    w_0Table = {
        "default": config.getfloat("perfusion", "w_0_healthy"),
        "vessel": config.getfloat("perfusion", "w_0_healthy"),
        "grey": config.getfloat("perfusion", "w_0_grey"),
        "white": config.getfloat("perfusion", "w_0_white"),
        "csf": config.getfloat("perfusion", "w_0_csf"),
        "tumor": config.getfloat("perfusion", "w_0_tumor")
    }
    mu_aTable = {
        "default": config.getfloat("optical", "mu_a_healthy"),
        "vessel": config.getfloat("optical", "mu_a_healthy"),
        "grey": config.getfloat("optical", "mu_a_grey"),
        "white": config.getfloat("optical", "mu_a_white"),
        "csf": config.getfloat("optical", "mu_a_csf"),
        "tumor": config.getfloat("optical", "mu_a_tumor")
    }
    mu_sTable = {
        "default": config.getfloat("optical", "mu_s_healthy"),
        "vessel": config.getfloat("optical", "mu_s_healthy"),
        "grey": config.getfloat("optical", "mu_s_grey"),
        "white": config.getfloat("optical", "mu_s_white"),
        "csf": config.getfloat("optical", "mu_s_csf"),
        "tumor": config.getfloat("optical", "mu_s_tumor")
    }
    labelTable = {
        config.get("labels", "greymatter"): "grey",
        config.get("labels", "whitematter"): "white",
        config.get("labels", "csf"): "csf",
        config.get("labels", "tumor"): "tumor",
        config.get("labels", "vessel"): "vessel"
    }
    labelCount = {
        "default": 0,
        "grey": 0,
        "white": 0,
        "csf": 0,
        "tumor": 0,
        "vessel": 0
    }
    # imaging params
    import vtk
    import vtk.util.numpy_support as vtkNumPy
    SegmentFile = config.get("exec", "segment_file")
    # set the default reader based on extension
    if (SegmentFile.split(".").pop() == "vtk"):
        vtkImageReader = vtk.vtkDataSetReader
    elif (SegmentFile.split(".").pop() == "vti"):
        vtkImageReader = vtk.vtkXMLImageDataReader
    else:
        raise RuntimeError("uknown file")

    # get dimension info from header
    vtkSetupReader = vtkImageReader()
    vtkSetupReader.SetFileName(SegmentFile)
    vtkSetupReader.Update()
    vtkImageMask = vtkSetupReader.GetOutput()
    dimensions = vtkSetupReader.GetOutput().GetDimensions()
    numberPointsImage = vtkSetupReader.GetOutput().GetNumberOfPoints()
    spacing_mm = vtkSetupReader.GetOutput().GetSpacing()
    origin_mm = vtkSetupReader.GetOutput().GetOrigin()
    # convert to meters
    spacing = [dx * .001 for dx in spacing_mm]
    origin = [x0 * .001 for x0 in origin_mm]

    # pass pointer to c++
    image_cells = vtkImageMask.GetPointData()
    data_array = vtkNumPy.vtk_to_numpy(image_cells.GetArray(0))
    # need to pass numpy array's w/ Fortran storage... ie painful to debug
    imageDataVec = PETSc.Vec().createWithArray(numpy.ravel(data_array,
                                                           order='F'),
                                               comm=PETSc.COMM_SELF)

    # FIXME - center around quadrature in out-of-plane direction
    # FIXME - need better out of plane cooling model
    quadratureOffset = 1. / numpy.sqrt(3.0) * spacing[2] / 2.0
    # expecting roi and subsample of the form:
    #     roi = [(40,210),(30,220),(6,78)]
    #     subsample = [3,3,2]
    ROI = eval(config.get('exec', 'roi'))
    subsample = eval(config.get('exec', 'subsample'))
    nelemROI = [(pixel[1] - pixel[0] - 1) / sub
                for pixel, sub in zip(ROI, subsample)]
    xbounds = [
        origin[0] + spacing[0] * (ROI[0][0] + 0.5),
        origin[0] + spacing[0] * (ROI[0][1] + 0.5)
    ]
    ybounds = [
        origin[1] + spacing[1] * (ROI[1][0] + 0.5),
        origin[1] + spacing[1] * (ROI[1][1] + 0.5)
    ]
    zbounds = [
        origin[2] + spacing[2] * (ROI[2][0] + 0.5),
        origin[2] + spacing[2] * (ROI[2][1] + 0.5)
    ]
    if (petscRank == 0):
        print "#points", numberPointsImage, "dimensions ", dimensions, "spacing ", spacing, "origin ", origin
        print "ROI", ROI, "nelemROI ", nelemROI, "bounds", xbounds, ybounds, zbounds

    #set to steady state solve
    getpot.SetIniValue("steadystate/domain_0", "true")

    # initialize FEM Mesh
    femMesh = femLibrary.PylibMeshMesh()
    #femMesh.SetupUnStructuredGrid(kwargs['mesh_file'],0,RotationMatrix, Translation  )
    #femMesh.ReadFile(kwargs['mesh_file'])

    femMesh.SetupStructuredGrid(nelemROI, xbounds, ybounds, zbounds,
                                [2, 2, 2, 2, 2, 2])
    # get output file name else set default name
    try:
        MeshOutputFile = config.get("exec", "exodus_file")
    except ConfigParser.NoOptionError:
        MeshOutputFile = "fem.e"

    # add the data structures for the Background System Solve
    # set deltat, number of time steps, power profile, and add system
    eqnSystems = femLibrary.PylibMeshEquationSystems(femMesh, getpot)

    #getpot.SetIniPower(1,[[19,119],[90.0,100.0]] )
    getpot.SetIniPower(1, kwargs['powerHistory'])
    # AddPennesSDASystem
    # AddPennesRFSystem
    # AddPennesDeltaPSystem
    pennesSystem = eval("eqnSystems.%s('StateSystem',kwargs['deltat'])" %
                        kwargs['physics'])
    pennesSystem.AddStorageVectors(kwargs['ntime'] + 1)

    # add system for labels
    # FIXME: need both nodal, for dirichlet bc, and element version, for parameter masks
    maskElemSystem = eqnSystems.AddExplicitSystem("ElemImageMask")
    maskElemSystem.AddConstantMonomialVariable("maskElem")

    # initialize libMesh data structures
    eqnSystems.init()

    # print info
    eqnSystems.PrintSelf()

    # setup imaging to interpolate onto FEM mesh
    femImaging = femLibrary.PytttkImaging(getpot, dimensions, origin, spacing)
    # Project imaging onto libMesh data structures
    femImaging.ProjectImagingToFEMMesh("ElemImageMask", 0.0, imageDataVec,
                                       eqnSystems)
    femImaging.ProjectImagingToFEMMesh("StateSystem", 0.0, imageDataVec,
                                       eqnSystems)

    # create dirichlet nodes from this mask
    numNodes = pennesSystem.PetscFEMSystemCreateNodeSetFromMask(
        config.getfloat("labels", "vessel"), dirichletID)
    print "# of dirichlet nodes %d" % numNodes

    # get image label as numpy array
    imageLabel = maskElemSystem.GetSolutionVector()[...]
    #imageLabel = numpy.floor(10.0*imageLabel.copy())+1
    k_0Label = imageLabel.copy()
    w_0Label = imageLabel.copy()
    mu_aLabel = imageLabel.copy()
    mu_sLabel = imageLabel.copy()
    for (idpos, label) in enumerate(imageLabel):
        try:
            tissueType = labelTable["%d" % int(label)]
        except KeyError:
            tissueType = "default"
        labelCount[tissueType] = labelCount[tissueType] + 1
        k_0Label[idpos] = k_0Table[tissueType]
        w_0Label[idpos] = w_0Table[tissueType]
        mu_aLabel[idpos] = mu_aTable[tissueType]
        mu_sLabel[idpos] = mu_sTable[tissueType]
    # create array of imaging data as petsc vec
    k_0Vec = PETSc.Vec().createWithArray(k_0Label, comm=PETSc.COMM_SELF)
    w_0Vec = PETSc.Vec().createWithArray(w_0Label, comm=PETSc.COMM_SELF)
    mu_aVec = PETSc.Vec().createWithArray(mu_aLabel, comm=PETSc.COMM_SELF)
    mu_sVec = PETSc.Vec().createWithArray(mu_sLabel, comm=PETSc.COMM_SELF)
    # copy material properties to the system
    eqnSystems.GetSystem("k_0").SetSolutionVector(k_0Vec)
    eqnSystems.GetSystem("w_0").SetSolutionVector(w_0Vec)
    eqnSystems.GetSystem("mu_a").SetSolutionVector(mu_aVec)
    eqnSystems.GetSystem("mu_s").SetSolutionVector(mu_sVec)

    # write IC
    exodusII_IO = femLibrary.PylibMeshExodusII_IO(femMesh)
    exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, 1, 0.0)
    exodusII_IO.WriteParameterSystems(eqnSystems)

    # setup IC
    pennesSystem.PetscFEMSystemSetupInitialConditions()

    # create list of laser positions
    laserPositionList = [((.015, .015, 2 * spacing[2] + quadratureOffset),
                          (.018, .018, 2 * spacing[2] + quadratureOffset)),
                         ((.015, .015, 2 * spacing[2] + quadratureOffset),
                          (.016, .018, 2 * spacing[2] + quadratureOffset)),
                         ((.015, .015, 1 * spacing[2] + quadratureOffset),
                          (.014, .014, 1 * spacing[2] + quadratureOffset)),
                         ((.015, .015, 1 * spacing[2] + quadratureOffset),
                          (.015, .018, 3 * spacing[2] + quadratureOffset))]
    # time stamp
    import pickle, time
    timeStamp = 0
    # set power id to turn laser on
    pennesSystem.PetscFEMSystemUpdateTimeStep(1)
    # loop over laser position and solve steady state equations for each position
    #for (idpos,(pos0,pos1)) in enumerate(laserPositionList):
    # loop and read new laser parameters
    while (True):
        if (os.path.getmtime(fem_params['ini_filename']) > timeStamp):
            timeStamp = os.path.getmtime(fem_params['ini_filename'])
            newIni = ConfigParser.SafeConfigParser({})
            newIni.read(fem_params['ini_filename'])

            laserParams = {}
            laserParams['position1'] = [
                newIni.getfloat("probe", varID)
                for varID in ["x_0", "y_0", "z_0"]
            ]
            laserParams['position2'] = [
                newIni.getfloat("probe", varID)
                for varID in ["x_1", "y_1", "z_1"]
            ]

            print "laser position = ", newIni.getfloat("timestep",
                                                       "power"), laserParams
            pennesSystem.PennesSDASystemUpdateLaserPower(
                newIni.getfloat("timestep", "power"), 1)
            pennesSystem.PennesSDASystemUpdateLaserPosition(
                laserParams['position1'], laserParams['position2'])
            pennesSystem.SystemSolve()
            #fem.StoreTransientSystemTimeStep("StateSystem",timeID )
            #exodusII_IO.WriteTimeStep(MeshOutputFile ,eqnSystems, idpos+2, idpos*kwargs['deltat'])
            exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, 2, 1.0)
            exodusII_IO.WriteParameterSystems(eqnSystems)
            # write to txt file
            if (petscRank == 0):
                time.sleep(1)
                vtkExodusIIReader = vtk.vtkExodusIIReader()
                print "opening %s " % MeshOutputFile
                vtkExodusIIReader.SetFileName(MeshOutputFile)
                vtkExodusIIReader.Update()
                ntime = vtkExodusIIReader.GetNumberOfTimeSteps()
                variableID = "u0"
                print "ntime %d %s " % (ntime, variableID)
                vtkExodusIIReader.SetTimeStep(1)
                vtkExodusIIReader.SetPointResultArrayStatus(variableID, 1)
                vtkExodusIIReader.Update()
                curInput = None
                # multi block
                if vtkExodusIIReader.GetOutput().IsA("vtkMultiBlockDataSet"):
                    iter = vtkExodusIIReader.GetOutput().NewIterator()
                    iter.UnRegister(None)
                    iter.InitTraversal()
                    curInput = iter.GetCurrentDataObject()
                else:
                    curInput = vtkExodusIIReader.GetOutput()
                #fem_point_data= curInput.GetPointData().GetArray('u0')
                #Soln=vtkNumPy.vtk_to_numpy(fem_point_data)
                #numpy.savetxt( "temperature.txt" ,Soln)

                # FIXME  notice that order of operations is IMPORTANT
                # FIXME   translation followed by rotation will give different results
                # FIXME   than rotation followed by translation
                # FIXME  Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview
                # scale back to millimeter
                # TODO verify that the data sets are registered in the native slicer coordinate system
                # TODO   segmented data MUST be read in with:
                # TODO add data -> volume -> show options -> ignore orientation
                # TODO add data -> volume -> show options -> ignore orientation
                # TODO add data -> volume -> show options -> ignore orientation
                AffineTransform = vtk.vtkTransform()
                AffineTransform.Translate([0.0, 0.0, 0.0])
                AffineTransform.RotateZ(0.0)
                AffineTransform.RotateY(0.0)
                AffineTransform.RotateX(0.0)
                AffineTransform.Scale([1000., 1000., 1000.])
                # scale to millimeter
                transformFilter = vtk.vtkTransformFilter()
                transformFilter.SetInput(curInput)
                transformFilter.SetTransform(AffineTransform)
                transformFilter.Update()

                # setup contour filter
                vtkContour = vtk.vtkContourFilter()
                vtkContour.SetInput(transformFilter.GetOutput())
                # TODO: not sure why this works...
                # set the array to process at the temperature == u0
                vtkContour.SetInputArrayToProcess(0, 0, 0, 0, 'u0')
                contourValuesList = eval(newIni.get('exec', 'contours'))
                vtkContour.SetNumberOfContours(len(contourValuesList))
                print "plotting array:", vtkContour.GetArrayComponent()
                for idContour, contourValue in enumerate(contourValuesList):
                    print "plotting contour:", idContour, contourValue
                    vtkContour.SetValue(idContour, contourValue)
                vtkContour.Update()

                # setup threshold filter
                vtkThreshold = vtk.vtkThreshold()
                vtkThreshold.SetInput(transformFilter.GetOutput())
                vtkThreshold.ThresholdByLower(contourValuesList[0])
                #vtkThreshold.SetSelectedComponent( 0 )
                vtkThreshold.SetComponentModeToUseAny()
                vtkThreshold.Update()

                # resample onto image
                vtkResample = vtk.vtkCompositeDataProbeFilter()
                vtkResample.SetInput(vtkImageMask)
                vtkResample.SetSource(vtkThreshold.GetOutput())
                vtkResample.Update()

                # write output
                print "writing fem.vtk "
                vtkImageWriter = vtk.vtkDataSetWriter()
                vtkImageWriter.SetFileTypeToBinary()
                vtkImageWriter.SetFileName("fem.vtk")
                vtkImageWriter.SetInput(vtkResample.GetOutput())
                vtkImageWriter.Update()

                # write stl file
                stlWriter = vtk.vtkSTLWriter()
                stlWriter.SetInput(vtkContour.GetOutput())
                stlWriter.SetFileName("fem.stl")
                stlWriter.SetFileTypeToBinary()
                stlWriter.Write()
                # write support file to signal full stl file is written
                #  Slicer module will wait for this file to be written
                #  before trying to open stl file to avoid incomplete reads
                with open('./fem.finish', 'w') as signalFile:
                    signalFile.write("the stl file has been written\n")

        else:
            print "waiting on user input.."
            # echo lookup table
            if (petscRank == 0):
                print "lookup tables"
                print "labeled %d voxels" % len(imageLabel)
                print "labels", labelTable
                print "counts", labelCount
                print "conductivity", k_0Table
                print "perfusion", w_0Table
                print "absorption", mu_aTable
                print "scattering", mu_sTable
            time.sleep(2)
def rfModeling(**kwargs):
    """
  treatment planning model 
  """
    # import petsc and numpy
    import petsc4py, numpy
    # init petsc
    PetscOptions = sys.argv
    PetscOptions.append("-ksp_monitor")
    PetscOptions.append("-ksp_rtol")
    PetscOptions.append("1.0e-15")
    #PetscOptions.append("-help")
    petsc4py.init(PetscOptions)

    # break processors into separate communicators
    from petsc4py import PETSc
    petscRank = PETSc.COMM_WORLD.getRank()
    petscSize = PETSc.COMM_WORLD.Get_size()
    sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize))

    # set shell context
    # TODO import vtk should be called after femLibrary ????
    # FIXME WHY IS THIS????
    import femLibrary
    # initialize libMesh data structures
    libMeshInit = femLibrary.PyLibMeshInit(PetscOptions, PETSc.COMM_WORLD)

    # store control variables
    getpot = femLibrary.PylibMeshGetPot(PetscOptions)
    # set dirichlet bc on vessel
    getpot.SetIniValue("bc/u_dirichletid", "1")
    # from Duck table 2.15
    getpot.SetIniValue("material/specific_heat", "3840.0")
    # set ambient temperature
    getpot.SetIniValue("initial_condition/u_init", "21.0")
    # from Duck
    getpot.SetIniValue("electric_conductivity/s_0_healthy", "6.0")

    # from Duck table 2.15
    getpot.SetIniValue("material/specific_heat", "3840.0")
    # set ambient temperature
    u_init = 34.3
    getpot.SetIniValue("initial_condition/u_init", "%f" % u_init)
    getpot.SetIniValue("initial_condition/probe_init", "%f" % u_init)
    # thermal conductivity from Duck/CRC Handbook
    getpot.SetIniValue("thermal_conductivity/k_0_healthy",
                       kwargs['cv']['k_0_healthy'])
    getpot.SetIniValue("thermal_conductivity/k_0_tumor",
                       kwargs['cv']['k_0_tumor'])
    # perfusion from Duck/CRC Handbook
    getpot.SetIniValue("perfusion/w_0_healthy", kwargs['cv']['w_0_healthy'])
    getpot.SetIniValue("perfusion/w_0_tumor", kwargs['cv']['w_0_tumor'])
    #
    #  given the original orientation as two points along the centerline z = x2 -x1
    #     the transformed orienteation would be \hat{z} = A x2 + b - A x1 - b = A z
    #  ie transformation w/o translation which is exactly w/ vtk has implemented w/ TransformVector
    #  TransformVector = TransformPoint - the transation
    #Setup Affine Transformation for registration
    RotationMatrix = [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]
    Translation = [0., 0., 0.]
    # original coordinate system laser input
    laserTip = Translation

    # set steady state
    getpot.SetIniValue("steadystate/domain_0", "true")
    getpot.SetIniValue("steadystate/domain_1", "true")

    # set laser orientation values
    getpot.SetIniValue("probe/domain", "2")
    getpot.SetIniValue("probe/x_0", "%f" % laserTip[0])
    getpot.SetIniValue("probe/y_0", "%f" % laserTip[1])
    getpot.SetIniValue("probe/z_0", "%f" % laserTip[2])

    # initialize FEM Mesh
    femMesh = femLibrary.PylibMeshMesh()
    #femMesh.SetupUnStructuredGrid(kwargs['mesh_file'],0,RotationMatrix, Translation  )
    # TODO input full path to FEM mesh here
    print "hopfully reading vessel mesh with diameter %s distance %s" % (
        kwargs['cv']['vessel_diameter'], kwargs['cv']['vessel_distance'])
    FEMMeshFileName = "./clusterVessel.e"
    femMesh.ReadFile(FEMMeshFileName)
    # http://en.wikipedia.org/wiki/Tmpfs
    # tmpfs /dev/shm file system should write to RAM = fast!
    MeshOutputFile = "/dev/shm/fem_data.%04d.e" % kwargs['fileID']
    MeshOutputFile = "./fem_data.%04d.e" % kwargs['fileID']
    #fem.SetupStructuredGrid( (10,10,4) ,[0.0,1.0],[0.0,1.0],[0.0,1.0])

    # add the data structures for the Background System Solve
    # set deltat, number of time steps, power profile, and add system
    eqnSystems = femLibrary.PylibMeshEquationSystems(femMesh, getpot)
    getpot.SetIniPower(nsubstep,
                       [[1, 2, 4, 7, ntime], [0.0, 4.0, 0.0, 9.0, 0.0]])
    rfSystem = eqnSystems.AddPennesRFSystem("StateSystem", deltat)
    rfSystem.AddStorageVectors(ntime)

    # initialize libMesh data structures
    eqnSystems.init()

    # quick error check
    #errCheckSoln = fem.GetSolutionVector( "StateSystem" )[...]
    #if (  errCheckSoln.size + 1 != kwargs['functions'] ):
    #  print "ERROR!! number of response functions incorrect!!"
    #  raise RuntimeError("soln vec + 1 = %d .NE. num_response = %d"%(errCheckSoln.size+1,kwargs['functions']) )

    # print info
    eqnSystems.PrintSelf()

    # write IC
    exodusII_IO = None
    WriteExodus = False
    WriteExodus = True
    if (WriteExodus):
        exodusII_IO = femLibrary.PylibMeshExodusII_IO(femMesh)
        exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, 1, 0.0)

    # loop over time steps and solve
    ObjectiveFunction = 0.0
    for timeID in range(1, ntime * nsubstep):
        #for timeID in range(1,3):
        print "time step = ", timeID
        eqnSystems.UpdatePetscFEMSystemTimeStep("StateSystem", timeID)
        rfSystem.SystemSolve()
        # write soln to disk for processing
        soln = eqnSystems.GetPetscFEMSystemSolnSubVector("StateSystem", 0)[...]
        if (petscRank == 0):
            numpy.savetxt(SolnOutputTemplate % timeID, soln)
        #fem.StoreTransientSystemTimeStep("StateSystem",timeID )
        if (WriteExodus):
            exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, timeID + 1,
                                      timeID * kwargs['deltat'])

    # clean up
    #os.remove(MeshOutputFile)

    # return values
    retval = dict([])
    retval['fns'] = [0.0]
    ##retval['fns'] = [ObjectiveFunction]
    ##retval['rank'] = petscRank
    return (retval)
#PetscOptions.append("-ksp_constant_null_space")
#PetscOptions.append("-help")
petsc4py.init(PetscOptions)

# get rank
from petsc4py import PETSc
petscRank = PETSc.COMM_WORLD.getRank()
petscSize = PETSc.COMM_WORLD.Get_size()
sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize))

# set shell context
# TODO import vtk should be called after femLibrary ????
# FIXME WHY IS THIS????
import femLibrary
# initialize libMesh data structures
libMeshInit = femLibrary.PyLibMeshInit(PetscOptions, PETSc.COMM_WORLD)

# load vtk modules to read imaging
import vtk
import vtk.util.numpy_support as vtkNumPy

FileNameTemplate = "/data/fuentes/biotex/MayoLiverDataJan2011/VTKData/226p-536/phase.%04d.vti"
FileNameTemplate = "/home/jyung/e137/Processed/s22000/phase.%04d.vtk"
# set the default reader based on extension
if (FileNameTemplate.split(".").pop() == "vtk"):
    vtkImageReader = vtk.vtkDataSetReader
elif (FileNameTemplate.split(".").pop() == "vti"):
    vtkImageReader = vtk.vtkXMLImageDataReader
else:
    raise RuntimeError("uknown file")