<file_sep># coding: utf-8

#####################################################################################
# This configuration file sets various parameters for training and evaluating DeepLabCut
#####################################################################################

# myconfig.py:

########################################
# Step 1: Selecting Frames from videos
########################################

Task = 'Adam_Pupils'

# Filename and path to behavioral video:
videopath = '/Users/adamlowet/Documents/Uchida/DistributionalRL/exampledata/pupil/test_animal/test_date/Pupil_Training_LightsON0'

# Put name of video: / or 'all' to extract frames from all videos in folder.
# filename='reachingvideo1.avi'
filename = 'all' 
videotype='.avi'

checkcropping=False #set "True" if you want to check cropping 
cropping = True #set "True" if you want to crop images with values below

# ROI dimensions / bounding box (only used if cropping == True)
# x1,y1 indicates the top left corner and
# x2,y2 is the lower right corner of the cropped region.

x1 = 200
x2 = 450
y1 = 120
y2 = 350

# Portion of the video to sample from in step 1 (In relative terms of video length, i.e. [0,1] is the full video)
start = 0
stop =1

# Number of frames to pick
numframes2pick = 10

# Method to pick frames: uniform or kmeans
selectionalgorithm='kmeans' 

# the algorithm 'uniform' temporally uniformly sampes frames in interval (start,stop). Visual information within video is irrelevant for this method. This code is very fast and sufficient (to extract distinct frames) when behavioral videos naturally covers many states.

# Alternatively consider using: 'kmeans'

# This code downsamples the video. The video is extracted as a numpy array, which is then 
# clustered by kmeans whereby each frames are treated as a vector. Frames from different clusters are then selected for labeling. This 
# procedure makes sure that the frames "look different", i.e. different postures etc. 
# On large videos this code is slow. Consider not extracting the frames from the whole video but rather set start and stop to a period around interesting behavior that you want DeepLabCut to resolve/analyze (i.e. a reach). 

########################################
# Step 2: Converting frames to pandas array 
########################################

bodyparts = ["Up","Left","Down", "Right"]  # Exact sequence of labels as were put by
# annotator in *.csv file (for multibodypartsfile). For single files order is irrelevant
Scorers = ['adam']  # who is labeling?

# Set this true if the data was sequentially labeled and if there is one file per folder (you can set the name of this file below, i.e. multibodypartsfilename)
# Otherwise there should be individual files per bodypart, i.e. in our demo case hand.csv, Finger1.csv etc.
# If true then those files will be generated from Results.txt
multibodypartsfile= True
multibodypartsfilename="Results.csv"

# When importing the images and the labels in the csv/xls files should be in the same order!
# During labeling in Fiji one can thus (for occluded body parts) click in the origin of the image 
#(i.e. top left corner (close to 0,0)), these "false" labels will then be removed. To do so set the following variable:
#set this to 0 if no labels should be removed!

invisibleboundary=20 # If labels are closer to origin than this number they are set to NaN (not a number). Please adjust to your situation. Units in pixel.
 
imagetype=".png" # image type of extracted frames (do not change if you used our step1). 
# If you started from already extracted frames in a different format then change the format here (for step2 to 4).

########################################
# Step 3: Check labels / makes plots
########################################

colormap = 'cool' #set color map, i.e. viridis, cool, hsv
scale = 1  # scale for plotting
msize=10   # size of labels
alphavalue =.6 #transparency of labels

########################################
# Step 4: Generate Training Files 
########################################

date = 'Oct24'
scorer = 'adam'

# Userparameters for training set. Other parameters can be set in pose_cfg.yaml
Shuffles = [1]  # Index for shuffles, i.e. range(5) for 5 shuffles, or [1] for 1. 
TrainingFraction = [0.95]  # Fraction of labeled images used for training (can be a list)

# Which resnet to use, 101 for deeper! 
# then change net_type and init_weights in Generating_a_Training_Set/pose_cfg.yaml 
resnet = 50

#Afterwards train your network!

########################################################################################################################
# For Evaluation your network
########################################################################################################################

#identifier of evaluation network: 
shuffleindex = 0 # indexes above Shuffles. [i.e. if 0 then the 1st shuffle in Shuffles, etc.]
snapshotindex = -1 #"all"
# To evaluate the last snapshot (i.e. the network that was trained longest) : -1 
# To evaluate all models (training stages) set this to: "all"  (as string!)


pcutoff=.1 # likelihood. RMSE will be reported for all pairs and pairs with larger likelihood than pcutoff (see paper). 
# This cutoff will also be used in plots.
plotting=True #If true will plot train & test images including DeepLabCut labels next to human labels. 
# Note that this will be plotted for all snapshots as indicated by snapshotindex
<file_sep>#!/usr/bin/env python

#SBATCH -J AnalysisLoop
#SBATCH -p serial_requeue
#SBATCH -N 1
#SBATCH -n 1
#SBATCH --mem 2000
#SBATCH -t 10 # minutes
#SBATCH -o job-scripts/out/Job.%x.%A_%a.%N.%j.out # STDOUT
#SBATCH -e job-scripts/err/Job.%x.%A_%a.%N.%j.err # STDERR
#SBATCH --mail-type=END,FAIL,TIME_LIMIT # notifications
#SBATCH --mail-user=<EMAIL> # send-to address

"""
Usage: sbatch analyze_all.sh

Written by <NAME>, Oct. 29, 2019
"""

import os, sys
from collections import Counter

subfolder = os.getcwd().split('analysis-tools')[0]
sys.path.append(subfolder)
sys.path.append(os.path.join(subfolder, "config"))
from myconfig_analysis import videofolderroot

def mkdir_p(dir):
    #make a directory (dir) if it doesn't exist
    if not os.path.isdir(dir):
        os.mkdir(dir)
    if not os.path.isdir(os.path.join(dir, 'out')):
    	os.mkdir(os.path.join(dir, 'out'))
    if not os.path.isdir(os.path.join(dir, 'err')):
    	os.mkdir(os.path.join(dir, 'err'))

video_folders = []
base_names = {}
for root, dirs, files in os.walk(videofolderroot):
	for file in files:
		if file.endswith('.avi'):
			path = os.path.dirname(os.path.join(root, file))
			base_name = os.path.splitext(os.path.basename(file))[0]
			# don't add if .mp4 already exists, meaning video has been analyzed already
			if not os.path.isfile(os.path.join(path, base_name + '.mp4')):
				video_folders.append(path)
				if path in base_names: base_names[path].append(base_name)
				else: base_names[path] = [base_name]

#unique_folders = list(Counter(video_folders).keys())
#avi_counts = list(Counter(video_folders).values())

