예제 #1
0
        /// <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;
            }
        }
예제 #3
0
 /// <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];
     }
 }
예제 #4
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();
            }
        }
예제 #5
0
        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();
        }
예제 #6
0
        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;
        }