Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

creating nested blocks and trials

Hello everyone,

I've been staring at this code for too long and don't seem to find the problem to the error messge: 'Block' object has no attribute 'trials'

The problem must lie in the design - when I build the hierarchy - but I double checked if I add all the trials to the block and the blocks to the experiment - and I checked whether I reach every level of the nested loops, and they do.

(I copy and paste the code, b/c there it doesn't allow me to upload an image eventhough it has a .jpg / .png extension? - SORRY)



# create experiment object

exp = design.Experiment(name='Inversion Effect')

control.initialize(exp)


# Define experiment hierarchy

# each category_block (faces_chairs, bodies_chairs) consits of 256 trials = total of 512 trials

for category_block_order in ['faces_chairs', 'bodies_chairs']:

  # each category_block is split up into 8 small experiments consiting of 32 trials each

  # --> each small experiment is represented by a block object (16 blocks in total - 8 faces_chairs + 8 bodies_chairs)

  for small_exp in range(8):

    block = design.Block()

    block.set_factor("category_order", category_block_order)


    #prepare variables needed based on between_subject variable

    if category_block_order == 'faces_chairs':

      categories = ['faces', 'chairs']

    else:

      categories = ['bodies', 'chairs']

    #prepare main path to get the stimuli

    path = Path.cwd() / category_block_order


    #each small experiment consists of 4x 8 unique conditions = 32 trials in total

    #Condition Design - 2x2x2 design: CATEGORY x ORIENTATION x DIRECTION --> 8 unique conditions

    for category in categories:

      for orientation in ['upright', 'inverted']:

        for direction in ['facing', 'non_facing']:

          trial = design.Trial()

          #get random path to one image within the stimulus_type

          stim_paths = path / category / orientation / direction

          if category == 'faces':

            stimulus = random.choice(list(stim_paths.rglob("*.tif")))

          else:

            stimulus = random.choice(list(stim_paths.rglob("*.jpg")))

          #get path to one mask

          mask_paths = path / 'masks'

          mask = random.choice(list(mask_paths.rglob("*.jpg")))

          #add stimulus and mask to trial

          trial.set_factor('target_stimulus', str(stimulus))

          trial.set_factor('orientation', orientation)

          trial.set_factor('direction', direction)

          trial.set_factor('mask', str(mask))

          #add the trial to the small experiment block

          block.add_trial(trial, copies=4)

    #shuffle the small experiment block and add the small experiment as a block to the experiment

    block.shuffle_trials()

    exp.add_block(block)



Any Ideas why this code doesn't properly create/initializes the block and trial objects?

Error message when calling trials/blocks:

for block in exp.blocks:

for trial in block.trials:

Comments

  • edited September 5

    Unfortunately, the example you posted has several other mistakes (unrelated to the one you are describing), which prevents the script from running and getting to the error message you descibe.


    I attempted to bypass these other mistakes, in order to get at least a running script:

    import os
    
    from expyriment import design, control
    
    
    control.set_develop_mode()
    
    # create experiment object
    exp = design.Experiment(name='Inversion Effect')
    control.initialize(exp)
    
    # Define experiment hierarchy
    
    # each category_block (faces_chairs, bodies_chairs) consits of 256 trials = total of 512 trials
    
    for category_block_order in ['faces_chairs', 'bodies_chairs']:
    
     # each category_block is split up into 8 small experiments consiting of 32 trials each
    
     # --> each small experiment is represented by a block object (16 blocks in total - 8 faces_chairs + 8 bodies_chairs)
    
     for small_exp in range(8):
       block = design.Block()
       block.set_factor("category_order", category_block_order)
    
       #prepare variables needed based on between_subject variable
       if category_block_order == 'faces_chairs':
         categories = ['faces', 'chairs']
       else:
         categories = ['bodies', 'chairs']
    
       #prepare main path to get the stimuli
       path = os.path.join(os.path.curdir, category_block_order)
    
       #each small experiment consists of 4x 8 unique conditions = 32 trials in total
       #Condition Design - 2x2x2 design: CATEGORY x ORIENTATION x DIRECTION --> 8 unique conditions
    
       for category in categories:
         for orientation in ['upright', 'inverted']:
           for direction in ['facing', 'non_facing']:
             trial = design.Trial()
             #get random path to one image within the stimulus_type
             stim_paths = os.path.join(path, category, orientation, direction)
             if category == 'faces':
               stimulus = "test.jpg" #random.choice(list(stim_paths.rglob("*.tif")))
             else:
               stimulus = "test.jpg" #random.choice(list(stim_paths.rglob("*.jpg")))
             #get path to one mask
             mask_paths = os.path.join(path, 'masks')
             mask = "test.jpg" #random.choice(list(mask_paths.rglob("*.jpg")))
             #add stimulus and mask to trial
             trial.set_factor('target_stimulus', str(stimulus))
             trial.set_factor('orientation', orientation)
             trial.set_factor('direction', direction)
             trial.set_factor('mask', str(mask))
             #add the trial to the small experiment block
             block.add_trial(trial, copies=4)
       #shuffle the small experiment block and add the small experiment as a block to the experiment
       block.shuffle_trials()
       exp.add_block(block)
    
    for block in exp.blocks:
       for trial in block.trials:
           print(trial)
    


    This script does not result in the mistake you are referring to. If you could provide me with a fully working example (i.e. something that directly results in the error message you see, without all the other mistakes that prevent it from running), then I can have another look if you want.


    Best,

    Florian

  • Hi Florian,

    thanks for the quick answer - could you maybe specify what the "several other mistakes" are?

    As to the changes you made, I want to use the pathlib libary since I will be runnig the experiment from a different hardware than the one I am writing it on at the moment, and pathlib is my preferred use anyway. I don't see any other changes in terms of structure, you just replaced all pathlib version with the os libary.. but in the end I am also passing a string to the trial.set_factor() argument.

    Best, Sarah

  • The script does not run, because it misses import statements (and it was not clear what packages need to be imported, such as pathlib), and that it uses stimuli that I don't have.

    So fixing these (now with using pathlib, not that it makes a difference):

    from pathlib import Path
    import random
    
    from expyriment import design, control
    
    control.set_develop_mode()
    
    # create experiment object
    exp = design.Experiment(name='Inversion Effect')
    control.initialize(exp)
    
    
    # Define experiment hierarchy
    # each category_block (faces_chairs, bodies_chairs) consits of 256 trials = total of 512 trials
    for category_block_order in ['faces_chairs', 'bodies_chairs']:
      # each category_block is split up into 8 small experiments consiting of 32 trials each
      # --> each small experiment is represented by a block object (16 blocks in total - 8 faces_chairs + 8 bodies_chairs)
      for small_exp in range(8):
        block = design.Block()
        block.set_factor("category_order", category_block_order)
        #prepare variables needed based on between_subject variable
        if category_block_order == 'faces_chairs':
          categories = ['faces', 'chairs']
        else:
          categories = ['bodies', 'chairs']
        #prepare main path to get the stimuli
        path = Path.cwd() / category_block_order
        #each small experiment consists of 4x 8 unique conditions = 32 trials in total
        #Condition Design - 2x2x2 design: CATEGORY x ORIENTATION x DIRECTION --> 8 unique conditions
        for category in categories:
          for orientation in ['upright', 'inverted']:
            for direction in ['facing', 'non_facing']:
              trial = design.Trial()
              #get random path to one image within the stimulus_type
              stim_paths = path / category / orientation / direction
              if category == 'faces':
                #stimulus = random.choice(list(stim_paths.rglob("*.tif")))
                stimulus = "test_face_stim.png"
              else:
                #stimulus = random.choice(list(stim_paths.rglob("*.jpg")))
                stimulus = "test_other_stim.png"
              #get path to one mask
              mask_paths = path / 'masks'
              #mask = random.choice(list(mask_paths.rglob("*.jpg")))
              mask = "test_mask.png"
              #add stimulus and mask to trial
              trial.set_factor('target_stimulus', str(stimulus))
              trial.set_factor('orientation', orientation)
              trial.set_factor('direction', direction)
              trial.set_factor('mask', str(mask))
              #add the trial to the small experiment block
              block.add_trial(trial, copies=4)
        #shuffle the small experiment block and add the small experiment as a block to the experiment
        block.shuffle_trials()
        exp.add_block(block)
    
    
    for block in exp.blocks:
        for trial in block.trials:
            print(trial)
    

    Again, this works just fine, and the trials are printed as you would expect. In other words, with the code you gave me, I cannot reproduce the error you are getting. Hence my suspicion that there is something happening in the parts of your script that I don't see (since you posted an incomplete script). If you don't want to send the entire code, could you create a minimal example in which you get this error?


    Thanks,

    Florian

  • Hi,

    sorry for not including everything, since I cannot upload a image of the code I didn't want to paste the whole experiment. But since the bug is still not fixed, and the mistake, as you convinced me must be in another part i will just upload the experiment as a .txt file

    - There are a lot of stimuli, and I don't think I am allowed to share them but some details:

    #stimulus = random.choice(list(stim_paths.rglob("*.tif")))
    

    so there is a directory called 'faces' which contains images of faces, which are in a .tif format, and there are 30 different faces so I want to randomly choose one each time.

    #stimulus = random.choice(list(stim_paths.rglob("*.jpg")))
    

    other two directory are called 'bodies' and 'chairs' and they contain 30 different images each which are in .jpg format, which I again want to choose randomly each time.

    same goes for the masks - there is a 'mask' directory with 240 different masks and I randomly want to choose one each time.


    Thank you for your quick help - Best,

    Sarah

  • Maybe this helps:

    I put a print(exp.block) into the design part - this is the output of one block - all 16 blocks are created but no trials are added... any thoughts?

    Block None: faces_chairs block: 0
    
      block factors: category_order = faces_chairs
    
      n trials: 0
    
      trial IDs = []
    
      trial factors:
    


  • If I fix the typo in line 101 from

    for trial in block.trails:

    to

    for trial in block.trials:


    and then also replace in line 135

    if (button == d) and (dir == 'facing'):

    with

    if (button == misc.constants.K_d) and (dir == 'facing'):


    and in line 140

    if (button == k) and (dir == 'facing'):

    with

    if (button == misc.constants.K_k) and (dir == 'facing'):


    all seems to run fine?

  • Printing the variable block after line 88:


    Block 0: unnamed
       block factors: category_order = faces_chairs
       n trials: 32
       trial IDs = [1, 25, 7, 23, 17, 21, 0, 26, 2, 12, 11, 20, 24, 31, 29, 8, 28, 19, 22, 13, 5, 3, 6, 27, 15, 18, 16, 14, 30, 10, 9, 4]
       trial factors: target_stimulus = [C:\Users\flokra\Downloads\sarah_forum\faces_chairs\chairs\inverted\facing\Stim1.tiff, C:\Users\flokra\D
    ownloads\sarah_forum\faces_chairs\chairs\inverted\non_facing\Stim1.tiff, C:\Users\flokra\Downloads\sarah_forum\faces_chairs\chairs\upright\fa
    cing\Stim1.tiff, C:\Users\flokra\Downloads\sarah_forum\faces_chairs\chairs\upright\non_facing\Stim1.tiff, C:\Users\flokra\Downloads\sarah_for
    um\faces_chairs\faces\inverted\facing\Stim1.tiff, C:\Users\flokra\Downloads\sarah_forum\faces_chairs\faces\inverted\non_facing\Stim1.tiff, C:
    \Users\flokra\Downloads\sarah_forum\faces_chairs\faces\upright\facing\Stim1.tiff, C:\Users\flokra\Downloads\sarah_forum\faces_chairs\faces\up
    right\non_facing\Stim1.tiff]
                      orientation = [inverted, upright]
                      direction = [facing, non_facing]
                      mask = [C:\Users\flokra\Downloads\sarah_forum\faces_chairs\masks\Mask1.tiff, C:\Users\flokra\Downloads\sarah_forum\faces_c
    hairs\masks\Mask2.tiff]
    


    Seems correct to me.

  • ok wow, it really was just a typo, sorry and thank you for your help!

  • Your welcome.

Sign In or Register to comment.