Пример #1
0
    def saveSettings(self):
        """
        Saves current configuration stored in the task object into AHF_task_*.jsn
        Call this function after modifying the contents of the task to save your changes

        :param: none
        :returns: nothing
        """
        self.edited = True
        # get name for new config file and massage it a bit
        if self.fileName == '':
            promptStr = 'Enter a name to save task settings as file:'
        else:
            promptStr = 'Enter a name to save task settings, or enter to use current name, \'' + self.fileName + '\':'
        newConfig = input(promptStr)
        if self.fileName != '' and newConfig == '':
            newConfig = self.fileName
        else:
            if newConfig.startswith('AHF_config_'):
                newConfig = newConfig[9:]
            if newConfig.endswith('.jsn'):
                newConfig.rstrip('.jsn')
            newConfig = ''.join([
                c for c in newConfig if c.isalpha() or c.isdigit() or c == '_'
            ])
            self.fileName = newConfig
        CAD.Obj_fields_to_file(self, 'config', newConfig, '.jsn',
                               'AHF_config/')
Пример #2
0
 def getConfigData(self, tag):
     """
     returns saved dictionary for given tag
     """
     return CAD.File_to_dict('mouse',
                             '{:013}'.format(int(tag)),
                             '.jsn',
                             dir=self.configPath)
Пример #3
0
 def storeConfig(self, tag, configDict, source=""):
     """
     saves data to corresponding json text file, overwriting old file
     """
     if tag is int:
         CAD.Dict_to_file(configDict,
                          'mouse',
                          '{:013}'.format(int(tag)),
                          '.jsn',
                          dir=self.configPath)
Пример #4
0
 def create_fillable_json(self):
     tags = self.miceDict.keys()
     self.miceDict = {}
     useOld = ""
     if len(tags) > 0:
         useOld = input("You have the following tags in your JSON: " +
                        str(tags) + " Would you like to use these?")
     addMore = True
     if len(useOld) > 0 and useOld[0].lower() == 'y':
         for tag in tags:
             self.add(int(tag))
         addMore = input("Add any more mice?")
         if len(addMore) > 0 and addMore[0].lower() == 'n':
             addMore = False
     if addMore:
         tempInput = input(
             'Add the mice for your task.\n'
             'Type A for adding a mouse with the tag number \n'
             'Type T for using the RFID Tag reader ')
         moreMice = True
         while moreMice:
             self.add(tempInput[0])
             stillmore = input('add another mouse? Y or N')
             if stillmore[0] == "n" or stillmore[0] == "N":
                 moreMice = False
     print(self.miceDict)
     CAD.Dict_to_file(self.miceDict,
                      "mice_fillable",
                      self.jsonName,
                      ".jsn",
                      dir=configPath)
     input("Please edit the values in AHF_mice_fillable_" + self.jsonName +
           '.jsn now. Do not modify the structure.\n' +
           "Press enter when done")
     os.system("sudo cp AHF_mice_fillable_" + self.jsonName + ".jsn" +
               " AHF_mice_" + self.jsonName + ".jsn")
     self.miceDict = CAD.File_to_dict('mice',
                                      self.jsonName,
                                      '.jsn',
                                      dir=configPath)
Пример #5
0
 def configGenerator(self):
     """
     Each configuration file has config data for a single subject. This function loads data
     from all of them in turn, and returning each as a a tuple of(tagID, dictionary)
     """
     for fname in listdir(self.configPath):
         if fname.startswith('AHF_mouse_') and fname.endswith('.jsn'):
             tagStr = fname[10:len(fname) - 4]
             yield (int(tagStr),
                    CAD.File_to_dict('mouse',
                                     tagStr,
                                     '.jsn',
                                     dir=self.configPath))
