Exemplo n.º 1
0
def autoLowerThreshold(averageTroughBinaryArea, peak2TroughDiff, peaksOnBinaryImage, fileSubset, thresholdingDir, recordingName):
    # completed automated based on averageTroughBinaryArea
    thresholdStep = 0.005
    chosenThreshold = 0.05

    testTroughAverage = averageTroughBinaryArea + 1

    while testTroughAverage > averageTroughBinaryArea:
        chosenThreshold += thresholdStep

        troughAreas = []
        for i, peak in enumerate(peaksOnBinaryImage):
            if peak + peak2TroughDiff < len(fileSubset):

                troughInfile = fileSubset[peak + peak2TroughDiff]

                troughImg = im.getJellyGrayImageFromFile(troughInfile)

                binaryTroughImg = im.getBinaryJelly(troughImg, chosenThreshold)

                jellyTroughBinaryArea = im.findBinaryArea(binaryTroughImg)

                troughAreas.append(jellyTroughBinaryArea)

        testTroughAverage = np.mean(troughAreas)

        print('chosenThreshold: {} (test area, {}; target area, {})'.format(chosenThreshold, testTroughAverage,
                                                                            averageTroughBinaryArea))

    for i, peak in enumerate(peaksOnBinaryImage):
        if peak + peak2TroughDiff < len(fileSubset):
            peakInfile = fileSubset[peak]
            troughInfile = fileSubset[peak + peak2TroughDiff]

            peakImg = im.getJellyGrayImageFromFile(peakInfile)
            troughImg = im.getJellyGrayImageFromFile(troughInfile)

            binaryPeakImg = im.getBinaryJelly(peakImg, chosenThreshold)
            binaryTroughImg = im.getBinaryJelly(troughImg, chosenThreshold)

            im.saveJellyPlot(im.juxtaposeImages(np.array([[binaryPeakImg, binaryTroughImg]])),
                             (thresholdingDir / '{}_thresholdVerification_{}.png'.format(recordingName, peak)))

    return chosenThreshold
