def calculateLRE(case):
    success, intraopLandmarks = slicer.util.loadMarkupsFiducialList(
        case['intraopLandmarks'], returnNode=True)
    success, preopTransformedLandmarks = slicer.util.loadMarkupsFiducialList(
        case['preopTransformedLandmarks'], returnNode=True)
    numLandmarks = intraopLandmarks.GetNumberOfFiducials()
    caseData = []
    caseTRE = 0

    for i in range(numLandmarks):
        label = preopTransformedLandmarks.GetNthFiducialLabel(i)
        label = "-" + label.split("-")[-1]
        fiducialIndex = getFiducialIndexByLabel(intraopLandmarks, label)
        intraopPos = ModuleLogicMixin.getTargetPosition(
            intraopLandmarks, fiducialIndex)
        preopTransformedPos = ModuleLogicMixin.getTargetPosition(
            preopTransformedLandmarks, i)
        landmarkTRE = ModuleLogicMixin.get3DEuclideanDistance(
            intraopPos, preopTransformedPos)
        caseTRE = caseTRE + landmarkTRE
        caseData.append([
            " ",
            intraopLandmarks.GetNthFiducialLabel(fiducialIndex), intraopPos[0],
            intraopPos[1], intraopPos[2],
            preopTransformedLandmarks.GetNthFiducialLabel(i),
            preopTransformedPos[0], preopTransformedPos[1],
            preopTransformedPos[2], "", landmarkTRE
        ])

    caseTRE = caseTRE / (numLandmarks * 1.0)
    caseData.append(["", "", "", "", "", "", "", "", "", "", "", caseTRE])

    return caseData
            else:
                print "Data was not found for case %s" % case
    return data


def calculateLRE(case, landmark, transformed):
    success, landmarksNode = slicer.util.loadMarkupsFiducialList(
        landmark, returnNode=True)
    success, transformedNode = slicer.util.loadMarkupsFiducialList(
        transformed, returnNode=True)

    caseData = []
    for i in range(landmarksNode.GetNumberOfFiducials()):
        landmarkData = [case]

        landmarkPos = ModuleLogicMixin.getTargetPosition(landmarksNode, i)
        transformedPos = ModuleLogicMixin.getTargetPosition(transformedNode, i)
        landmarkTRE = ModuleLogicMixin.get3DEuclideanDistance(
            landmarkPos, transformedPos)

        landmarkData.append(landmarksNode.GetNthFiducialLabel(i))
        landmarkData.append(str(landmarkPos))
        landmarkData.append(transformedNode.GetNthFiducialLabel(i))
        landmarkData.append(str(transformedPos))
        landmarkData.append(landmarkTRE)

        caseData.append(landmarkData)

    return caseData

def findTransformFromDataDirectory(directory):

    coverProstateFiles = [
        item for item in os.listdir(directory)
        if re.search('.?-T2-COVER-PROSTATE-.?', item)
    ]

    if len(coverProstateFiles):
        seriesNumber = coverProstateFiles[0].split("-")[0]

    coverProstateFiles = [
        i for i in os.listdir(directory) if i.startswith("%s-" % seriesNumber)
    ]

    # filter unapproved case first holding -approved
    suffix = ""

    targets = {}
    transforms = {}

    approvedTargets = None

    regTypes = ['rigid', 'affine', 'bSpline']

    for f in coverProstateFiles:
        if f.endswith("-approved.fcsv"):
            success, approvedTargets = slicer.util.loadMarkupsFiducialList(
                os.path.join(directory, f), returnNode=True)
        # elif any(regType in f for regType in regTypes):
        #   if "TARGETS" in f:
        #     targets[]
        #   elif "TRANSFORM" in f:
        elif f.endswith("-affine.fcsv"):
            targets["affine"] = os.path.join(directory, f)
        elif f.endswith("-bSpline.fcsv"):
            targets["bSpline"] = os.path.join(directory, f)
        elif f.endswith("-rigid.fcsv"):
            targets["rigid"] = os.path.join(directory, f)
        elif f.endswith("-affine.h5"):
            transforms["affine"] = os.path.join(directory, f)
        elif f.endswith("-bSpline.h5"):
            transforms["bSpline"] = os.path.join(directory, f)
        elif f.endswith("-rigid.h5"):
            transforms["rigid"] = os.path.join(directory, f)

    minDistance = None
    smallestDistanceType = None

    for regType, filepath in targets.iteritems():
        print filepath
        success, tempNode = slicer.util.loadMarkupsFiducialList(
            filepath, returnNode=True)

        distance = ModuleLogicMixin.get3DDistance(
            ModuleLogicMixin.getTargetPosition(tempNode, 0),
            ModuleLogicMixin.getTargetPosition(approvedTargets, 0))
        if not minDistance or distance < minDistance:
            minDistance = distance
            smallestDistanceType = regType

    if smallestDistanceType:
        print "Smallest distance to approved targets could be computed for type %s" % smallestDistanceType
        return transforms[smallestDistanceType]

    raise ValueError(
        "Approved Cover Prostate transform could not be computed from parsing case directory!"
    )