Пример #6
0
    def setup(self):
        # hardware.json subject.json

        self.settingsTuple = ('HeadFixer', 'Rewarder', 'Stimulator')
        self.loadConfigs = self.settingsDict.get('loadMiceConfigs')
        self.jsonName = self.settingsDict.get('jsonName')
        self.inChamberTimeLimit = self.settingsDict.get('inChamberTimeLimit')
        self.miceDict = {}
        self.resultsDict = {}
        if self.loadConfigs == "database" and hasattr(
                self.task, 'DataLogger'
        ):  # try to load mice configuration from dataLogger
            dataLogger = self.task.DataLogger
            for configTuple in dataLogger.configGenerator("current_subjects"):
                self.miceDict.update(configTuple)
        elif self.loadConfigs == "provide_json":  #check file, if not existing or not correct provide a fillable json, then update miceDict when user is ready
            try:
                direc = ""
                if os.getcwd() == "/root":
                    with open("/home/pi/config.txt", "r") as file:
                        configs = file.readlines()
                        for config in configs:
                            config = config.split("=")
                            if config[0] == "path":
                                direc = config[1].rstrip("\n")
                self.miceDict = CAD.File_to_dict('mice', self.jsonName, '.jsn',
                                                 self.configPath)
                if self.check_miceDict(self.miceDict) == False:
                    raise Exception('Could not confirm dictionary')
            except Exception as e:
                print(
                    'Unable to open and fully load subjects configuration, we will create a fillable json for you.\n'
                    'This file will be named AHF_mice_fillable' +
                    self.jsonName + ".jsn\n")
                self.create_fillable_json()
            while self.check_miceDict(self.miceDict) == False:
                input(
                    'could not load json, please edit and try again. Press enter when done'
                )

            for tag in self.miceDict.keys():
                for source in self.miceDict.get(tag):
                    self.task.DataLogger.storeConfig(
                        int(tag),
                        self.miceDict.get(tag).get(source), source)
Пример #7
0
 def retireMouse(self, tag, reason):
     CAD.Remove_file('mouse',
                     '{:013}'.format(int(tag)),
                     '.jsn',
                     dir=self.configPath)
     self.writeToLogFile(tag, "Retirement", {'reason': reason}, time())
Пример #8
0
 def subjectSettings(self):
     """
     Allows user to add mice to file, maybe use TagReader, give initial values to paramaters
     """
     from time import sleep
     while True:
         inputStr = '\n************** Mouse Configuration ********************\nEnter:\n'
         inputStr += 'A to add a mouse, by its RFID Tag\n'
         inputStr += 'T to read a tag from the Tag Reader and add that mouse\n'
         inputStr += 'M to modify mouse information for a specific mouse\n'
         inputStr += 'R to remove a mouse from the list, by RFID Tag\n'
         inputStr += 'J to create a Json file for subject settings from Database\n'
         inputStr += 'E to exit :'
         event = input(inputStr)
         tag = 0
         if event[0].lower() == 'm':
             mouse = input("Enter a tag, or leave blank for all mice: ")
             if len(mouse) > 0:
                 mouse = self.get(mouse)
                 if mouse is not None:
                     for source in self.settingsTuple:
                         reference = getattr(self.task, source)
                         sourceDict = reference.config_user_subject_get(
                             mouse.get(source, {}))
                         mouse.update({source: sourceDict})
             else:
                 for tag, dict in self.get_all().items():
                     print("Tag:", tag)
                     for source in self.settingsTuple:
                         reference = getattr(self.task, source)
                         sourceDict = reference.config_user_subject_get(
                             dict.get(source, {}))
                         dict.update({source: sourceDict})
         elif event[0].lower() == 'r':  # remove a mouse
             mice = self.task.DataLogger.getMice()
             tag = input(
                 'Mice currently known to be in the cage : {}.\n'
                 'Enter the RFID tag of the mouse to be removed: '.format(
                     str(mice)))
             reason = input(
                 'Why do you want to retire the mouse(e.g. participation, window, health, finished): '
             )
             if tag != '' and tag in mice:
                 self.task.DataLogger.retireMouse(tag, reason)
                 mice = self.task.DataLogger.getMice()
                 print('mice now in cage: {}'.format(str(mice)))
             else:
                 print("wrong tag")
         elif event[0].lower() == 'j':
             default = input(
                 'Use CURRENT settings for each mouse for Json?(otherwise DEFAULT settings are used'
             )
             if default[0] == 'y' or default[0] == 'Y':
                 settings = "current_subjects"
             else:
                 settings = "default_subjects"
             jsonDict = {}
             for config in self.task.DataLogger.configGenerator(settings):
                 jsonDict.update(config)
             if len(jsonDict) > 0:
                 nameStr = input(
                     'Chose a filename. Your file will be automatically named: AHF_mice_filename.json'
                 )
                 configFile = 'AHF_mice' + nameStr + '.json'
                 with open(configFile, 'w') as fp:
                     fp.write(
                         json.dumps(jsonDict,
                                    separators=('\n', '='),
                                    sort_keys=True,
                                    skipkeys=True))
                     fp.close()
                     uid = pwd.getpwnam('pi').pw_uid
                     gid = grp.getgrnam('pi').gr_gid
                     os.chown(
                         configFile, uid, gid
                     )  # we may run as root for pi PWM, so we need to explicitly set ownership
                 # TODO check this
         elif event[0].lower() == 'a' or event[0].lower(
         ) == 't':  # other two choices are for adding a mouse by RFID Tag, either reading from Tag Reader, or typing it
             self.task.Reader.stopLogging()
             self.add(event)
             CAD.Dict_to_file(self.miceDict,
                              "mice",
                              self.jsonName,
                              ".jsn",
                              dir='AHF_config/')
             self.task.Reader.startLogging()
         else:
             break
     response = input(
         'Save changes in settings to a json file, too?(recommended)')
     if response[0] == 'Y' or response[0] == 'y':
         CAD.Dict_to_file(self.miceDict,
                          "mice",
                          self.jsonName,
                          ".jsn",
                          dir='AHF_config/')
