示例#1
0
def main():

    tagReader = TagReader(serialPort, True, timeOutSecs=0.05, kind='ID')
    tagReader.installCallback(tag_in_range_pin)
    print("Waiting for tags....")
    while True:
        try:
            """
            Loop with a brief sleep, waiting for a tag to be read.
            After reading the tag, it is printed. This is the point
            where you might do something interesting
            """
            while RFIDTagReader.globalTag == 0:
                sleep(0.02)
            print('Tag = ', RFIDTagReader.globalTag)
            """
            Loop with a brief sleep, waiting for a tag to exit reading range
            """
            while RFIDTagReader.globalTag != 0:
                sleep(0.02)
            print('Tag went away')
        except KeyboardInterrupt:
            del tagReader
            GPIO.cleanup()
            print("Quitting")
            break
def main():
    global globalReader
    global globalTag
    globalReader = TagReader(serialPort, True, timeOutSecs=0.05, kind='ID')
    globalReader.installCallback(tag_in_range_pin,
                                 callbackFunc=tagReaderGraceCallback)

    print("Waiting for tags....")
    while True:
        try:
            """
            Loop with a brief sleep, waiting for a tag to be read.
            After reading the tag, it is printed. This is the point
            where you might do something interesting
            """
            while globalTag == 0:
                sleep(0.02)
            tag = globalTag
            print('Tag = {:d}'.format(tag))
            while globalTag == tag:
                sleep(0.02)
            print('Tag went away, really.')

        except KeyboardInterrupt:
            del globalReader
            print("Quitting")
            break
示例#3
0
 def remove_mouse(self):
     try:
         tagreader = TagReader(RFID_serialPort,
                               RFID_doCheckSum,
                               timeOutSecs=RFID_timeout,
                               kind=RFID_kind)
     except Exception as e:
         raise e
     i = 0
     print('Scan mice to remove now')
     while i < 1:
         try:
             tag = tagreader.readTag()
             i += 1
             print(tag)
         except ValueError as e:
             print(str(e))
     del self.mice_config[str(tag)]
示例#4
0
 def add_mice(self):
     try:
         tagreader = TagReader(RFID_serialPort,
                               RFID_doCheckSum,
                               timeOutSecs=RFID_timeout,
                               kind=RFID_kind)
     except Exception as e:
         raise e
     i = 0
     print('Scan mice now')
     while i < 1:
         try:
             tag = tagreader.readTag()
             i += 1
             print(tag)
         except ValueError as e:
             print(str(e))
     tagreader.clearBuffer()
     SPT_lvl = input('Enter SPT level for new mouse:')
     SPT_Spout = input('Enter initial SPT spout for new mouse (R/L):')
     temp = {tag: {'SPT_Pattern': SPT_Spout, 'SPT_level': int(SPT_lvl)}}
     self.mice_config.update(temp)
示例#5
0
DATABASE = input('Enter database to connecnt to:')
PASSWD = input('Enter password for database:')

RFID_timeout = None
RFID_doCheckSum = True
read = True
db1 = pymysql.connect(host=HOST,
                      user=USER,
                      db=DATABASE,
                      password=PASSWD,
                      autocommit=True)
cur1 = db1.cursor()
insert_statment = 'INSERT INTO Weight_ManualLog (Tag,Timestamp,Weight, Change_To_Baseline, Water_Needed,Cage) VALUES (%s,%s,%s,%s,%s,%s)'
try:
    tagReader = TagReader(RFID_serialPort,
                          RFID_doCheckSum,
                          timeOutSecs=RFID_timeout,
                          kind=RFID_kind)
except Exception as e:
    raise e
while read:
    try:
        print('Waiting for tags...')
        tag = tagReader.readTag()
        print(tag)
        weight_float = input("Please enter the mouse's weight (g): ")
        Cage = input('Please enter the cage of the mouse:')
        record_filename = "/home/pi/Documents/RFIDTagReader/Mice/" + str(
            tag) + ".csv"
        tm = datetime.now()
        timestamp = str(tm.year) + format(tm.month, '02d') + format(tm.day, '02d') + \
                           format(tm.hour, '02d') + format(tm.minute, '02d') + format(tm.second, '02d')
