def createSession(self, inputVolume):
        t = self.volumeToAiaaSessions.get(self.nodeCacheKey(inputVolume))
        if t is None or t[0] is None:
            in_file = tempfile.NamedTemporaryFile(suffix=self.inputFileExtension(), dir=self.aiaa_tmpdir).name
            self.reportProgress(5)
            start = time.time()
            slicer.util.saveNode(inputVolume, in_file)

            logging.info('Saved Input Node into {0} in {1:3.1f}s'.format(in_file, time.time() - start))
        else:
            in_file = t[0]
        self.reportProgress(30)

        session_id = None
        if self.useSession:
            aiaaClient = AIAAClient(self.server_url)
            response = aiaaClient.create_session(in_file)
            logging.info('AIAA Session Response Json: {}'.format(response))

            session_id = response.get('session_id')
            logging.info('Created AIAA session ({0}) in {1:3.1f}s'.format(session_id, time.time() - start))

        self.volumeToAiaaSessions[self.nodeCacheKey(inputVolume)] = (in_file, session_id, self.server_url)
        self.reportProgress(100)
        return in_file, session_id
    def deepgrow(self, image_in, session_id, model, foreground_point_set, background_point_set):
        logging.debug('Preparing for Deepgrow Action (model: {})'.format(model))

        result_file = tempfile.NamedTemporaryFile(suffix=self.outputFileExtension(), dir=self.aiaa_tmpdir).name
        aiaaClient = AIAAClient(self.server_url)
        aiaaClient.deepgrow(model, foreground_point_set, background_point_set, image_in, result_file,
                            session_id=session_id)
        return result_file
    def dextr3d(self, image_in, session_id, model, pointset):
        logging.debug('Preparing for Annotation/Dextr3D Action')

        result_file = tempfile.NamedTemporaryFile(suffix=self.outputFileExtension(), dir=self.aiaa_tmpdir).name
        aiaaClient = AIAAClient(self.server_url)
        aiaaClient.dextr3d(model, pointset, image_in, result_file,
                           pre_process=(not self.useSession),
                           session_id=session_id)
        return result_file
    def closeSession(self, inputVolume):
        t = self.volumeToAiaaSessions.get(self.nodeCacheKey(inputVolume))
        if t:
            session_id = t[1]
            server_url = t[2]

            if self.useSession:
                aiaaClient = AIAAClient(server_url)
                aiaaClient.close_session(session_id)
            self.volumeToAiaaSessions.pop(self.nodeCacheKey(inputVolume))
    def __init__(self,
                 server_url=None,
                 server_version=None,
                 progress_callback=None):

        self.aiaa_tmpdir = slicer.util.tempDirectory('slicer-aiaa')
        self.volumeToImageFiles = dict()
        self.progress_callback = progress_callback
        self.useCompression = True

        # Create Single AIAA Client Instance
        self.aiaaClient = AIAAClient()
        self.setServer(server_url, server_version)
    def segmentation(self, image_in, session_id, model):
        logging.debug('Preparing input data for segmentation')
        self.reportProgress(0)

        result_file = tempfile.NamedTemporaryFile(suffix=self.outputFileExtension(), dir=self.aiaa_tmpdir).name
        aiaaClient = AIAAClient(self.server_url)
        params = aiaaClient.inference(model, {}, image_in, result_file, session_id=session_id)

        extreme_points = params.get('points', params.get('extreme_points'))
        logging.debug('Extreme Points: {}'.format(extreme_points))

        self.reportProgress(100)
        return extreme_points, result_file
    def closeAllSessions(self):
        for k in self.volumeToAiaaSessions.keys():
            t = self.volumeToAiaaSessions[k]
            in_file = t[0]
            session_id = t[1]
            server_url = t[2]

            if self.useSession:
                aiaaClient = AIAAClient(server_url)
                aiaaClient.close_session(session_id)

            if os.path.exists(in_file):
                os.unlink(in_file)
        self.volumeToAiaaSessions.clear()