unique_folders = list(set(video_folders))
job_directory = "./job-scripts"

# Make top level directories
mkdir_p(job_directory)

# Run a separate  job for each recording session
for i in range(len(unique_folders)):
	
	folder = unique_folders[i]
	last_folder = os.path.basename(os.path.normpath(folder))

	# if not os.path.isdir(os.path.join(job_directory,'out',last_folder)):
	# 	os.makedirs(os.path.join(job_directory,'out',last_folder))
	# if not os.path.isdir(os.path.join(job_directory,'err',last_folder)):
	# 	os.makedirs(os.path.join(job_directory,'err',last_folder))

	# base_name = base_names[folder][i]
	# base_stem = base_name.split('_')
	# base_stem = base_stem[:-1]
	# base_stem = '_'.join(base_stem)

	job_file = os.path.join(job_directory, last_folder + '.job')

	with open(job_file, 'w') as fh:
		fh.writelines("#!/bin/bash\n")
		fh.writelines("#SBATCH --job-name=%sSession\n" % last_folder)
		fh.writelines("#SBATCH --output=%s.out\n" % os.path.join(job_directory,'out','%x.%A_%a.%N.%j'))
		fh.writelines("#SBATCH --error=%s.err\n" % os.path.join(job_directory,'err','%x.%A_%a.%N.%j'))
		fh.writelines("#SBATCH --time=0-02:00\n")
		fh.writelines("#SBATCH --mem=12000\n") #memory for each task
		fh.writelines("#SBATCH -p fas_gpu\n") # partition (queue)
		fh.writelines("#SBATCH --gres=gpu:1\n")
		fh.writelines("#SBATCH --mail-type=FAIL,TIME_LIMIT,END\n")
		fh.writelines("#SBATCH --mail-user=$<EMAIL>\n")
		fh.writelines("#SBATCH --export=ALL\n")
		fh.writelines("#SBATCH --exclude=shakgpu[01-50],aagk80gpu[09,10,11,39,50,60]\n")

		fh.writelines("cd /n/holylfs/LABS/uchida_lab/globus_alowet/DeepLabCut/analysis-tools/parallel-session\n")

		fh.writelines("module load Anaconda3/5.0.1-fasrc01\n")
		fh.writelines("module load cuda/8.0.61-fasrc01 cudnn/6.0_cuda8.0-fasrc01\n")
		fh.writelines("module load bazel/0.13.0-fasrc01 gcc/4.9.3-fasrc01 hdf5/1.8.12-fasrc08 cmake\n")
		fh.writelines("module load ffmpeg/2.7.2-fasrc01\n")
		fh.writelines("source activate dcut_tf13\n")

		fh.writelines("srun -N 1 python3 -u AnalyzeVideosSession.py %s 0\n" %folder)
		fh.writelines("srun -N 1 python3 -u MakingLabeledVideoSession.py %s 1\n" %folder)

	os.system("sbatch %s" %job_file)

<file_sep>"""
DeepLabCut Toolbox
https://github.com/AlexEMG/DeepLabCut

<NAME>, <EMAIL>
<NAME>, <EMAIL>

Edited by:
<NAME>, <EMAIL>

This script labels the bodyparts in videos as analzyed by "AnalyzeVideos.py". 
This code does not store any frames and substantially faster! 

python3 MakingLabeledVideo_fast.py

Videos are not inteded to be created in the docker container (due to missing ffmpeg bindings)
You can find the directory by: "find / | grep ffmpeg" and then setting it. 
"""

####################################################
# Dependencies
####################################################
import os.path
import sys
subfolder = os.getcwd().split('analysis-tools')[0]
sys.path.append(subfolder)
# add parent directory: (where nnet & config are!)
sys.path.append(os.path.join(subfolder, "pose-tensorflow"))
sys.path.append(os.path.join(subfolder, "config"))
# Dependencies for video:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from tqdm import tqdm

from skimage.draw import circle_perimeter, circle
from VideoProcessor import VideoProcessorSK as vp

from skvideo import setFFmpegPath
setFFmpegPath('/n/helmod/apps/centos7/Core/ffmpeg/2.7.2-fasrc01/bin')

####################################################
# Loading descriptors of model
####################################################

from myconfig_analysis import videofolder, cropping, Task, date, cam_fps, \
    resnet, shuffle, trainingsiterations, pcutoff, deleteindividualframes, x1, x2, y1, y2, videotype, alphavalue, dotsize, colormap
from myconfig_analysis import scorer as humanscorer

# loading meta data / i.e. training & test files
#basefolder = os.path.join('..','pose-tensorflow','models')
#datafolder = os.path.join(basefolder , "UnaugmentedDataSet_" + Task + date)
#Data = pd.read_hdf(os.path.join(datafolder , 'data-' + Task , 'CollectedData_' + humanscorer + '.h5'),'df_with_missing')

# Name for scorer based on passed on parameters from myconfig_analysis. Make sure they refer to the network of interest.
scorer = 'DeepCut' + "_resnet" + str(resnet) + "_" + Task + str(date) + 'shuffle' + str(shuffle) + '_' + str(trainingsiterations)

####################################################
# Auxiliary function
####################################################

def CreateVideo(clip,Dataframe):
        ''' Creating individual frames with labeled body parts and making a video''' 
        scorer=np.unique(Dataframe.columns.get_level_values(0))[0]
        bodyparts2plot = list(np.unique(Dataframe.columns.get_level_values(1)))
        colorclass=plt.cm.ScalarMappable(cmap=colormap)
        C=colorclass.to_rgba(np.linspace(0,1,len(bodyparts2plot)))
        colors=(C[:,:3]*255).astype(np.uint8)
        ny,nx,fps = clip.height(),clip.width(), clip.fps()
        nframes = len(Dataframe.index)
        duration = nframes/fps
        
        print("Duration of video [s]: ", duration, ", recorded with ", fps,"fps!")
        print("Overall # of frames: ", nframes, "with cropped frame dimensions: ",ny,nx)
        
        print("Generating frames")
        for index in tqdm(range(nframes)):
            image = clip.load_frame()
            for bpindex, bp in enumerate(bodyparts2plot):
                if Dataframe[scorer][bp]['likelihood'].values[index] > pcutoff:# and image is not None:
                    xc = int(Dataframe[scorer][bp]['x'].values[index])
                    yc = int(Dataframe[scorer][bp]['y'].values[index])
                    #rr, cc = circle_perimeter(yc,xc,radius)
                    rr, cc = circle(yc,xc,dotsize,shape=(ny,nx))
                    image[rr, cc, :] = colors[bpindex]
        
            frame = image
            clip.save_frame(frame)
        
        clip.close()