Exemplo n.º 2
0
def differenceAngleFinder(files):

    global currentSegmentEndingFrame

    i = 0

    # movement parameters
    firstStationaryAfterMovement = 0  # first stationary frame (i) after movement
    isMoving = False
    isQuestionablyStationary = False
    centroidBefore = None
    lastStationaryCentroid = None
    counter = 0
    peak = 0
    pulseCountInQuestionablyStationary = 0
    centroid = None

    data = []
    movingPeaks = []

    # initializes lists with 'numConsecutiveDrops' of files
    def reinitializeTestFramesAndAreas(j):
        testFrames = [
        ]  # this list should never be more than 5 entries long, ex. [51, 52, 53, 54, 55]
        testAreas = [
        ]  # this list should never be more than 5 entries long, ex. [253, 255, 256, 255, 255]

        while len(testFrames) < numConsecutiveDrops and j < framesInChunk:
            image = im.getJellyImageFromFile(files[j])
            binary_image = im.getBinaryJelly(image, lowerThreshold)
            area = im.findBinaryArea(binary_image)

            testFrames.append(j)
            testAreas.append(area)
            j += 1

        return testFrames, testAreas, j

    # function to save out data
    def saveOutData():
        df = pd.DataFrame(data,
                          columns=[
                              'global frame', 'chunk frame', 'angle',
                              'centroid x', 'centroid y'
                          ])
        if DEBUG: print(df.head())
        dataTitle = '{}_{:03}.csv'.format(chunkName, movementSegment)
        df.to_csv(str(angleOutputDir / dataTitle), index=False)

    testFrames, testAreas, i = reinitializeTestFramesAndAreas(i)

    try:
        while i < framesInChunk:

            isDownturn = dm.is_downturn(0, testAreas, numConsecutiveDrops)

            if isDownturn:
                peak = i - numConsecutiveDrops

                print("chunk: {}, i: {}, peak: {}".format(chunkName, i, peak))

                # checks that peaks are within testing bounds
                if peak + peak2InflectionDiff >= 0 and peak + peak2TroughDiff < framesInChunk:

                    troughInfile = files[peak + peak2TroughDiff]
                    relaxedInfile = files[peak + peak2InflectionDiff]

                    troughImg = im.getJellyGrayImageFromFile(troughInfile)
                    relaxedImg = im.getJellyGrayImageFromFile(relaxedInfile)

                    centroidDiff = im.getGrayscaleImageDiff_absolute(
                        troughImg, relaxedImg)
                    binaryCentroidDiff = im.getBinaryJelly(centroidDiff,
                                                           lower_bound=0.05,
                                                           upper_bound=1)
                    centroidRegion = im.findJellyRegion(binaryCentroidDiff)
                    centroid = im.findCentroid_boundingBox(centroidRegion)

                    if lastStationaryCentroid is None:
                        lastStationaryCentroid = centroid

                    if CONFIRMATIONIMAGES:
                        im.saveJellyPlot(
                            im.getCentroidVerificationImg(
                                centroidDiff, binaryCentroidDiff, centroid),
                            str(confirmationImagesPath /
                                '{}_{}_centroid.png'.format(peak, chunkName)))

                    if isMoving:

                        data.append([
                            peak + lastFrameOfPreviousChunk, peak, np.nan,
                            centroid[0], centroid[1]
                        ])

                        movedBefore = isMoving
                        isMoving = im.distance(centroid, lastStationaryCentroid
                                               ) > movementThreshold2KeepMoving

                        lastStationaryCentroid = centroid

                        if movedBefore and not isMoving:
                            firstStationaryAfterMovement = i
                            pulseCountInQuestionablyStationary = 0
                            isQuestionablyStationary = True

                    elif isQuestionablyStationary:

                        data.append([
                            peak + lastFrameOfPreviousChunk, peak, np.nan,
                            centroid[0], centroid[1]
                        ])

                        isMoving = im.distance(
                            centroid, lastStationaryCentroid
                        ) > movementThreshold4reinitialization

                        if isMoving:
                            movingPeaks.append(peak)
                            isQuestionablyStationary = False

                        pulseCountInQuestionablyStationary += 1

                        if i - firstStationaryAfterMovement > numFrames2ConfirmStationary:
                            # now there is confirmed time after initial stationary point

                            if firstStationaryAfterMovement == 0:
                                data = []
                            else:
                                # must mutate data to take out
                                data = data[:
                                            -pulseCountInQuestionablyStationary]
                                currentSegmentEndingFrame = i
                                saveSegmentVariableParams()
                                saveOutData()
                                data = []

                            i = firstStationaryAfterMovement

                            # peak2InflectionDiff, peak2TroughDiff, postPeakRefractoryPeriod, infflectionTestDiff,
                            # inflectionTestBinaryThreshold, and chosen SD are all static.

                            initialize_params(files, i)

                            isQuestionablyStationary = False

                            pulseCountInQuestionablyStationary = 0

                        # until count from current i to last stationary i reaches this point,
                        # the program is in a holding pattern of sorts.

                    else:
                        testInfile = files[peak + peak2InflectionDiff +
                                           inflectionTestDiff]
                        testImg = im.getJellyGrayImageFromFile(testInfile)

                        if CONFIRMATIONIMAGES:
                            plt.imsave(
                                str(confirmationImagesPath /
                                    '{}_{}_interestFrames.png'.format(
                                        peak, chunkName)),
                                im.juxtaposeImages(
                                    np.array([[
                                        relaxedImg, testImg, peakImg, troughImg
                                    ]])))

                        if centroidBefore is not None:
                            reinitializeAreaPlot = im.distance(
                                centroid, centroidBefore
                            ) > movementThreshold4newNormalizationImg
                            if reinitializeAreaPlot:
                                peakInfile = files[peak]
                                peakImg = im.getJellyGrayImageFromFile(
                                    peakInfile)
                                peakDiff = im.getGrayscaleImageDiff_absolute(
                                    troughImg, peakImg)
                                binaryPeakDiff = im.getBinaryJelly(
                                    peakDiff, lower_bound=0.05, upper_bound=1)
                                averagedDynamicRangeMaskedImg = im.dynamicRangeImg_AreaBased(
                                    relaxedImg, binaryPeakDiff, 5)

                        else:
                            peakInfile = files[peak]
                            peakImg = im.getJellyGrayImageFromFile(peakInfile)
                            peakDiff = im.getGrayscaleImageDiff_absolute(
                                troughImg, peakImg)
                            binaryPeakDiff = im.getBinaryJelly(
                                peakDiff, lower_bound=0.05, upper_bound=1)
                            averagedDynamicRangeMaskedImg = im.dynamicRangeImg_AreaBased(
                                relaxedImg, binaryPeakDiff, 5)

                        centroidBefore = centroid

                        if CONFIRMATIONIMAGES:
                            im.saveJellyPlot(
                                averagedDynamicRangeMaskedImg,
                                str(confirmationImagesPath /
                                    '{}_{}_dynRng.png'.format(peak,
                                                              chunkName)))

                        testDiff = im.getGrayscaleImageDiff_absolute(
                            testImg, relaxedImg)
                        normalizedTestDiff = testDiff / averagedDynamicRangeMaskedImg

                        binaryDiffImg = im.getBinaryJelly(
                            normalizedTestDiff,
                            lower_bound=inflectionTestBinaryThreshold)

                        biggestRegion = im.findJellyRegion(binaryDiffImg)

                        if biggestRegion is not None:
                            local_com = im.findCentroid_regionProp(
                                biggestRegion)
                            zeroDegreePoint = (centroid[0], 0)

                            angle = dm.getAngle(zeroDegreePoint, centroid,
                                                local_com)

                            if CONFIRMATIONIMAGES:
                                im.saveJellyPlot(
                                    binaryDiffImg,
                                    str(confirmationImagesPath /
                                        '{}_{}_angle.png'.format(
                                            peak, chunkName)),
                                    [centroid, local_com, zeroDegreePoint])
                        else:
                            angle = np.nan

                            if CONFIRMATIONIMAGES:
                                im.saveJellyPlot(
                                    binaryDiffImg,
                                    str(confirmationImagesPath /
                                        '{}_{}_angle.png'.format(
                                            peak, chunkName)), [centroid])

                        data.append([
                            peak + lastFrameOfPreviousChunk, peak, angle,
                            centroid[0], centroid[1]
                        ])

                        movedBefore = isMoving
                        isMoving = im.distance(
                            centroid, lastStationaryCentroid
                        ) > movementThreshold4reinitialization

                        if isMoving and not movedBefore:
                            isQuestionablyStationary = False

                            lastStationaryCentroid = centroid

                i += postPeakRefractoryPeriod
                counter += 1

                testFrames, testAreas, i = reinitializeTestFramesAndAreas(i)

            else:
                testFrames.pop(0)
                testAreas.pop(0)

                image = im.getJellyImageFromFile(files[i])
                binary_image = im.getBinaryJelly(image, lowerThreshold)
                area = im.findBinaryArea(binary_image)

                testFrames.append(i)
                testAreas.append(area)
                i += 1
                counter += 1

    except Exception as error:
        print('{} error occured.'.format(error))
        print(
            "chunkName: {}, index: {}, isMoving: {}, isQStat: {}, centroid: {}"
            .format(chunkName, i, isMoving, isQuestionablyStationary,
                    str(centroid)))
        raise

    finally:
        currentSegmentEndingFrame = i
        saveSegmentVariableParams()
        saveOutData()
