def test_median(self):
        """ test Analyzer computing mediansignal within mask """
        # settings dictionary for this test
        settings = {'maskFile': maskFile,
                    'analysisChoice': 'Median',
                    'maskIsWeighted': False}

        # create instance of Analyzer class
        analyzer = Analyzer(settings)

        # loop over series and test
        seriesData = nib.load(seriesFile)
        results = []
        for volIdx in range(seriesData.shape[3]):
            # extract the 3d array for this vol
            thisVol = seriesData.get_data()[:, :, :, volIdx]
            result = analyzer.runAnalysis(thisVol, volIdx)

            results.append(result['median'])

        # make np arrays of results and what results are expected to be
        results = np.array(results)
        expectedResults = np.array([1017.00, 1020.5, 1026.00])

        # use np testing method to assert with customized precision
        np.testing.assert_almost_equal(results, expectedResults, decimal=2)
    def test_customAnalysis(self):
        """ test Analyzer computing customAnalysis within mask """
        # settings dictionary for this test
        settings = {'maskFile': maskFile,
                    'numTimepts': 3,
                    'analysisChoice': join(paths['testDataDir'], 'test_customAnalysisScript.py'),
                    'maskIsWeighted': False}

        # create instance of Analyzer class
        analyzer = Analyzer(settings)

        # loop over series and test
        seriesData = nib.load(seriesFile)
        results = []
        for volIdx in range(seriesData.shape[3]):
            # extract the 3d array for this vol
            thisVol = seriesData.get_data()[:, :, :, volIdx]
            result = analyzer.runAnalysis(thisVol, volIdx)

            results.append(result['customResult'])

        # make np arrays of results and what results are expected to be
        results = np.array(results)
        expectedResults = np.array([1029.15, 1032.78, 1034.14])

        # use np testing method to assert with customized precision
        np.testing.assert_almost_equal(results, expectedResults, decimal=2)
示例#3
0
    def test_median(self):
        """ test Analyzer computing mediansignal within mask """
        # settings dictionary for this test
        settings = {
            'maskFile': maskFile,
            'analysisChoice': 'Median',
            'maskIsWeighted': False
        }

        # create instance of Analyzer class
        analyzer = Analyzer(settings)

        # loop over series and test
        seriesData = nib.load(seriesFile)
        results = []
        for volIdx in range(seriesData.shape[3]):
            # extract the 3d array for this vol
            thisVol = seriesData.get_data()[:, :, :, volIdx]
            result = analyzer.runAnalysis(thisVol, volIdx)

            results.append(result['median'])

        # make np arrays of results and what results are expected to be
        results = np.array(results)
        expectedResults = np.array([1017.00, 1020.5, 1026.00])

        # use np testing method to assert with customized precision
        np.testing.assert_almost_equal(results, expectedResults, decimal=2)
示例#4
0
    def test_customAnalysis(self):
        """ test Analyzer computing customAnalysis within mask """
        # settings dictionary for this test
        settings = {
            'maskFile':
            maskFile,
            'numTimepts':
            3,
            'analysisChoice':
            join(paths['testDataDir'], 'test_customAnalysisScript.py'),
            'maskIsWeighted':
            False
        }

        # create instance of Analyzer class
        analyzer = Analyzer(settings)

        # loop over series and test
        seriesData = nib.load(seriesFile)
        results = []
        for volIdx in range(seriesData.shape[3]):
            # extract the 3d array for this vol
            thisVol = seriesData.get_data()[:, :, :, volIdx]
            result = analyzer.runAnalysis(thisVol, volIdx)

            results.append(result['customResult'])

        # make np arrays of results and what results are expected to be
        results = np.array(results)
        expectedResults = np.array([1029.15, 1032.78, 1034.14])

        # use np testing method to assert with customized precision
        np.testing.assert_almost_equal(results, expectedResults, decimal=2)