##################################################
# Datafolder
##################################################

os.chdir(videofolder)
videos = np.sort([fn for fn in os.listdir(os.curdir) if (videotype in fn) and ("labeled" not in fn)])
print("Starting ", videofolder, videos)

for video in videos:
    vname = video.split('.')[0]
    if os.path.isfile(os.path.join(vname + '_DeepLabCutlabeled.mp4')):
        print("Labeled video already created.")
    else:
        clip =vp(video, fps=cam_fps)
        print("Loading ", video, "and data.")
        dataname = video.split('.')[0] + scorer + '.h5'
        try:
            Dataframe = pd.read_hdf(dataname)
            clip = vp(fname = video,sname = os.path.join(vname + '_DeepLabCutlabeled.mp4'), fps=cam_fps)
            CreateVideo(clip,Dataframe)
        except FileNotFoundError:
            datanames=[fn for fn in os.listdir(os.curdir) if (vname in fn) and (".h5" in fn) and "resnet" in fn]
            if len(datanames)==0:
                print("The video was not analyzed with this scorer:", scorer)
                print("No other scorers were found, please run AnalysisVideos.py first.")
            elif len(datanames)>0:
                print("The video was not analyzed with this scorer:", scorer)
                print("Other scorers were found, however:", datanames)
                print("Creating labeled video for:", datanames[0]," instead.")

                Dataframe = pd.read_hdf(datanames[0])
                clip = vp(fname = video,sname = os.path.join(vname + '_DeepLabCutlabeled.mp4'), fps=cam_fps)
                CreateVideo(clip,Dataframe)
<file_sep>"""
DeepLabCut Toolbox
https://github.com/AlexEMG/DeepLabCut

<NAME>, <EMAIL>
<NAME>, <EMAIL>

A key point for a successful feature detector is to select diverse frames, which are typical for the behavior
you study that should be labeled. 

This helper script selects frames either uniformly sampled from a particular video (or folder) (selectionalgorithm=='uniform'). 
Note: this might not yield diverse frames, if the behavior is sparsely distributed (consider using kmeans), and/or select frames manually etc.

Also make sure to get select data from different (behavioral) sessions and different animals if those vary substantially (to train an invariant feature detector).

Individual images should not be too big (i.e. < 850 x 850 pixel). Although this
can be taken care of later as well, it is advisable to crop the frames, to
remove unnecessary parts of the frame as much as possible.
"""

import imageio
#imageio.plugins.ffmpeg.download()
import matplotlib
matplotlib.use('Agg')
from moviepy.editor import VideoFileClip
from skimage import io
from skimage.util import img_as_ubyte
import numpy as np
import os
import math
import sys

sys.path.append(os.getcwd().split('Generating_a_Training_Set')[0])
from myconfig import Task, videopath, videotype, filename, x1, x2, y1, y2, start, stop, \
    date, cropping, numframes2pick, selectionalgorithm, checkcropping
import auxiliaryfunctions, frameselectiontools

def CheckCropping(videopath,filename,x1,x2,y1,y2,cropping, videotype, time=start):
    ''' Display frame at time "time" for video to check if cropping is fine. 
    Select ROI of interest by adjusting values in myconfig.py
    
    USAGE for cropping:
    clip.crop(x1=None, y1=None, x2=None, y2=None, width=None, height=None, x_center=None, y_center=None)
    
    Returns a new clip in which just a rectangular subregion of the
    original clip is conserved. x1,y1 indicates the top left corner and
    x2,y2 is the lower right corner of the croped region.
    
    All coordinates are in pixels. Float numbers are accepted.
    '''
    videos=auxiliaryfunctions.GetVideoList(filename,videopath,videotype)
    if filename!='all':
        videotype=filename.split('.')[1]

    for vindex,video in enumerate(videos):
        clip = VideoFileClip(os.path.join(videopath,video))
        print("Extracting ", video)
        
        ny, nx = clip.size  # dimensions of frame (width, height)
        if cropping==True:
            # Select ROI of interest by adjusting values in myconfig.py
            clip=clip.crop(y1=y1,y2=y2,x1 = x1,x2=x2)
        
        image = clip.get_frame(time*clip.duration) #frame is accessed by index *1./clip.fps (fps cancels)
        io.imsave("IsCroppingOK"+video.split('.')[0]+".png", image)
        
        if vindex==len(videos)-1:
            print("--> Open the CroppingOK-videofilename-.png file(s) to set the output range! <---")
            print("--> Adjust shiftx, shifty, fx and fy accordingly! <---")
    return image

def SelectFrames(videopath,filename,x1,x2,y1,y2,cropping, videotype,start,stop,Task,selectionalgorithm):
    ''' Selecting frames from videos for labeling.'''
    if start>1.0 or stop>1.0 or start<0 or stop<0 or start>=stop:
            print("Please change start & stop, they should form a normalized interval with 0<= start < stop<=1.")
    else:
        basefolder = 'data-' + Task + '/'
        auxiliaryfunctions.attempttomakefolder(basefolder)
        videos=auxiliaryfunctions.GetVideoList(filename,videopath,videotype)
        for vindex,video in enumerate(videos):
            print("Loading ", video)
            clip = VideoFileClip(os.path.join(videopath, video))
            print("Duration of video [s], ", clip.duration, "fps, ", clip.fps,
                  "Cropped frame dimensions: ", clip.size)

            ####################################################
            # Creating folder with name of experiment and extract random frames
            ####################################################
            folder = video.split('.')[0]
            auxiliaryfunctions.attempttomakefolder(os.path.join(basefolder,folder))
            indexlength = int(np.ceil(np.log10(clip.duration * clip.fps)))
            # Extract the first frame (not cropped!) - useful for data augmentation
            index = 0
            image = img_as_ubyte(clip.get_frame(index * 1. / clip.fps))
            io.imsave(os.path.join(basefolder,folder,"img" + str(index).zfill(indexlength) + ".png"),image)
            
            if cropping==True:
                # Select ROI of interest by adjusting values in myconfig.py
                clip=clip.crop(y1=y1,y2=y2,x1 = x1,x2=x2)
            print("Extracting frames ...")
            if selectionalgorithm=='uniform':
                frames2pick=frameselectiontools.UniformFrames(clip,numframes2pick,start,stop)
            elif selectionalgorithm=='kmeans':
                frames2pick=frameselectiontools.KmeansbasedFrameselection(clip,numframes2pick,start,stop)
            else:
                print("Please implement this method yourself and send us a pull request!")
                frames2pick=[]
            
            indexlength = int(np.ceil(np.log10(clip.duration * clip.fps))) 
            for index in frames2pick:
                try:
                    image = img_as_ubyte(clip.get_frame(index * 1. / clip.fps))
                    io.imsave(os.path.join(basefolder,folder,"img" + str(index).zfill(indexlength) + ".png"),image)
                except FileNotFoundError:
                    print("Frame # ", index, " does not exist.")