Exemplo n.º 3
0
def initialize_params(files, startingFrameNum):

    global lowerThreshold
    global pathOfCurrentParamDF
    global segmentVerificationDir
    global movementSegment
    global currentSegmentStartingFrame
    global currentSegmentEndingFrame
    global isChunkAnalysisFinished

    currentSegmentStartingFrame = startingFrameNum
    currentSegmentEndingFrame = startingFrameNum

    reinitializeElapsedTime()
    saveSegmentVariableParams()

    if startingFrameNum != 0:
        movementSegment += 1

    if startingFrameNum + numFramesForParamInitialization < framesInChunk:
        fileSubset = files[startingFrameNum:startingFrameNum +
                           numFramesForParamInitialization]
    else:
        fileSubset = files[startingFrameNum:]

    # create segment directory named with global movement segment
    segmentName = '{}_{}_{:03}'.format(recordingName, chunkName,
                                       movementSegment)
    segmentVerificationDir = dm.makeOutDir(segmentDir, segmentName)

    pathOfCurrentParamDF = segmentVerificationDir / '{}_params.csv'.format(
        segmentName)

    saveSegmentVariableParams()

    thresholdingDir = dm.makeOutDir(segmentVerificationDir,
                                    '{}_ThresholdingPlots'.format(segmentName))
    plotDir = dm.makeOutDir(segmentVerificationDir,
                            '{}_AngleVerificationPlots'.format(segmentName))
    centroidDir = dm.makeOutDir(
        segmentVerificationDir,
        '{}_CentroidVerificationPlots'.format(segmentName))
    segmentOrientationDir = dm.makeOutDir(
        segmentVerificationDir,
        '{}_RelaxedFramesForOrientation'.format(segmentName))
    dynamicRangeDir = dm.makeOutDir(
        segmentVerificationDir,
        '{}_dynamicRangeNormalizationImages'.format(segmentName))

    if DEBUG: print('loading initialization stack\n')
    init_movie = init.get_init_movie(fileSubset)

    if DEBUG: print('calculating lowerThreshold\n')
    lowerThreshold = init.autoLowerThreshold(
        init_movie, roughness_saveOut_dir=thresholdingDir)

    saveSegmentVariableParams()

    # get areas of jellies both the region and the whole value true in binary image.
    binaryImageAreas = init.getBinaryAreas(init_movie, lowerThreshold)
    peaksOnBinaryImage = init.downturnFinder(
        init_movie, postPeakRefractoryPeriod, lowerThreshold,
        numConsecutiveDrops, peak2InflectionDiff, peak2TroughDiff)

    plotOutpath = segmentVerificationDir / '{}_areaPlot.png'.format(
        segmentName)
    init.saveAreasPlot(binaryImageAreas, peaksOnBinaryImage, plotOutpath, [
        peak2InflectionDiff, peak2InflectionDiff + inflectionTestDiff,
        peak2TroughDiff
    ], postPeakRefractoryPeriod)

    saveSegmentVariableParams()

    i = 0
    while i < len(peaksOnBinaryImage):
        if peaksOnBinaryImage[
                i] + peak2InflectionDiff < 0 or peaksOnBinaryImage[
                    i] + peak2TroughDiff >= numFramesForParamInitialization:
            peaksOnBinaryImage.pop(i)
        else:
            i += 1

    for i, peak in enumerate(peaksOnBinaryImage):
        relaxedInfile = fileSubset[peak + peak2InflectionDiff]
        testInfile = fileSubset[peak + peak2InflectionDiff +
                                inflectionTestDiff]
        peakInfile = fileSubset[peak]
        troughInfile = fileSubset[peak + peak2TroughDiff]

        relaxedImg = im.getJellyGrayImageFromFile(relaxedInfile)
        testImg = im.getJellyGrayImageFromFile(testInfile)
        peakImg = im.getJellyGrayImageFromFile(peakInfile)
        troughImg = im.getJellyGrayImageFromFile(troughInfile)

        centroidDiff = im.getGrayscaleImageDiff_absolute(troughImg, relaxedImg)
        binaryCentroidDiff = im.getBinaryJelly(centroidDiff, lower_bound=0.05)
        centroidRegion = im.findJellyRegion(binaryCentroidDiff)
        centroid = im.findCentroid_boundingBox(centroidRegion)

        centroidVerOutFile = centroidDir / 'centroid for {}_{:03}.png'.format(
            segmentName, peak + peak2InflectionDiff)
        im.saveJellyPlot(
            im.getCentroidVerificationImg(centroidDiff, binaryCentroidDiff,
                                          centroid), centroidVerOutFile)

        if i == 0:
            orientationFrameStamp = dm.getFrameNumFromFile(peakInfile)

            orientationTimeStamp = int(orientationFrameStamp / framerate)

            orientationOutFile = orientationDir / '{}_ts_{:02}h_{:02}m_{:02}s_{:03}.png'.format(
                chunkName, int(orientationTimeStamp / 3600),
                int(orientationTimeStamp / 60) % 60, orientationTimeStamp % 60,
                movementSegment)
            im.saveJellyPlot(relaxedImg, orientationOutFile,
                             [centroid, (centroid[0], 15)])

        orientationOutFile = segmentOrientationDir / 'relaxedFrame_{:03}.png'.format(
            peak + peak2InflectionDiff)
        im.saveJellyPlot(relaxedImg, orientationOutFile,
                         [centroid, (centroid[0], 15)])

        peakDiff = im.getGrayscaleImageDiff_absolute(troughImg, peakImg)
        binaryPeakDiff = im.getBinaryJelly(peakDiff,
                                           lower_bound=0.05,
                                           upper_bound=1)
        averagedDynamicRangeMaskedImg = im.dynamicRangeImg_AreaBased(
            relaxedImg, binaryPeakDiff, 5)

        dynamicRangeImgOutfile = dynamicRangeDir / 'dynamicRangeImg_{:03}.png'.format(
            peak + peak2InflectionDiff)
        im.saveJellyPlot(averagedDynamicRangeMaskedImg, dynamicRangeImgOutfile)

        testDiff = im.getGrayscaleImageDiff_absolute(testImg, relaxedImg)
        normalizedTestDiff = testDiff / averagedDynamicRangeMaskedImg

        binaryDiffImg = im.getBinaryJelly(
            normalizedTestDiff, lower_bound=inflectionTestBinaryThreshold)

        biggestRegion = im.findJellyRegion(binaryDiffImg)

        if biggestRegion is not None:
            local_com = im.findCentroid_regionProp(biggestRegion)
            zeroDegreePoint = (centroid[0], 0)

            testingOutfile = plotDir / 'testPlot for {} - {:03}.png'.format(
                segmentName, peak + peak2InflectionDiff)
            im.saveJellyPlot(binaryDiffImg, testingOutfile,
                             [centroid, zeroDegreePoint, local_com])
        else:
            testingOutfile = plotDir / 'testPlot for {} - {:03}.png'.format(
                segmentName, peak + peak2InflectionDiff)
            im.saveJellyPlot(binaryDiffImg, testingOutfile, [centroid])

    # saves important parameters used in analysis to csv
    saveSegmentVariableParams()

    if DEBUG: print('saved parameter data')

    if DEBUG:
        print('finished saving outplots and angle verification at: {}'.format(
            segmentVerificationDir))

    return True