示例#5
0
def launchPyneal(headless=False, customSettingsFile=None):
    """Main Pyneal Loop.

    This function will launch setup GUI, retrieve settings, initialize all
    threads, and start processing incoming scans

    """
    ### Read Settings ------------------------------------
    # Read the settings file, and launch the setup GUI to give the user
    # a chance to update the settings. Hitting 'submit' within the GUI
    # will update the setupConfig file with the new settings
    if customSettingsFile:
        print('Loading custom settings file: {}'.format(customSettingsFile))
        settingsFile = customSettingsFile
    else:
        settingsFile = join(pynealDir, 'src/GUIs/pynealSetup/setupConfig.yaml')

    if not headless:
        # Launch GUI to let user update the settings file
        setupGUI.launchPynealSetupGUI(settingsFile)
    elif headless:
        print('Running headless...')
        print('Using settings in {}'.format(settingsFile))
        assert os.path.exists(
            settingsFile
        ), 'Running headless, but settings file does not exist: {}'.format(
            settingsFile)

    # Read the new settings file, store as dict
    with open(settingsFile, 'r') as ymlFile:
        settings = yaml.load(ymlFile)

    ### Create the output directory, put in settings dict
    outputDir = createOutputDir(settings['outputPath'])
    settings['seriesOutputDir'] = outputDir

    ### Set Up Logging ------------------------------------
    # The createLogger function will do a lot of the formatting set up
    # behind the scenes. You can write to this log by calling the
    # logger var and specifying the level, e.g.: logger.debug('msg')
    # Other modules can write to this same log by calling
    # the command: logger = logging.getLogger('PynealLog')
    logFname = join(outputDir, 'pynealLog.log')
    logger = createLogger(logFname)
    print('Logs written to: {}'.format(logFname))

    # write all settings to log
    for k in settings:
        logger.info('Setting: {}: {}'.format(k, settings[k]))
    print('-' * 20)

    ### Launch Threads -------------------------------------
    # Scan Receiver Thread, listens for incoming volume data, builds matrix
    scanReceiver = ScanReceiver(settings)
    scanReceiver.daemon = True
    scanReceiver.start()
    logger.debug('Starting Scan Receiver')

    # Results Server Thread, listens for requests from end-user (e.g. task
    # presentation), and sends back results
    resultsServer = ResultsServer(settings)
    resultsServer.daemon = True
    resultsServer.start()
    logger.debug('Starting Results Server')

    ### Create processing objects --------------------------
    # Class to handle all preprocessing
    preprocessor = Preprocessor(settings)

    # Class to handle all analysis
    analyzer = Analyzer(settings)

    ### Launch Real-time Scan Monitor GUI
    if settings['launchDashboard']:
        ### launch the dashboard app as its own separate process. Once called,
        # it will set up a zmq socket to listen for inter-process messages on
        # the 'dashboardPort', and will host the dashboard website on the
        # 'dashboardClientPort'
        pythonExec = sys.executable  # path to the local python executable
        p = subprocess.Popen([
            pythonExec,
            join(pynealDir, 'src/GUIs/pynealDashboard/pynealDashboard.py'),
            str(settings['dashboardPort']),
            str(settings['dashboardClientPort'])
        ])

        # Set up the socket to communicate with the dashboard server
        dashboardContext = zmq.Context.instance()
        dashboardSocket = dashboardContext.socket(zmq.REQ)
        dashboardSocket.connect('tcp://127.0.0.1:{}'.format(
            settings['dashboardPort']))

        # make sure subprocess and dashboard ports get killed at close
        atexit.register(cleanup, p, dashboardContext)

        # Open dashboard in browser
        # s = '127.0.0.1:{}'.format(settings['dashboardClientPort'])
        # print(s)
        # web.open('127.0.0.1:{}'.format(settings['dashboardClientPort']))

        # send configuration settings to dashboard
        configDict = {
            'mask':
            os.path.split(settings['maskFile'])[1],
            'analysisChoice':
            (settings['analysisChoice'] if settings['analysisChoice']
             in ['Average', 'Median'] else 'Custom'),
            'volDims':
            str(nib.load(settings['maskFile']).shape),
            'numTimepts':
            settings['numTimepts'],
            'outputPath':
            outputDir
        }
        sendToDashboard(dashboardSocket,
                        topic='configSettings',
                        content=configDict)

    ### Wait For Scan To Start -----------------------------
    while not scanReceiver.scanStarted:
        time.sleep(.5)
    logger.debug('Scan started')

    ### Set up remaining configuration settings after first volume arrives
    while not scanReceiver.completedVols[0]:
        time.sleep(.1)
    preprocessor.set_affine(scanReceiver.get_affine())

    ### Process scan  -------------------------------------
    # Loop over all expected volumes
    for volIdx in range(settings['numTimepts']):

        ### make sure this volume has arrived before continuing
        while not scanReceiver.completedVols[volIdx]:
            time.sleep(.1)

        ### start timer
        startTime = time.time()

        ### Retrieve the raw volume
        rawVol = scanReceiver.get_vol(volIdx)

        ### Preprocess the raw volume
        preprocVol = preprocessor.runPreprocessing(rawVol, volIdx)

        ### Analyze this volume
        result = analyzer.runAnalysis(preprocVol, volIdx)

        # send result to the resultsServer
        resultsServer.updateResults(volIdx, result)

        ### Calculate processing time for this volume
        elapsedTime = time.time() - startTime

        # update dashboard (if dashboard is launched)
        if settings['launchDashboard']:
            # completed volIdx
            sendToDashboard(dashboardSocket, topic='volIdx', content=volIdx)

            # timePerVol
            timingParams = {
                'volIdx': volIdx,
                'processingTime': np.round(elapsedTime, decimals=3)
            }
            sendToDashboard(dashboardSocket,
                            topic='timePerVol',
                            content=timingParams)

    ### Save output files
    resultsServer.saveResults()
    scanReceiver.saveResults()

    ### Figure out how to clean everything up nicely at the end
    resultsServer.killServer()
    scanReceiver.killServer()