Пример #9
0
 def userEdit(self):
     """
     Allows user interaction to add and remove subjects, print out and edit individual configuration
     """
     CAD.Edit_dict(self.miceDict, 'Mice')
Пример #10
0
    def __init__(self, fileName='', object=None):
        """
        Initializes a Task object with settings for various hardware, stimulator, and Subjects classes

        """
        fileErr = False
        if fileName != '':
            # file name passed in may or may not start with AFH_task_ and end with .jsn
            self.fileName = fileName
            if self.fileName.startswith('AHF_config_'):
                self.fileName = self.filename[11:]
            if self.fileName.endswith('.jsn'):
                self.filename = self.fileName.rstrip('.jsn')
            if not CAD.File_exists('config', self.fileName, '.jsn'):
                self.fileName = ''
        else:
            self.fileName = ''
        # Initialization dictionary found from database
        if object is not None:
            for key, value in object.items():
                if type(value) is str and key.endswith('Class'):
                    if value.startswith("AHF_"):
                        setattr(
                            self, key,
                            CAD.Class_from_file(value[4:],
                                                '',
                                                dirName='AHF_' + key[:-5]))
                    else:
                        setattr(self, key, None)
                else:
                    setattr(self, key, value)

        # no file passed in, or passed in file could not be found. Get user to choose a file
        if object is None and self.fileName == '':
            try:
                self.fileName = CAD.File_from_user(
                    'config', 'Auto Head Fix task configuration', '.jsn', True)
            except FileNotFoundError:
                self.fileName = ''
                print('Let\'s configure a new task.\n')
                fileErr = True
        # if we found a file, try to load it
        if object is None and self.fileName != '':
            try:
                CAD.File_to_obj_fields('config',
                                       self.fileName,
                                       '.jsn',
                                       self,
                                       dir='AHF_config')
            except ValueError as e:
                print('Unable to open and fully load task configuration:' +
                      str(e))
                fileErr = True
        # check for any missing settings, all settings will be missing if making a new config, and call setting functions for
        # things like head fixer that are subclassable need some extra work , when either loaded from file or user queried
        ########## Head Fixer(obligatory) makes its own dictionary #################################
        if not hasattr(self, 'HeadFixerClass') or not hasattr(
                self, 'HeadFixerDict'):
            self.HeadFixerClass = CAD.Class_from_file(
                'HeadFixer',
                CAD.File_from_user('HeadFixer', 'Head Fixer Class', '.py'),
                dirName='AHF_HeadFixer')
            self.HeadFixerDict = self.HeadFixerClass.config_user_get()
            fileErr = True
        ################################ Stimulator(Obligatory) makes its own dictionary #######################
        if not hasattr(self, 'StimulusClass') or not hasattr(
                self, 'StimulusDict'):
            self.StimulusClass = CAD.Class_from_file(
                'Stimulus',
                CAD.File_from_user('Stimulus', 'Experiment Stimulus Class',
                                   '.py'),
                dirName='AHF_Stimulus')
            #requires a starter dict?
            self.StimulusDict = self.StimulusClass.config_user_get()
            fileErr = True
        ################################ Stimulator(Obligatory) makes its own dictionary #######################
        if not hasattr(self, 'StimulatorClass') or not hasattr(
                self, 'StimulatorDict'):
            self.StimulatorClass = CAD.Class_from_file(
                'Stimulator',
                CAD.File_from_user('Stimulator', 'Experiment Stimulator Class',
                                   '.py'),
                dirName='AHF_Stimulator')
            #requires a starter dict?
            self.StimulatorDict = self.StimulatorClass.config_user_get()
            fileErr = True
        ################################ Rewarder(Obligatory) class makes its own dictionary #######################
        if not hasattr(self, 'RewarderClass') or not hasattr(
                self, 'RewarderDict'):
            self.RewarderClass = CAD.Class_from_file('Rewarder',
                                                     CAD.File_from_user(
                                                         'Rewarder',
                                                         'Rewarder', '.py'),
                                                     dirName='AHF_Rewarder')
            self.RewarderDict = self.RewarderClass.config_user_get()
            fileErr = True
        ############################ Reader(Obligatory) makes its own dictionary ##############
        if not hasattr(self, 'ReaderClass') or not hasattr(self, 'ReaderDict'):
            self.ReaderClass = CAD.Class_from_file(
                'Reader',
                CAD.File_from_user('Reader', 'RFID-Tag Reader', '.py'),
                dirName='AHF_Reader')
            self.ReaderDict = self.ReaderClass.config_user_get()
            fileErr = True
        ################################ Camera(optional) makes its own dictionary of settings ####################
        if not hasattr(self, 'CameraClass') or not hasattr(self, 'CameraDict'):
            if object is not None:
                self.cameraClass = None
                self.cameraDict = None
            else:
                tempInput = input(
                    'Does this system have a main camera installed(Y or N):')
                if tempInput[0] == 'y' or tempInput[0] == 'Y':
                    self.CameraClass = CAD.Class_from_file(
                        'Camera',
                        CAD.File_from_user('Camera', 'main camera', '.py'),
                        dirName='AHF_Camera')
                    self.CameraDict = self.CameraClass.config_user_get()
                else:
                    self.cameraClass = None
                    self.cameraDict = None
                fileErr = True
        ############################# ContactCheck(Obligatory) makes its own dictionary of settings ###################
        if not hasattr(self, 'ContactCheckClass') or not hasattr(
                self, 'ContactCheckDict'):
            self.ContactCheckClass = CAD.Class_from_file(
                'ContactCheck',
                CAD.File_from_user('ContactCheck', 'Contact Checker', '.py'),
                dirName='AHF_ContactCheck')
            self.ContactCheckDict = self.ContactCheckClass.config_user_get()
            fileErr = True
        ############################ NOT just A single GPIO pin for brain illumination, unless you want that ###########
        if not hasattr(self, 'BrainLightClass') or not hasattr(
                self, 'BrainLightDict'):
            self.BrainLightClass = CAD.Class_from_file(
                'BrainLight',
                CAD.File_from_user('BrainLight', 'Brain illuminator', '.py'),
                dirName='AHF_BrainLight')
            self.BrainLightDict = self.BrainLightClass.config_user_get()
            fileErr = True
        ####################################### triggers for alerting other computers(Optional) only 1 subclass so far ######################3
        if not hasattr(self, 'TriggerClass') or not hasattr(
                self, 'TriggerDict'):
            if object is not None:
                self.TriggerClass = None
                self.TriggerDict = None
            else:
                tempInput = input(
                    'Send triggers to start tasks on secondary computers(Y or N):'
                )
                if tempInput[0] == 'y' or tempInput[0] == 'Y':
                    self.TriggerClass = CAD.Class_from_file(
                        'Trigger',
                        CAD.File_from_user('Trigger', 'Trigger', '.py'),
                        dirName='AHF_Trigger')
                    self.TriggerDict = self.TriggerClass.config_user_get()
                else:
                    self.TriggerClass = None
                    self.TriggerDict = None
                fileErr = True
        ############################## LickDetector(optional) only 1 subclass so far ##############
        if not hasattr(self, 'LickDetectorClass') or not hasattr(
                self, 'LickDetectorDict'):
            if object is not None:
                self.LickDetectorClass = None
                self.LickDetectorDict = None
            else:
                tempInput = input(
                    'Does this setup have a Lick Detector installed?(Y or N)')
                if tempInput[0] == 'y' or tempInput[0] == 'Y':
                    self.LickDetectorClass = CAD.Class_from_file(
                        'LickDetector',
                        CAD.File_from_user('LickDetector', 'Lick Detector',
                                           '.py'),
                        dirName='AHF_LickDetector')
                    self.LickDetectorDict = self.LickDetectorClass.config_user_get(
                    )
                else:
                    self.LickDetectorClass = None
                    self.LickDetectorDict = None
                fileErr = True
        ###################### DataLogger(Obligatory) for logging data in text files, or database of HD5,or .... #################
        if not hasattr(self, 'DataLoggerClass') or not hasattr(
                self, 'DataLoggerDict'):
            self.DataLoggerClass = CAD.Class_from_file(
                'DataLogger',
                CAD.File_from_user('DataLogger', 'Data Logger', '.py'),
                dirName='AHF_DataLogger')
            self.DataLoggerDict = self.DataLoggerClass.config_user_get()
            fileErr = True
        ############################ text messaging using textbelt service(Optional) only 1 subclass so far ######################
        if not hasattr(self, 'NotifierClass') or not hasattr(
                self, 'NotifierDict'):
            if object is not None:
                self.NotifierClass = None
                self.NotifierDict = None
            else:
                tempInput = input(
                    'Send notifications if subject exceeds criterion time in chamber?(Y or N):'
                )
                if tempInput[0] == 'y' or tempInput[0] == 'Y':
                    self.NotifierClass = CAD.Class_from_file(
                        'Notifier',
                        CAD.File_from_user('Notifier',
                                           'Text Messaging Notifier', '.py'),
                        dirName='AHF_Notifier')
                    self.NotifierDict = self.NotifierClass.config_user_get()
                    self.NotifierDict.update(
                        {'cageID': self.DataLoggerDict.get('cageID')})
                else:
                    self.NotifierClass = None
                    self.NotifierDict = None
                fileErr = True
        ############################## Subjects only 1 subclass so far(generic mice) ##############
        if not hasattr(self, 'SubjectsClass') or not hasattr(
                self, 'SubjectsDict'):
            self.SubjectsClass = CAD.Class_from_file(
                'Subjects',
                CAD.File_from_user('Subjects', 'test subjects', '.py'),
                dirName='AHF_Subjects')
            self.SubjectsDict = self.SubjectsClass.config_user_get()
            fileErr = True
        ###################### things we track in the main program #################################
        self.tag = 0  # RFIG tag number, 0 for no tag, updated by threaded callback
        self.contact = False  # true if contact is true
        self.contactTime = 0
        self.lastFixedTag = 0
        self.lastFixedTime = 0
        self.entryTime = 0.0
        self.fixAgainTime = float('inf')
        self.fixed = False
        self.isFixTrial = False
        self.inChamberLimitExceeded = False
        self.edited = False
        self.logToFile = True  # a flag for writing to the shell only, or to the shall and the log
        ################ if some of the paramaters were set by user, give option to save ###############
        if fileErr:
            response = input(
                'Save new/updated settings to a task configuration file?')
            if response[0] == 'y' or response[0] == 'Y':
                self.saveSettings()
Пример #11
0
 def editSettings(self):
     if (CAD.Edit_Obj_fields(self, 'Auto Head Fix Task',
                             isTaskConfig=True)):
         response = input('Save changes in settings to a file? y/n')
         if response[0] == 'Y' or response[0] == 'y':
             self.saveSettings()