if __name__ == "__main__":
    if checkcropping==True:
        #####################################################################
        # First load the image and crop (if necessary)/ set checkcropping = True (in myconfig to do so)
        #####################################################################
        CheckCropping(videopath,filename,x1,x2,y1,y2,cropping, videotype)
    else:
        ####################################################
        # Creating folder with name of experiment and extract random frames
        ####################################################
        SelectFrames(videopath,filename,x1,x2,y1,y2,cropping, videotype,start,stop,Task,selectionalgorithm)<file_sep>"""
DeepLabCut Toolbox
https://github.com/AlexEMG/DeepLabCut

<NAME>, <EMAIL>
<NAME>, <EMAIL>

This script labels the bodyparts in videos as analzyed by "AnalyzeVideos.py". This code is relatively slow as 
it stores all individual frames. Use  MakingLabeledVideo_fast.py instead for faster (and slightly different) version (frames are not stored).

python3 MakingLabeledVideo.py

Note: run python3 AnalyzeVideos.py first.
"""

####################################################
# Dependencies
####################################################
import os.path
import sys
subfolder = os.getcwd().split('analysis-tools')[0]
sys.path.append(subfolder)
# add parent directory: (where nnet & config are!)
sys.path.append(os.path.join(subfolder, "pose-tensorflow"))
sys.path.append(os.path.join(subfolder, "config"))
# Dependencies for video:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import imageio
from skimage.util import img_as_ubyte
from moviepy.editor import VideoFileClip
import subprocess
import pandas as pd
import numpy as np
from tqdm import tqdm
import os
import glob
import auxiliaryfunctions

####################################################
# Loading descriptors of model
####################################################


from myconfig_analysis import videofolder, cropping, Task, date, \
    resnet, shuffle, trainingsiterations, pcutoff, deleteindividualframes, x1, x2, y1, y2, videotype, alphavalue, dotsize, colormap

from myconfig_analysis import scorer as humanscorer

# loading meta data / i.e. training & test files
#basefolder = os.path.join('..','pose-tensorflow','models')
#datafolder = os.path.join(basefolder , "UnaugmentedDataSet_" + Task + date)
#Data = pd.read_hdf(os.path.join(datafolder , 'data-' + Task , 'CollectedData_' + humanscorer + '.h5'),'df_with_missing')

# Name for scorer based on passed on parameters from myconfig_analysis. Make sure they refer to the network of interest.
scorer = 'DeepCut' + "_resnet" + str(resnet) + "_" + Task + str(date) + 'shuffle' + str(shuffle) + '_' + str(trainingsiterations)

####################################################
# Auxiliary function
####################################################

# https://stackoverflow.com/questions/14720331/how-to-generate-random-colors-in-matplotlib
def get_cmap(n, name=colormap):
    '''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
    RGB color; the keyword argument name must be a standard mpl colormap name.'''
    return plt.cm.get_cmap(name, n)

def CreateVideo(clip,Dataframe):
    ''' Creating individual frames with labeled body parts and making a video''' 
    scorer=np.unique(Dataframe.columns.get_level_values(0))[0]
    bodyparts2plot = list(np.unique(Dataframe.columns.get_level_values(1)))
    colors = get_cmap(len(bodyparts2plot))

    ny, nx = clip.size  # dimensions of frame (height, width)
    fps = clip.fps
    nframes = len(Dataframe.index)
    if cropping:
        # one might want to adjust
        clip = clip.crop(y1=y1, y2=y2, x1=x1, x2=x2)
    clip.reader.initialize()
    print("Duration of video [s]: ", clip.duration, ", recorded with ", fps,
          "fps!")
    print("Overall # of frames: ", nframes, "with cropped frame dimensions: ",
          clip.size)
    print("Generating frames")
    for index in tqdm(range(nframes)):
        
        imagename = tmpfolder + "/file%04d.png" % index
        if os.path.isfile(tmpfolder + "/file%04d.png" % index):
            pass
        else:
            plt.axis('off')
            image = img_as_ubyte(clip.reader.read_frame())
            #image = img_as_ubyte(clip.get_frame(index * 1. / clip.fps))

            if np.ndim(image) > 2:
                h, w, nc = np.shape(image)
            else:
                h, w = np.shape(image)

            plt.figure(frameon=False, figsize=(w * 1. / 100, h * 1. / 100))
            plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)
            plt.imshow(image)

            for bpindex, bp in enumerate(bodyparts2plot):
                if Dataframe[scorer][bp]['likelihood'].values[index] > pcutoff:
                    plt.scatter(
                        Dataframe[scorer][bp]['x'].values[index],
                        Dataframe[scorer][bp]['y'].values[index],
                        s=dotsize**2,
                        color=colors(bpindex),
                        alpha=alphavalue)

            plt.xlim(0, w)
            plt.ylim(0, h)
            plt.axis('off')
            plt.subplots_adjust(
                left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)
            plt.gca().invert_yaxis()
            plt.savefig(imagename)

            plt.close("all")

    os.chdir(tmpfolder)

    print("Generating video")
    subprocess.call([
        'ffmpeg', '-framerate',
        str(clip.fps), '-i', 'file%04d.png', '-r', '30', '../'+vname + '_DeepLabCutlabeled.mp4'])
    if deleteindividualframes:
        for file_name in glob.glob("*.png"):
            os.remove(file_name)

    os.chdir("../")

##################################################
# Datafolder
##################################################
# videofolder='../videos/' #where your folder with videos is.

os.chdir(videofolder)
videos = np.sort([fn for fn in os.listdir(os.curdir) if (videotype in fn) and ("labeled" not in fn)])