def htloop (cageSet, tagReader, headFixer, stimulator, expSettings):
    """
    Presents a menu asking user to choose a bit of hardware to test, and runs the tests

    If a test fails, a dialog is presented asking user to change the pin setup. The modified pinout
    can be saved, overwriting the configuration in ./AHF_Config.jsn
    Commands are:
    t= tagReader: trys to read a tag and, if successful, monitors Tag in Range Pin until tag goes away
    r = reward solenoid:  Opens the reward solenoid for a 1 second duration, then closes it
    c = contact check:  Monitors the head contact pin until contact, and then while contact is maintained
    f = head Fixer
    e = Entry beam break
    p = pistons solenoid: Energizes the pistons for a 2 second duration, and then de-energizes them
    l = LED: Turns on the brain illumination LED for a 2 second duration, then off
    h = sHow config settings: Prints out the current pinout in the AHF_CageSet object
    v = saVe modified config file: Saves the the AHF_CageSet object to the file ./AHF_Config.jsn
    q = quit: quits the program
    """
    if cageSet.contactPolarity == 'RISING':
          contactEdge = GPIO.RISING
          noContactEdge = GPIO.FALLING
          contactState = GPIO.HIGH
          noContactState = GPIO.LOW
    else:
          contactEdge = GPIO.FALLING
          noContactEdge = GPIO.RISING
          contactState = GPIO.LOW
          noContactState = GPIO.HIGH
    try:
        while (True):
            inputStr = input ('t=tagReader, r=reward solenoid, c=contact check, e= entry beam break, f=head Fixer, l=LED, s=stimulator tester, h=sHow config, v= saVe config, q=quit:')
            if inputStr == 't': # t for tagreader
                if tagReader == None:
                    cageSet.serialPort = input ('First, set the tag reader serial port:')
                    try:
                        tagReader = TagReader (cageSet.serialPort, True)
                        inputStr =  input ('Do you want to read a tag now?')
                        if inputStr[0] == 'n' or inputStr[0] == "N":
                            continue
                    except IOError as anError:
                        print ('Try setting the serial port again.')
                        tagReader = None
                if tagReader is not None:
                    try:
                        if (tagReader.serialPort.inWaiting() < 16):
                            print ('No data in serial buffer')
                            tagError = True
                        else:
                            tagID = tagReader.readTag()
                            tagError = False
                    except (IOError, ValueError) as anError:
                        tagError = True
                    if tagError == True:
                        print ('Serial Port Tag-Read Error\n')
                        tagReader.clearBuffer()
                        inputStr = input ('Do you want to change the tag reader serial port (currently ' + cageSet.serialPort + ')?')
                        if inputStr == 'y' or inputStr == "Y":
                            cageSet.serialPort = input ('Enter New Serial Port:')
                            # remake tagReader and open serial port
                            tagReader = TagReader (cageSet.serialPort, True)
                    else:
                        print ("Tag ID =", tagID)
                        # now check Tag-In-Range pin function
                        if (GPIO.input (cageSet.tirPin)== GPIO.LOW):
                            print ('Tag was never registered as being "in range"')
                            tagError = True
                        else:
                            startTime = time()
                            GPIO.wait_for_edge (cageSet.tirPin, GPIO.FALLING, timeout= 10000)
                            if (time () > startTime + 10.0):
                                print ('Tag stayed in range for over 10 seconds')
                                tagError = True
                            else:
                                print ('Tag no longer in range')
                                tagError = False
                        if (tagError == True):
                            inputStr = input ('Do you want to change the tag-in-range Pin (currently ' + str (cageSet.tirPin) + ')?')
                            if inputStr[0] == 'y' or inputStr[0] == "Y":
                                cageSet.tirPin = int (input('Enter New tag-in-range Pin:'))
                                GPIO.setup (cageSet.tirPin, GPIO.IN)
            elif inputStr == 'r': # r for reward solenoid
                print ('Reward Solenoid opening for 3 sec')
                GPIO.output(cageSet.rewardPin, 1)
                sleep(3.0)
                GPIO.output(cageSet.rewardPin, 0)
                inputStr= input('Reward Solenoid closed.\nDo you want to change the Reward Solenoid Pin (currently ' + str (cageSet.rewardPin) + ')?')
                if inputStr[0] == 'y' or inputStr[0] == "Y":
                    cageSet.rewardPin = int (input('Enter New Reward Solenoid Pin:' ))
                    GPIO.setup (cageSet.rewardPin, GPIO.OUT, initial=GPIO.LOW)
            elif inputStr == 'c': #c for contact on head fix
                if GPIO.input (cageSet.contactPin)== contactState:
                    print ('Contact pin already indicates contact.')
                    err=True
                else:
                    GPIO.wait_for_edge (cageSet.contactPin, contactEdge, 100)
                    if GPIO.input (cageSet.contactPin)== noContactState:
                        print ('No Contact after 10 seconds.')
                        err = True
                    else:
                        print ('Contact Made.')
                        GPIO.wait_for_edge (cageSet.contactPin, noContactEdge, 100)
                        if GPIO.input (cageSet.contactPin)== contactState:
                            print ('Contact maintained for 10 seconds.')
                            err = True
                        else:
                            print ('Contact Broken')
                            err = False
                if err == True:
                    inputStr= input ('Do you want to change Contact settings (currently pin=' + str (cageSet.contactPin) + ', polarity=' + str(cageSet.contactPolarity) + ', pull up/down =' + str (cageSet.contactPUD) + ')?')
                    if inputStr[0] == 'y' or inputStr[0] == "Y":
                        cageSet.contactPin= int (input ('Enter the GPIO pin connected to the headbar contacts or IR beam-breaker:'))
                        contactInt = int (input ('Enter the contact polarity, 0=FALLING for IR beam-breaker or falling polarity electrical contacts, 1=RISING for rising polarity elctrical contacts:'))
                        if contactInt == 0:
                            cageSet.contactPolarity = 'FALLING'
                        else:
                            cageSet.contactPolarity = 'RISING'
                        contactInt = int (input('Enter desired resistor on contact pin, 0=OFF if external resistor present, else 1=DOWN if rising polarity electrical contact or 2 = UP if IR beam-breaker or falling polarity electrical contacts:'))
                        if contactInt ==0:
                            cageSet.contactPUD = 'OFF'
                        elif contactInt == 1:
                            cageSet.contactPUD = 'DOWN'
                        else:
                            cageSet.contactPUD='UP'
                    GPIO.setup (cageSet.contactPin, GPIO.IN, pull_up_down=getattr (GPIO, "PUD_" + cageSet.contactPUD))
                    if cageSet.contactPolarity =='RISING':
                        contactEdge = GPIO.RISING
                        noContactEdge = GPIO.FALLING
                        contactState = GPIO.HIGH
                        noContactState = GPIO.LOW
                    else:
                        contactEdge = GPIO.FALLING
                        noContactEdge = GPIO.RISING
                        contactState = GPIO.LOW
                        noContactState = GPIO.HIGH
            elif inputStr == 'e': # beam break at enty
                if GPIO.input (cageSet.entryBBpin)== GPIO.LOW:
                    print ('Entry beam break is already broken')
                    err=True
                else:
                    GPIO.wait_for_edge (cageSet.entryBBpin, GPIO.FALLING, timeout= 10000)
                    if GPIO.input (cageSet.entryBBpin)== GPIO.HIGH:
                        print ('Entry beam not broken after 10 seconds.')
                        err = True
                    else:
                        print ('Entry Beam Broken.')
                        GPIO.wait_for_edge (cageSet.entryBBpin, GPIO.RISING, timeout= 10000)
                        if GPIO.input (cageSet.entryBBpin)== GPIO.LOW:
                            print ('Entry Beam Broken maintained for 10 seconds.')
                            err = True
                        else:
                            print ('Entry Beam Intact Again.')
                            err = False
                if err == True:
                    inputStr= input ('Do you want to change the Entry Beam Break Pin (currently pin=' + str (cageSet.entryBBpin)+ '?')
                    if inputStr[0] == 'y' or inputStr[0] == "Y":
                        cageSet.entryBBpin= int (input ('Enter the GPIO pin connected to the tube entry IR beam-breaker:'))
                        GPIO.setup (cageSet.entryBBpin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

            elif inputStr == 'f': # head Fixer, run test from headFixer class
                headFixer.test(cageSet)
            elif inputStr == 'l': # l for LED trigger
                print ('LED turning ON for 2 seconds.')
                GPIO.output(cageSet.ledPin, 1)
                sleep (2)
                GPIO.output(cageSet.ledPin, 0)
                inputStr=input ('LED turned OFF\nDo you want to change the LED Pin (currently ' + str(cageSet.ledPin) + ')?')
                if inputStr == 'y' or inputStr == "Y":
                    cageSet.ledPin = int (input('Enter New LED Pin:'))
                    GPIO.setup (cageSet.ledPin, GPIO.OUT, initial = GPIO.LOW)
            elif inputStr == 's':
                for i,j in enumerate(expSettings.stimulator):
                    print('\t'+str(i)+': '+str(j))
                inputStr = input ('Which stimulator tester would you like to run?')
                try:
                    stimulator[int(inputStr)].tester(expSettings)
                except:
                    print('Input is not a valid number!')
            elif inputStr == 'h':
                cageSet.show()
            elif inputStr=='v':
                cageSet.save()
            elif inputStr == 'q':
                break
    except KeyboardInterrupt:
        print ("quitting.")
    finally:
        if __name__ == '__main__':
            GPIO.cleanup() # this ensures a clean exit
示例#7
0
def main():
    """
    The main function for the AutoHeadFix program.

    It initializes or loads settings and configurations, then endlessly loops running entries and head fix trials
    Ctrl-C is used to enter a menu-driven mode where settings can be altered.
    """
    try:
        # load general settings for this cage, mostly hardware pinouts
        # things not expected to change often - there is only one AHFconfig.jsn file, in the enclosing folder
        cageSettings = AHF_CageSet()
        #print (cageSettings)
        # get settings that may vary by experiment, including rewarder, camera parameters, and stimulator
        # More than one of these files can exist, and the user needs to choose one or make one
        # we will add some other  variables to expSettings so we can pass them as a single argument to functions
        # logFP, statsFP, dateStr, dayFolderPath, doHeadFix,
        # configFile can be specified if launched from command line, eg, sudo python3 myconfig or sudo python3 AHFexp_myconfig.jsn
        configFile = None
        if argv.__len__() > 1:
            configFile = argv[1]
        expSettings = AHF_Settings(configFile)
        # nextDay starts tomorrow at KDAYSTARTHOUR
        #nextDay = (int((time() - timezone)/KSECSPERDAY) + 1) * KSECSPERDAY + timezone + (KDAYSTARTHOUR * KSECSPERHOUR)
        nextDay = ((int(
            (time() - timezone + localtime().tm_isdst * 3600) / KSECSPERDAY)) *
                   KSECSPERDAY) + timezone - (localtime().tm_isdst * 3600
                                              ) + KSECSPERDAY + KDAYSTARTHOUR
        # Create folders where the files for today will be stored
        makeDayFolderPath(expSettings, cageSettings)
        # initialize mice with zero mice
        mice = Mice()
        # make daily Log files and quick stats file
        makeLogFile(expSettings, cageSettings)
        makeQuickStatsFile(expSettings, cageSettings, mice)
        #Generate h5 file to store mouse-individual data
        makeH5File(expSettings, cageSettings, mice)
        updateStats(expSettings.statsFP, mice)
        backup_H5(expSettings, cageSettings)
        # set up the GPIO pins for each for their respective functionalities.
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        GPIO.setup(cageSettings.ledPin, GPIO.OUT,
                   initial=GPIO.LOW)  # turns on brain illumination LED
        GPIO.setup(cageSettings.led2Pin, GPIO.OUT,
                   initial=GPIO.LOW)  # turns on masking stim LED2
        GPIO.setup(cageSettings.tirPin,
                   GPIO.IN)  # Tag-in-range output from RFID tag reader
        GPIO.setup(cageSettings.contactPin,
                   GPIO.IN,
                   pull_up_down=getattr(GPIO,
                                        "PUD_" + cageSettings.contactPUD))
        if cageSettings.contactPolarity == 'RISING':
            expSettings.contactEdge = GPIO.RISING
            expSettings.noContactEdge = GPIO.FALLING
            expSettings.contactState = GPIO.HIGH
            expSettings.noContactState = GPIO.LOW
        else:
            expSettings.contactEdge = GPIO.FALLING
            expSettings.noContactEdge = GPIO.RISING
            expSettings.contactState = GPIO.LOW
            expSettings.noContactState = GPIO.HIGH
        # make head fixer - does its own GPIO initialization from info in cageSettings
        headFixer = AHF_HeadFixer.get_class(
            cageSettings.headFixer)(cageSettings)
        # make a rewarder
        rewarder = AHF_Rewarder(30e-03, cageSettings.rewardPin)
        rewarder.addToDict('entrance', expSettings.entranceRewardTime)
        rewarder.addToDict('task', expSettings.taskRewardTime)
        # make a notifier object
        if expSettings.hasTextMsg == True:
            notifier = AHF_Notifier(cageSettings.cageID, expSettings.phoneList)
        else:
            notifier = None
        # make RFID reader
        tagReader = TagReader(cageSettings.serialPort, False, None)
        # configure camera
        camera = AHF_Camera(expSettings.camParamsDict)
        # make UDP Trigger
        if expSettings.hasUDP == True:
            UDPTrigger = AHF_UDPTrig(expSettings.UDPList)
            print(UDPTrigger)
        else:
            UDPTrigger = None
        # make a lick detector
        simpleLogger = Simple_Logger(expSettings.logFP)
        lickDetector = AHF_LickDetector((0, 1), 26, simpleLogger)
        sleep(1)
        lickDetector.start_logging()
        # make stimulator(s)
        stimulator = [
            AHF_Stimulator.get_class(i)(cageSettings, expSettings, rewarder,
                                        lickDetector, camera)
            for i in expSettings.stimulator
        ]
        #Stimdict is chosen from the first stimulator
        expSettings.stimDict = stimulator[0].configDict
        # Entry beam breaker
        if cageSettings.hasEntryBB == True:
            GPIO.setup(cageSettings.entryBBpin,
                       GPIO.IN,
                       pull_up_down=GPIO.PUD_UP)
            GPIO.add_event_detect(cageSettings.entryBBpin, GPIO.BOTH,
                                  entryBBCallback)
            #GPIO.add_event_callback (cageSettings.entryBBpin, entryBBCallback)
            gTubePanicTime = time() + 25920000  # a month from now.
            gTubeMaxTime = expSettings.inChamberTimeLimit
    except Exception as anError:
        print('Unexpected error starting AutoHeadFix:', str(anError))
        raise anError
        exit(0)
    try:
        print('Waiting for a mouse...')
        while True:  #start main loop
            try:
                # wait for mouse entry, with occasional timeout to catch keyboard interrupt
                GPIO.wait_for_edge(
                    cageSettings.tirPin, GPIO.RISING, timeout=kTIMEOUTmS
                )  # wait for entry based on Tag-in-range pin
                if (GPIO.input(cageSettings.tirPin) == GPIO.HIGH):
                    try:
                        tag = tagReader.readTag()
                    except (IOError, ValueError):
                        tagReader.clearBuffer()
                        continue
                    entryTime = time()
                    if cageSettings.hasEntryBB == True:
                        GPIO.remove_event_detect(cageSettings.entryBBpin)
                    thisMouse = mice.getMouseFromTag(tag)
                    if thisMouse is None:
                        # try to open mouse config file to initialize mouse data
                        thisMouse = Mouse(tag, 1, 0, 0, 0, 0, 0)
                        mice.addMouse(thisMouse, expSettings.statsFP)
                    writeToLogFile(expSettings.logFP, thisMouse, 'entry')
                    thisMouse.entries += 1
                    # if we have entrance reward, first wait for entrance reward or first head-fix, which countermands entry reward
                    if thisMouse.entranceRewards < expSettings.maxEntryRewards:
                        giveEntranceReward = True
                        expSettings.doHeadFix = expSettings.propHeadFix > random(
                        )
                        while GPIO.input(
                                cageSettings.tirPin) == GPIO.HIGH and time(
                                ) < (entryTime + expSettings.entryRewardDelay):
                            GPIO.wait_for_edge(cageSettings.contactPin,
                                               expSettings.contactEdge,
                                               timeout=kTIMEOUTmS)
                            if (GPIO.input(cageSettings.contactPin) ==
                                    expSettings.contactState):
                                runTrial(thisMouse, expSettings, cageSettings,
                                         rewarder, headFixer,
                                         stimulator[thisMouse.stimType],
                                         UDPTrigger)
                                giveEntranceReward = False
                                break
                        if (GPIO.input(cageSettings.tirPin)
                                == GPIO.HIGH) and giveEntranceReward == True:
                            thisMouse.reward(
                                rewarder, 'entrance'
                            )  # entrance reward was not countermanded by an early headfix
                            writeToLogFile(expSettings.logFP, thisMouse,
                                           'entryReward')
                    # wait for contacts and run trials till mouse exits or time in chamber exceeded
                    expSettings.doHeadFix = expSettings.propHeadFix > random()
                    while GPIO.input(
                            cageSettings.tirPin) == GPIO.HIGH and time(
                            ) < entryTime + expSettings.inChamberTimeLimit:
                        if (GPIO.input(cageSettings.contactPin) ==
                                expSettings.noContactState):
                            GPIO.wait_for_edge(cageSettings.contactPin,
                                               expSettings.contactEdge,
                                               timeout=kTIMEOUTmS)
                        if (GPIO.input(cageSettings.contactPin) ==
                                expSettings.contactState):
                            runTrial(thisMouse, expSettings, cageSettings,
                                     rewarder, headFixer,
                                     stimulator[thisMouse.stimType],
                                     UDPTrigger)
                            expSettings.doHeadFix = expSettings.propHeadFix > random(
                            )  # set doHeadFix for next contact
                    # either mouse left the chamber or has been in chamber too long
                    if GPIO.input(cageSettings.tirPin) == GPIO.HIGH and time(
                    ) > entryTime + expSettings.inChamberTimeLimit:
                        # explictly turn off pistons, though they should be off at end of trial
                        headFixer.releaseMouse()
                        if expSettings.hasTextMsg == True:
                            notifier.notify(thisMouse.tag,
                                            (time() - entryTime), True)
                        # wait for mouse to leave chamber, with no timeout, unless it left while we did last 3 lines
                        if GPIO.input(cageSettings.tirPin) == GPIO.HIGH:
                            GPIO.wait_for_edge(cageSettings.tirPin,
                                               GPIO.FALLING)
                        if expSettings.hasTextMsg == True:
                            notifier.notify(thisMouse.tag,
                                            (time() - entryTime), False)
                    tagReader.clearBuffer()
                    if cageSettings.hasEntryBB == True:
                        #GPIO.setup (cageSettings.entryBBpin, GPIO.IN, pull_up_down = GPIO.PUD_UP)
                        GPIO.add_event_detect(cageSettings.entryBBpin,
                                              GPIO.BOTH, entryBBCallback)
                    # after exit, update stats
                    writeToLogFile(expSettings.logFP, thisMouse, 'exit')
                    updateH5File(expSettings, cageSettings, mice, stimulator)
                    updateStats(expSettings.statsFP, mice, thisMouse)
                    # after each exit check for a new day
                    if time() > nextDay:
                        # stop lick logging so we dont write to file when it is closed
                        lickDetector.stop_logging()
                        mice.show()
                        writeToLogFile(expSettings.logFP, None, 'SeshEnd')
                        expSettings.logFP.close()
                        expSettings.statsFP.close()
                        makeDayFolderPath(expSettings, cageSettings)
                        makeLogFile(expSettings, cageSettings)
                        simpleLogger.logFP = expSettings.logFP
                        makeQuickStatsFile(expSettings, cageSettings, mice)
                        for i in stimulator:
                            i.nextDay(expSettings.logFP)
                        nextDay += KSECSPERDAY
                        mice.clear()
                        updateH5File(expSettings, cageSettings, mice,
                                     stimulator)
                        updateStats(expSettings.statsFP, mice)
                        backup_H5(expSettings, cageSettings)
                        # reinitialize lick detector because it can lock up if too many licks when not logging
                        lickDetector.__init__((0, 1), 26, simpleLogger)
                        lickDetector.start_logging()
                    print('Waiting for a mouse...')
                else:
                    # check for entry beam break while idling between trials
                    if cageSettings.hasEntryBB == True and time(
                    ) > gTubePanicTime:
                        print(
                            'Some one has been in the entrance of this tube for too long'
                        )
                        # explictly turn off pistons, though they should be off
                        headFixer.releaseMouse()
                        BBentryTime = gTubePanicTime - gTubeMaxTime
                        if expSettings.hasTextMsg == True:
                            notifier.notify(
                                0, (time() - BBentryTime), True
                            )  # we don't have an RFID for this mouse, so use 0
                        # wait for mouse to leave chamber
                        while time() > gTubePanicTime:
                            sleep(kTIMEOUTmS / 1000)
                        print(
                            'looks like some one managed to escape the entrance of this tube'
                        )
                        if expSettings.hasTextMsg == True:
                            notifier.notify(0, (time() - BBentryTime), False)
            except KeyboardInterrupt:
                GPIO.output(cageSettings.ledPin, GPIO.LOW)
                headFixer.releaseMouse()
                GPIO.output(cageSettings.rewardPin, GPIO.LOW)
                lickDetector.stop_logging()
                if cageSettings.hasEntryBB == True:
                    sleep(1)
                    GPIO.remove_event_detect(cageSettings.entryBBpin)
                    print('removed BB event detect')
                while True:
                    event = input(
                        'Enter:\nr to return to head fix trials\nq to quit\nv to run valve control\nh for hardware tester\nm for mice inspection\nc for camera configuration\ne for experiment configuration\n:'
                    )
                    if event == 'r' or event == "R":
                        lickDetector.start_logging()
                        sleep(1)
                        if cageSettings.hasEntryBB == True:
                            sleep(1)
                            print('Restarting entry bb')
                            GPIO.setup(cageSettings.entryBBpin,
                                       GPIO.IN,
                                       pull_up_down=GPIO.PUD_UP)
                            GPIO.add_event_detect(cageSettings.entryBBpin,
                                                  GPIO.BOTH, entryBBCallback)
                        break
                    elif event == 'q' or event == 'Q':
                        exit(0)
                    elif event == 'v' or event == "V":
                        valveControl(cageSettings)
                    elif event == 'h' or event == 'H':
                        hardwareTester(cageSettings, tagReader, headFixer,
                                       stimulator, expSettings)
                        if cageSettings.contactPolarity == 'RISING':
                            expSettings.contactEdge = GPIO.RISING
                            expSettings.noContactEdge = GPIO.FALLING
                            expSettings.contactState = GPIO.HIGH
                            expSettings.noContactState = GPIO.LOW
                        else:
                            expSettings.contactEdge = GPIO.FALLING
                            expSettings.noContactEdge = GPIO.RISING
                            expSettings.contactState = GPIO.LOW
                            expSettings.noContactState = GPIO.HIGH
                    elif event == 'm' or event == 'M':
                        mice.show()
                        for i, j in enumerate(expSettings.stimulator):
                            print('\t' + str(i) + ': ' + str(j))
                        inputStr = input(
                            'Which stimulator-specific inspection method would you like to run?'
                        )
                        try:
                            stimulator[int(inputStr)].inspect_mice(
                                mice, cageSettings, expSettings)
                        except:
                            print("Stimulator doesn't exist.")
                        updateH5File(expSettings, cageSettings, mice,
                                     stimulator)
                    elif event == 'c' or event == 'C':
                        camParams = camera.adjust_config_from_user()
                    elif event == 'e' or event == 'E':
                        modCode = expSettings.edit_from_user()
                        if modCode >= 2:
                            stimulator[modCode - 2] = AHF_Stimulator.get_class(
                                expSettings.stimulator[modCode - 2])(
                                    cageSettings, expSettings.stimDict,
                                    rewarder, lickDetector, expSettings.logFP,
                                    camera)
                        if modCode & 1:
                            for stim in stimulator:
                                stim.change_config(expSettings.stimDict)
    except Exception as anError:
        print('AutoHeadFix error:' + str(anError))
        raise anError
    finally:
        for stim in stimulator:
            stim.quitting()
        GPIO.output(cageSettings.ledPin, False)
        headFixer.releaseMouse()
        GPIO.output(cageSettings.rewardPin, False)
        GPIO.cleanup()
        writeToLogFile(expSettings.logFP, None, 'SeshEnd')
        expSettings.logFP.close()
        expSettings.statsFP.close()
        camera.close()
        print('AutoHeadFix Stopped')
def read_tag():
    try:
        tag = reader.readTag()
        print(tag)
        wait_for_tag_exit()
    except ValueError as e:
        print(str(e))
        reader.clearBuffer()
    except KeyboardInterrupt:
        GPIO.cleanup()


def wait_for_tag_exit():
    try:
        sleep(1)
        while True:
            i = GPIO.input(21)
            if not i:
                print('Tag has left')
                break
        read_tag()
    except KeyboardInterrupt:
        GPIO.cleanup()


if __name__ == "__main__":
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(21, GPIO.IN)
    reader = TagReader()
    read_tag()
示例#9
0
def main():
    global globalReader
    global globalTag
    global cage
    global log
    global mice_dic
    globalReader = TagReader(serialPort, True, timeOutSecs=0.05, kind='ID')
    globalReader.installCallback(tag_in_range_pin)
    now = dt.datetime.now()
    mice_dic = SPT.mice_dict(cage)
    txtspacer = input('txt spacer?')
    while True:
        # loops to check date and if date passes the define time settings, a new day/file is started
        now = dt.datetime.now()
        print("Waiting for mouse....")
        log = SPT.data_logger(cage, txtspacer)
        #switches the spout for L/R every indicated time interval (in hours)
        mice_dic.spout_swtich()
        while dt.datetime.now() - now < dt.timedelta(minutes=hours * 60):
            if RFIDTagReader.globalTag == 0:
                sleep(0.02)
            else:
                tag = RFIDTagReader.globalTag
                filename = vs.record(tag)
                print(mice_dic.mice_config)
                print(str(tag))
                print(filename)
                log.event_outcome(mice_dic.mice_config, str(tag), 'VideoStart',
                                  filename)
                # provides the mouse at level 0 an entry reward; the reward is given randomly at r or l at 50% each
                if mice_dic.mice_config[str(tag)]['SPT_level'] == 0:
                    if mice_dic.mice_config[str(tag)]['SPT_Pattern'] == 'R':
                        solenoid_LW.activate(0.5)
                        log.event_outcome(mice_dic.mice_config, str(tag),
                                          'Entered', 'Entry_Reward')
                        pass
                    elif mice_dic.mice_config[str(tag)]['SPT_Pattern'] == 'L':
                        solenoid_RW.activate(0.5)
                        log.event_outcome(mice_dic.mice_config, str(tag),
                                          'Entered', 'Entry_Reward')
                        pass
                else:
                    log.event_outcome(mice_dic.mice_config, str(tag),
                                      'Entered', 'No_Entry_Reward')
                #tag is read and checks the mouse spt level
                #level 0: a water reward is given
                #level 1: only one the spt pattern spout will dispense water, licking the other will give a buzz
                #level 2: the spt preference test, spt dispensed at the spt pattern spout
                while RFIDTagReader.globalTag == tag:
                    while GPIO.input(tag_in_range_pin) == GPIO.HIGH:
                        if lickdector[0].value:
                            if mice_dic.mice_config[str(
                                    tag)]['SPT_level'] == 0:
                                solenoid_RW.activate(0.1)
                                log.event_outcome(mice_dic.mice_config,
                                                  str(tag), 'licked-Rightside',
                                                  'Water_Reward')
                            elif mice_dic.mice_config[str(
                                    tag)]['SPT_level'] == 1:
                                if mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'R':
                                    solenoid_RW.activate(0.1)
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Rightside',
                                                      'Water_Reward')
                                elif mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'L':
                                    #speaker on
                                    print('Speaker on\n')
                                    buzzer.buzz()
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Rightside',
                                                      'No_Reward')
                                    sleep(0.2)
                            elif mice_dic.mice_config[str(
                                    tag)]['SPT_level'] == 2:
                                if mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'R':
                                    solenoid_RW.activate(0.1)
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Rightside',
                                                      'Sucrose_Reward')
                                elif mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'L':
                                    solenoid_LW.activate(0.1)
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Rightside',
                                                      'Water_Reward')
                        elif lickdector[1].value:
                            if mice_dic.mice_config[str(
                                    tag)]['SPT_level'] == 0:
                                solenoid_LW.activate(0.1)
                                log.event_outcome(mice_dic.mice_config,
                                                  str(tag), 'licked-Leftside',
                                                  'Water_Reward')
                            elif mice_dic.mice_config[str(
                                    tag)]['SPT_level'] == 1:
                                if mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'R':
                                    print('Speaker on\n')
                                    buzzer.buzz()
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-leftside',
                                                      'No_Reward')
                                    sleep(0.2)
                                elif mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'L':
                                    solenoid_LW.activate(0.1)
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Leftside',
                                                      'Water_Reward')
                            elif mice_dic.mice_config[str(
                                    tag)]['SPT_level'] == 2:
                                if mice_dic.mice_config[tag][
                                        'SPT_Pattern'] == 'R':
                                    solenoid_LW.activate(0.1)
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Leftside',
                                                      'Water_Reward')
                                elif mice_dic.mice_config[str(
                                        tag)]['SPT_Pattern'] == 'L':
                                    solenoid_LS.activate(0.1)
                                    log.event_outcome(mice_dic.mice_config,
                                                      str(tag),
                                                      'licked-Leftside',
                                                      'Sucrose_Reward')
                        else:
                            sleep(0.02)
                vs.stop_record()
                log.event_outcome(mice_dic.mice_config, str(tag), 'VideoEnd',
                                  filename)
                ###sleep time must match reward and buzzer sleep time
                sleep(0.05)
                log.event_outcome(mice_dic.mice_config, str(tag), 'Exit',
                                  'None')
                print('Waiting for mouse')