def copyData(data, outputDir):

    logic = DeepInfer.DeepInferLogic()
    parameters = DeepInfer.ModelParameters()
    segmenter_json_file = os.path.join(DeepInfer.JSON_LOCAL_DIR,
                                       "ProstateNeedleFinder.json")
    with open(segmenter_json_file, "r") as fp:
        j = json.load(fp, object_pairs_hook=OrderedDict)

    iodict = parameters.create_iodict(j)
    dockerName, modelName, dataPath = parameters.create_model_info(j)

    csvData = [[
        'Case', 'SeriesNumber', 'TargetName', 'Pos', 'NeedleDistance',
        'ErrorVector', 'Comment'
    ]]

    for case, caseData in data.iteritems():
        if not caseData:
            continue
        outputCaseDir = os.path.join(outputDir, case)
        if not os.path.exists(outputCaseDir):
            ModuleLogicMixin.createDirectory(outputCaseDir)

        print "processing data of case %s" % case

        for data in caseData:
            seriesNumber = data["seriesNumber"]

            inputs = dict()

            temp = os.path.join(outputCaseDir,
                                "{}-label.nrrd".format(seriesNumber))
            if not os.path.exists(temp):
                copy(os.path.join(data["path"], data["label"]), temp)
            # success, inputs['InputProstateMask'] = slicer.util.loadLabelVolume(temp, returnNode=True)

            temp = os.path.join(outputCaseDir,
                                "{}-volume.nrrd".format(seriesNumber))
            if not os.path.exists(temp):
                copy(os.path.join(data["path"], data["volume"]), temp)
            # success, inputs['InputVolume'] = slicer.util.loadVolume(temp, returnNode=True)

            temp = os.path.join(outputCaseDir,
                                "{}-targets.fcsv".format(seriesNumber))
            if not os.path.exists(temp):
                copy(os.path.join(data["path"], data["targets"]), temp)
            success, targetNode = slicer.util.loadMarkupsFiducialList(
                temp, returnNode=True)

            temp = os.path.join(outputCaseDir,
                                "{}-needle-label.nrrd".format(seriesNumber))
            if not os.path.exists(temp):
                outputs = dict()
                outputs['OutputLabel'] = slicer.mrmlScene.AddNewNodeByClass(
                    "vtkMRMLLabelMapVolumeNode")
                outputs[
                    'OutputFiducialList'] = slicer.mrmlScene.AddNewNodeByClass(
                        "vtkMRMLMarkupsFiducialNode")

                params = dict()
                params['InferenceType'] = 'Ensemble'

                logic.executeDocker(dockerName, modelName, dataPath, iodict,
                                    inputs, params)
                logic.updateOutput(iodict, outputs)

                ModuleLogicMixin.saveNodeData(
                    outputs['OutputLabel'],
                    outputCaseDir,
                    FileExtension.NRRD,
                    name="{}-needle-label".format(seriesNumber))
                ModuleLogicMixin.saveNodeData(
                    outputs['OutputFiducialList'],
                    outputCaseDir,
                    FileExtension.FCSV,
                    name="{}-needle-tip".format(seriesNumber))

            temp = os.path.join(
                outputCaseDir,
                "{}-needle-centerline.fcsv".format(seriesNumber))
            if not os.path.exists(temp):
                centerLine = CenterLinePoints(
                    os.path.join(outputCaseDir,
                                 "{}-needle-label.nrrd".format(seriesNumber)))
                points_ijk = centerLine.get_needle_points_ijk()
                points_ras = centerLine.convert_points_ijk_to_ras(points_ijk)
                centerLineNode = slicer.mrmlScene.AddNewNodeByClass(
                    "vtkMRMLMarkupsFiducialNode")
                for point in points_ras:
                    centerLineNode.AddFiducialFromArray(point)
                centerLineNode.SetLocked(True)
                ModuleLogicMixin.saveNodeData(
                    centerLineNode,
                    outputCaseDir,
                    FileExtension.FCSV,
                    name="{}-needle-centerline".format(seriesNumber))

            success, centerLineNode = slicer.util.loadMarkupsFiducialList(
                temp, returnNode=True)
            if not centerLineNode.GetNumberOfFiducials():
                csvData.append([
                    case, seriesNumber, "", "", "", "",
                    "No centerline was found"
                ])
            else:
                cmLogic = CurveMaker.CurveMakerLogic()
                cmLogic.DestinationNode = slicer.mrmlScene.CreateNodeByClass(
                    "vtkMRMLModelNode")
                cmLogic.SourceNode = centerLineNode
                cmLogic.updateCurve()

                cmLogic.CurvePoly = vtk.vtkPolyData()
                cmLogic.enableAutomaticUpdate(1)

                for idx in range(targetNode.GetNumberOfFiducials()):
                    targetName = targetNode.GetNthFiducialLabel(idx)
                    if targetName.lower() in ["right", "left"]:
                        continue
                    pos = ModuleLogicMixin.getTargetPosition(targetNode, idx)
                    (distance,
                     minErrorVec) = cmLogic.distanceToPoint(pos, True)
                    # print "{}: {} ({})".format(targetName, distance, minErrorVec)

                    csvData.append([
                        case, seriesNumber, targetName, pos, distance,
                        minErrorVec, ""
                    ])

                def cleanup():
                    slicer.mrmlScene.RemoveNode(cmLogic.DestinationNode)

                cleanup()

    return csvData