Exemplo n.º 4
0
        maskedImg = im.applyMask2Img(binaryImg, grayImg)

        jellyRegion = im.findJellyRegionWithGray(binaryImg, grayImg)
        maxIntensity = jellyRegion.max_intensity
        minIntensity = jellyRegion.min_intensity
        print(maxIntensity)
        print(minIntensity)

        thresholdedGrayImg = im.getBinaryJelly(grayImg,
                                               lower_bound=minIntensity,
                                               upper_bound=maxIntensity)

        print(maskedImg)

        plt.hist(maskedImg.ravel())
        plt.show()
        #
        im.saveJellyPlot(
            maskedImg,
            str(jellyOutDir /
                'maskedImg_{}_{}.jpg'.format(stack.name, relaxedFrameNum)))
        im.saveJellyPlot(
            thresholdedGrayImg,
            str(jellyOutDir / 'thresholdwithmask_{}_{}.jpg'.format(
                stack.name, relaxedFrameNum)))
        im.saveHistogram(
            maskedImg,
            str(jellyOutDir /
                'histogram_{}_{}.jpg'.format(stack.name, relaxedFrameNum)))
Exemplo n.º 5
0
            jellyRegion = im.findJellyRegionWithGray(binaryCentroidDiff,
                                                     maskedImg)
            maxIntensity = jellyRegion.max_intensity
            minIntensity = jellyRegion.min_intensity
            print(maxIntensity)
            print(minIntensity)

            # thresholded image off of centroid image jelly mask intensities
            thresholdedGrayImg = im.getBinaryJelly(relaxedImg,
                                                   lower_bound=minIntensity,
                                                   upper_bound=maxIntensity)

            # saving jelly plots
            im.saveJellyPlot(
                centroidDiff,
                str(centroidDiffGrayOutDir /
                    'centroidDiffGray {} - {}.jpg'.format(
                        stack.name, peak - prePeakInflectionDiff)))
            im.saveJellyPlot(
                binaryCentroidDiff,
                str(centroidDiffBinaryOutDir /
                    'centroidDiffBinary {} - {}.jpg'.format(
                        stack.name, peak - prePeakInflectionDiff)))
            im.saveJellyPlot(
                maskedImg,
                str(centroidDiffMaskedOutDir / 'maskedImg_{}_{}.jpg'.format(
                    stack.name, peak - prePeakInflectionDiff)))
            im.saveJellyPlot(
                thresholdedGrayImg,
                str(centroidDiffThresholdedOutDir /
                    'thresholded_{}_{}.jpg'.format(
def initialization_Main(pathOfPreInitializationDF, pathOfInitializationStack,
                        recordingHomeDir, macintosh):
    global MAC
    MAC = macintosh

    preInitializationDf = pd.read_csv(str(pathOfPreInitializationDF))
    initializationStack = dm.getFrameFilePaths(pathOfInitializationStack)

    print(len(initializationStack))

    # static variables across single recording that must be read in from df
    recordingName = preInitializationDf.iloc[0]['RecordingName']
    initializationOutputDir = dm.makeOutDir(recordingHomeDir,
                                            'InitializationVerification')
    framerate = preInitializationDf.iloc[0]['FrameRate']
    framesInRecording = sum(preInitializationDf['NumFramesInChunk'].tolist()
                            )  # not saved in final DF
    lengthOfRecording = timedelta(0, framesInRecording / framerate)

    # static variables across single recording that must be initialized
    lowerThreshold = None
    peak2InflectionDiff = -15
    peak2TroughDiff = 30
    postPeakRefractoryPeriod = 40
    inflectionTestDiff = None
    inflectionTestBinaryThreshold = None
    chosenSD = None  # not saved in final DF
    numConsecutiveDrops = 10
    use_conserved_trough = False

    # static variables across all recordings
    movementThreshold4reinitialization = 20
    movementThreshold2KeepMoving = 10
    movementThreshold4newNormalizationImg = 5
    pct2skip4RefractionaryPeriod = 2 / 5
    numFramesForParamInitialization = 3200  # 120 * 30
    numFrames2ConfirmStationary = 3600  # 120 * 60, 60 seconds of recording to stay stationary (just for testing)

    thresholdingDir = dm.makeOutDir(
        initializationOutputDir, '{}_ThresholdingPlots'.format(recordingName))
    angleArrImageDir = dm.makeOutDir(
        initializationOutputDir, '{}_AngleArrImageDir'.format(recordingName))
    centroidDir = dm.makeOutDir(
        initializationOutputDir,
        '{}_CentroidVerificationDir'.format(recordingName))
    dynamicRangeDir = dm.makeOutDir(
        initializationOutputDir,
        '{}_dynamicRangeVerificationDir'.format(recordingName))
    areaPlotOutpath = initializationOutputDir / 'areaVerificationPlot.jpg'

    def saveVariableParams():
        imp_parameters = pd.DataFrame(np.array([
            [recordingName, 'the name of the recording being processed'],
            [
                initializationOutputDir,
                'place where all the initialization verification images and directories are stored'
            ],
            [framerate, 'framerate of the specified recording'],
            [framesInRecording, 'number of total frames in recording'],
            [lengthOfRecording, 'length of recording in timedelta format'],
            [
                lowerThreshold,
                'lower threshold to create binary image of jelly to assess area (for downturns)'
            ],
            [
                peak2InflectionDiff,
                'the number of frames past the peak where the inflection point occurs (this should always be negative)'
            ],
            [
                peak2TroughDiff,
                'the number of frames past the peak where the lowest area is found on average'
            ],
            [
                postPeakRefractoryPeriod,
                'the number of frames to preclude from analysis'
            ],
            [
                inflectionTestDiff,
                'the number of frames after inflection point where the difference in calculated'
            ],
            [
                inflectionTestBinaryThreshold,
                'the ideal threshold to locate the area of difference'
            ],
            [
                chosenSD,
                'the sd of the chosen test diff and threshold when they were initialized'
            ],
            [
                numConsecutiveDrops,
                'the number of consecutive drops needed to count something as a downturn'
            ],
            [
                use_conserved_trough,
                'if True, the trough becomes conserved point of the pulse instead of the peak'
            ],
            [
                movementThreshold4reinitialization,
                'number of pixels from one centroid to another to consider a jelly as moving.'
            ],
            [
                movementThreshold2KeepMoving,
                'number of pixels from one centroid to the next to continue to be considered moving'
            ],
            [
                movementThreshold4newNormalizationImg,
                'number of pixels from one centroid to another to reinitialize the average normalization img'
            ],
            [
                pct2skip4RefractionaryPeriod,
                'percent on average Interpulse Interval to skip when initializing postPeakRefractoryPeriod'
            ],
            [
                numFramesForParamInitialization,
                'number of frames to use when initializing params for a new segment'
            ],
            [
                numFrames2ConfirmStationary,
                'number of frames after first stationary frame after movement to confirm jellyfish is stationary'
            ],
        ]),
                                      index=[
                                          'recordingName',
                                          'initializationOutputDir',
                                          'framerate', 'framesInRecording',
                                          'lengthOfRecording',
                                          'lowerThreshold',
                                          'peak2InflectionDiff',
                                          'peak2TroughDiff',
                                          'postPeakRefractoryPeriod',
                                          'inflectionTestDiff',
                                          'inflectionTestBinaryThreshold',
                                          'chosenSD', 'numConsecutiveDrops',
                                          'use_conserved_trough',
                                          'movementThreshold4reinitialization',
                                          'movementThreshold2KeepMoving',
                                          'movementThreshold4newNormalizationImg',
                                          'pct2skip4RefractionaryPeriod',
                                          'numFramesForParamInitialization',
                                          'numFrames2ConfirmStationary'
                                      ],
                                      columns=['data', 'notes'])

        imp_parameters.to_csv(
            str(initializationOutputDir /
                '{}_initializationParameters.csv'.format(recordingName)))

    saveVariableParams()

    if DEBUG: print('intial parameters set\n')

    if DEBUG: print('loading initialization stack\n')
    init_movie = get_init_movie(initializationStack)

    if DEBUG: print('calculating lowerThreshold\n')
    lowerThreshold = autoLowerThreshold(
        init_movie, roughness_saveOut_dir=initializationOutputDir)

    saveVariableParams()

    if DEBUG: print('getting BinaryAreas\n')
    binaryImageAreas = getBinaryAreas(init_movie, lowerThreshold)

    if DEBUG: print('getting peaksOnBinaryImage\n')
    # gets peak frame nums from binaryImageAreas
    peaksOnBinaryImage = downturnFinder(
        init_movie,
        postPeakRefractoryPeriod,
        lowerThreshold,
        numConsecutiveDrops,
        peak2InflectionDiff,
        peak2TroughDiff,
        use_conserved_trough=use_conserved_trough)

    saveAreasPlot(
        binaryImageAreas, peaksOnBinaryImage, areaPlotOutpath,
        [peak2InflectionDiff, peak2InflectionDiff + 5, peak2TroughDiff],
        postPeakRefractoryPeriod)

    if DEBUG: print('peaks: {}\n'.format(peaksOnBinaryImage))

    for peak in peaksOnBinaryImage:
        init_movie_binary = init_movie > lowerThreshold

        thresholdingImgOutfile = thresholdingDir / 'thresholdingImg_{:03}.png'.format(
            peak)

        im.saveJellyPlot(init_movie_binary[peak], thresholdingImgOutfile)

    # gets peak2TroughDiff from peaksOnBinaryImage and binaryImageAreas
    troughsOnBinaryImage = dm.getTroughs(binaryImageAreas)

    if DEBUG: print('troughs: {}'.format(troughsOnBinaryImage))

    peak2TroughDiff = dm.likelyPostPeakTroughDiff(troughsOnBinaryImage,
                                                  peaksOnBinaryImage)

    # initializes inflection diff from jellyRegionAreas
    peak2InflectionDiff = dm.getLikelyInflectionDiff(binaryImageAreas,
                                                     peaksOnBinaryImage)

    # initializes frames to skip for analysis after each peak
    averageIPI = dm.averageInterpulseInterval(peaksOnBinaryImage)
    postPeakRefractoryPeriod = int(pct2skip4RefractionaryPeriod * averageIPI)

    if CHIME: dm.chime(MAC, 'input time')
    while True:

        diffsList = [
            peak2InflectionDiff, peak2InflectionDiff + 5, 0, peak2TroughDiff
        ]
        if use_conserved_trough:
            diffsList = [x - peak2TroughDiff for x in diffsList]
        saveAreasPlot(binaryImageAreas, peaksOnBinaryImage, areaPlotOutpath,
                      diffsList, postPeakRefractoryPeriod)

        print('Params to change: ')
        print('select \'1\' to change {} which is {}'.format(
            'postPeakRefractoryPeriod', postPeakRefractoryPeriod))
        print('select \'2\' to change {} which is {}'.format(
            'numConsecutiveDrops', numConsecutiveDrops))
        print('select \'3\' to change {} which is {}'.format(
            'peak2InflectionDiff', peak2InflectionDiff))
        print('select \'4\' to change {} which is {}'.format(
            'peak2TroughDiff', peak2TroughDiff))
        print('select \'5\' to toggle {} which is {}'.format(
            'use_conserved_trough', use_conserved_trough))
        print('or \'6\' to continue.')

        selectionVar = dm.getSelection([1, 2, 3, 4, 5, 6])

        if selectionVar == '1':
            postPeakRefractoryPeriod = dm.reassignIntVariable(
                postPeakRefractoryPeriod, 'postPeakRefractoryPeriod')
        elif selectionVar == '2':
            numConsecutiveDrops = dm.reassignIntVariable(
                numConsecutiveDrops, 'numConsecutiveDrops')

            peaksOnBinaryImage = downturnFinder(
                init_movie,
                postPeakRefractoryPeriod,
                lowerThreshold,
                numConsecutiveDrops,
                peak2InflectionDiff,
                peak2TroughDiff,
                use_conserved_trough=use_conserved_trough)
            troughsOnBinaryImage = dm.getTroughs(binaryImageAreas)
            peak2TroughDiff = dm.likelyPostPeakTroughDiff(
                troughsOnBinaryImage, peaksOnBinaryImage)
            peak2InflectionDiff = dm.getLikelyInflectionDiff(
                binaryImageAreas, peaksOnBinaryImage)
            postPeakRefractoryPeriod = int(
                pct2skip4RefractionaryPeriod *
                dm.averageInterpulseInterval(peaksOnBinaryImage))
        elif selectionVar == '3':
            peak2InflectionDiff = dm.reassignIntVariable(
                peak2InflectionDiff, 'peak2InflectionDiff')
        elif selectionVar == '4':
            peak2TroughDiff = dm.reassignIntVariable(peak2TroughDiff,
                                                     'peak2TroughDiff')
        elif selectionVar == '5':
            use_conserved_trough = not use_conserved_trough
            peaksOnBinaryImage = downturnFinder(
                init_movie,
                postPeakRefractoryPeriod,
                lowerThreshold,
                numConsecutiveDrops,
                peak2InflectionDiff,
                peak2TroughDiff,
                use_conserved_trough=use_conserved_trough)
        else:
            break

    if DEBUG:
        print(
            'finished setting postPeakRefractoryPeriod, numConsecutiveDrops, peak2InflectionDiff, peak2TroughDiff'
        )

    saveVariableParams()

    # makes sure pulses are within bounds
    i = 0
    while i < len(peaksOnBinaryImage):
        if peaksOnBinaryImage[
                i] + peak2InflectionDiff < 0 or peaksOnBinaryImage[
                    i] + peak2TroughDiff >= numFramesForParamInitialization:
            peaksOnBinaryImage.pop(i)
        else:
            i += 1

    # decreases number of by eye measurements if there is a fast pulse rate
    if len(peaksOnBinaryImage) > 20:
        peaksOnBinaryImage = peaksOnBinaryImage[:20]

    if DEBUG: print('Running \'selectInflectionThresholdandDiff\'\n')

    inflectionTestDiff, inflectionTestBinaryThreshold, chosenSD = selectInflectionThresholdandDiff(
        peaksOnBinaryImage, init_movie, recordingName, peak2InflectionDiff,
        peak2TroughDiff, use_conserved_trough, initializationOutputDir,
        angleArrImageDir, centroidDir, dynamicRangeDir)

    saveVariableParams()

    # static params for each chunk (fraction over overall video recording ex. xaa, xab, xac, etc.)
    lastFrameOfPreviousChunk = 0  # calculated from framesInChunk

    postInitiationDF = preInitializationDf.copy()

    # static params for each recording
    postInitiationDF[
        'peak2InflectionDiff'] = peak2InflectionDiff  # the number of frames past the peak where the inflection point occurs (this should always be negative)
    postInitiationDF[
        'peak2TroughDiff'] = peak2TroughDiff  # the number of frames past the peak where the lowest area is found on average
    postInitiationDF[
        'postPeakRefractoryPeriod'] = postPeakRefractoryPeriod  # the number of frames to preclude from analysis
    postInitiationDF[
        'inflectionTestDiff'] = inflectionTestDiff  # the number of frames after inflection point where the difference in calculated
    postInitiationDF[
        'inflectionTestBinaryThreshold'] = inflectionTestBinaryThreshold  # the ideal threshold to locate the area of difference
    postInitiationDF[
        'numConsecutiveDrops'] = numConsecutiveDrops  # the number of consecutive drops needed to count something as a downturn
    postInitiationDF['use_conserved_trough'] = use_conserved_trough

    # static params for all recording
    postInitiationDF[
        'movementThreshold4reinitialization'] = movementThreshold4reinitialization  # number of pixels from one centroid to another to consider a jelly as moving.
    postInitiationDF[
        'movementThreshold2KeepMoving'] = movementThreshold2KeepMoving  # number of pixels from one centroid to the next to continue to be considered moving
    postInitiationDF[
        'movementThreshold4newNormalizationImg'] = movementThreshold4newNormalizationImg  # number of pixels from one centroid to another to reinitialize the average normalization img
    postInitiationDF[
        'numFramesForParamInitialization'] = numFramesForParamInitialization  # number of frames to use when initializing params for a new segment
    postInitiationDF[
        'numFrames2ConfirmStationary'] = numFrames2ConfirmStationary  # number of frames after first stationary frame after movement to confirm jellyfish is stationary

    chunkFrameCounts = preInitializationDf['NumFramesInChunk'].tolist()
    previousChunkTotals = []

    for i in range(len(postInitiationDF)):
        previousChunkTotals.append(sum(chunkFrameCounts[:i]))

    postInitiationDF['lastFrameOfPreviousChunk'] = previousChunkTotals

    postInitiationDFOutName = pathOfPreInitializationDF.stem[:pathOfPreInitializationDF
                                                             .stem.rindex(
                                                                 '_'
                                                             )] + '_PostInitializationDF.csv'

    postInitiationDFOutpath = pathOfPreInitializationDF.parent / postInitiationDFOutName

    postInitiationDF.to_csv(str(postInitiationDFOutpath))
def selectInflectionThresholdandDiff(peaksOnBinaryImage, init_movie,
                                     recordingName, peak2InflectionDiff,
                                     peak2TroughDiff, use_conserved_trough,
                                     initializationOutputDir, angleArrImageDir,
                                     centroidDir, dynamicRangeDir):

    if use_conserved_trough:
        peaksOnBinaryImage = [x - peak2TroughDiff for x in peaksOnBinaryImage]

    # make directory to store verification jelly plots
    postInflectionDiffCases = list(range(2, 12))
    thresholdCases = [0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5]

    # out data: pulse angles x testDiffs
    angleData = np.empty(
        (len(peaksOnBinaryImage), len(postInflectionDiffCases),
         len(thresholdCases)))  # 3D array
    angleData[:] = np.nan

    otherDataCols = np.array(['relaxed', 'peak', 'trough', 'by eye', ''])
    otherData = np.empty((len(peaksOnBinaryImage), len(otherDataCols)))
    otherData[:] = np.nan

    # read in by eye angle measurements
    byEyeAngleDF = pd.DataFrame(peaksOnBinaryImage, columns=['peaks'])
    byEyeAngleDF['by eye measurement (0 to 360)'] = np.nan
    byEyeAngleDFioPath = initializationOutputDir / '{}_byEyeAngles.csv'.format(
        recordingName)
    byEyeAngleDF.to_csv(str(byEyeAngleDFioPath), index=False)

    for i, peak in enumerate(peaksOnBinaryImage):
        if DEBUG: print("{}: {}".format(i, peak))

        troughImg = init_movie[peak + peak2TroughDiff]
        relaxedImg = init_movie[peak + peak2InflectionDiff]

        centroidDiff = im.getGrayscaleImageDiff_absolute(troughImg, relaxedImg)
        binaryCentroidDiff = im.getBinaryJelly(centroidDiff, lower_bound=0.05)
        centroidRegion = im.findJellyRegion(binaryCentroidDiff)[0]
        centroid = im.findCentroid_boundingBox(centroidRegion)

        centroidVerOutFile = centroidDir / 'centroid for {} - {:03}.png'.format(
            recordingName, peak + peak2InflectionDiff)
        im.saveJellyPlot(
            im.getCentroidVerificationImg(centroidDiff, binaryCentroidDiff,
                                          centroid), centroidVerOutFile)

        peakImg = init_movie[peak]
        peakDiff = im.getGrayscaleImageDiff_absolute(troughImg, peakImg)
        binaryPeakDiff = im.getBinaryJelly(peakDiff, lower_bound=0.05)
        if np.sum(binaryCentroidDiff) > np.sum(binaryPeakDiff):
            binaryPeakDiff = binaryCentroidDiff
        averagedDynamicRangeMaskedImg = im.dynamicRangeImg_AreaBased(
            relaxedImg, binaryPeakDiff, 5)

        dynamicRangeImgOutfile = dynamicRangeDir / 'dynamicRangeImg_{:03}.png'.format(
            peak + peak2InflectionDiff)

        im.saveJellyPlot(averagedDynamicRangeMaskedImg, dynamicRangeImgOutfile)

        # dealing with inflection thresholding
        testDiffImages = []
        for j in postInflectionDiffCases:
            testImg = init_movie[peak + peak2InflectionDiff + j]
            testDiff = im.getGrayscaleImageDiff_absolute(testImg, relaxedImg)
            normalizedTestDiff = testDiff / averagedDynamicRangeMaskedImg
            testDiffImages.append(normalizedTestDiff)

        testingOutfile = angleArrImageDir / 'testPlot for {} - {:03}.png'.format(
            recordingName, peak + peak2InflectionDiff)
        pulseAngleData = im.saveDifferenceTestingAggregationImage(
            relaxedImg,
            testDiffImages,
            thresholdCases,
            testingOutfile,
            discludeVerificationArrayImg=False,
            centroid=centroid)

        for n, row in enumerate(pulseAngleData):
            for m, angle in enumerate(row):
                angleData[i][m][n] = angle

        otherData[i][0] = peak + peak2InflectionDiff
        otherData[i][1] = peak
        otherData[i][2] = peak + peak2TroughDiff

    angleDataAsRows = [x.ravel() for x in angleData]
    pulseAngleOutput = np.concatenate(
        (np.tile([postInflectionDiffCases],
                 len(thresholdCases)), angleDataAsRows))
    otherDataOut = np.concatenate(([otherDataCols], otherData))

    # warning: this results in mixed data. This cannot be saved by numpy csv methods. Pandas is easiest way to save.
    outframe = np.concatenate((otherDataOut, pulseAngleOutput), axis=1)

    # saves data into verification frame
    dfOut = pd.DataFrame(outframe)
    dataTitle = '{}_testDifferenceVerification.csv'.format(recordingName)
    verificationCSVOutFile = initializationOutputDir / dataTitle
    dfOut.to_csv(str(verificationCSVOutFile), header=False, index=False)

    # setting test difference and threshold
    def runSDanalysis():
        if CHIME: dm.chime(MAC, 'input time')

        print('time to enter by eye angles for each pulse')
        print('entries must be from 0 to 360')
        print('Enter \'1\' to continue.')
        dm.getSelection([1])

        byEyeAngleDF = pd.read_csv(str(byEyeAngleDFioPath))

        byEyeAngles = byEyeAngleDF['by eye measurement (0 to 360)'].tolist()

        i = 0
        while i < len(byEyeAngles):
            if byEyeAngles[i] == np.nan:
                np.delete(angleData, i, 0)
                byEyeAngles.pop(i)
            else:
                i += 1

        angleDataShape = angleData.shape

        diff2byeye = np.empty(
            (angleDataShape[2], angleDataShape[1], angleDataShape[0]))
        diff2byeye[:] = np.nan
        for i in range(angleDataShape[0]):
            for j in range(angleDataShape[1]):
                for k in range(angleDataShape[2]):
                    diff2byeye[k][j][i] = dm.angleDifferenceCalc(
                        angleData[i][j][k], byEyeAngles[i])

        squaredDiffs = np.square(diff2byeye)
        summedDiffs = np.sum(squaredDiffs, axis=2)
        varianceTable = summedDiffs / diff2byeye.shape[2]
        sdTable = np.sqrt(varianceTable)

        sdTableMinIndex = list([
            np.where(sdTable == np.nanmin(sdTable))[0][0],
            np.where(sdTable == np.nanmin(sdTable))[1][0]
        ])

        lowSDthresholds = []
        lowSDtestFrames = []

        for x in np.sort(sdTable.ravel())[0:5]:
            loc = np.where(sdTable == x)
            lowSDthresholds.append(loc[0][0])
            lowSDtestFrames.append(loc[1][0])

        inflectionTestBinaryThreshold = thresholdCases[int(
            np.median(lowSDthresholds))]
        inflectionTestDiff = postInflectionDiffCases[int(
            np.median(lowSDtestFrames))]

        return inflectionTestBinaryThreshold, inflectionTestDiff, sdTable, sdTableMinIndex

    inflectionTestBinaryThreshold, inflectionTestDiff, sdTable, sdTableMinIndex = runSDanalysis(
    )

    if CHIME: dm.chime(MAC, 'input time')
    while True:
        print('thresholding options: {}'.format(thresholdCases))
        print('test frame options: {}'.format(postInflectionDiffCases))
        np.set_printoptions(threshold=np.inf)
        print(np.asarray(sdTable))
        print('index of min sd: {}'.format(sdTableMinIndex))
        print('selected sd: {}'.format(
            sdTable[thresholdCases.index(inflectionTestBinaryThreshold)][
                postInflectionDiffCases.index(inflectionTestDiff)]))

        print('Params to change: ')
        print('select \'1\' to change {} which is {}'.format(
            'inflectionTestBinaryThreshold', inflectionTestBinaryThreshold))
        print('select \'2\' to change {} which is {}'.format(
            'inflectionTestDiff', inflectionTestDiff))
        print('select \'3\' to update by eye measurements')
        print('or \'4\' to continue.')

        selectionVar = dm.getSelection([1, 2, 3, 4])
        if selectionVar == '1':
            inflectionTestBinaryThreshold = float(
                dm.getSelection(thresholdCases))
        elif selectionVar == '2':
            inflectionTestDiff = int(dm.getSelection(postInflectionDiffCases))
        elif selectionVar == '3':
            inflectionTestBinaryThreshold, inflectionTestDiff, sdTable, sdTableMinIndex = runSDanalysis(
            )
        else:
            break

    chosenSD = sdTable[thresholdCases.index(inflectionTestBinaryThreshold)][
        postInflectionDiffCases.index(inflectionTestDiff)]

    return inflectionTestDiff, inflectionTestBinaryThreshold, chosenSD
Exemplo n.º 8
0
def selectAverageTroughBinaryArea(fileSubset, thresholdingDir, recordingName, peaksOnBinaryImage, peak2InflectionDiff, peak2TroughDiff):
    maxIntensities = []
    minIntensities = []
    for i, peak in enumerate(peaksOnBinaryImage):
        if peak + peak2InflectionDiff >= 0 and peak + peak2TroughDiff < len(fileSubset):
            troughInfile = fileSubset[peak + peak2TroughDiff]
            relaxedInfile = fileSubset[peak + peak2InflectionDiff]
            troughImg = im.getJellyGrayImageFromFile(troughInfile)
            relaxedImg = im.getJellyGrayImageFromFile(relaxedInfile)

            centroidDiff = im.getGrayscaleImageDiff_absolute(troughImg, relaxedImg)
            binaryCentroidDiff = im.getBinaryJelly(centroidDiff, lower_bound=0.05)
            maskedImg = im.applyMask2Img(binaryCentroidDiff, relaxedImg)
            jellyRegion = im.findJellyRegionWithGray(binaryCentroidDiff, maskedImg)
            maxIntensity = jellyRegion.max_intensity
            minIntensity = jellyRegion.min_intensity
            maxIntensities.append(maxIntensity)
            minIntensities.append(minIntensity)

    indensityDifference = np.mean(maxIntensities) - np.mean(minIntensities)

    lowerThreshold = np.mean(minIntensities) + (0.1 * indensityDifference)

    print('peak2TroughDiff: {}'.format(peak2TroughDiff))

    while True:

        troughAreas = []

        for peak in peaksOnBinaryImage:
            peakInfile = fileSubset[peak]
            troughInfile = fileSubset[peak+peak2TroughDiff]

            peakImg = im.getJellyGrayImageFromFile(peakInfile)
            troughImg = im.getJellyGrayImageFromFile(troughInfile)

            binaryPeakImg = im.getBinaryJelly(peakImg, lowerThreshold)
            binaryTroughImg = im.getBinaryJelly(troughImg, lowerThreshold)

            im.saveJellyPlot(im.juxtaposeImages(np.array([[binaryPeakImg, binaryTroughImg]])),
                             (thresholdingDir / '{}_thresholdVerification_{}.png'.format(recordingName, peak)))

            jellyTroughBinaryArea = im.findBinaryArea(binaryTroughImg)

            troughAreas.append(jellyTroughBinaryArea)

        if CHIME: dm.chime(MAC, 'input time')
        print('average trough area: {}, sd of trough areas: {}'.format(np.mean(troughAreas), np.std(troughAreas)))

        print('Change thresholds: ')
        print('select \'1\' to change {} which is {}'.format('lowerThreshold', lowerThreshold))
        print('select \'2\' to remove a peak from peaksOnBinaryImage')
        print('or \'3\' to continue.')

        selectionVar = dm.getSelection([1, 2, 3])
        if selectionVar == '1':
            lowerThreshold = dm.reassignFloatVariable(lowerThreshold, 'lowerThreshold')
            dm.replaceDir(thresholdingDir)
        elif selectionVar == '2':
            print('peaksOnBinaryImage: {}'.format(peaksOnBinaryImage))
            index2Pop = int(dm.getSelection(list(range(len(peaksOnBinaryImage)))))
            peaksOnBinaryImage.pop(index2Pop)
        else:
            return np.mean(troughAreas)