示例#6
0
def launchPyneal(headless=False, customSettingsFile=None):
    """Main Pyneal Loop.

    This function will launch setup GUI, retrieve settings, initialize all
    threads, and start processing incoming scans

    """
    ### Read Settings ------------------------------------
    # Read the settings file, and launch the setup GUI to give the user
    # a chance to update the settings. Hitting 'submit' within the GUI
    # will update the setupConfig file with the new settings
    if customSettingsFile:
        print('Loading custom settings file: {}'.format(customSettingsFile))
        settingsFile = customSettingsFile
    else:
        settingsFile = join(pynealDir, 'src/GUIs/pynealSetup/setupConfig.yaml')

    if not headless:
        # Launch GUI to let user update the settings file
        setupGUI.launchPynealSetupGUI(settingsFile)
    elif headless:
        print('Running headless...')
        print('Using settings in {}'.format(settingsFile))
        assert os.path.exists(settingsFile), 'Running headless, but settings file does not exist: {}'.format(settingsFile)

    # Read the new settings file, store as dict
    with open(settingsFile, 'r') as ymlFile:
        settings = yaml.load(ymlFile)

    ### Create the output directory, put in settings dict
    outputDir = createOutputDir(settings['outputPath'])
    settings['seriesOutputDir'] = outputDir

    ### Set Up Logging ------------------------------------
    # The createLogger function will do a lot of the formatting set up
    # behind the scenes. You can write to this log by calling the
    # logger var and specifying the level, e.g.: logger.debug('msg')
    # Other modules can write to this same log by calling
    # the command: logger = logging.getLogger('PynealLog')
    logFname = join(outputDir, 'pynealLog.log')
    logger = createLogger(logFname)
    print('Logs written to: {}'.format(logFname))

    # write all settings to log
    for k in settings:
        logger.info('Setting: {}: {}'.format(k, settings[k]))
    print('-'*20)

    ### Launch Threads -------------------------------------
    # Scan Receiver Thread, listens for incoming volume data, builds matrix
    scanReceiver = ScanReceiver(settings)
    scanReceiver.daemon = True
    scanReceiver.start()
    logger.debug('Starting Scan Receiver')

    # Results Server Thread, listens for requests from end-user (e.g. task
    # presentation), and sends back results
    resultsServer = ResultsServer(settings)
    resultsServer.daemon = True
    resultsServer.start()
    logger.debug('Starting Results Server')

    ### Create processing objects --------------------------
    # Class to handle all preprocessing
    preprocessor = Preprocessor(settings)

    # Class to handle all analysis
    analyzer = Analyzer(settings)

    ### Launch Real-time Scan Monitor GUI
    if settings['launchDashboard']:
        ### launch the dashboard app as its own separate process. Once called,
        # it will set up a zmq socket to listen for inter-process messages on
        # the 'dashboardPort', and will host the dashboard website on the
        # 'dashboardClientPort'
        pythonExec = sys.executable     # path to the local python executable
        p = subprocess.Popen([
                        pythonExec,
                        join(pynealDir,
                             'src/GUIs/pynealDashboard/pynealDashboard.py'),
                        str(settings['dashboardPort']),
                        str(settings['dashboardClientPort'])
                        ])

        # Set up the socket to communicate with the dashboard server
        dashboardContext = zmq.Context.instance()
        dashboardSocket = dashboardContext.socket(zmq.REQ)
        dashboardSocket.connect('tcp://127.0.0.1:{}'.format(settings['dashboardPort']))

        # make sure subprocess and dashboard ports get killed at close
        atexit.register(cleanup, p, dashboardContext)

        # Open dashboard in browser
        # s = '127.0.0.1:{}'.format(settings['dashboardClientPort'])
        # print(s)
        # web.open('127.0.0.1:{}'.format(settings['dashboardClientPort']))

        # send configuration settings to dashboard
        configDict = {'mask': os.path.split(settings['maskFile'])[1],
                      'analysisChoice': (settings['analysisChoice'] if settings['analysisChoice'] in ['Average', 'Median'] else 'Custom'),
                      'volDims': str(nib.load(settings['maskFile']).shape),
                      'numTimepts': settings['numTimepts'],
                      'outputPath': outputDir}
        sendToDashboard(dashboardSocket,
                        topic='configSettings',
                        content=configDict)

    ### Wait For Scan To Start -----------------------------
    while not scanReceiver.scanStarted:
        time.sleep(.5)
    logger.debug('Scan started')

    ### Set up remaining configuration settings after first volume arrives
    while not scanReceiver.completedVols[0]:
        time.sleep(.1)
    preprocessor.set_affine(scanReceiver.get_affine())

    ### Process scan  -------------------------------------
    # Loop over all expected volumes
    for volIdx in range(settings['numTimepts']):

        ### make sure this volume has arrived before continuing
        while not scanReceiver.completedVols[volIdx]:
            time.sleep(.1)

        ### start timer
        startTime = time.time()

        ### Retrieve the raw volume
        rawVol = scanReceiver.get_vol(volIdx)

        ### Preprocess the raw volume
        preprocVol = preprocessor.runPreprocessing(rawVol, volIdx)

        ### Analyze this volume
        result = analyzer.runAnalysis(preprocVol, volIdx)

        # send result to the resultsServer
        resultsServer.updateResults(volIdx, result)

        ### Calculate processing time for this volume
        elapsedTime = time.time() - startTime

        # update dashboard (if dashboard is launched)
        if settings['launchDashboard']:
            # completed volIdx
            sendToDashboard(dashboardSocket, topic='volIdx', content=volIdx)

            # timePerVol
            timingParams = {'volIdx': volIdx,
                            'processingTime': np.round(elapsedTime, decimals=3)}
            sendToDashboard(dashboardSocket, topic='timePerVol',
                            content=timingParams)

    ### Save output files
    resultsServer.saveResults()
    scanReceiver.saveResults()

    ### Figure out how to clean everything up nicely at the end
    resultsServer.killServer()
    scanReceiver.killServer()