print("Starting ", videofolder, videos)
for video in videos:
    vname = video.split('.')[0]
    tmpfolder = 'temp' + vname
    auxiliaryfunctions.attempttomakefolder(tmpfolder)
    
    if os.path.isfile(os.path.join(tmpfolder, vname + '_DeepLabCutlabeled.mp4')):
        print("Labeled video already created.")
    else:
        print("Loading ", video, "and data.")
        dataname = video.split('.')[0] + scorer + '.h5'
        try: # to load data for this video + scorer
            Dataframe = pd.read_hdf(dataname)
            clip = VideoFileClip(video)
            CreateVideo(clip,Dataframe)
        except FileNotFoundError:
            datanames=[fn for fn in os.listdir(os.curdir) if (vname in fn) and (".h5" in fn) and "resnet" in fn]
            if len(datanames)==0:
                print("The video was not analyzed with this scorer:", scorer)
                print("No other scorers were found, please run AnalysisVideos.py first.")
            elif len(datanames)>0:
                print("The video was not analyzed with this scorer:", scorer)
                print("Other scorers were found, however:", datanames)
                print("Creating labeled video for:", datanames[0]," instead.")

                Dataframe = pd.read_hdf(datanames[0])
                clip = VideoFileClip(video)
                CreateVideo(clip,Dataframe)<file_sep>"""
Author: <NAME>
<EMAIL>

This is the helper class for video reading and saving in DeepLabCut

"""
import numpy as np
import skvideo.io
import skvideo
skvideo.setFFmpegPath('/n/helmod/apps/centos7/Core/ffmpeg/2.7.2-fasrc01/bin/ffmpeg')

class VideoProcessor(object):
    '''
    Base class for a video processing unit, 
    implementation is required for video loading and saving
    '''
    def __init__(self,fname='',sname='', nframes = -1, fps=30):
        self.fname = fname
        self.sname = sname

        self.nframes = nframes
        
        self.h = 0 
        self.w = 0
        self.sh = 0
        self.sw = 0
        self.FPS = fps
        self.nc = 3
        self.i = 0
        
        try:
            if self.fname != '':
                self.vid = self.get_video()
                self.get_info()
            if self.sname != '':
                self.sh = self.h
                self.sw = self.w
                self.svid = self.create_video()

        except Exception as ex:
            print('Error: %s', ex)
            
    def load_frame(self):
        try:
            frame = self._read_frame()
            self.i += 1
            return frame
        except Exception as ex:
            print('Error: %s', ex)
    
    def height(self):
        return self.h
    
    def width(self):
        return self.w
    
    def fps(self):
        return self.FPS
    
    def counter(self):
        return self.i
    
    def frame_count(self):
        return self.nframes
        
                       
    def get_video(self):
        '''
        implement your own
        '''
        pass
    
    def get_info(self):
        '''
        implement your own
        '''
        pass

    def create_video(self):
        '''
        implement your own
        '''
        pass
    

        
    def _read_frame(self):
        '''
        implement your own
        '''
        pass
    
    def save_frame(self,frame):
        '''
        implement your own
        '''
        pass
    
    def close(self):
        '''
        implement your own
        '''
        pass


class VideoProcessorSK(VideoProcessor):
    '''
    Video Processor using skvideo.io
    requires sk-video in python,
    and ffmpeg installed in the operating system
    '''
    def __init__(self, *args, **kwargs):
        super(VideoProcessorSK, self).__init__(*args, **kwargs)
    
    def get_video(self):
         return skvideo.io.FFmpegReader(self.fname)
        
    def get_info(self):
        infos = skvideo.io.ffprobe(self.fname)['video']
        self.h = int(infos['@height'])
        self.w = int(infos['@width'])
        self.FPS = eval(infos['@avg_frame_rate'])
        vshape = self.vid.getShape()
        all_frames = vshape[0]
        self.nc = vshape[3]

        if self.nframes == -1 or self.nframes>all_frames:
            self.nframes = all_frames
            
    def create_video(self):
        return skvideo.io.FFmpegWriter(self.sname, outputdict={'-r':str(self.FPS)})

    def _read_frame(self):
        return self.vid._readFrame()
    
    def save_frame(self,frame):
        self.svid.writeFrame(frame)
    
    def close(self):
        self.svid.close()
        self.vid.close()<file_sep>"""
DeepLabCut Toolbox
https://github.com/AlexEMG/DeepLabCut

<NAME>, <EMAIL>
<NAME>, <EMAIL>

This script analyzes videos based on a trained network (as specified in myconfig_analysis.py)

You need tensorflow for evaluation. Run by:

CUDA_VISIBLE_DEVICES=0 python3 AnalyzeVideos.py

"""

####################################################
# Dependencies
####################################################

import os.path
import sys
subfolder = os.getcwd().split('analysis-tools')[0]
sys.path.append(subfolder)
# add parent directory: (where nnet & config are!)
sys.path.append(os.path.join(subfolder, "pose-tensorflow"))
sys.path.append(os.path.join(subfolder, "config"))

from myconfig_analysis import videofolder, cropping, Task, date, \
    trainingsFraction, resnet, snapshotindex, shuffle,x1, x2, y1, y2, videotype, storedata_as_csv

# Deep-cut dependencies
from config import load_config
from nnet import predict
from dataset.pose_dataset import data_to_input

# Dependencies for video:
import pickle
# import matplotlib.pyplot as plt
import imageio
from skimage.util import img_as_ubyte
from moviepy.editor import VideoFileClip
import skimage
import skimage.color
import time
import pandas as pd
import numpy as np
import os
from tqdm import tqdm


def getpose(image, cfg, outputs, outall=False):
    ''' Adapted from DeeperCut, see pose-tensorflow folder'''
    image_batch = data_to_input(skimage.color.gray2rgb(image))
    outputs_np = sess.run(outputs, feed_dict={inputs: image_batch})
    scmap, locref = predict.extract_cnn_output(outputs_np, cfg)
    pose = predict.argmax_pose_predict(scmap, locref, cfg.stride)
    if outall:
        return scmap, locref, pose
    else:
        return pose


####################################################
# Loading data, and defining model folder
####################################################

basefolder = os.path.join('..','pose-tensorflow','models')
modelfolder = os.path.join(basefolder, Task + str(date) + '-trainset' +
               str(int(trainingsFraction * 100)) + 'shuffle' + str(shuffle))

cfg = load_config(os.path.join(modelfolder , 'test' ,"pose_cfg.yaml"))

##################################################
# Load and setup CNN part detector
##################################################

# Check which snapshots are available and sort them by # iterations
Snapshots = np.array([
    fn.split('.')[0]
    for fn in os.listdir(os.path.join(modelfolder , 'train'))
    if "index" in fn
])
increasing_indices = np.argsort([int(m.split('-')[1]) for m in Snapshots])
Snapshots = Snapshots[increasing_indices]

print(modelfolder)
print(Snapshots)

##################################################
# Compute predictions over images
##################################################

# Check if data already was generated:
cfg['init_weights'] = os.path.join(modelfolder , 'train', Snapshots[snapshotindex])

