Remove the screw from the front of the miniature compressed air regulator (placing the inlet down and the regulator screw at the right) and screw in the pressure gauge. Place the straight reducer, 3/8 x 1/8 NPT male at the inlet of the regulator and a push-to-connect tube fitting for 3/8" tube OD x 1/8 NPT male at the oulet of the regulator. Then screw the assembly into the second outlet of the air supply manifold.
TIP
Make sure to place this assembly before screwing the air supply manifold to the T-slotted frame.
Have made the air puffs control manifold in a machine shop in aluminum. Insert at the right end (placing the small 10-32 holes facing down) a plug with hex drive, 1/8 NPTF, at the bottom a pair of 1/16" tube ID x 10-32 thread male pipe barbed tube fitting, at the left a push-to-connect tube fitting for 3/8" tube OD x 1/8 NPT male, and finally a pair of subminiature solenoid valves for air from Gems sensors and controls (EG2020-06MM-B-G1-204).
Place a couple of 10-24 square nuts at the back of the manifold to DIN rail clip adapter, if needed apply some pressure to it for them to enter completely into the hole (you could use a hammer for this), then use a couple of 6-32 x 1" long screws to screw the manifold to the adapter. After that, use a couple of number 6 size, 1/4" long thread-forming screws to attach a 75 mm DIN rail mounting clip to the adapter. Place the entire assembly into the bottom DIN rail, somewhere between the hole for the tubing and the air supply manifold.
Connect the manifold outputs to the tube fitting at the back of the spout holder inside the rig using tygon PVC tubing for food, beverage, and dairy 1/16" ID, 1/8" OD. If you installed a hose and cable carrier, make sure to pass them through it.
Connect the valves to the proper outputs of the solenoid valve driver in the control module.
The air supply module consist of a manifold that is connected to the main lab air supply, a air flow control valve that is connected into the manifold and its output goes to a airflowmeter, which provides a constant flow of air trough an adapter placed in the panel of the cabinet to the cup to make the styrofoam ball float. The manifold also provide air to other modules, such as the air puffs, and has the flexibility to add another manifold if other modules require an air supply.
If the air puffs are going to be used, we recommend to add the pressure gauge during this step, otherwise place a plug instead of the gauge on the second outlet of the manifold. First, install a 1/2 NPT plug and a Push-to-Connect tube fitting for air straight sdapter, for 3/8" Tube OD x 1/2 NPT Male in the manifold. Then install the pressure gauge or another plug if air puffs are not going to be installed. Finally, install a 3/8 NPT male inlet x 3/8" push-to-connect female outlet air flow control valve into the first outlet of the manifold.
Once assembled, place the manifold in the lower T-slotted profile at the left side of the cabinet (the same as the DIN rails). First, use a T-slotted framing drop-in nut with spring tab, 5/16"-18 thread size and insert a pair of them on the profile. Then, place the pair of 10-24 square nuts at the back of the 3D printed frame to manifold adapter and using 5/16"-18 x 1/2" long low-profile screws screw it to the frame.
Attach the manifold to the adapter using a pair of 10-24 x 1-7/8" long screws.
To assemble the air flowmeter first attach at the top outlet a push-to-connect tube fitting for air
+90 degree swivel elbow, for 1/4" tube OD x 1/4 NPT male, and at the bottom inlet a push-to-connect tube fitting for air 90 degree swivel elbow, for 3/8" tube OD x 1/4 NPT male. Then, use a couple of 10-32 x 5/16" long screws to attach the air flowmeter to DIN mounting clip adapter to the air flowmeter. Finally, use a number 8 x 5/16" long rounded head thread-forming screws to attach a spring clip DIN rail mounting adapter.
Attach the airflowmeter to the din rail by inserting the bottom part only and push it from the bottom up and forward at the same time.
Then, insert a firm polyurethane tubing for air 1/4" ID, 3/8" OD from one end into the inlet of the air flowmeter until it click and the tube can't come out of the connector, then measure the distance to the air flow control valve outler connector (bottom of the connector, as seen in the pictures below), cut the hose and connect the hose.
To install the air flow adapter, first screw the push-to-connect tube fitting through-wall adapter, 1/4" tube OD x 1/4 NPT female in the cabinet hole. Then, screw the 1/4 NPT male air nozzle from inside the cabinet in the adapter, and over it insert the air supply to ball adapter to panel gasket and the 3D printed sose to panel adapter, use 4 1/4"-20 x 3/4" long screws and 4 1/4"-20 locknuts to attach it to the panel. Follow the same procedure to connect a 1/8" ID, 1/4" OD firm polyurethane tubing for air from the flowmeter outlet to the cabinet inlet.
Use a very flexible PVC duct hose, 1 1/4" ID, 1 1/2" OD, and attach one screw-on fitting, PVC, for 1 1/4" ID to one end and connect it to the adapter in the cabinet; pull the stage all the way out and measure the length of the hose, cut it and attach a fitting to the other end, finally connect it to the cup in the stage.
The cabinet is the box made out of T-slotted frames and panels in which all the components of the training rig are going to be held, and works as an sound insulated space in which the mice wild be performing the tasks. All the control and other modules components are going to be placed on one of the sides of the cabinet, and the projector will be placed at the back of it.
We use 75% sound absorbing sheets with adhesive backing that are glued at the internal part of all the panels of the cabinet, which helps to isolate the sound from the lab environment, nevertheless the rooms should be silent and darks when the animals are training.
Cut cardboard molds to cut the foams for the panels according to the following table.
Panel
Size in inches
Front doors
19" x 9 1/2"
Back doors
9 3/8" x 9 3/8
Sides
19" x 24 3/8"
Top
24 1/2" x 22 3/8"
Bottom back
7 11/16" x 22 3/8"
Place the sound absorbing sheet with the foam looking up, then put the mold on top of it and use a black marker to draw through the edges.
Then place a pair of profiles on top to keep the sheet flat, use a long ruler (or any flat and thin surface, I used a DIN rail to do this) to place it along the marked edges and apply a good ammount of pressure; with a sharp exacto knife cut the sheets following the marker square, we required to pass the knife two times to cut all the way through.
TIP
Constantly change the blades of the exacto knife, a good indicator is if the blade doesn't flow smoothly and sometimes get stuck.
We use 1.5" x 1.5" T-slotted profile to build the frame of the cabinet and 1/4" black harcell ABS (smooth side up) to build the panels. Our supplier the Knotts Company, which is an authorized supplier of 80/20, and sent them the drawings for a quote. Another option is to buy the pieces described in the drawing from other supplier or suppliers, but it will require to do adjustments, and a lot of holes. Assemble the cabinet following the steps below.
We start building the cabinet from the bottom up. Slide a pair of bottom plate holders (8020 - 2425) into the 24.5 inches long profile. Make sure the top part of the holder is at the same height as the top part of the profile, as shown in the picture below. Repeat the process for another 24.5" long profile.
Insert a standard end fastener to both ends of the 24.5" long profile with the bottom plate holders and to a pair of 22.5" long profiles. First insert the fastener into one of the slots and loosely screw it, repeat the process with the other end making sure the direction of the fastener is the same. Make this for both ends of the 4 profiles.
Arrange the profiles in a square, making sure that the profiles with the plate holders are facing each other to the left and right, and in the correct position (top part of the holder must be at the same height as the top part of the profile); and the 22.5" long profiles are fecing each other at the back and front. Use the 22.05" long profile with holes at 1.5" from the ends to join the front part, and use the 22.05" long profile with holes at 1.5" from both ends and a hole at 11.675" from the top down to join the back part of the rig. Introduce the profiles from the top down and tight screw trough the holes.
Place the aluminum bottom plate on top of the frames, slide the bottom plate holders so that they match the plate holes. If the holes don't match in the lateral position, you can unscrew the holders just enough for them to reach the holes. Use 5/16-18 x 0.625" long screws to tight screw the bottom plate to the holders.
TIP
If working on an elevated table, you could push into the air the structure just enough to have visibility on the bottom and match the holders to the holes, then turn around the structure and repeat the process.
TIP
Use a permanent marker to draw two straight lines on top of the botomm plate using the groves at the sides as shown below, this will be extremely useful for the projection calibration.
Cut 8.2 inches to the top base of the drawer slider, then use 1/4"-20 x 1/2" long low-profile screws to install the 26" long steel base-mount drawer sliders. Screw with M4x0.7 mm, 8 mm long screws the latch holder to the latch holder adapter, then use 1/4"-20 x 11/16" flat head screws to attach the latch holder with the adapter to the bottom plate.
Install the structure to hold the projector at the back of the rig. Set the height of the structure at 3 15/16" from a flat surfate to the top of the profile.
TIP
You can install the projector bottom plate before measuring to make it easier to set the height.
To install the back panel of the rig, first make the hole for the projection to go trough. Make a hole at 2 3/4" from the top of the panel and at the middle of the panel, or 11 5/8" from the side. We recommend to do a small hole first and then use a 1" drill bit or hole saw.
Install the soundproof foam, then cut the hole from the foam.
TIP
To install the soundproof foam first clean the smooth surface of the panel with a solution of 70% ethanol and let dry. Then remove just a small portion of the protective layer of the adhesive part of the sound absorbing sheet as shown below.
Center the sheet in the panel and paste the uncovered portion by applying pressure along the sheet from the top down.
Remove another small-medium portion of the protective layer and apply pressure onto the panel from the top down, repeat the process until the whole sound absorbing sheet is placed into the panel.
Finally, slide down the panel into the T-slotted profiles at the back of the rig, slidw down a 22.5" profile with fasteners already screwed until it reaches the panel and use the holes at the profiles sides to tighten the screws.
For the left panel, first cut the square in which the air supply adapter is going to be attached from the sound absorbing sheet, then glue the sheet to the panel and afterwards cut the hole for the cable and hoses (just like we did in the last step). Install both lateral panels first, then arrange two 24.5" long profile and two 22.5" long profile with fasteners loosely screwed at the four sides of the top panel and place them on top of the structure from the top down. Tight the screws when the structure is in place.
TIP
Sometimes when placing the top panel and profiles they don't fit in properly, if you are having troubles fitting them, loose the screws from the bottom of the four corners and the screws from the middle in the back of the frame so you can push down the top structure. Once the top structure is on place, tighten all the screws.
Assemble the doors by joining a U shape structure first. For the front doors screw at the bottom a 9.65" long profile and a pair of 22.05" long profile, for the back doors form the U shape with 9.65" long profiles. Then slide down the panels with the sound absorbing sheet already in place. After that, screw at the top a 9.65" long profile for both front and back doors. Finally, insert the joining strip along the out edges of the doors.
Insert the joining strip to all of the panels in the cabinet.
Install the DIN rails by screwing 4 DIN rail mounting adapters into the profile using a T-slotted framing drop-in nut, 1/4"-20 thread size. We buy a 2 m long steel DIN rail and cut two pieces at 27.5". Then attach the pair of DIN rail to the mounting adapters and repeat the process for the other rail.
TIP
Before placing the top DIN rail mounting adapter at the back of the rig, slide down the middle door hinge. Alternatively, you could replace the standard framing nut with a 1/4"-20 T-slotted framing drop-in nut to install that door hinge.
Install the doors by screwing the lift-off hinges, you will need to place a couple of them for each door at the top and at the bottom. Finally install the lock using a 1/4"-20 screw and 1/4"-20 T-slotted framing drop-in nut.
The control module consist on a 24V power source, a couple of distribution blocks, which make it easier to connect any other stuff that works on 24V; a custom made solenoid valve driver, an USB NiDAQ card from National Instruments and an Arduino due that is inside a 3D printed housing with a DIN rail clip attached. Each of these parts will be explained in detail below with instructions for assembly.
We designed a simple solenoid valve driver circuit using a MOSFET, the gate is driven by a digital input that will be supplied by the NIDAQ card, which open and closes the circuit from the solenoid valve to a 24V power supply. We added a diode to protect the circuit from discharge from the solenoid valve. To assembly the solenoid valve driver follow the next steps.
Have the PCB made (we use pcbway since they can make and ship the stencil, you can found our project here(opens new window)) and make sure to order a stencil. We use a manual printer for PCB stencil to spread the soldering paste across the PCB pads evenly. First, place the PCB on the surface using high temperature tape and place the stencil on top of it. Make sure to match the solder pads to the holes of the stencil.
Use solder paste and a flexible wipe down knife and spread evenly the solder paste into the pads. Then lift and remove the stencil.
Place each component into place, we place the resistances (R1, R3, R5, R7, and R9 resistor values are 10K Ohm and R2, R4, R6, R8 and R10 resistor values are 1K Ohm) first, then place the MOSFET and finally the diodes, make sure that the diodes are placed correctly (the band should match the ] symbol on the PCB). The picture below show the correct position of the components.
TIP
Each time you place a component in the pad make sure to slightly press it against the solder paste with the same tweezers that you use.
Use a heat gun (we set the temperature at 1000F) at the lowest intensity allowed (to avoid components flying around) and move it around on top of the components until the solder melt and the components get attached in place.
Remove the high temperature tape and solder the pluggable terminal blocks, place the fillers and slide down the PCB into the case, then close the case.
Place the labels (make sure they are placed correctly) and place the driver on the DIN rail.
Place the power supply and the distribution blocks on the DIN rails, connect the power supply to the distribution block input accordigly. The TRACO Power TBLC 50-124 is a 50W power supply, which is more than enough to power both the reward module solenoid valve (7 Watts) and the two air puffs solenoid valves (0.65 Watts each one), and have plenty of power left (~40W) for other modules if required. One power supply could be use for a stack of 2 or 3 rigs if desired.
TIP
Use a standard PC power cable and cut the portion of the connector that goes to the PC, cut the ground cable and connect the neutral cable to the negative input of the power supply and the hot cable to the positive input.
Open the NIDAQ case and make a hole at the middle of the back case. Screw the DIN rail mounting clip to it, then close the case and place the top screws only.
Connect everything!
Start by connecting the positive output of the power supply from one of the pins of the red distribution blocks to the V IN input of the solenoid valve driver, then the ground from one of the pins of the black distribution block to the GND pin of the solenoid valve driver.
Then connect the one of the GND pins of the solenoid valve driver to the the digital ground pin of the NIDAQ.
Connect the solenoid valve driver inputs to the NIDAQ outputs as follows: P0.0 from NIDAQ to V IN 1, P0.1 to V IN 2 and P0.2 to V IN 3.
Finally connect the solenoid valve driver outputs to the solenoid valve drivers. Since the solenoid valves doesn't have polarity, you should use the V OUT (+) as common in the valves, you can use one or multiple pins of the solenoid valve driver. Then connect the V OUT 1 (-) pin to the reward solenoid valve, the V OUT 2 (-) pin to the left solenoid valve and the V OUT 3 (-) to the right solenoid valve.
TIP
The solenoid valve driver has more outputs for you to connect and control with the NIDAQ digital outputs any other piece of hardware (like a 24 V IR light source for example), just make sure to wire the ports to the input and output of the driver and match them in the Rig Parameters portion of ViRMEN.
Have printed the arduino case and screw the arduino. Insert the connector in place and crimp the cables. Make sure to follow the color code and connect the cables to the arduino.
Cover the case and install the din rail mounting clip. Install the arduino module in the top DIN rail.
Make the cable to connect the arduino to the 3D printer cup. Unscrew the outer portion of the connector and insert it into the cable (you need to do this before connecting the cables, otherwise you will not be able to insert the cover and will have to do everything again). Unscrew all the conectors and insert the cable following the color code in the image below, screw them and place the connector cover.
TIP
Place one connector first and connect it to the arduino box placed in the top DIN rail at the outer portion of the rig, then measure the lenght of the cable by inserting into the rig and into the cable carrier. Cut the cable and place the other connector, finally connect it to the 3D printed cup.
Use double side tape to glue the USB Hub to the cabinet at the top left portion above the DIN rail and connect everything that must be connected there (if using USB or USB powered speakers, the NIDAQ). Use a USB C extension to connect the hub to the computer.
Place the speaker inside the cabinet and connect to Hub - Make an upper hole on the cabinet for other cables as shown in the picture above. You can use a USB speakers or a desktop speakers and place them on top of the screen plate and connect it to the hub and, if necessary, to the computer audio input.
This website is a central repository for the documentation regarding the building of mini virtual reality training rigs as part of BRAIN CoGS at Princeton Neuroscience Institute.
If you need any other file, any other format, need help or just wanted to reach out don't hesitate to contact Juan Luna or any other memeber of the BRAIN CoGS team.
Begin with the assembly of the bottom part of the cabinet (steps 1-6 of cabinet assembly). In parallel, you can start with the construction of the screen.
Follow the intructions to assemble the stage and install it in the cabinet.
Screw the mirror and the pillars, but not the top plates that will hold the screen.
Install the air supply hose adapter on the side panel and make the holes on the panel if necessary, install the side panels on the cabinet (step 8 of cabinet assembly).
Make the hole on the back panel for the projector if necessary, install the back panel and slide down the frame (step 7 of cabinet assembly) and insert the joining strip along the out edges of the panels.
Place the adapters on top of the pillars and install the screen (step 2 of screen assembly).
Assemble the top portion of the cabinet (step 8 of cabinet assembly).
The lick detection module is based on a simple transistor design (Slotnick 2009), we modified the design to allow the detection of 2 lick spouts in the same module. Additionally, we added a DC-DC converter to isolate the circuit from the power source and added a 5V voltage regulator after the relays to have a TTL signal at the output of both circuits.
The module was designed this way to enable a specific task that require the use of two spouts, but it can also be used in a one spout setting (e.g count the number of licks during a task). Below is an example of a setup using two lick spouts during a decision making task developed by one member of the BRAIN CoGS team.
The schematics of the PCB can be found here and the drawings with the specs of the part can be found here, below is an image that can be used as a reference. The step by step instructions to solder the components on the solenoid valve driver from the control module can be used as well for this module, making sure to use the appropiate components and placing them as labeled in the PCB.
After assemblying the module, place the labels as shown in the picture below.
The description of each pin of the lick detector module can be found in the table below.
PIN
Description
1. GROUND
Input - ground
2. 24V
Input - 24V DC
3. OUT LEFT
Output - TTL output pin for the left spout
4. OUT RIGHT
Output - TTL output pin for the right spout
5. RIGHT SPOUT
Input - Connect the right spout to this pin
6. LEFT SPOUT
Input - Connect the left spout to this pin
7. HEADPLATE
Input - Connect the headplate to this pin
8. COMMON
Input - Connect the ground from the NiDAQ (or any acquisition device) to this pin
# Soldering a cable to the feeding spout and headplate
Use sandpaper to remove the outer layer of the stainless steel spout at one of the sides if the luer lock connector (as far as possible from the connector tip), do the same with the headplate (wherever you want to place the cable, we recommend to use the arm without the tapped hole to fit a heat shrinkable tube).
Clean the sanded surface with isopropyl alcohol and let it dry. In the meantime, prepare the coaxial cable (we recommend a 26(opens new window) or 28(opens new window) AWG coaxial cable like these ones ) by removing the jacket and the shield, then expose the conductor by removing a portion of the insulation material. Repeat the process on the other end of the cable.
Drop a small drop of flux in the sanded surface and place the tip of the solder iron over the flux - the tip might stick to the stainless steel, that's normal - continue heating the surface and use soldering wire (we found lead works best) to solder the coaxial cable to the spout and headplate.
Use heat shrinkable tube to cover the soldering spot.
The positioning system is designed to fix the subject within the projection and correct posture boundaries, but also to have high repeatibility, allowing to have specific coordinates for different subjects trained on the same rig. There are two different positioning systems currently used at our facilities, an automated positioning system that ensures repeatibility and personalized positioning for each subject across training rigs and training sessions; and the manual positioning system, which consist of low cost thorlabs components and a positioning tool developed in house.
The animal position in the ball should prioritize the correct posture for running whithin boundaries of the projection calibration. The projection is calibrated assuming the animal eyes are going to be positioned 0.256 inches behind the center of the ball on the X axis, 1 inch over the top of the center of the ball on the Y axis and centered along the Z axis. A 0.5 inches range error is acceptable.
The automated positioning system consist of a set of motorized platforms set in a XYZ configuration. We use the small factor 25mm linear stage (LSA25) from Zaber technologies. A 3D printed arm in Nylon 12 with glass beads - PA12 (MJF) from shapeways - from the top motor (height control) was designed, at the end of the arm we designed a stainless steel headplate holder. The whole assembly is attached to the stage breadboard using a custom adapter.
The headplate holder has to be designed to fit the head plate to be used in order to minimize the variability in the pitch, roll and yaw of the head plate and the animal position. This way, the motors can have better repeatability by adjusting the antero-posterior, dorso-ventral and medio-lateral position of the animal.
The positioning system is designed to be fixed at the expected position of the headplate in the antero-posterior (AP) and mediolateral (ML) position as shown in the picture below when the motorized stages are set at midrange.
To assemble the positioning system, first attach the custom made breadboard adapter to the top stage breadboard at the position shown below using 82 Degree Countersink Angle, 1/4"-20 Thread Size, 1/2" Long Drive Flat Head screws. Then attach the first motorized stage at correct position as shown in the image below using Low-Profile, M3 x 0.5 mm Thread, 5 mm Long screws.
Attach the second (AP position) motorized linear stage to the first one using the same kind of screws at the position shown in the image below. Then, attach the Z adapter from zaber technologies (AB106) to the stage using M2 x 0.4 mm Thread, 5 mm Long Low profile socket head screws at the position as shown below.
Attach the third (DV position) motorized linear stage to the AB106 Zaber adapter using Low-Profile, M3 x 0.5 mm Thread, 5 mm Long screws at the position indicated in the image below. Finally, screw the 3D printed arm to the DV position motorized linear stage using M3 x 0.5 mm Thread, 30 mm Long Hex Drive Flat Head screws as shown below.
One of the most importants variables for the mice on the VR tasks are the DV positioning (height), the mice needs to be comfortable enough to properly run on top of the styrofoam ball. The automated positioning system allows to set customizable heights for each subject. The whole coordinated of the subjects can also be stored on a DB and retrieved before training, which improves the repeatibility and decreases the time needed to set the subjects.
The manual positioning system consist of a set of Thorlabs and custom made parts. To assemble it, first attach a 4" post (either PSR-4.0 from siskiyou or RS4 from Throlabs) at the position of the top stage breadboard shown in the image below. Then, attach a 3" post (RS3 from Thorlabs) on top of the previous installed posts.
Screw down a RB2 part from Thorlabs down the right post (looking at the stage from behind), then attach a TR1 using a 4-40 screw to the RB2 clamp. Then slide down and tight a RA90 Thorlabs part to the TR1 post as indicated in the image below.
Finally, screw the custom made stainless steel head plate adapter to the a TR2 post from Thorlans, then attach it to the RA90 and tight it down as shown below.
A positioning tool was designed taking as reference the 2 pillars that are part of the stage of the mini VR rig. The tool consist on a 3D printed part that hold a glued transparency, lines are made with a marker for the Y position of the animal (1st and 2nd dents of the tool) and the Z line (A and B arrows on the tool). The user can easily use this tool to adjust the animal in the right X and Y position, and the height must be fine tuned to allow the animal to run comfortable.
The tool also has space to add a magnet fixed with epoxy resin on the pillars holes to be steady when placed on top of the pillars.
WARNING
The pillars must be placed in the correct holes of the breadboard as shown in the figure, otherwise the distance from the center of the ball could be wrong.
The projection module consist on the screen assembly inside the cabinet, a projector is positioned at the back of the exterior part of the cabinet and it throws the image towards an spherical mirror attached to the cabinet positioned in the bottom part of the screen. The spherical mirror reflects the image onto the dome screen.
The spherical mirror is custom made from Thorlabs with the item number LA1740-P01-SP, be sure to contact them for a quote before polaceing the order and ask for the price breaks if you're planning to build more than 5 training rigs (it could go down up to 50% from 5 to 10 pieces).
We place the spherical mirror on an aluminum custom made base that is sent to a machine shop. The instruction for the assembly are descripted below.
Start by assembling the mirror holder, which is composed of the custom made holder, one 1" diameter 2" long post (RS1), one 1" diameter 1.5" long post (RS2) and a BA2 post base from Thorlabs. Use a screwdriver thin enough to pass through the hole at the center of the post and apply enough force to properly screw each piece onto each other.
To align the pieces, screw the base but not all the way. Then, place the pieces on a flat surface and make sure that both the mirror base and the BA2 post base lie completely flat on the surface, apply some force with one of your hands to make sure they stay that way and with the other hand tight screw the base.
Use a file to scratch the surface that will hold the mirror, then clean it with ethanol. Use estructural epoxy, follow the instruction on your specific type, and apply to the aluminum base. Make sure to use a nitrile gloves to carefully place the mirror on top of the base and apply some pressure to let it sit flat on the base surface, wait and clean apoxy leakage if any. Let the epoxy dry for 24 hrs.
TIP
Apply just a sufficient ammount of epoxy in the middle of the aluminum base, don't spread it all over since it could leak once you place the mirror and apply pressure on it.
Screw the mirror and the base to the cabinet bottom plate using 1/4-20 screws, make sure to place the base as far as it can get from the stage (push it all the ways toward the projector, then screw it), as shown below.
The projector is installed at the back of the cabinet, at the top of a T-slotted frame structure. To assembly, use a couple of T-slot fasteners and place them on the frame at the back of the cabinet. Then, loosely screw the projector aluminum plate, measure 1 and 1/4 inches from the edge of the plate to the intersection of the frames as shown in the pictures below and tighten the screws. Finally, screw the projector to the aluminum plate.
The whole process of screen building can take up to 5 days. We describe the whole process in steps, adding which steps we make in a day and the time it took for us to follow the steps. We recommend to do it this way to allow the materials to properly dry. You could use the time it takes to dry to parallelize the work and assembly other modules in the meantime.
The first step for building the projection module consist on the fabrication of the dome screen. A styrofoam ball of 18" outer diameter and 16" inner diameter is being fabricated by an external provider. For ease of transportation the screens were sent as half spheres.
If the balls are shipped in halfs, first mark the equator in each of the half spheres. Use a thread to measure the outer diameter of the screen (should be around 18") and place a mark at the middle (or around 9"), place the thread at the bottom of the half sphere and mark at the sphere the joint of the thread and the middle (9") mark. We use a laser level to project a straight line through both marks and draw a line with a sharpie.
Use 3M Foam Fast 74 CA spray adhesive to glue both half spheres. Spray from 3 to 5 inches away both surfaces and wait for 1 minute, then attach both half spheres making sure to match the equator drawed lines, apply pressure on the union and leave it to dry and harden for at least 15 min.
Use lightweight joint compound to fill the line and the holes the adhesive might have caused, use a hand applicator to spread even on the surface trying to keep it as as smooth as possible. Let the joint compound dry from 30 min to 1 hour.
Place the aluminum plate in a flat surface making sure is hanging with enough space to fit the screen. Use a sharpie to mark a straigth line by joining the marks in the aluminum plate (placed at the middle of the circle) as seen in the pictures. Place the screen in the plate, making sure to align the equator with the plate and the meridian (the mark where the half spheres where joined) with the plate marked line.
TIP
Sometimes the diameter of the balls is different from the plate, you can use some paper or carboard and tape it to fill the space between the screen and the plate for it to hang properly.
Glue about 5 inches of the sides and the back of the ball with an electric glue gun and wit for it to harden. Once cold, remove taped paper/cardboard and turn the plate around and glue the whole screen to the aluminum plate, wait for it to harden; turn once more time the plate and finish gluing the top part of the screen to the plate.
Place the screen with the plate on a flat surface. We use a couple 14" (1 inch diameter) pillars, other stuff could potentially be used just making sure the ball is freely hanguing from the plate and have enough space (at least ~6 inches) from the bottom of the screen to the flat surface. We place the pillars diagonally for stability.
Mark a line below 4.75" from the equator of the screen. We use a set of Thorlabs BA2 and 1/2" post (with a post holder) with a 90 degrees 1/2" post holder to insert a sharpie marker as a tool to mark the line. We set the height of the post at 4.75" below the equator and then mark the screen by moving the shapie along making sure the tool is flat on the surface.
Place a mark at the half of the scren across the meridian using the same tool as step 1 in day 1. The place the laser level in the flat surface facing the screen, use the vertical laser to throw a projection and align both marks at the half of the screen across the meridian. Mark a line from the top to the bottom of the screen (at least at the bottom line).
Measure from the joint of the two half spheres 4" to the top and 4.75" to the sides, place a mark and draw by hand a half circle using those 3 points.
Place a mark at 4.75" and at 6" from the midline along the joint of the spheres (at the top) and along the equator. Use the laser level to project a line from the top marks to the marks on the equator and draw with a marker a pointed line.
Place a mark at 2.5" from the equator to the top of the ball along the 4.75" and 6" lines.
Join with a marker (we used a different color to make it noticeable) the intersections between the pointed lines as shown in the pictures below.
(A & I) The intersection between the bottom 4.75" line from the equator and the 6" line from the meridian.
(B & H) The intersection between the top 2.5" line from the equator and the 6" line from the meridian.
(C & G) The intersection between the top 2.5" line from the equator and the 4.75" line from the meridian.
(D & F) The intersection between the top joint of the sphere and the 4.75" line from the meridian.
(E) The intersection between the top 4" mark from the top joint of the sphere and the meridian.
Use a styrofoam cutter (we use the 200 W Pro Electric Hot Knife from RoMech Foam Cutter) to cut the sphere though the marked lines. We recommend to use a bench vise or C-clamps to hold the sphere through the aluminum plate follow the next steps:
Cut the bottom part of the sphere following the line marked at 4.75" below the equator.
Cut the line through intersections (B) toward (A).
Cut the line through the instersection (D) toward (C).
Cut the line through the intersection (B) toward (C).
Repeat the steps for the other side.
Cut the line through the intersection (D) toward (F).
Remove cutted styrofoam part as shown in the picture below.
Cut a line from the mark (E) toward the bottom of the sphere.
Cut a line through the intersection (D) toward (E) and remove the cutted styrofoam part.
Cut a line through the intersection (F) toward (E) and remove the cutted styrofoam part.
Apply joint compound to the crack on the half spheres intersection from the inside of the screen using a curved rubber wipe down knife. Let it dry overnight and apply a second hand if necessary to have a smooth surface.
Apply All purpose foam coat + Bounce from Hot Wire Factory following the instructions for mixing (just make sure the mix is thin enough to handle but thick enough to work as a protective layer). Apply one coat to the exterior part of the sphere, if you find the layer to thin you can apply 2 layers. We recommend to first apply to the top part of the sphere from the aluminum plate, then the bottom part and finally the cutted edges of the sphere (everything but the inner surface of the sphere). Let it dry for 24 hrs.
# Day 4 [time: ~1/2 hour each layer plus drying time]
Apply white lightweight spackling to the inner surface of the sphere using a curved rubber wipe down knife, making sure cover the imperfections on the surface as much as you can. Let it dry for ~3 hours (or more depending on ambient temperature and humidity), you can touch the surface and it shouldn't stick to your hand. Sand the surface and apply another layer. Repeat the process from 2 to 3 times until you get a smooth surface on the screen.
# Day 5 [time: ~1/2 hour each layer plus drying time]
Paint the outer part of the screen with a black matte paint (we recommend the black paint on screen wall and ceiling ambien light rejectting acoustic dampening) using a 3" or 4" brush. Do not paint the edges of the screen yet. Apply 2 layers of paint to the outer part.
Use a roller to paint the inner part of the screen. Apply 1 layer of primer (we recommend to use the paint on screen leveling primer) and 2 to 3 layers of silver paint (we use the paint on screen S1 Screen Plus).
Using a 1" brush paint the edges of the sphere with black matte paint.
Once the screen is built, follow the isntructions to install them in the cabinet.
Assemble the 1.5" diameter 10" long posts (P10) by screwing a pair of mounting bases (BA2) from Thorlabs at the bottom. Then install the posts to the cabinet bottom plate using 1/4-20 screws at at the closest position to the projector as shown in the picture below.
Have the custom made aluminum screen plate to post adapter in a machine shop, then screw it to the screen plate and place it over the posts. Tight screw the screen to the posts.
The pupillometry module consist on a monochrome camera mounted at the side of the screen pointing laterally to the face of the mice, the lens used allows to frame the pupil with enough detail to be processed by markeless pose estimation software. The field of view obtained with the lens allows to track sniffing and whisking, altough that is out of the scope of this building guide.
We use a Teledyne FLIR FFY-U3-04S2M-S camera, the small factor allows to place it right below the aluminum plate holding the screen without taking much space on the rig. We use a 0.4 MP, 121 FPS, monochromatic camera with an IR light source; a mono camera has better sensitivity and allow us to capture the details of the pupil better than the color sensor. Despite the fact that pupillometry can be detected at 30 Hz, we decided to use a 0.4 MP 121 FPS camera to have the flexibility in case we need another kind of measurement (whiskers move), but using the 1.6 MP 60 FPS camera should work fine for pupillometry and should result in a better image resolution.
Make a 1" hole on the screen at the position showed below. If you're setting up a pupillometry module on a built screen first mark the position where the hole is going to be made, then use a precision knife to remove the outer part of the screen (make sure not to introduce the knife all the way into the other side), remove the outer part using your fingers and then use your fingers to remove the styrofoam up to the inner part of the screen (the paint layer). Then, use the precision knife to cut the paint layer in the inner part of the screen, this way the hole from the inside out will be cleaner and the smaller size possible (it will adjust to the diameter of the lens).
TIP
Despite the fact that the screen has a hole in one of the sides, we didn't observe any behavioral impact in any of the pilot -or subsequent- sessions. The position and the fact that the hole is tailored to the diameter of the lens can be the reason.
Set up the camera and position it on the aluminum plate.
The reward module consist on a open srynge that holds the reward liquid that will be dispensed to the mice through a lick spout controlled by a solenoid valve.
The solneoid valve assembly consist of a standard plastic 60 mL srynge placed at the top of the rig conncected to a solenoid valve driver using Tygon PVC (for dairy) tubing. Since it's a gravity based module, it is recommended to place the srygne as high as possible. The srynge can be placed in the top frame of the rig cabinet using a 15/16" cable holder (you could use some thorlabs parts placed at the top of the rig to adjust the height of the srynge and place it in a higher position), remove the plunger from the srynge and use a luer lock to 1/16" ID tubing fitting to connect the srynge to the solenoid valve driver (we use the 003-0096-900 model from Parker).
To fix the reward solenoid valve to the DIN rail we use a 3D printed part, to which the solenoid valve is attached using 4-40 x 3/16" long screws and a DIN valve clip using a Rounded Head Thread-Forming Screws no. 8 5/16" long. Assemble them as shown in the picture below and attach it to the bottom DIN rail.
Finally, connect the srynge to the IN plug of the solenoid valve driver and connect the OUT plug to the srynge inside the rig using 1/16" ID 1/8" OD Tygon soft tubing for food, beverages and dairy.
TIP
Ee don't use the cable carrier for this tubing because it has to be replaced every month and it makes maintenance time consuming.
The lick spout holder is designed to be fixed in the sagital and coronal position and adjustable in the Z (height) position. This way the variability in the position of both the mice and the spout is reduced. To this end, we designed a 3D printed arm that holds a spout holder, which also serves as the air puffs delivery system, that is attached to a kinetic base to make it easy to place and remove when the styrofoam ball need to be taken out. The kinetic base is screwed to a dovetail translation stage with 1/4" travel to adjust the height of the spout.
To assemble, follow the next steps.
Have printed the arm (we recommend an external service and PA12GB material) and install a 8-32 thread size, 0.312" installed length heath insert for plastic in the hole at the lower part of the arm that is going to be attached to the kinetic base. Then, screw the top part of the KB1X1 kinetic base from Thorlabs to the arm using an 8-32 thread size, 1/4" long low-profile screw.
TIP
To install the heat insert follow the instructions in the step 3 of the bottom plate assembly in the stage section.
Install the 1/16" tube ID x 10-32 thread male pipe in the back of the spout holder and place it into the arm using a pair of 2-56 thread size, 5/32" long screws. Put the FNS-18-2-2 straight feeding needle from Kent scientific on the spout holder and fix the top part of the holder using a four 100 degree countersink, 0-80 thread, 7/32" long screws.
Print or have printed the breadboard to DT12 adapter and screw the DT12 dovetail translation stage from Thorlabs to the adapter using a 8-32 thread size, 3/8" long flat head screw, making sure the screw to move the stage is facing up (to the ceiling of the rig). Attach at the other end the bottom part of the KB1X1 kinetic base from Thorlabs using an 8-32 thread size, 1/4" long low-profile screw. Finally, install into the breadboard using a pair of 1/4"-20 thread size, 11/16" long flat head screw.
TIP
Due to inaccuracies in the 3D printed part the spout might be out of position, if this problem is present it is recommended to use a different printed breadboard to DT 12 adapter as shown in the picture below, this way the position of the reward spout can be adjusted.
Finally place the arm with the spout holder in place by connecting the top and bottom parts of the kinetic base.
The stage holds a 3D printed cup where the optical flow sensor is placed at the bottom and a hose is connected to deliver a constant air flow to make a styrofoam ball float at the top. The mice is head fixed on top of the ball, allowing it to run, while the optical flow sensor update the virtual world projected on the screen.
The stage consist on a pair of optical breadboards attached by a set of posts. The posts lenght is calculated so that the stage has the proper height at which the mice will be positioned and the projection will be calibrated. The top optical breadboard is modified to insert the cup that will direct the constant air flow to the bottom of the styrofoam ball and will make it float, allowing the mice to freely move and run.
We send the optical breadboard to be modified at a machine shop. To assemble the stage you have to first screw the 4 posts by attaching a 1" diameter 1" long post to a 1" diamater 2" long post using a 1/4" set screw (alternatively, you can use a 1" diamater 3" long post). Then attach both the top plate and the bottom plate to each end of the 4 posts using 1/4" screws.
Send the adapter to be made at a machine shop, then attach the latch holder to the adapter using a pair of M4 x 0.7mm, 8mm long screws. Attach the adapter to the bottom part of the bottom plate, in the intersection of the middle columns and the second row as shown in the picture below.
Install the stage into the cabinet using 1/4"-20 1/2" long low profile socket head screws from the bottom of the drawer slider into the breadboard (the stage can be installed in the cabinet before or after placing the 3D printed cup). Extend the drawer all the way out and place the stage on top of it, align it according to the image below.
The cup has 2 main components, the cup itself that includes a circular arm through which a constant air flow will be introduced to the inner part and a connector that will transmit the power and data from the sensor to the arduino that is part of the control module of the training mini VR. The second main component is the bottom plate, that has attached the optical flow sensor, a mirror, and a LED printed circuit board (PCB).
We use a 3D printing external service to manufacture the cup, Nylon 12 works fine and ideally the top curved surface of the cup should be smooth (smoothing it manually with fine sandpaper does the work).
Use a transparent epoxy to place a small ammount aroung the circular hole in the middle of the cup from the bottom up and place the 30 mm gorilla glass window, gently press the window making sure the epoxy covers the edges to avoid air leakage but making sure it doesn't spread into the middle of the mirror.
Cut the cables from the 8 pin connector to 4 inches and remove the tip of the plastic protective cover, also remove the dark purple lead, cut the black and red 26 AWG cables at 3 inches and remove the plastic cover from the tips as well. Place a female crimp pin in each cable one at the time and use the crimping tool following the instructions here(opens new window). For the grey and red cables, crimp the black and red 26 AWG cables with them respectively; as shown in the picture below.
Insert each crimped cable into the housing with the correct position, according to the following picture.
TIP
The strain relief barrel sometimes ends up a little overly flattened, making it too wide to fit comfortably into the crimp pin housing. In such situations, you can use a pair of pliers to gently squeeze the wider axis of the barrel into a more cylindrical shape that will slide easily into the housing. This tip is taken directly from the source(opens new window)
The bottom plate design is sent to a machine shop to be made in aluminum. The bottom plate will hold the optical flow sensor which, due to space constrains, is place horizontally in the front part of the plate (toward the mice and the back to the screen) facing a 45 degrees mirror right below the gorilla glass window, instead of being placed directly at the bottom of the styrofoam ball. We also add a printed circuit board with a resistance and an IR LED to illuminate the bottom part of the ball.
We send the sensor holder to be made at a machine shop in aluminum, but i could also be 3D printed. Solder the 90 degrees angled pins to the optical flow sensor, then use a pair of 4-40 1/4" long screws to screw the sensor to the sensor holder (one at the top left and one at the bottom right is enough).
We use an external service to make our PCBs using the GERBER files, some options are PCBway or OSH park. Add some solder to the pads, then place the IR LED on top, making sure the pin ID matches the PCB ID mark as seen in the picture below (the ID pin is a small dent on one of the square corners of the LED, you might need a magnifying glass for this) and use a fine tip to solder it to the PCB. Repeat the process with the resistance and finally solder the pins.
Use the heat insert installation tool to install a 4-40 x 0.17" long heat insert in the mirror and IR LED printed holder. Insert the correct tip into the soldering iron, then place the insert in the tip and connect it to a wall outlet; wait for a few seconds until it is hot and place it in the holes of the mirror holder. Press until the whole insert is inside and the surface is flat.
Cut a first surface mirror in a 1" x 0.75" square. Use a strong 2 side tape and cut some squares to fill both of the surfaces of the mirror and IR LED holder. Paste both the mirror and the PCB.
Screw the sensor and the mirror to the aluminum bottom plate.
Laser cut a rubber gasket to be placed between the aluminum plate and the cup. Connect the cables from the connector to the optical flow sensor, making sure the ground cable (grey) is at the bottom pin of the sensor (the one closer to the bottom plate). Use the thin red and black cables to connect to the IR LED PCB to the positive and negative pin respectively.
Place the rubber gasket between the bottom plate and the 3D printed cup and screw the bottom plate. Make sure that the optical flow sensor is between the cables connector and the air hose connector as shown in the figure below.
Screw the bottom plate to the cup and screw the cup to the top plate of the stage, the air hose connector should be facing the upper right part of the top optical breadboard, so that the optical flow sensor is directed toward facing the mice.
We place a cable and hose carrier to avoid them to be crushed or damaged while the stage is taken in and out. It is also useful to keep the working space clean and neat. Follow the next steps for assembly.
Print the carrier to breadboard adapter and install it in the bottom part of the top breadboard (it is easier to screw it before the posts, but you can always take the top breadboard apart or screw brom the bottom). Place the M6 x 1mm square nuts on the square hole in the bottom part of the adapter and use a pair of M6 x 1mm, 10 mm long to screw the carrier mounting bracket to it.
Place the second mounting bracket for the carrier on the 2 holes at the bottom left part of the aluminum bottom plate in the cabinet.
We order a 3 ft. long cable and hose carrier. Count 17 pieces of the carrier and snap off the rest of them. Attach the carrier to both mounting brackets.
This website is a central repository for the documentation regarding the maintenance of mini virtual reality rigs as part of BRAIN CoGS at Princeton Neuroscience Institute.
Maintenance documentation is also divided into modules, each module contains the process and tools needed to perform both preventive and corrective maintenance, as well as common troubleshooting.
The automated positioning system maintenance conssist of checking the motors and making sure everything is properly tighten (use loctite if necessary, altough it is recommended). Troubleshooting is mostly related to the motors driver.
The manual positioning system is low maintenance and consist mainly of tightening the Thorlabs parts and maintening the positioning tool in shape.
The projection module maintenance consist primarily on the initial calibration and subsequent maintenance calibrations that should be performed every ~6 months, and the projector bulb replacement that must be done whenever the projector ask for it, since the projector has an internal counter of how many hours the bulb has been used.
Creating correctly warped images given a particular projector, mirror, and dome arrangement requires finding the point on the projector frustum for any point on the dome. The problem is three-dimensional but can be turned into a simpler two dimensional problem by firstly translating the geometry so the spherical mirror is at the origin and then rotating the geometry so that the point on the mirror, dome, and projector lies in a single plane.
The projector is located at P1, the mirror is of radius r, and the position on the dome is P2. The path length from the projector to the mirror is L1, the path length from the dome to the mirror is L2. In the case of a spherical mirror: the line at mid-angle between the vectors OP1 and OP2 and its intersection with the surface of the mirror defines the reflection point.
Fermat’s principle states that light travels by the shortest route, so the reflection point on the mirror can be found by minimising the total light path length from the projector to the position on the dome, namely minimising (L1^2 + L2^2)^1/2. It is quite simple in the case of a spherical mirror: the line at mid-angle between the vectors OP1 and OP2 and its intersection with the surface of the mirror defines the reflection point.
The projection calibration will align the projection within certain boundaries, specifically the horizon, the center and the left and right side will be aligned to the physical position of the dome. This method has a trade-off in the time that has to be inverted to perform the alignment vs the accuracy of the rendered projection, since the height of the towers might be different across systems.
To calibrate the projection:
Turn on the projector and make sure to mirror the projection horizontally, otherwise left/right will be inverted.
Place the alignment tool. We recommend to use a 3 laser alignment tool(opens new window). Use the marked lines at the bottom plate to align the center and sides lasers on the dome. Set the height of the horizontal laser to 12" from the bottom plate.
Create a new subject in the ViRMEn training GUI and select the livecalibration.mat experiment. This is the calibration world that was developed, it is necessary to set the simulation mode to true in the RigParameters file. This will project a static world with 3 towers set at the center and at the left and right of the mouse eyes. The goal is to align the horizon to the animal eyes position, the center tower to the center of the screen and the left and right towers to the mouse eyes position.
Set the initial vairables of the projection parameters as below (these parameters has been obatained empirically and they are a good starting point for the training mini VR rigs as they are built).
%% Mini VR projection parameters
+% Spherical screen radius
+proj_param_Rs = 8;
+
+% Screen's center location relative to the animal eyes
+proj_param_xsm = 1.814;
+proj_param_ysm = 0;
+proj_param_zsm = 0.47;
+
+% Mirror position relative to the animal eyes
+% Mirror position measurement is facilitated knowing that the center of
+%spherical mirror is (43.8-24.2=)19.6mm (0.77in) behind the back surface.
+proj_param_xOm = 5.582;
+proj_param_yOm = 0;
+proj_param_zOm = -6.62;
+
+% Radius of the spherical mirror (Silver coated lens LA1740-Thorlabs)
+proj_param_r = 1.724;
+
+% Projector position relative to the mirror center
+proj_param_xP1o = 11.1;
+proj_param_yP1o = 0;
+proj_param_zP1o = -0.6;
+
+% Horizontal coordinate shift and rescaling
+proj_param_hrescaling = 5.5;
+proj_param_hshift = 0.000;
+
+% Vertical coordinate shift and rescaling
+proj_param_vrescaling = 5.5;
+proj_param_vshift = -1.017;
+
+
+
First, try to align certain variables by physically moving the projector. Unscrew the plate that holds the projector and move it horizontally until the middle tower is centered with the laser. Make sure that the left and rigth towers are equidistant from the middle of the dome, you may be able to achieve this by slightly moving the plate forward from one side or the other.
TIP
The position of the towers will move when the plate is thightened, don't untight the screws all the way if it is not necessary, unthight until it is possible to move the plate and checking the projection, then thight and adjust accordingly.
The goal of doing this physically instead of modifying the projection transformation parameters is that it decreases the differences across the projections in different training rigs.
Adjust the rest of the parameters until the towers and horizon are aligned. A brief description of how each parameter adjust the projection can be found below.
Rs should not be modified.
xsm will adjust the middle tower height without affecting the lateral towers, values should be around [1.5 - 2]. This value canbe adjusted since there will be idiosincrasies due to the screen fabrication.
zOm will adjust the horizon. This value can be adjusted since there can be differences in how the mirror is glued to its aluminum base.
xP1o will extend or contract the lateral towers and zP1o will lower or elevate the middle tower but will modify the distal part of the lateral towers. These values can be adjusted since there are idiosincrasies in the origin of the projection between projectors in their fabrication.
The hrescaling and the vrescaling should be the same, otherwise it will modify elongate or contract the projection, and there will be significant differences across sytems.
The hshift and vshift will move the entire projection up, down, left or right. Ideally the hshift should be 0 if the projection is calibrated manually, but it can be modified if necessary since it shouldn't affect significatly the projection across differente systems.
The projector has a counter used to determine how long the bulb has been used, it will emit an alert that the bulb should be replaced. Make sure to have in stock projector bulbs and follow each projector instruction to replace it.
The reward module maintenance consist mainly on the daily cleaning of the lines and valves, valve calibration procedure done every 2 weeks and a monthly cleaning of the reward valves and replacement of the lines if using a combination of condensed milk and water (70-30).
Once the day’s training is complete, gently pull the rig’s central stage towards you, leaving some space between you and the rig’s edge. Take the reward spout out of its holding area and place it on the edge of the rig’s stage, reward spout pointed down, place a beaker under it to dispose all the liquids.
If milk was prepared that day, pour any remaining milk from the syringes into the milk bottle. Otherwise, empty all of the syringes into the beaker.
Pick up the bottle of H2O2 from the shelf labeled “Cleaning Supplies” and fill the syringe with the hydrogen peroxide up to the 40 mL line.
When ready, press the “Open Valve” button in the regiment window or open the valve using the rig tester and let the H2O2 drain into the beakers.
Once the syringes are empty, fill the syringes with 100 mL in total of distilled water and let them drain into the beakers. When the distilled water reaches the 10 mL line on the syringe, press the “Close Valve” button.
This maintenance procedure should be done monthly if using a combination of condensed milk and water as reward during mice training, we currently don't have an accurate range for other kind of reward liquid but estimate to do it every 2 months for sucrose and water solutions and way longer for plain water.
Follow the procedure below.
Remove all liquids in the circuit, first by emptying the srynge into a dispose beaker and then open the valve to realease the rest of the liquid into the same beaker.
Take off the lines from the srynge to the valve and from the valve to the spout, use those lines to measure and cut the new lines from tubing.
Follow the appropiate instructions to clean the valves, for the 003-0096-900 model from Parkerparker valves fill a srynge with hydrogen peroxide, connect it to the IN port and flush it while the valve is open, repeat the process filling the srynge with air this time.
Use a srynge to flush the spout with hydrogen peroxide, then fill the srynge with air and flush it once more.
Install a new srynge and connect the circuit with the new lines.
To perform the valve calibration we determine the time required to deliver 0.1 ml in total after valve opened 25 times. That is, each drop should have volume of 4 microliters. Follow the steps below.
Gather the following materials: A one mL Eppendorf with a mark at 0.1 mL and a blunt metal tipped syringe.
Open MatLab and open the solenoidValveCalibration.m and RigParameters files.
Make sure that the spout is a vertical position at the same height as it would be with an animal, place the eppendorf under the reward spout and run the solenoid valve calibration script.
Once the run time has ended and every drop collected, use the blunt metal tipped syringe to drag any extraneous drops into the pool at the bottom of the eppendorf. If the pool of milk isn't at 0.1 ml (whether it is over or under), change the run duration time next to the command that reads “timeValveOpen =” in the Solenoid Valve Calibration window, and click “Run” when ready, keep adjusting until the pool of milk is at 0.1 mL.
Once the milk is close to the 1 ml mark, then change the value of the rewardDuration parameter in the Rig Parameters window.
Be sure to save (click Ctrl and S at the same time) what was changed in the Rig Parameters window if the run duration was changed.
Troubleshooting is mostly done from top down. Check first for clogging or anything else from srynge to valve, then from valve in to valve out, then from valve out to spout, and clean or replace accordingly.
Glue two 8" diameter half balls(opens new window) using lightweight styrophoam glue(opens new window). Make sure to use a fair ammount of glue, press each half against each other (make sure to squeeze them together for a few seconds to make sure the ball halves remain stuck to each other) and use your finger to flat the excess of glue laong the edges. Let them sit for a few hours or overnight.
Once the Styrofoam ball is smoothed, use a red sharpie to label the ball, then use a black industrial sharpie to mark the ball with a cross-hatch design - try to ensure that there are no large white gaps in-between the cross-hatch design.
The image quality from the optical sensor should be maximized in order for it to obtain reliable measurements, which can be achieved by:
Ensuring sufficient infrared (IR) illumination (but increasing it past a certain threshold does not help).
Adjusting the focal plane of the M12 lens to be at the surface to be measured.
Using a surface with more texture (of the appropriate size given the limited number of sensor pixels).
The ADNS-3080 chip reports a SQUAL value that can be read out using software as explained below. This value needs to be at least 30 if the velocities to be measured are around 100cm/s-150cm/s. For lower values of SQUAL, the sensor tends to under-measure the actual displacement, with the size of the effect increasing with higher surface velocities. The following are examples of images of a Styrofoam ball at various SQUAL values ranging from unusable to ideal (for velocities not far exceeding 100cm/s).
Follow the procedure below to adjust the focus of the optical flow sensor lens.
Load Arduino Code\ADNS_image_v1\ADNS_image_v1.ino in the Arduino IDE.
Edit the reset_pin to 6 and select_pin to 10 values (lines 20-24).
Upload the Arduino code to the board. Note that you will have to reprogram the board after this to use it as a displacement readout.
Print the left side of the following image (an optical spoke target) using a laser printer. The spoke target consists of lines of vanishing size towards the center, therefore allowing you to probe the single pixel limit of the optical sensor as shown in the calibrated image (from the sensor) in the right:
Find some way of placing the spoke target in front of the optical sensor at the same location and orientation as the actual surface to be measured. For example for the mouse virtual reality rig it can be taped onto a Styrofoam ball and the ball can be suspended at the height it would usually be at during experiments.
Run the Matlab Code\Calibration\display_image.m function. It is programmed to continuously display the sensor image for a predetermined amount of time, and can be terminated by pressing <Ctrl+C>.
Adjust the IR LED so that it points towards the center of the surface to be imaged. You should see the illuminated region shift around in the display_image figure.
The display_image figure is normalized so that the brightest regions appear white and the darkest regions appear black, i.e. absolute luminosity information is not available. You can change this behavior by editing the code to replace imagesc(im) (line 66) with image(im) and setting the color scale manually: set(gca, 'CLim', […])
+Oblique illumination can help increase feature contrast on uneven surfaces, but in general just illuminating the largest amount of surface available is sufficient.
Adjust the focus of the optical sensor lens by rotating it. You should see the spoke target lines get sharper and the SQUAL value increase if you’re going in the right direction. You should be able to find a distance at which the SQUAL value is maximal (there is a decent amount of leeway).
Replace the spoke target with the actual surface to be measured, and verify that the SQUAL value is still high enough (>> 30). Values of 50-80 have been achieved with Styrofoam balls, the higher end if they have been “weathered” by running mice.
If the SQUAL value is 30-ish or worse, consider using a more textured surface. For example, scour the Styrofoam ball with steel wool.
Follow the procedure below to calibrate the lenght scale of the optical flow sensor.
Load Arduino Code\ADNS_aout_wUSB_1sensor\ADNS_aout_wUSB_1sensor.ino in the Arduino IDE.
Upload the Arduino code to the board.
Suspend a Styrofoam ball on an axle, or a cylindrical Styrofoam wheel, at the position it would be in relative to the optical sensor in a real experiment. Mark a reference position on the ball, e.g. with a piece of black tape as shown in the mouse VR calibration photo below.
Ensure that Matlab Code\Calibration\calibrateBall.m is either in the current folder in the Matlab console, or otherwise in the Matlab path, before continuing the rest of this procedure.
While holding the ball in place, run the calibrateBall script.
Spin the ball 10 times (this can be done quickly), counting the number of times that the black tape returns to approximately its original location.
If necessary, a small correction can be made to rotate the ball further until the tape is exactly at its original position. This should cancel out errors incurred in the previous step.
Stop calibrateBall by pressing Ctrl+C.
Input fclose(instrfindall) at the Matlab command line to close Arduino communications.
Input [dx,dy] at the Matlab command line to view the accumulated displacements. If the optical sensor has been correctly aligned w.r.t. the axis of rotation of the ball, one of these displacements should be large (> thousands) and the other one small (< tens).
In the following the measured displacement along the axis of interest will be referred to as nDots, and the number of revolutions used as nRev.
Repeat this measurement until satisfied (with more rotations if necessary), then enter the obtained constants into RigParameters.m.
ballCircumference: Actual displacement (e.g. in cm) of the calibration surface per revolution. For an 8-inch diameter Styrofoam ball, this is its circumference, 63.8cm.
sensorDotsPerRev: This should be set directly to nDots/nRev in the case of a single sensor. In the case of two sensors, use the code sensorDotsPerRev = RigParameters.sensorCalibration() and set the latter as described below.
sensorCalibration: This is only used for two sensors, which may have differing constants. In this case use the appropriate MovementSensor label for the sensor of interest to record dotsPerRev, e.g.: dotsPerRev(MovementSensor.FrontVelocity) = nDots/nRev;
Troubleshooting should be done from cleaning the 3D cup and window first, making sure the ball is in proper conditions, and then the optical flow sensor replacement if necessary, then the arduino. If the arduino is the problem, refer to the troubleshooting guide in the control portion of the documentation.
# Automated cronjobs in BRAINCoGS (Developer Guide)
There are some processes that are triggered automatically in BRAINCoGS.
All these processes are handled by u19proc virtual machine administered by PNI Help. Contact Garrett T. McGrath gmcgrath@princeton.edu for permissions to it.
All processes are handled by u19prod user account so it's not linked to any personal account.
Location in u19proc: /home/u19prod@pu.win.princeton.edu/Datajoint_projs/U19-pipeline-matlab/scripts/call_u19_night_cronjob.sh
Overview: Call populate_tables.m script. Ingest all Behavior related tables from acquision.SessionStarted & acquisition.Session new records from that day. Check the populate_tables.m script for more information
Location in u19proc: /home/u19prod@pu.win.princeton.edu/Datajoint_projs/U19-pipeline_python/u19_pipeline/alert_system/call_cronjob_alert.sh
Overview: Call cronjob_alert.py script . Read <a href="https://braincogs.github.io/software/alert_system.html"'> Alert System section for more information.
The automation GUI is located on the desktop in all microscope/ephys recording system across BRAINCoGS. You can identify it by a desktop BRAINCoGS icon called "Recording_Automation_GUI".
It is encouraged to register & process every recording with the Automation GUI just after recording has ended.
In "proc. Param Set Description" edit, write a small description for the new parameters.
Click "Upload Proc-Parm Set json file" button and search/load for your json file with parameters. You can check your parameters on the text area on the right.
Click "Register Proc. Param Set" button.
# Create new preprocessing parameters (a single step on preprocessing list)
Note: You need a json file with all parameters ready before starting this process.
Here is an example of a catgt parameter json file. It can serve you as an example for creating your own:
In "Preproc.-Param Set Description" edit, write a small description for the new parameters.
Click "Upload Preproc.-Parm Set json file" button and search/load for your json file with parameters. You can check your parameters on the text area on the right.
Click "Register PreProc. Param Set" button.
# Create new preprocessing parameters list (a set of preprocessing paramaters)
Note: If you just created a preprocessing parameter, restart GUI.
Authenticate with your NetID and PU password (NOT your PNI password, which may be different). When prompted for your username, enter PRINCETON\netid (note that PRINCETON can be upper or lower case) where netid is your PU NetID.
Authenticate with your NetID and PU password (NOT your PNI password, which may be different). When prompted for your username, enter PRINCETON\netid (note that PRINCETON can be upper or lower case) where netid is your PU NetID.
Copy Automation GUI files: copy \\cup.pni.princeton.edu\braininit\Shared\AutomationGUI_Installation\AutomationGUI_update to the Desktop.
Run Desktop\AutomationGUI_update\firstTimeAutomationGUI.BAT
Install git bash and anaconda from it.
On Anaconda advanced options step: check "Add Anaconda3 to my PATH environment variable" checkbox.
Run Desktop\AutomationGUI_update\update_AutomationGUI.BAT
Follow instructions to install Recording Automation GUI. (Also called Workflow Console GUI).
Authenticate with your NetID and PU password (NOT your PNI password, which may be different). When prompted for your username, enter PRINCETON\netid (note that PRINCETON can be upper or lower case) where netid is your PU NetID.
DataJoint development and use can be done with a plain text editor in the
+terminal. However, an integrated development environment (IDE) can improve your
+experience. Several IDEs are available.
A virtual environment allows you to install the packages required for a
+specific project within an isolated environment on your computer.
It is highly recommended to create a virtual environment to run the workflow.
Conda and virtualenv are virtual environment managers and you can use either
+option. Below are the commands for Conda.
If you are setting up the pipeline on your local machine follow the instructions below for Conda. If you are using spock.pni.princeton.edu or scotty.pni.princeton.edu, Conda is preinstalled and you can access it by running module load anacondapy/2021.11.
We will install Miniconda which is a minimal installer for conda.
When trying to fetch from a table with external storage and corresponding network cup drive is not mounted:
Error using dj.store_plugins.File (line 89)
+Directory `/Volumes/u19_dj/external_dj_blobs` not accessible.
+
+Error in dj.internal.ExternalTable (line 52)
+ self.spec = dj.store_plugins.(storePlugin)(config);
+
Error using fread
+Invalid file identifier. Use fopen to generate a valid file identifier.
+
+Error in dj.store_plugins.File.download_buffer (line 63)
+ result = fread(fileID);
+
Just mount all cup drives and try agian !!
key reference more than one session when function was supposed to work for single sessions
Error using dj.internal.GeneralRelvar/fetch1 (line 250)
+fetch1 can only retrieve a single existing tuple.
+
User Stores general information for all researchers and technicians in BRAINCoGS. Being registered in this table is a requirement to add subjects in your behalf Check here for more information. Important fields include, user_id (NETID), active_gui_user & slack_webhook URLS for users (for notifications). Check set slack alerts for more info.
Location All systems associated with rigs, recordings & technician use. All behavior sessions are associated with one of the systems recorded here, each recording (ephys/imaging) is associated with a system recorded here. Check here for more information. Important fields include, user_id (NETID), active_gui_user & slack_webhook (for notifications). Check Configure systems section for more info.
Path Paths for the cup drives in BRAINCoGS. Paths are divided by OS and local or network system types.
AcquisitionType All possible acquisitions modalities in BRAINCoGS. (Each location in Path is associated with one modality as well). Modalities include: behavior, electrophysiology, 2photon, mesoscope, etc).
DjCustomVariables Configuration variables for datajoint, mainly paths for special directories. This table is used in the background when DB access configuration is set for a system is made. Check DB Access section
DjStores External storage path locations on the network drives (cup) for several Datajoint tables. This table is used in the background when DB access configuration is set for a system is made. Check DB Access section
InsertionDevice Device types for insertion in subjects. (From ephys electrodes, to optogenetic cannula). Paired with u19_action.SurgeryLocation table.
SlackWebhooks Slack webhooks URLs for general notifications. Check set slack alerts for more info.
Subject Stores general information for all subjects in BRAINCoGS. Being registered in this table is a requirement to train and perform behavior sessions.
LickometerMotorPosition Stores ml, ap, & dv motor coordinates for a subject in a rig with positioning motor installed. Check Set up motor positioning subsection for more information.
CagingStatus Subject-Cage relationship storage.
HealthStatus Daily health assesment for subject. Fields like normal_behavior, posture_grooming, technician_comments etc.
Stores all reference and general information of behavior sessions. Other tables in this DB also stores reference to blocks, trials, manipulation and subtasks of a behavior session.
SessionStarted Reference to all sessions that are started with training GUI. Path to behavior file ia located here.
Session Basic information (performance, experiment code used, etc.) for a behavior session. Record written after training is finished
SessionBlock Basic reference to all blocks from all behavior sessions.
SessionBlockTrial Basic reference to all trials from all behavior sessions.
SessionManipulation Reference to which manipulation (if any) was performed for a behavior session. Check manipulation pipeline section for more information.
SessioSubtask Reference to which subtask (if any) was performed for a behavior session. Check subtask pipeline section for more information.
Weighing Records daily weight of subjects. Written by weighingGUI used by technicians.
WaterAdministration Records daily water administration to subjects. Earned water written at the end of training. Supplement water Written by weighingGUI used by technicians.
DaiyPositionData For subjects with automatic motor positioning on rig, stores daily ml,ap & dv coordinates. If cameras are present on rig a lateral and tops reference images are also stored.
Towers Session/Subject ** Psych Group of tables with Psychometric Curves parameters per session, block_type (main, guiding), subject, etc. Check Using psychometric data to know how to use this. Check BRAINCoGS Data viewer to check psychometric curves.
OptogeneticSession Reference to a behavior session that is also an optogenetic session. Stores which protocol and software parameter set were used fot the session.
OptogeneticSessionTrial Stores specific optogenetic data on a trial by trial basis.
OptogeneticSoftwareParameters MATLAB Structure with parameters to be used during the behavior session specific for a subset of optogenetic sessions.
OptogeneticProtocol Describes metadata that will be associated with optogenetic sessions. (e.g. laser wavelength, stimulation frequency, etc.)
Stores all reference to all processing jobs for ephys & imaging on the automation pipeline. Almost all information in this table is shown in the Automation pipeline GUI .
Processing Reference to all processing jobs. For ephys it has a one to one relationship with recording probes. For imaging it has a one to one relationship with Field of View. Stores status_processing, raw_path (recording_process_pre_path), processed_path (recording_process_post_path) for each of these "fragments" of recording.
ProcessingEphysParams Relationship between jobs & which ephys processing parameters were used for that job.
ProcessingImagingParams Relationship between jobs & which imaging processing parameters were used for that job.
LogStatus Stores all status change for processing jobs and corresponding messages & exceptions if applicable.
EphysPipelineSession List of recording_ids that correspond with ephys recordings.
BehaviorSync Synchronization data between ephys recording and behavior session. trial_index_nidq & iteration_index_nidq are trial and iteration # for each sample on the electrophysiology data.
Datajoint element array electrophysiology DB. Database schema is designed to store all data from an ephys recording and subsequent kilosort processing. More info: Datajoint element array electrophysiology docs. For BRAINCoGS ephys_precluster schema was used.
ClusteringParamSet Table that contains a list of parameter dictionaries/structures used for sorting process.
PreClusterparamSet Table that contains a list of parameter dictionaries/structures used for preprocessing steps.
PreClusterparamSteps Table that contains lists of lists of preCluster param Sets that form a preprocessing sequence for recordings.
+preprocessing steps. (e.g. catgt)
CuratedClusteringUnit Main data for all the units found in sorting process. (spike_times, cluster_quality_label, etc.)
LFPElectrode LFP data for each of the electrodes in recording.
WaveformSetWaveform All waveforms from a unit captured by each electrode in recording.
ProbeInsertion Records which probe was used for the corresponding recording-insertion_number pair. Check 5. u19_pipeline_probe_element.
Datajoint element array electrophysiology DB for probes. Database schema is designed to store probes and electorde configurations used in recordings. More info: Datajoint element array electrophysiology docs. For BRAINCoGS ephys_precluster schema was used.
ImagingPipelineSession List of recording_ids that correspond with imaging recordings.
TiffSplit Identified fields of view for a single recording (regularly 2photon = 1 FOV, mesoscope = 3 FOV). Each FOV is processed separately.
AcquiredTiff TIFF file header metadata for each FOV.
SyncImagingBehavior Synchronization data between imaging recording and behavior session. sync_behav_%%_by_im_frame = Correspoding behavior block, trial and iteration for each imaging frame.
+sync_im_frame_span_by_behav_%% = Fist and last imaging frame for each behavior block, trial and iteration.
Datajoint element calcium imaging DB. Database schema is designed to store all data from an imaging recording and subsequent segmentation process. More info: Datajoint element calcium imaging docs.
Datajoint element calcium imaging DB. Database schema is designed to store scan info and metadata from imaging files. More info: Datajoint element calcium imaging docs.
In this section, we will document all software and database tools and pipelines developed for BRAIN CoGS community.
Software documentation is divided in sections, in each section you will find the information you need to access as a user or how to modify things as a developer. Many sections will also have MATLAB and Python subsection for you to choose your preferred language.
Create new manipulation schema (substitute manipulation_name with the real name of the manipulation: create_new_manipulation_schema('(manipulation_name)', 1)
This will create a new schema “base” code on the U19-pipeline-matlab/schemas directory:
(We will use “thermal” manipulation for this example).
The protocol table stores related information that defines the current manipulation “type” to be used on a behavior session.
Here is the minimum table definition for a manipulation protocol table, it is composed by an id to identify the protocol and a description field.
Generic "Manipulation" Protocol.m
%{
+# Defined <manipulation> protocols for training
+<manipulation>_protocol_id : int AUTO_INCREMENT
+---
+protocol_description : varchar(256)
+%}
+
# Adding features to "Manipulation" Protocol table
For each manipulation protocol it is possible to add from 0 to n “features” that will define & describe the protocol. We are going to describe all features added for OptogeneticsProtocol as an example:
It is important to know from an optogenetic experiment what kind of stimulation was given to the subject: Frequency, wavelength, power etc. All these variables can be stored into a “feature” table and be categorized as StimulationParameters.
What if stimulation was not a square pulse ? We can create a “feature” table to define (if needed) specific waveforms for a given session. (OptogeneticsWaveform)
What if different rooms have different laser systems models ? We can create a “feature” table to store all possible devices to be used in an optogenetic experiment (OptogeneticsDevice).
For each of these features we need to create a new table that encompasses the needed information for that feature. We will call all these extra tables a protocol “feature” table.
For a guide on how to define DJ tables go to: this link.
For the current guide we will only show OptogeneticsStimulationParameters definition as an example:
id field: as an int AUTO_INCREMENT type as the only primary key (e.g. stim_parameter_set_id).
extra_fields: Any other field that helps to define the feature.
After all feature tables are defined they should be added to the "Manipulation" Protocol table.
For our Optogenetics example:
% Declare new "feature" table
+optogenetics.OptogeneticsStimulationParameters
+% Add the feature -> protocol table
+add_feature_key_protocol_table(optogenetics.OptogeneticsProtocol, ... optogenetics.OptogeneticsStimulationParameters)
+% Sync definition from DB to .m file
+syncDef(optogenetics.OptogeneticsProtocol);
+% clear previous connection and connect again
+clear all
+connect_datajoint00
+
After the “features” tables are added to the "Manipulation" Protocol table we are ready to add protocols to be “ready” and selectable for a behavior session:
% Insert stim parameter record
+ stim_parameter_rec.stim_parameter_description = 'cool stims'
+ stim_parameter_rec.stim_wavelength = 473
+ stim_parameter_rec.stim_power = 10
+ stim_parameter_rec.stim_frequency = 100
+ stim_parameter_rec.stim_pulse_width = 1
+ insert(optogenetics.OptogeneticsStimulationParameters, stim_parameter_rec)
+
+ % get last inserted stim_id
+ stim_id = fetch(optogenetics.OptogeneticsStimulationParameters, 'ORDER BY stim_parameter_set_id desc LIMIT 1');
+
+ % or look for a previously inserted parameter
+ all_stim_params = fetch(optogenetics.OptogeneticsStimulationParameters, '*')
+ stim_id = 1;
+
+ % Insert new protocol with new stimulation parameter
+ new_protocol.protocol_description = 'this_is_new_protocol'
+ new_protocol.stim_parameter_set_id = stim_id;
+ insert(optogenetics.OptogeneticsProtocol, new_protocol)
+
The software parameters table stores a set of parameters (a matlab struct, a python dictionary) that the code that handles the behavior will use during the session.
We will show how to insert new software parameters:
This for the optogenetics.OptogeneticSoftwareParameter table
param_struct = struct();
+param_struct.software_parameter_description = 'stimulation_sequence # 1';
+
+% All parameters goes in here
+%(P_on and lsrepoch are the common and needed for current opto experiments)
+param_struct.software_parameters.P_on = 0.21;
+param_struct.software_parameters.lsrepoch = 'cue';
+
+%Insert parameter
+software_param_id = try_insert(optogenetics.OptogeneticSoftwareParameter, param_struct)
+
This table stores manipulation data for a specific behavior session. This table “links” a manipulationProtocol & manipulationSoftwareParameters with a behavior Session.
This table does not need any additional code on it. (Unless extra fields from the behavior file are needed to be stored). Researcher should contact DB designer if that is their intention
OptogeneticSession.m
+%{
+# Information of a optogenetic session
+-> acquisition.Session
+---
+-> acquisition.SessionManipulation
+-> optogenetics.OptogeneticProtocol
+-> optogenetics.OptogeneticSoftwareParameter
+%}
+
This table stores data, on a trial by trial basis, corresponding to the manipulation performed during the behavior session.
There is a section on any "Manipulation" SessionTrial class on the get_manipulation_trial_data function code where researcher has to add lines to fetch specific trial manipulation data:
After all code for new manipulation has been set up the researcher will be able to select a specific manipulation type, protocol & software parameters that will be associated with the schedule for a given animal. Subsequent behavior sessions will correspond to that selection.
Create new subtask base code (substitute subtask_name with the real name of the subtask: create_new_subtask_classes('(subtask_name)')
This will create table codes templates for subtask : (Subtask)Session.m, (Subtask)Block.m & (Subtask)Trial.m on the U19-pipeline-matlab/schemas/+behavior_subtask directory:
(We will use “Twolickspouts” subtask for this example).
%{
+# Block level data for a twolickspouts subtask session
+-> behavior_subtask.TwolickspoutsSession
+-> acquisition.SessionBlock
+---
+sublevel : int # sublevel for the block
+trial_params : blob # maze features of current block
+%}
+.
+.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% fill here read corresponding TestSubtask data for each block
+tuple.sublevel = block_data.sublevel;
+tuple.trial_params = block_data.trialParams;
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
In this example two fields were added to TwolickspoutsBlock table: (sublevel & trial_params)
Two things are needed:
Adding them to the table definition (1st part of the code block)
Add how this fields are being set from block_data variable: (search for fill here section on the code). block_data has all block data from behavior file.
%{
+ # Trial level data for a twolickspouts subtask session
+ -> behavior_subtask.TwolickspoutsBlock
+ -> acquisition.SessionBlockTrial
+ ---
+ licks : tinyblob # all iterations with lick detected and side
+ trial_difficult_type : varchar(16) # trial type label (easy, medium, difficult, etc)
+ forced_automatic_reward=null : tinyint # 1 if reward was forced for trial 0 otherwise
+ %}
+ .
+ .
+ %%%%%%%%%%%%%%%%%%%%%%%
+ %%%% fill here read corresponding Twolickspouts data for each trial
+ trial_data.licks = curr_trial.licks;
+ if isfield(curr_trial, 'forced_automatic_reward')
+ trial_data.forced_automatic_reward = curr_trial.forced_automatic_reward;
+ else
+ trial_data.forced_automatic_reward = NaN;
+ end
+ if isfield(curr_trial, 'trialDifficultyType')
+ trial_data.trial_difficult_type = curr_trial.trialDifficultyType;
+ else
+ trial_data.trial_difficult_type = '';
+ end
+ %%%%%%%%%%%%%%%%%%%%%%%%
+
In this example three fields were added to TwolickspoutsBlockTrial table: (licks & trial_difficult_type, forced_automatic_reward)
Two things are needed:
Adding them to the table definition (1st part of the code block)
Add how this fields are being set from trial_data variable: (search for fill here section on the code). trial_data has all trial data from behavior file.
After all code has been written on "Subtask"Session, "Subtask"Block & "Subtas"BlockTrial codebase it is needed to actually create the tables in the DB.
After all code for new sbutask has been set up and tables have been created the researcher will be able to select a specific subtask that will be associated with the schedule for a given animal. Subsequent behavior sessions will correspond to that selection.
Located in ViRMEn\experiments (Rigs) or tankmousevr\experiments (Personal computer) directory.
File that controls stimulus presentation and trial/block progression. Each frame this code is executed, it's general structure is a state machine that follow the trial schema.
Detailed guide on how to modify things on ViRMEn Manual.
Original file: C:\Experiments\ViRMEn\experiments\poisson_blocks.m
Most common use:
Copy the existing Experiment code file from the most similar task.
Rename file to descriptive name (e.g. "TaskName"_ExperimentCode.mat)
Change Experiment code logic.
Check "Tips and Tricks to modify Experiment Code" for detailed tips
Parameters for a stimulus inherited when running the experiment (so stimulus parameters that change between mazes but are not defined by the stimuli themselves)
Cell array (see below for more details)
vr.inheritedVariables
Parameters for a maze inherited when running the experiment (so maze parameters that change between mazes but are not defined by the stimuli themselves)
Cell array (see below for more details)
Global settings variables:
Parameter name
Definition
Values accepted
cueMinSeparation
Min distance between two towers on the same side
Real number (>0)
fracDuplicated
Proportion of trials that are duplicated
Real number ([0-1])
trialDuplication
Number of times each set of stimulus parameters are duplicated, for a given fracDuplicated (i.e., number of exact replications of each trial type for the duplicated fraction of trials)
Located in ViRMEn\experiments\protocols (Rigs) or tankmousevr\experiments\protocols (Personal computer) directory.
File that contains stimuli sets that will be drawn for during session. It contains trial data: towers positions, number of towers for each maze level depending on protocol variables.
Original file: C:\Experiments\ViRMEn\experiments\protocols\stimulus_trains_PoissonBlocksCondensed3m.mat
Most common use:
Create protocol and world files.
Run generatePoissonStimuli(('world_file'), @('protocol_file')). Substitute world_file & protocol_file with corresponding names.
The most common use for this file when working on a personal computer is to run ViRMEn simulations without interacting with the hardware, to do this set:
simulationMode: = true
hasDAQ: = false
This will allow you to run simulations on any Windows computer and use the keyboard to simulate mouse movement.
If the rig where training is happening has a motor positioning system (ask lab manager about it). It is needed to set up initial coordinates for each subject training in the rig.
Adjust subject positioning for the first time in the rig with the motor GUI (installed in the rig computer).
In MATLAB write the following (replace code in brackets with corresponding info for the subject):
new_record = struct
+new_record.subject_fullname = ['efonseca_ef481_actpg004']; # Subject fullname
+new_record.ml_position = [17.5] # ml position in mm (motor axis#1 position in GUI)
+new_record.ap_position = [10] # ap position in mm (motor axis#2 position in GUI)
+new_record.dv_position = [15.3] # dv position in mm (motor axis#3 position in GUI)
+insert(subject.LickometerMotorPosition, new_record)
+
In this section all elements of the training GUI will be described:
From the main screen we have divided all elements in three categories (red = rarely used or not used at all; yellow = used in specific situations; green = widely used).
Branch information section: For git users, informs which branch is checked out right now and if the current version code has current changes on it. The vast majority of the times it should be written "master" & "synced". Go to section pulling/pushing code if not the case.
Schedule calendar: Day of the week & time when subjects should be trained. This information is not crucial for training at the moment.
Ball displacement plot: Figure that shows real time velocity in X & Y for the subject in the rig. This plot is used to detect ball movement sensor issues.
RigParameters info bar: This bar is in red color whenever simulation mode is activated or hasDaq parameter is set to false. If this is the case both parameters should be reset for training to start. If simulation mode is intended ignore this bar.
Test session checkbox: If next session goal will be to test code or behavior won't be analyzed check this box. Session will not be stored in our DB.
Open valve buttons: These buttons are used to give a little reward to subject in rig and/or to test valve function.
Connect to DB button: Use this button to connect to DB, it should be the first thing to do when training GUI is open. Check set up training seciton
From the add animal dialog we have divided all elements in three categories (red = rarely used or not used at all; yellow = used in specific situations; green = widely used). Sections not described are not used.
Subject selection: Dropdown list of all available for training subjects in BRAINCoGS.
Reward Factor: Multiplier to be used for reward for each one of the warm-up & main mazes. Regularly reward is 4ul for each correct trial on Towers Task. (e.g. if RewardFactor = 1.25 -> Reward = 4*1.25 = 5 ul).
Motion blur range: Parameter to set up cue elongation effect opposite to direction of subject motion in virtual reality. 2x1 vector where first element is distance (in cm) from subject to tower cue to start elongation and second element is distance (in cm) to stop elongation effect. No motion blur effect if empty. Common values: [28 5], []
Restart or append session: Action to perform if a session is restarted.
If APPEND SESSION is selected, every time session is restarted, the "new" session will be counted as new blocks of the same session.
If START NEW SESSION is selected, every time session is restarted a new session will be created (recommended when physiology recordings are performed to facilitare syncing process)
stimulus Set edit: If stimulus bank has more than one set it can be set from here. Only change this if you know deeply the stimulus bank file and you know what you are doing.
How warm up trials are drawn: Strategy to select left or right trials based on previous bias and performance. Default value eradeTrial described here
How main trials are drawn: Strategy to select left or right trials based on previous bias and performance. Default value eradeTrial described here
Subtask selector: If session is from a specific subtask you can select it here. Check subtask pipeline section for more information.
Pupillometry video: If pupillometry video is going to be captured, select video parameters here.
Behavior video: If behavior video is going to be captured, select video parameters here.
Manipulation selector: If session is from a specific manipulation you can select it here. Check manipulation pipeline section for more information.
Stimulation protocol: If session is from a specific manipulation Select stimulation protocol in this dropdown. Check manipulation pipeline section for more information.
Software parameters: If session is from a specific manipulation Select software parameters in this dropdown. Check manipulation pipeline section for more information.
Search all lines is experiment code that interact with hardware: (all lines starting with: nidaq.. and updateDAQSyncSignals function. (hardware code lines)
Add this line if RigParameters.hasDAQ before hardware code lines and close if after them.
Open failed: Port: COM7 is not available. Available ports: COM1.
+Use INSTRFIND to determine if other instrument objects are connected to the requested device.
+
Serial communications have not been properly initiated.
+
Device Error: Unanticipated host error
+
Are the most common error during training. Check if Arduino COM Port is found in device manager and restart MATLAB and/or system to solve this.
[nidaqPulseRightReward:commit] Requested operation could not be performed, because the specified digital lines are either reserved or the device is not present in NI-DAQmx.
+ It is possible that these lines are reserved by another task or the device is being reset. If you are using these lines with another task, wait for the task to complete. If you want to force the other task to relinquish the device, reset the device. If you are resetting the device, wait for the reset to finish.
+ Device: Dev1
+
+ Task Name: RightReward
+
+ Status Code: -200587
+
Review RigParameters.m file and check that there is no overlap between input/output channel variables: (rewardChannel, laserChannel, rightPuffChannel, leftPuffChannel,rightRewardChannel, leftRewardChannel, newIterationChannel, newTrialChannel, etc.)