Problematic .mwel files

Hi Chris,

Thank you so much for your help! I will try your suggestions on the laser protocols and will email you if I have more questions.

The following attachments are the .mwel files that fail to send the success event code. The “dispense_juice” macro is line 162-187 in the config_Vpixx and the problematic state is the “Stim Acquired” state from line 441-452 in the protocol_2afc.

I’ve also attached a screenshot of the part in the config_Laser where we would like to implement a try-except function for the two serial ports.

Please let me know if you have trouble opening or viewing. Thank you!

Best,
Taylor

Hi Taylor,

I’ve been thinking about the missing success event code, and I still don’t know what’s going wrong.

I rechecked your code and some MWorks internals, and I can confirm that the three assignments attached to blackrock_sync_word should never be interrupted. This means that different invocations of vpixx_send_blackrock_sync_word can’t overlap or interfere with each other, even if (as in the case of dispense_juice) one of the invocations happens asynchronously.

That said, there are some things that could happen, which might be causing confusion when you look at your data. Specifically:

  1. The e_stimulus_success code in state “Success” could be sent to the Blackrock before the e_reward_off code triggered by dispense_juice in state “Stim Acquired” is sent.

  2. The invocations of dispense_juice in states “Stim Acquired” and “Reward” could overlap. That is, the second invocation could set juice_dispensing to 1 before the first invocation resets it to 0.

Case (1) means that you can’t just look for e_stimulus_success after e_reward_off. Case (2) should result in the Blackrock data containing two e_reward_on’s followed by two e_reward_off’s. Either of the two cases might make it harder to find the e_stimulus_success you’re looking for, but neither should prevent if from being sent at all.

Can you remind me what you said about how changing some time interval eliminated the problem? Did you decrease reward_duration_target_acquired, increase maximum_time, or something else?

I’m still thinking about the serial port issue. I’ll get back to you once I have some ideas.

Cheers,
Chris

Hi Taylor,

Here’s an idea for how to select the correct serial port:

If both of the device names begin with “/dev/cu.usbserial-A”, and, on a given machine, there are no other device names that start that way, you can use MWorks’ filenames function to obtain the full device name using just the prefix:

iodevice/qcualor laser (
    serial_port = (filenames('/dev/cu.usbserial-A*') + ['not_found'])[0]
    ...
    )

The addition of “not_found” to the end of the list returned by filenames ensures that, if there are no matches (e.g. because the device is not connected), the QCUALOR interface will fail to initialize in an obvious way.

Does that work for you?

Cheers,
Chris

Hi Chris -

Thanks for all this info.

Taylor’s under the weather today - but she’ll look at all this when she’s feeling better and back in the lab.

Cheers,
Yasmine

Hi Chris,

Thank you for the idea! I just tested it on the laser we have right now and it works! I will let you know once I test it on the other laser when it gets here.

Best,
Taylor

Hi Chris,

I double-checked the recordings with the problematic reward on and the problem is that it didn’t send the success event code at all. I tried to find all the success event codes but none was sent with the reward on.

We increased both the maximum_time and the reward_duration_target_acquired before and it worked. But I just tried a bunch of combinations and I think I sorted out the problem. I kept the maximum_time at 500 ms and the success event codes were sent if the reward_duration_target_acquired was >= 60 ms. The success event codes were still failed to be sent even if I increased the maximum_time to 2000 ms and kept the reward_duration_target_acquired at 50 ms. So it seems like the problem is the reward_duration_target_acquired being too short which is confusing. Our solenoid of the reward system should open for a 50 ms reward and it shouldn’t affect the event code even if the solenoid doesn’t open?

Best,
Taylor

Hi Chris,

Just a follow-up question on config_Laser. We would like to switch between channels in some of the protocols and would like to give the mode names (i.e. “mode_1”, “mode_2”, etc. ) a variable name so we can call the variable name directly in a state rather than hard-coding “mode_1” or “mode_2” in the protocol.

I’ve attached the screenshots of how I tried to do it. I tried to put the mode name in a variable called “channel_num” and “channel_num” changes depending on the channel we would like to turn on.

PastedGraphic-1.png

But it didn’t seem to work. It only activated mode_2 and didn’t allow me to change the wave form of mode_2 either in the following protocol where the laser wave form is supposed to change depending on the input “laser_type". “channel_num” is also set to the corresponding wave form and still didn’t work even if I reset it back to “mode_1” or “mode_2”, etc. at the end. Do you have any suggestions on how to do this?