# Name for scorer:
trainingsiterations = (cfg['init_weights'].split('/')[-1]).split('-')[-1]

# Name for scorer:
scorer = 'DeepCut' + "_resnet" + str(resnet) + "_" + Task + str(
    date) + 'shuffle' + str(shuffle) + '_' + str(trainingsiterations)


cfg['init_weights'] = os.path.join(modelfolder , 'train', Snapshots[snapshotindex])
sess, inputs, outputs = predict.setup_pose_prediction(cfg)
pdindex = pd.MultiIndex.from_product(
    [[scorer], cfg['all_joints_names'], ['x', 'y', 'likelihood']],
    names=['scorer', 'bodyparts', 'coords'])

##################################################
# Datafolder
##################################################

# videofolder='../videos/' #where your folder with videos is.
frame_buffer = 10

os.chdir(videofolder)
videos = np.sort([fn for fn in os.listdir(os.curdir) if (videotype in fn)])
print("Starting ", videofolder, videos)
for video in videos:
    dataname = video.split('.')[0] + scorer + '.h5'
    try:
        # Attempt to load data...
        pd.read_hdf(dataname)
        print("Video already analyzed!", dataname)
    except FileNotFoundError:
        print("Loading ", video)
        clip = VideoFileClip(video)
        ny, nx = clip.size  # dimensions of frame (height, width)
        fps = clip.fps
        #nframes = np.sum(1 for j in clip.iter_frames()) #this is slow (but accurate)
        nframes_approx = int(np.ceil(clip.duration * clip.fps) + frame_buffer)
        # this will overestimage number of frames (see https://github.com/AlexEMG/DeepLabCut/issues/9) This is especially a problem
        # for high frame rates and long durations due to rounding errors (as <NAME> found). Later we crop the result (line 187)
        
        if cropping:
            clip = clip.crop(
                y1=y1, y2=y2, x1=x1, x2=x2)  # one might want to adjust

        print("Duration of video [s]: ", clip.duration, ", recorded with ", fps,
              "fps!")
        print("Overall # of frames: ", nframes_approx,"with cropped frame dimensions: ", clip.size)

        start = time.time()
        PredicteData = np.zeros((nframes_approx, 3 * len(cfg['all_joints_names'])))
        clip.reader.initialize()
        print("Starting to extract posture")
        for index in tqdm(range(nframes_approx)):
            #image = img_as_ubyte(clip.get_frame(index * 1. / fps))
            image = img_as_ubyte(clip.reader.read_frame())
            # Thanks to <NAME> for the  following snipplet:
            # if close to end of video, start checking whether two adjacent frames are identical
            # this should only happen when moviepy has reached the final frame
            # if two adjacent frames are identical, terminate the loop
            if index==int(nframes_approx-frame_buffer*2):
                last_image = image
            elif index>int(nframes_approx-frame_buffer*2):
                if (image==last_image).all():
                    nframes = index
                    print("Detected frames: ", nframes)
                    break
                else:
                    last_image = image
            pose = getpose(image, cfg, outputs)
            PredicteData[index, :] = pose.flatten()  # NOTE: thereby cfg['all_joints_names'] should be same order as bodyparts!

        stop = time.time()

        dictionary = {
            "start": start,
            "stop": stop,
            "run_duration": stop - start,
            "Scorer": scorer,
            "config file": cfg,
            "fps": fps,
            "frame_dimensions": (ny, nx),
            "nframes": nframes
        }
        metadata = {'data': dictionary}

        print("Saving results...")
        DataMachine = pd.DataFrame(PredicteData[:nframes,:], columns=pdindex, index=range(nframes)) #slice pose data to have same # as # of frames.
        DataMachine.to_hdf(dataname, 'df_with_missing', format='table', mode='w')
        
        if storedata_as_csv:
            DataMachine.to_csv(video.split('.')[0] + scorer+'.csv')
        
        with open(dataname.split('.')[0] + 'includingmetadata.pickle',
                  'wb') as f:
            pickle.dump(metadata, f, pickle.HIGHEST_PROTOCOL)
<file_sep>#!/bin/bash

#SBATCH -J AnalyzePupil
#SBATCH -N 1 # 1 node
#SBATCH -p fas_gpu # partition (queue)
#SBATCH --gres=gpu:1
#SBATCH --mem 16000 # memory pool for all cores
#SBATCH -t 0-24:00 # time (D-HH:MM)
#SBATCH --export=ALL
#SBATCH -o Jobs/Job.%x.%N.%j.out # STDOUT
#SBATCH -e Jobs/Job.%x.%N.%j.err # STDERR
#SBATCH --exclude=shakgpu[01-50],aagk80gpu[09,10,11,39,50,60]
#!SBATCH --test-only

#SBATCH --mail-type=END,FAIL,TIME_LIMIT # notifications
#SBATCH --mail-user=<EMAIL> # send-to address

module load Anaconda3/5.0.1-fasrc01
module load cuda/8.0.61-fasrc01 cudnn/6.0_cuda8.0-fasrc01
module load bazel/0.13.0-fasrc01 gcc/4.9.3-fasrc01 hdf5/1.8.12-fasrc08 cmake
source activate dcut_tf13
module load ffmpeg/2.7.2-fasrc01

srun -N 1 python3 AnalyzeVideos.py 0
srun -N 1 python3 MakingLabeledVideo.py 1<file_sep>"""
DeepLabCut Toolbox
https://github.com/AlexEMG/DeepLabCut
<NAME>, <EMAIL>
<NAME>, <EMAIL>

This script evaluates a trained model at a particular state on the data set (images)
and stores the results in a pandas dataframe.

You need tensorflow for evaluation. Run by:

CUDA_VISIBLE_DEVICES=0 python3 Step1_EvaluateModelonDataset.py

"""

####################################################
# Dependencies
####################################################

import sys, os
import subprocess

subfolder = os.getcwd().split('evaluation-tools')[0]
sys.path.append(subfolder)

pardir = os.path.abspath(os.path.join(subfolder, os.pardir))

# add parent directory: (where nnet & config are!)
#sys.path.append(os.path.join(pardir, "pose-tensorflow"))
#sys.path.append(os.path.join(pardir, "config"))
sys.path.append(os.path.join(subfolder, "pose-tensorflow"))
sys.path.append(os.path.join(subfolder, "config"))

from myconfig import Task, date, Shuffles, TrainingFraction, snapshotindex
import numpy as np
import pandas as pd
# Deep-cut dependencies
from config import load_config

####################################################
# Loading data and evaluating network on data
####################################################