class AIAALogic():
    def __init__(self,
                 server_url=None,
                 server_version=None,
                 progress_callback=None):

        self.aiaa_tmpdir = slicer.util.tempDirectory('slicer-aiaa')
        self.volumeToImageFiles = dict()
        self.progress_callback = progress_callback
        self.useCompression = True

        # Create Single AIAA Client Instance
        self.aiaaClient = AIAAClient()
        self.setServer(server_url, server_version)

    def __del__(self):
        shutil.rmtree(self.aiaa_tmpdir, ignore_errors=True)

    def inputFileExtension(self):
        return ".nii.gz" if self.useCompression else ".nii"

    def outputFileExtension(self):
        # output is currently always generated as .nii.gz
        return ".nii.gz"

    def setServer(self, server_url=None, server_version=None):
        if not server_url:
            server_url = 'http://0.0.0.0:5000'
        if not server_version:
            server_version = 'v1'
        logging.debug('Using AIAA server {}: {}'.format(
            server_version, server_url))
        self.aiaaClient.server_url = server_url
        self.aiaaClient.api_version = server_version

    def setUseCompression(self, useCompression):
        self.useCompression = useCompression

    def setProgressCallback(self, progress_callback=None):
        self.progress_callback = progress_callback

    def reportProgress(self, progress):
        if self.progress_callback:
            self.progress_callback(progress)

    def list_models(self, label=None):
        #self.reportProgress(0)
        logging.debug('Fetching List of Models for label: {}'.format(label))
        result = self.aiaaClient.model_list(label)
        #self.reportProgress(100)
        return result

    def nodeCacheKey(self, mrmlNode):
        return mrmlNode.GetID() + "*" + str(mrmlNode.GetMTime())

    def segmentation(self, model, inputVolume):
        logging.debug('Preparing input data for segmentation')
        self.reportProgress(0)
        in_file = self.volumeToImageFiles.get(self.nodeCacheKey(inputVolume))
        if in_file is None:
            # No cached file
            in_file = tempfile.NamedTemporaryFile(
                suffix=self.inputFileExtension(), dir=self.aiaa_tmpdir).name
            self.reportProgress(5)
            start = time.time()
            slicer.util.saveNode(inputVolume, in_file)
            logging.info('Saved Input Node into {0} in {1:3.1f}s'.format(
                in_file,
                time.time() - start))
            self.volumeToImageFiles[self.nodeCacheKey(inputVolume)] = in_file
        else:
            logging.debug('Using cached image file: {}'.format(in_file))

        self.reportProgress(30)

        result_file = tempfile.NamedTemporaryFile(
            suffix=self.outputFileExtension(), dir=self.aiaa_tmpdir).name
        params = self.aiaaClient.segmentation(model,
                                              in_file,
                                              result_file,
                                              save_doc=False)

        extreme_points = params.get('points', params.get('extreme_points'))
        logging.debug('Extreme Points: {}'.format(extreme_points))

        self.reportProgress(100)
        return extreme_points, result_file

    def dextr3d(self, model, pointset, inputVolume, modelInfo):
        self.reportProgress(0)

        logging.debug('Preparing for Annotation/Dextr3D Action')

        node_id = inputVolume.GetID()
        in_file = self.volumeToImageFiles.get(self.nodeCacheKey(inputVolume))
        logging.debug('Node Id: {} => {}'.format(node_id, in_file))

        if in_file is None:
            in_file = tempfile.NamedTemporaryFile(
                suffix=self.inputFileExtension(), dir=self.aiaa_tmpdir).name

            self.reportProgress(5)
            start = time.time()
            slicer.util.saveNode(inputVolume, in_file)
            logging.info('Saved Input Node into {0} in {1:3.1f}s'.format(
                in_file,
                time.time() - start))

            self.volumeToImageFiles[self.nodeCacheKey(inputVolume)] = in_file
        else:
            logging.debug('Using Saved Node from: {}'.format(in_file))

        self.reportProgress(30)

        # Pre Process
        pad = 20
        roi_size = '128x128x128'
        if (modelInfo is not None) and ('padding' in modelInfo):
            pad = modelInfo['padding']
            roi_size = 'x'.join(map(str, modelInfo['roi']))

        result_file = tempfile.NamedTemporaryFile(
            suffix=self.outputFileExtension(), dir=self.aiaa_tmpdir).name
        self.aiaaClient.dextr3d(model, pointset, in_file, result_file, pad,
                                roi_size)

        self.reportProgress(100)
        return result_file
 def list_models(self, label=None):
     logging.debug('Fetching List of Models for label: {}'.format(label))
     aiaaClient = AIAAClient(self.server_url)
     return aiaaClient.model_list(label)
        # Update GUI
        self.updateModelFromSegmentMarkupNode()

    def onSegmentMarkupNodeModified(self, observer, eventid):
        self.updateModelFromSegmentMarkupNode()
        self.updateGUIFromMRML()

    def updateModelFromSegmentMarkupNode(self):
        self.updateGUIFromMRML()

    def interactionNodeModified(self, interactionNode):
        self.updateGUIFromMRML()


# Create Single AIAA Client Instance
aiaaClient = AIAAClient()
volumeToImageFiles = dict()

# TODO:: Support multiple slicer instances running in same box
aiaa_tmpdir = os.path.join(tempfile.gettempdir(), 'slicer-aiaa')
shutil.rmtree(aiaa_tmpdir, ignore_errors=True)
if not os.path.exists(aiaa_tmpdir):
    os.makedirs(aiaa_tmpdir)


def goodbye():
    print('GOOD BYE!! Removing Temp Dir: {}'.format(aiaa_tmpdir))
    shutil.rmtree(aiaa_tmpdir, ignore_errors=True)


atexit.register(goodbye)