Thank you!

Best,
Taylor

Hi Taylor,

I double-checked the recordings with the problematic reward on and the problem is that it didn’t send the success event code at all. I tried to find all the success event codes but none was sent with the reward on.

OK. I suggested that it might be a data analysis issue, because I was remembering a previous question from your lab that involved an incorrect expectation about where e_reward_off could appear in the data stream. But it sounds like that isn’t the problem here.

I kept the maximum_time at 500 ms and the success event codes were sent if the reward_duration_target_acquired was >= 60 ms. The success event codes were still failed to be sent even if I increased the maximum_time to 2000 ms and kept the reward_duration_target_acquired at 50 ms. So it seems like the problem is the reward_duration_target_acquired being too short which is confusing.

That is indeed confusing. I guess we have to assume that when reward_duration_target_acquired is 60ms, e_stimulus_success is sent before e_reward_off, whereas at 50ms, they overlap and interfere with each other somehow. (Again, I don’t see how.) I wonder what would happen if you decreased reward_duration_target_acquired to 30 or 40ms. If an overlap is the issue, it seems like that should resolve it, too.

Also, out of curiosity, what is the value of fixation_requirement_stimulus?

Our solenoid of the reward system should open for a 50 ms reward and it shouldn’t affect the event code even if the solenoid doesn’t open?

Yes, whether or not the solenoid actually opens has no bearing on the data sent to the Blackrock. From MWorks’ perspective, opening and closing the solenoid means nothing more than toggling a digital output line on the VIEWPixx. Even if there were no solenoid connected to the output line, the experiment would proceed normally.

Chris

Hi Chris,

I did a quick test again and yes, it worked when I decreased reward_duration_target_acquired to 30ms or 40ms. Also, in this case, the solenoid didn’t open but the codes were still sent. The fixation_requirement_stimulus is 50ms so it does seem like overlapping is the problem here. After 50ms, there are two event codes being sent, “e_reward_off” and “e_stimulus_success”. Is there a way to have both sent? If not, we can always make a note to make reward_duration_target_acquired to be greater than 50ms.

Thank you!

Best,
Taylor

Hi Taylor,

I did a quick test again and yes, it worked when I decreased reward_duration_target_acquired to 30ms or 40ms. Also, in this case, the solenoid didn’t open but the codes were still sent. The fixation_requirement_stimulus is 50ms so it does seem like overlapping is the problem here.

Thanks for testing that. Yes, it seems like an overlap must be the issue, and thinking about it some more, I believe there is actually a way that the two code sends could interfere with each other. I think the symptom of this would be that, instead of the Blackrock data containing one e_stimulus_success and one e_reward_off, it would contain two e_reward_off’s and no e_stimulus_success. Is that something you see?

In any case, it seems like we need a more robust mechanism for preventing overlaps. Let me work on that a bit and get back to you.

Cheers,
Chris

Hi Chris,

I just checked and the Blackrock data indeed contains two e_reward_off and no e_stimulus_success.

No rush at all and thank you!

Best,
Taylor

Hi Taylor,

We would like to switch between channels in some of the protocols and would like to give the mode names (i.e. “mode_1”, “mode_2”, etc. ) a variable name so we can call the variable name directly in a state rather than hard-coding “mode_1” or “mode_2” in the protocol.

Apologies for not responding sooner.

I’m not 100% sure that I understand what you want to do, but I’m pretty sure you’re confused about the difference between component parameters and variables.

Taking a look at the start of the definition of a QCUALOR device:

iodevice/qcualor laser (
    mode_1 = mode_1
    ...

The “mode_1” on the left is a parameter name and refers to the mode_1 parameter of the QCUALOR device. The “mode_1” on the right is a variable name. The variable is declared elsewhere in your experiment, with a statement like

var mode_1 = 'continuous'

In the device definition, “mode_1 = mode_1” means “take the value for the parameter named mode_1 from the variable named mode_1”. This might be clearer if the variable had a different name. For example:

var channel_1_mode = 'continuous'
var channel_2_mode = 'off'

iodevice/qcualor laser (
    mode_1 = channel_1_mode
    mode_2 = channel_2_mode
    ...

To change the mode of a laser channel, you have to change the value of the variable that is assigned to the parameter for that mode, e.g.

channel_1_mode = 'sinusoidal'

If you want to change the active channel, you have to do two such assignments: one to turn off the current channel, and another to turn on the new channel, e.g.

channel_1_mode = 'off'
channel_2_mode = 'continuous'

If your goal is to avoid writing the “if” statements mapping laser_type to channel modes multiple times, maybe try using a macro like this:

%define set_laser_channel (mode_var, mode_type)
    assignment(
        variable = mode_var
        value = {
            0: 'off',
            1: 'continuous',
            2: 'sinusoidal',
            3: 'inverse_sinusoidal',
            4: 'square'
            }[mode_type]
        )
%end

Then, to turn channel 1 off and set channel 2 to the mode specified by laser_type:

set_laser_channel (
    mode_var = mode_1
    mode_type = 0
    )

set_laser_channel (
    mode_var = mode_2
    mode_type = laser_type
    )

Does that get you closer to your goal?

Cheers,
Chris

Hi Chris,

Thank you for the explanation. I was indeed a little confused.

I think the macro you suggested works for our current protocols and I just tried implementing it. I ran into the same problem, though, where only channel 2 was activated when I tried to switch the channels. I put the macro in the config_Laser file and in the protocol where we test 4 channels, I have something like this:

laser_type = selection_matrix[current_selection]

if (laser_channel == 1){
set_laser_channel (
mode_var = mode_1
mode_type = laser_type
)
}
if (laser_channel == 2){
set_laser_channel (
mode_var = mode_2
mode_type = laser_type
)
}
if (laser_channel == 3){
set_laser_channel (
mode_var = mode_3
mode_type = laser_type
)
}
if (laser_channel ==4){
set_laser_channel (
mode_var = mode_4
mode_type = laser_type
)
}

Everything else in the config_Laser is unchanged but it wasn’t activating other channels when I changed the laser_channel to a different number. The laser_type is taken out from a matrix consists of 0 to 4. Do you have any idea why?

Best,
Taylor

Hi Taylor,

I ran into the same problem, though, where only channel 2 was activated when I tried to switch the channels.

Are you stopping and restarting the laser after changing the channel modes? The changes won’t take effect until you do so.

Also, I don’t think I have your config_Laser file. Could you send me that, so I can take a look?

Thanks,
Chris

Hi Chris,

I have a turn_laser_on definition that is similar to the dispense_juice definition. turn_laser_on starts the laser and stops it after the laser_on_duration. I also changed the channel modes before I started the protocol so the whole thing should be restarted. In my last test, the channel was only switched if I went into the config_Laser to set mode_1 = mode_1 and other channel mode = ‘off’ in the definition of the QCUALOR device and reload the experiment.

I’ve attached the latest version of the config_Laser. Thank you for taking a look!

Best,
Taylor

config_Laser.mwel (4.93 KB)

Hi Taylor,

I have a turn_laser_on definition that is similar to the dispense_juice definition. turn_laser_on starts the laser and stops it after the laser_on_duration.

That looks good.

In my last test, the channel was only switched if I went into the config_Laser to set mode_1 = mode_1 and other channel mode = ‘off’ in the definition of the QCUALOR device and reload the experiment.

As I said previously, to change the mode of a laser channel, you have to change the value of the variable that is assigned to the parameter for that mode. From your laser device definition:

iodevice/qcualor laser (
    ...
    mode_1 = 'off'
    mode_2 = mode_2
    mode_3 = 'off'
    mode_4 = 'off'
    ...
    )

Only parameter mode_2 has a variable assigned to it. The other mode parameters are all set to the constant “off”, which means that there is no way to change them.

You need to assign a variable to the mode parameter for every laser channel that you want to use in your experiment, like this:

var mode_1 = 'off'
var mode_2 = 'off'
var mode_3 = 'off'
var mode_4 = 'off'

iodevice/qcualor laser (
    ...
    mode_1 = mode_1
    mode_2 = mode_2
    mode_3 = mode_3
    mode_4 = mode_4
    ...
    )

Then, within your protocol, use set_laser_channel to set the mode of the desired channel(s).

Does that make sense?

Chris

Hi Chris,

Ah it makes sense! I thought I was changing the mode parameter in the QCUALOR definition in the protocol but now it makes sense. I’m out of office today but I’ll take a closer look and do more testing next week.

Thank you for taking a look!

Best,
Taylor