basefolder = os.path.join('..','pose-tensorflow','models')
folder = os.path.join('UnaugmentedDataSet_' + Task + date)

for shuffleIndex, shuffle in enumerate(Shuffles):
    for trainFractionIndex, trainFraction in enumerate(TrainingFraction):
        ################################################################################
        # Check which snapshots exist for given network (with training data split).
        ################################################################################
        
        experimentname = Task + date + '-trainset' + str(
            int(trainFraction * 100)) + 'shuffle' + str(shuffle)
        modelfolder = os.path.join(basefolder, experimentname)
        cfg = load_config(os.path.join(basefolder , experimentname , 'test' ,"pose_cfg.yaml"))
        # Check which snap shots are available and sort them by # iterations
        Snapshots = np.array([
            fn.split('.')[0]
            for fn in os.listdir(os.path.join(basefolder, experimentname , 'train'))
            if "index" in fn])

        increasing_indices = np.argsort([int(m.split('-')[1]) for m in Snapshots])
        Snapshots = Snapshots[increasing_indices]

        if snapshotindex == -1:
            snapindices = [-1]
        elif snapshotindex == "all":
            snapindices = range(len(Snapshots))
        elif snapshotindex<len(Snapshots):
            snapindices=[snapshotindex]
        else:
            print("Invalid choice, only -1 (last), any integer up to last, or all (as string)!")

        for snapIndex in snapindices:
            cfg['init_weights'] = os.path.join(modelfolder,'train',Snapshots[snapIndex])
            trainingsiterations = (cfg['init_weights'].split('/')[-1]).split('-')[-1]
            scorer = 'DeepCut' + "_" + str(cfg["net_type"]) + "_" + str(
                int(trainFraction *
                    100)) + 'shuffle' + str(shuffle) + '_' + str(trainingsiterations) + "forTask_" + Task

            print("Running ", scorer, " with # of trainingiterations:", trainingsiterations)
            try:
                Data = pd.read_hdf(os.path.join("Results",scorer + '.h5'),'df_with_missing')
                print("This net has already been evaluated!")
            except FileNotFoundError:
                    # if not analyzed, then call auxiliary script to analyze the network:
                    try: 
                        subprocess.call(['python3','EvaluateNetwork.py',str(snapIndex),str(shuffleIndex),str(trainFractionIndex)])
                    except FileNotFoundError: #in case you call python3 with the command: python.
                        subprocess.call(['python','EvaluateNetwork.py',str(snapIndex),str(shuffleIndex),str(trainFractionIndex)])<file_sep># DeepLabCluster
Quick startup guide to using the FAS cluster to train, evaluate, and analyze video with [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Some modifications have been made to accommodate parallelization and alternative directory structures at the analysis phase.

If you are unfamiliar with cluster computing, a good place to start is [here](https://docs.google.com/document/d/1HxHSsm9UJd7QF6eIsLBPAaDiSg4_w653RKRPY_2-6TI/edit?usp=sharing) and [here](https://www.rc.fas.harvard.edu/resources/quickstart-guide/).

# Training a new neural network
## I. Label Frames Locally
([Credit to Korleki](https://github.com/alowet/Novelty_analysis_KA/blob/master/Docs/Training_a_new_network.md))

This is the only part of the workflow that is done on your local computer. Make sure you have Fiji installed, as well as the `Generating_a_Training_Set` directory cloned from the `local` directory of this repo.

##### 0. Configuration of your project:

Edit `myconfig.py` in the `Generating_a_Training_Set` folder.

##### 1. Selecting data to label:
```
cd Generating_a_Training_Set
python3 Step1_SelectRandomFrames_fromVideos.py
```
##### 2. Label the frames:

 - open ImageJ or Fiji
 - File > Import > Image Sequence
 ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.38.43.png)
 - within pop-up window navigate to folder with images to be labeled (Generating_a_Training_Set -> data-YOUR_NETWORK)
 ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.41.15.png)
 - click first image, then click open
 - you will see window pop up named "Sequence Options"
 
   ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.41.37.png)
 - Make sure 2 boxes are checked: "Sort names numerically" and "Use virtual stack"
 - window will pop up with all your images in stack (scroll bar at bottom)
 - in tool bar (with File, Edit, etc), click Multi-point button (to right of angle button and to left of wand button)
     - you may see this botton as "point tool" (single star). if this happens, right click and change to be multi-point
  ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.42.48.png)
  ![alt_text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.43.04.png)
 - click on body features in EXACT order for every image (order specified in myconfig.py - Step 2, bodyparts variable)
 
   ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.46.30.png)
 
   (if a point can't be determined, click in the top left corner of the image, so that X and Y positions are less than 50 pixels)
   ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.48.13.png)
 - once you get through all frames, go to Analyze -> Measure
 ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.48.36.png)
 - window will pop up: "Results"
     - the points you labeled will appear in rows, with each column representing a different feature of that point
     - make sure that the number of rows corresponds to N x BP where N = number of frames and BP = number of body parts you label in each frame
 ![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.49.40.png)
 - save Results window as "Results.csv" in same folder as the images you're labeling
