/// <summary> /// Creates a new file that will be used to store an M-Maze behavior session /// </summary> /// <param name="rat_name">The rat name that is being run in the M-Maze</param> public void CreateFile(string rat_name) { //If no rat name is defined, we will define a default name here if (string.IsNullOrEmpty(rat_name)) { rat_name = "_UNDEFINED_ANIMAL_NAME_"; } //Figure out the path to the saved file var path = MMazeConfiguration.GetInstance().SavePath; var rat_path = rat_name + "/"; var fully_qualified_path = path + rat_path; //Create the path if it does not already exist Directory.CreateDirectory(fully_qualified_path); //Create a file name for this new session var file_time = DateTime.Now.ToFileTime(); string file_name = rat_name + "-" + file_time.ToString(); string file_name_with_extension = file_name + ".PTSD"; //Combine the path and file name to get a full path string fully_qualified_path_and_file = path + rat_path + file_name_with_extension; //Create the new handle to the new file _writer = new StreamWriter(fully_qualified_path_and_file); }
/// <summary> /// Creates a new file that will be used to store an M-Maze behavior session /// </summary> /// <param name="rat_name">The rat name that is being run in the M-Maze</param> public void CreateFile(string rat_name, int width, int height) { lock (_writer_object_lock) { //If no rat name is defined, we will define a default name here if (string.IsNullOrEmpty(rat_name)) { rat_name = "_UNDEFINED_ANIMAL_NAME_"; } //Figure out the path to the saved file var path = MMazeConfiguration.GetInstance().SavePath; var rat_path = rat_name + "/videos/"; var fully_qualified_path = path + rat_path; //Create the path if it does not already exist Directory.CreateDirectory(fully_qualified_path); //Create a file name for this new session var file_time = DateTime.Now.ToFileTime(); string file_name = rat_name + "-" + file_time.ToString(); string file_name_with_extension = file_name + ".avi"; //Combine the path and file name to get a full path string fully_qualified_path_and_file = path + rat_path + file_name_with_extension; //Create the new handle to the new file _writer = new Accord.Video.FFMPEG.VideoFileWriter(); _writer.Open(fully_qualified_path_and_file, width, height); //Keep track of when the last frame was written to this video //Initialize this to the current time for the new video being written. _last_call = DateTime.Now; } }
/// <summary> /// Constructor /// </summary> private MMazeBehaviorSession() { //Set the list of available stages. //Stages should already be loaded in at this point in the program. AvailableStages = MMazeConfiguration.GetInstance().LoadedStages; if (AvailableStages.Count > 0) { CurrentStage = AvailableStages[0]; } }
public MainWindow() { InitializeComponent(); //Load in the configuration file and the list of stages MMazeConfiguration.GetInstance().LoadConfigurationFile(); MMazeConfiguration.GetInstance().LoadStages(); //Look for the camera in the list of available cameras Accord.Video.DirectShow.FilterInfoCollection j = new Accord.Video.DirectShow.FilterInfoCollection( Accord.Video.DirectShow.FilterCategory.VideoInputDevice); List <Accord.Video.DirectShow.FilterInfo> my_list = j.Cast <Accord.Video.DirectShow.FilterInfo>().ToList(); Accord.Video.DirectShow.FilterInfo my_camera = my_list.Where(x => x.Name.Equals("HD USB Camera")).FirstOrDefault(); //Accord.Video.DirectShow.FilterInfo my_camera = my_list.Where(x => x.Name.Contains("Logitech")).FirstOrDefault(); if (my_camera != null) { //Set up the camera as the capture devices var camera = new Accord.Video.DirectShow.VideoCaptureDevice(my_camera.MonikerString); camera.NewFrame += Camera_NewFrame; //Set camera properties camera.SetCameraProperty(Accord.Video.DirectShow.CameraControlProperty.Exposure, -6, Accord.Video.DirectShow.CameraControlFlags.Manual); //Select the proper video mode for (int i = 0; i < camera.VideoCapabilities.Length; i++) { var selected_video_capabilities = camera.VideoCapabilities[i]; if (selected_video_capabilities.FrameSize.Width == _camera_frame_width && selected_video_capabilities.FrameSize.Height == _camera_frame_height) { camera.VideoResolution = selected_video_capabilities; } } CameraVideoSourcePlayer.VideoSource = camera; } else { //Make sure the video source is null, indicating we do not have a camera connected CameraVideoSourcePlayer.VideoSource = null; } //Set the data context for this window //DataContext = new MMazeBehaviorViewModel(CameraVideoSourcePlayer); DataContext = MMazeBehaviorViewModel.GetInstance(); MMazeBehaviorViewModel.GetInstance().SetupVideoSource(CameraVideoSourcePlayer); //Start the camera MMazeBehaviorViewModel vm = DataContext as MMazeBehaviorViewModel; if (vm != null) { vm.StartCamera(); } }
private void PlaySound() { //Reset the flag to play a sound _playSoundFlag = false; lock (sound_list_lock) { SoundList_TimeSinceSessionStart.Add(Convert.ToInt32(timer.Elapsed.TotalSeconds)); } //Play the sound if (CurrentStage.SoundFiles.Count > 0) { //Get the sound file name var sound_file_name = CurrentStage.SoundFiles[0].Item1; var sound_file_path = MMazeConfiguration.GetInstance().SoundPath_Base; var fully_qualified_path = sound_file_path + sound_file_name; //Write an event to the file indicating we are playing a sound at this time MMazeEvent sound_event = new MMazeEvent(DateTime.Now, MMazeEventNames.SoundCue); _session_file_writer.WriteEvent(sound_event, sound_file_name); FileInfo finfo = new FileInfo(fully_qualified_path); if (finfo.Exists) { //Set the variable in the model indicating that the sound is playing IsSoundPlaying = true; //Load the sound into memory //SoundPlayer k = new SoundPlayer(finfo.FullName); //Play the sound (asynchronously) //k.Play(); //Play the sound PlaySoundAsync(finfo.FullName); } } //Restart timer 1 StartTimer1(); }
private void _background_thread_DoWork(object sender, DoWorkEventArgs e) { //If a stage has not been defined, return immediately. We cannot proceed. if (CurrentStage == null) { return; } //Get an instance of the microcontroller that is connected to this computer var microcontroller = Microcontroller.GetInstance(); microcontroller.ConnectToMicrocontroller(); //Initialize variables for this behavior session LeftFeedCount = 0; RightFeedCount = 0; TrialState = MMazeTrialState.NoTrialStarted; IsSoundPlaying = false; //Open a file for this session _session_file_writer = new MMazeFileWriter(); _session_file_writer.CreateFile(RatName); _session_file_writer.WriteFileHeader( RatName, DateTime.Now.ToFileTime(), CurrentStage.StageName, MMazeConfiguration.GetInstance().BoothName ); //Make hard copies of the timer lists for the current stage so we can use them this session _this_session_timer_map = CurrentStage.StageRefractoryPeriods.ToList(); _this_session_max_timer_map = CurrentStage.StageMaxSoundDelays.ToList(); //Start a timer for the session. timer.Restart(); //Start timer 1 - the refractory period timer StartTimer1(); //Set the initial value of the "most recent feed" to be the current time _most_recent_feed = DateTime.Now; //Initialize the "feed lists" FeedList_TimeSincePreviousFeed = new List <int>(); FeedList_TimeSinceSessionStart = new List <int>(); lock (sound_list_lock) { SoundList_TimeSinceSessionStart = new List <int>(); } //Loop until the session is ended while (!_background_thread.CancellationPending) { //Get the total seconds elapsed so far during this session SecondsElapsed = Convert.ToInt32(timer.Elapsed.TotalSeconds); //Read in the most recent event from the microcontroller var latest_event = microcontroller.ReadStream(); if (latest_event != null && latest_event.EventType != MMazeEventNames.Undefined) { //Write the latest event to the file _session_file_writer.WriteEvent(latest_event); //If it was a feeder event, update the feed lists we are maintaining (which will also be used to update //the plot) if (latest_event.EventType == MMazeEventNames.LeftFeederTriggered || latest_event.EventType == MMazeEventNames.RightFeederTriggered) { var time_since_last_feed = DateTime.Now - _most_recent_feed; _most_recent_feed = DateTime.Now; switch (latest_event.EventType) { case MMazeEventNames.LeftFeederTriggered: LeftFeedCount++; break; case MMazeEventNames.RightFeederTriggered: RightFeedCount++; break; } FeedList_TimeSincePreviousFeed.Add(Convert.ToInt32(time_since_last_feed.TotalSeconds)); FeedList_TimeSinceSessionStart.Add(Convert.ToInt32(timer.Elapsed.TotalSeconds)); _background_properties_to_update.Add("FeedList"); } //Set the user-facing nosepoke and prox-sensor state variables based upon the most recent event //that we have received from the microcontroller switch (latest_event.EventType) { case MMazeEventNames.LeftNosepokeEnter: LeftNosepokeState = true; break; case MMazeEventNames.LeftNosepokeLeave: LeftNosepokeState = false; break; case MMazeEventNames.RightNosepokeEnter: RightNosepokeState = true; break; case MMazeEventNames.RightNosepokeLeave: RightNosepokeState = false; break; case MMazeEventNames.LeftProxEnter: LeftProxState = true; break; case MMazeEventNames.LeftProxLeave: LeftProxState = false; break; case MMazeEventNames.RightProxEnter: RightProxState = true; break; case MMazeEventNames.RightProxLeave: RightProxState = false; break; } //Handle the trial state based upon the most recent event we received from the microcontroller switch (TrialState) { case MMazeTrialState.NoTrialStarted: //Set the trial state based upon the nosepoke that has been exited if (latest_event.EventType == MMazeEventNames.LeftNosepokeLeave) { TrialState = MMazeTrialState.LeftToRight; } else if (latest_event.EventType == MMazeEventNames.RightNosepokeLeave) { TrialState = MMazeTrialState.RightToLeft; } break; case MMazeTrialState.LeftToRight: //This is a "left to right" trial, handle a beam break in the left prox area if (latest_event.EventType == MMazeEventNames.LeftProxEnter) { TrialState = MMazeTrialState.LeftToRight_EnterLeftProx; if (CurrentStage.StageCueType == MMazeStageCueType.ProximitySensor) { HandleBeamBreak(); } } break; case MMazeTrialState.RightToLeft: //This is a "right to left" trial, handle a beam break in the right prox area if (latest_event.EventType == MMazeEventNames.RightProxEnter) { TrialState = MMazeTrialState.RightToLeft_EnterRightProx; if (CurrentStage.StageCueType == MMazeStageCueType.ProximitySensor) { HandleBeamBreak(); } } break; case MMazeTrialState.LeftToRight_EnterLeftProx: //This is the end of a "left to right" trial, reset the trial state if (latest_event.EventType == MMazeEventNames.RightNosepokeEnter) { TrialState = MMazeTrialState.NoTrialStarted; if (CurrentStage.StageCueType == MMazeStageCueType.Nosepoke) { HandleBeamBreak(); } } break; case MMazeTrialState.RightToLeft_EnterRightProx: //This is the end of a "right to left" trial, reset the trial state if (latest_event.EventType == MMazeEventNames.LeftNosepokeEnter) { TrialState = MMazeTrialState.NoTrialStarted; if (CurrentStage.StageCueType == MMazeStageCueType.Nosepoke) { HandleBeamBreak(); } } break; } } //Update the GUI based on what is happening in the background thread _background_properties_to_update.Add("SoundList"); _background_thread.ReportProgress(0); //Sleep the thread Thread.Sleep(33); } //Close the file for this session _session_file_writer.WriteFileFooter(DateTime.Now.ToFileTime()); _session_file_writer.CloseFile(); //Stop the session timer timer.Stop(); //Stop the sound timers if (_timer1 != null) { _timer1.Stop(); _timer1.Close(); } if (_timer2 != null) { _timer2.Stop(); _timer2.Close(); } //Close up SecondsElapsed = 0; _background_thread.ReportProgress(0); //Report the thread being canceled e.Cancel = true; }