示例#10
0
def main():
    """
    Read in settings from AMW_config.jsn. If we don't find the file, make it.
    Note that we save the file with new line as a separator, but can't load it with a non-standard separator,
    so we replace new lines with  commas, he default separator character
    
    """
    try:
        with open('AMW_config.jsn', 'r') as fp:
            data = fp.read()
            data = data.replace('\n', ',')
            configDict = json.loads(data)
            fp.close()
            # Constants for saving data
            # cage name, to tell data from different cages
            kCAGE_NAME = configDict.get('Cage Name')
            # path where data from each day will be saved
            kCAGE_PATH = configDict.get('Data Path')
            # rollover time, 0 to start the file for each day at 12 midnight. Could set to 7 to synch files to mouse day/night cycle
            kDAYSTARTHOUR = configDict.get('Day Start Hour')
            # size of array used for threaded reading from load cell amplifier
            kTHREADARRAYSIZE = configDict.get('Thread Array Size')
            # cuttoff weight where we stop the thread from reading when a mouse steps away
            kMINWEIGHT = configDict.get('Minimum Weight')
            # GPIO pin numbers and scaling for HX711, adjust as required for individual setup
            kDATA_PIN = configDict.get('GPIO Data Pin')
            kCLOCK_PIN = configDict.get('GPIO Clock Pin')
            kGRAMS_PER_UNIT = configDict.get('Grams Per Unit')
            # RFID Reader. Note that code as written only works with ID tag readers not RDM readers because of reliance on Tag-In-Range Pin
            kSERIAL_PORT = configDict.get('Serial Port')
            kTIR_PIN = configDict.get('GPIO Tag In Range Pin')
            #whether data is saved locally 1 or, not yet supported, sent to a server 2, or both, 3
            kSAVE_DATA = configDict.get('Data Save Options')
            # a dictionary of ID Tags and cutoff weights, as when monitoring animal weights over time
            kHAS_CUTOFFS = configDict.get('Has Cutoffs')
            if kHAS_CUTOFFS:
                kCUT_OFF_DICT = configDict.get('Cutoff Dict')
            else:
                kCUT_OFF_DICT = None
            # can call get day weights code and email weights, needs extra options
            kEMAIL_WEIGHTS = configDict.get('Email Weights')
            if kEMAIL_WEIGHTS:
                kEMAIL_DICT = configDict.get('Email Dict')
            else:
                kEMAIL_DICT = None
    except (TypeError, IOError, ValueError) as e:
        #we will make a file if we didn't find it, or if it was incomplete
        print(
            'Unable to load configuration data from AMW_config.jsn, let\'s make a new AMW_config.jsn.\n'
        )
        jsonDict = {}
        kCAGE_NAME = input(
            'Enter the cage name, used to distinguish data from different cages:'
        )
        kCAGE_PATH = input(
            'Enter the path where data from each day will be saved:')
        kDAYSTARTHOUR = int(
            input(
                'Enter the rollover hour, in 24 hour format, when a new data file is started:'
            ))
        kTHREADARRAYSIZE = int(
            input(
                'Enter size of array used for threaded reading from Load Cell:'
            ))
        kMINWEIGHT = float(
            input(
                'Enter cutoff weight where we stop the thread from reading:'))
        kDATA_PIN = int(
            input(
                'Enter number of GPIO pin connected to data pin on load cell:')
        )
        kCLOCK_PIN = int(
            input(
                'Enter number of GPIO pin connected to clock pin on load cell:'
            ))
        kGRAMS_PER_UNIT = float(
            input(
                'Enter the scaling of the load cell, in grams per A/D unit:'))
        kSERIAL_PORT = input(
            'Enter the name of serial port used for tag reader,e.g. serial0 or ttyAMA0:'
        )
        kTIR_PIN = int(
            input(
                'Enter number of the GPIO pin connected to the Tag-In-Range pin on the RFID reader:'
            ))
        kSAVE_DATA = int(
            input(
                'To save data locally, enter 1; to send data to a server, not yet supported, enter 2:'
            ))
        tempInput = input('Track weights against existing cutoffs(Y or N):')
        kHAS_CUTOFFS = bool(tempInput[0] == 'y' or tempInput[0] == 'Y')
        if kHAS_CUTOFFS:
            kCUT_OFF_DICT = {}
            while True:
                tempInput = input(
                    'Enter a Tag ID and cuttoff weight, separated by a comma, or return to end entry:'
                )
                if tempInput == "":
                    break
                entryList = tempInput.split(',')
                try:
                    kCUT_OFF_DICT.update({entryList[0]: float(entryList[1])})
                except Exception as e:
                    print('bad data entered', str(e))
        else:
            kCUT_OFF_DICT = None
        jsonDict.update({
            'Has Cutoffs': kHAS_CUTOFFS,
            'Cutoff Dict': kCUT_OFF_DICT
        })
        tempInput = input('Email weights every day ? (Y or N):')
        kEMAIL_WEIGHTS = bool(tempInput[0] == 'y' or tempInput[0] == 'Y')
        if kEMAIL_WEIGHTS:
            kEMAIL_DICT = {}
            kFROMADDRESS = input(
                'Enter the account used to send the email with  weight data:')
            kPASSWORD = input(
                'Enter the password for the email account used to send the mail:'
            )
            kSERVER = input(
                'Enter the name of the email server and port number, e.g., smtp.gmail.com:87, with separating colon:'
            )
            kRECIPIENTS = tuple(
                input(
                    'Enter comma-separated list of email addresses to get the daily weight email:'
                ).split(','))
            kEMAIL_DICT.update({
                'Email From Address': kFROMADDRESS,
                'Email Recipients': kRECIPIENTS
            })
            kEMAIL_DICT.update({
                'Email Password': kPASSWORD,
                'Email Server': kSERVER
            })
        else:
            kEMAIL_DICT = None
        jsonDict.update({
            'Email Weights': kEMAIL_WEIGHTS,
            'Email Dict': kEMAIL_DICT
        })
        # add info to a dictionay we will write to file
        jsonDict.update({
            'Cage Name': kCAGE_NAME,
            'Data Path': kCAGE_PATH,
            'Day Start Hour': kDAYSTARTHOUR,
            'Thread Array Size': kTHREADARRAYSIZE
        })
        jsonDict.update({
            'Minimum Weight': kMINWEIGHT,
            'GPIO Data Pin': kDATA_PIN,
            'GPIO Clock Pin': kCLOCK_PIN
        })
        jsonDict.update({
            'GPIO Tag In Range Pin': kTIR_PIN,
            'Grams Per Unit': kGRAMS_PER_UNIT,
            'Serial Port': kSERIAL_PORT
        })
        jsonDict.update({
            'Data Save Options': kSAVE_DATA,
            'Email Weights': kEMAIL_WEIGHTS
        })
        with open('AMW_config.jsn', 'w') as fp:
            fp.write(
                json.dumps(jsonDict, sort_keys=True, separators=('\r\n', ':')))
    """
    Initialize the scale from variables listed above and do an initial taring
    of the scale with 10 reads. Because pins are only accessed from C++, do not call
    Python GPIO.setup for the dataPin and the clockPin
    """
    scale = Scale(kDATA_PIN, kCLOCK_PIN, kGRAMS_PER_UNIT, kTHREADARRAYSIZE)
    scale.weighOnce()
    scale.tare(10, True)
    """
    Setup tag reader and GPIO for TIR pin, with tagReaderCallback installed as
    an event callback when pin changes either from low-to-high, or from high-to-low.
    """
    tagReader = TagReader('/dev/' + kSERIAL_PORT,
                          doChecksum=False,
                          timeOutSecs=0.05,
                          kind='ID')
    tagReader.installCallBack(kTIR_PIN)
    """
    A new binary data file is opened for each day, with a name containing the 
    current date, so open a file to start with
    """
    now = datetime.fromtimestamp(int(time()))
    startDay = datetime(now.year, now.month, now.day, kDAYSTARTHOUR, 0, 0)
    if startDay > now:  # it's still "yesterday" according to kDAYSTARTHOUR definition of when a day starts
        startDay = startDay - timedelta(hours=24)
    startSecs = startDay.timestamp(
    )  # used to report time of an entry through the weighing tube
    nextDay = startDay + timedelta(hours=24)
    filename = kCAGE_PATH + kCAGE_NAME + '_' + str(
        startDay.year) + '_' + '{:02}'.format(
            startDay.month) + '_' + '{:02}'.format(startDay.day)
    if kSAVE_DATA & kSAVE_DATA_LOCAL:
        print('opening file name = ' + filename)
        outFile = open(filename, 'ab')
        from OneDayWeights import get_day_weights
    """
    Weight data is written to the file as grams, in 32 bit floating point format. Each run of data is
    prefaced by metadata from a 32 bit floating point metaData array of size 2. The first point contains
    the last 6 digits of the RFID code, as a negative value to make it easy for analysis code to find the
    start of each run. The second point contains the time in seconds since the start of the day.
    Both data items have been selected to fit into a 32 bit float.
    """
    metaData = array('f', [0, 0])

    while True:
        try:
            """
            Loop with a brief sleep, waiting for a tag to be read
            or a new day to start, in which case a new data file is made
            """
            while RFIDTagReader.globalTag == 0:
                if datetime.fromtimestamp(int(time())) > nextDay:
                    if kSAVE_DATA & kSAVE_DATA_LOCAL:
                        outFile.close()
                        print('save data date =', startDay.year,
                              startDay.month, startDay.day)
                        try:
                            get_day_weights(kCAGE_PATH, kCAGE_NAME,
                                            startDay.year, startDay.month,
                                            startDay.day, kCAGE_PATH, False,
                                            kEMAIL_DICT, kCUT_OFF_DICT)
                        except Exception as e:
                            print('Error getting weights for today:' + str(e))
                    startDay = nextDay
                    nextDay = startDay + timedelta(hours=24)
                    startSecs = startDay.timestamp()
                    filename = kCAGE_PATH + kCAGE_NAME + '_' + str(
                        startDay.year) + '_' + '{:02}'.format(
                            startDay.month) + '_' + '{:02}'.format(
                                startDay.day)
                    if kSAVE_DATA & kSAVE_DATA_LOCAL:
                        outFile = open(filename, 'ab')
                        print('opening file name = ' + filename)
                else:
                    sleep(kTIMEOUTSECS)
            """
            A Tag has been read. Fill the metaData array and tell the C++ thread to start
            recording weights
            """
            thisTag = RFIDTagReader.globalTag
            startTime = time()
            print('mouse = ', thisTag)
            #scale.turnOn()
            metaData[0] = -(thisTag % 1000000)
            metaData[1] = startTime - startSecs
            scale.threadStart(scale.arraySize)
            nReads = scale.threadCheck()
            lastRead = 0
            """
            Keep reading weights into the array until a new mouse is read by 
            the RFID reader, or the last read weight drops below 2 grams, or
            the array is full, then stop the thread print the metaData array
            and the read weights from the thread array to the file
            """
            while ((RFIDTagReader.globalTag == thisTag or
                    (RFIDTagReader.globalTag == 0
                     and scale.threadArray[nReads - 1] > kMINWEIGHT))
                   and nReads < scale.arraySize):
                if nReads > lastRead:
                    print(nReads, scale.threadArray[nReads - 1])
                    lastRead = nReads
                sleep(0.05)
                nReads = scale.threadCheck()
            nReads = scale.threadStop()
            if kSAVE_DATA & kSAVE_DATA_LOCAL:
                metaData.tofile(outFile)
                scale.threadArray[0:nReads - 1].tofile(outFile)
            if kSAVE_DATA & kSAVE_DATA_REMOTE:
                # modify to send : Time:UNIX time stamp, RFID:FULL RFID Tag, CageID: id, array: weight array
                response = requests.post(
                    kSERVER_URL,
                    data={
                        'tag':
                        thisTag,
                        'cagename':
                        kCAGE_NAME,
                        'datetime':
                        int(startTime),
                        'array':
                        str((metaData +
                             scale.threadArray[0:nReads - 1]).tobytes(),
                            'latin_1')
                    }).text
                if response != '\nSuccess\n':
                    print(reponse)
            #scale.turnOff()
        except KeyboardInterrupt:
            #scale.turnOn()
            event = scale.scaleRunner('10:\tQuit AutoMouseWeight program\n')
            if event == 10:
                if kSAVE_DATA & kSAVE_DATA_LOCAL:
                    outFile.close()
                GPIO.cleanup()
                return
        except Exception as error:
            print("Closing file...")
            outFile.close()
            GPIO.cleanup()
            raise error