![alt text](https://github.com/ckakiti/Novelty_analysis_KA/blob/master/Docs/Labeling_images/Screen%20Shot%202019-10-16%20at%2012.50.13.png)

##### 3. Formatting the data I:
```
python3 Step2_ConvertingLabels2DataFrame.py
```
##### 4. Checking the formatted data:
```
python3 Step3_CheckLabels.py
```
##### 5. Formatting the data II:
```
python3 Step4_GenerateTrainingFileFromLabelledData.py
```

## II. Configuring the Anaconda environment on the cluster

##### 1. Copy all folders in the `remote` directory of this repo to your directory on the cluster
This directory is probably called something like `/n/holystore01/LABS/uchida_users/Users/$YOUR_RC_ID`. Since your folders are currently local, you'll have to do this with either `scp` or a client like FileZilla, e.g.
```
scp -r remote <EMAIL>:/n/holystore01/LABS/uchida_users/Users/$YOUR_RC_ID
```
You'll have to make sure to overwrite the default config.py file in the `configs` folder with your own `config.py`, which is currently only local!

##### 2. Log in to the cluster and start an interactive session.
In this example, I request two hours and 4 GB of RAM on the `test` partition.
```
srun --pty -p test -t 2:00:00 --mem 4G /bin/bash
```
For help on how to use the cluster, see this page: https://www.rc.fas.harvard.edu/resources/quickstart-guide/.

##### 3. Load the Anaconda environment from a .yml file.
First, `cd` to whereever you uploaded the contents of the `remote` directory. You may want to rename it to DeepLabCut, e.g.
```
cd /n/holystore01/LABS/uchida_users/Users/$YOUR_RC_ID
mv remote DeepLabCut
cd DeepLabCut
```
This folder should contain `TF1_3GPUEnv_DeeperCut.yml`. Then,
```
module load Anaconda3/5.0.1-fasrc01
module load cuda/8.0.61-fasrc01 cudnn/6.0_cuda8.0-fasrc01
conda env create -f TF1_3GPUEnv_DeeperCut.yml
```
(Thanks to <NAME> for this step.)

## III. Training  the deep neural network

##### 1. Get the pretrained networks.

```
cd pose-tensorflow/models/pretrained
curl http://download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz | tar xvz
curl http://download.tensorflow.org/models/resnet_v1_101_2016_08_28.tar.gz | tar xvz
```

##### 2. Copy the two folders generated from the `Formatting the data II` step to `/pose-tensorflow/models/`.
Since your folders are currently local, you'll have to do this with either `scp` or a client like FileZilla. For example, assuming you extracted everything to a directory titled `DeepLabCut`, then from a *local* command line, you'd run:
```
scp -r YOURexperimentNameTheDate-trainset95shuffle1 $<EMAIL>:/n/holystore01/LABS/uchida_users/Users/$YOUR_RC_ID/DeepLabCut/pose-tensorflow/models/
scp -r UnaugmentedDataSet_YOURexperimentNameTheDate $<EMAIL>:/n/holystore01/LABS/uchida_users/Users/$YOUR_RC_ID/DeepLabCut/pose-tensorflow/models/
```

##### 3. Start training
Make sure to edit the path in `train_requeueDC.sh` first!
```
cd pose-tensorflow
sbatch train_requeueDC.sh
```
If this is working properly, it will take ~10 hours to run.

## IV. Evaluate your network
```
cd ../evaluation-tools
sbatch evaluateDC.sh
```
Evaluation metrics will be printed to STDOUT, and images will be saved in the `evaluation-tools` directory in a new folder called `LabeledImages_...`.

## V. Analyzing videos

##### 0. Configuration of your project

Edit: `myconfig_analysis.py` in the `configs` folder within `remote`. If you do this locally (recommended), don't forget to re-upload to the cluster!

##### 1. Analyzing/making labeled videos:
```
cd ../analysis-tools
sbatch analyzeDC.sh
```
This step can be easily parallelized, making it ideal to be run on the cluster! For example, let's say you wanted to run each recording session as its own job. This is more efficient when there are many short trials, which don't deserve their own job or job array because of load on the Slurm scheduler. Use:
```
cd ../analysis-tools/parallel-session
sbatch analyze_all.sh
```
If you had relatively few sessions but many trials, each named something like `path-to-file/trial_$trial-num`, and each trial was relatively long, it would be more efficient to submit each trial as a task within a job array. For example, try:
```
cd ../analysis-tools/parallel-trial
sbatch analyze_all_array.sh
```
However, note that these parallelization methods are all directory structure and naming-convention dependent. The code is provided to give you an idea of how to do this, but it should not be expected to work out of the box.
<file_sep>#!/bin/bash
#SBATCH --job-name=Pupil_Training_LightsON0
#SBATCH --output=./job-scripts/out/%x.%A_%a.%N.%j.out
#SBATCH --error=./job-scripts/err/%x.%A_%a.%N.%j.err
#SBATCH --time=0-02:00
#SBATCH --mem=12000
#SBATCH -p fas_gpu
#SBATCH --gres=gpu:1
#SBATCH --mail-type=FAIL,TIME_LIMIT,END
#SBATCH --mail-user=$<EMAIL>
#SBATCH --export=ALL
#SBATCH --exclude=shakgpu[01-50],aagk80gpu[09,10,11,39,50,60]
cd /n/holylfs/LABS/uchida_lab/globus_alowet/DeepLabCut/analysis-tools/parallel-session
module load Anaconda3/5.0.1-fasrc01
module load cuda/8.0.61-fasrc01 cudnn/6.0_cuda8.0-fasrc01
module load bazel/0.13.0-fasrc01 gcc/4.9.3-fasrc01 hdf5/1.8.12-fasrc08 cmake
module load ffmpeg/2.7.2-fasrc01
source activate dcut_tf13
srun -N 1 python3 -u AnalyzeVideosSession.py /n/holylfs/TRANSFER/alowet/DeepLabCut/videos/Pupil_Training_LightsON0 0
srun -N 1 python3 -u MakingLabeledVideoSession.py /n/holylfs/TRANSFER/alowet/DeepLabCut/videos/Pupil_Training_LightsON0 1
<file_sep>#!/bin/bash
#SBATCH --job-name=Pupil_Training_LightsON0Trial
#SBATCH --output=/n/holylfs/TRANSFER/alowet/DeepLabCut/analysis-tools/parallel-trial/job-scripts/out/Pupil_Training_LightsON0/Pupil_Training_LightsON0.%x.%A_%a.%N.%j.out
#SBATCH --error=/n/holylfs/TRANSFER/alowet/DeepLabCut/analysis-tools/parallel-trial/job-scripts/err/Pupil_Training_LightsON0/Pupil_Training_LightsON0.%x.%A_%a.%N.%j.err
#SBATCH --time=0-00:20
#SBATCH --mem=2000
#SBATCH -N 1
#SBATCH -p fas_gpu
#SBATCH --gres=gpu:1
#SBATCH --mail-type=FAIL,TIME_LIMIT,END
#SBATCH --mail-user=$<EMAIL>
#SBATCH --export=ALL
#SBATCH --exclude=shakgpu[01-50],aagk80gpu[09,10,11,39,50,60]
module load Anaconda3/5.0.1-fasrc01
module load cuda/8.0.61-fasrc01 cudnn/6.0_cuda8.0-fasrc01
module load bazel/0.13.0-fasrc01 gcc/4.9.3-fasrc01 hdf5/1.8.12-fasrc08 cmake
module load ffmpeg/2.7.2-fasrc01
source activate dcut_tf13
python3 -u AnalyzeVideosTrial.py /n/holylfs/TRANSFER/alowet/DeepLabCut/videos/Pupil_Training_LightsON0/Pupil_Training_LightsON0_${SLURM_ARRAY_TASK_ID}.avi
python3 -u MakingLabeledVideoTrial.py /n/holylfs/TRANSFER/alowet/DeepLabCut/videos/Pupil_Training_LightsON0/Pupil_Training_LightsON0_${SLURM_ARRAY_TASK_ID}.avi
