relative vs absolute stimulus file paths

Apparently, Superlab keeps two paths in its scenario file for each external stimulus file or folder, one an absolute path from the filesystem root, the other a relative path from the last place that the scenario was saved. If you move the scenario file and/or the stimuli somewhere else, if either the absolute or the relative path still works, the other is updated to the new location both while running and also if the scenario is saved. If neither works, you have to specify the new location.

Based on some testing, plus on how the experiment package feature works, it looks like superlab tries the relative path first, then the absolute path. What I’d like to know is whether this is always true. Can I count on the relative path being used first, so that if I copy an experiment hierarchy (scenario and stimuli) to another location, it will use the stimuli in the copy (relative path), not the stimuli in the original location (absolute path)? (Assume that both paths point to stimuli with the same file names, but different contents.)

I ask because I want to make copies of an experiment and then modify some of the stimuli in the copy while using the same file names, to avoid having to alter each scenario.

If not, I see two workarounds: I could make sure the original location is not there when running experiments, or I could use a binary editor like bbe to scribble x’s over all the absolute paths in the scenario before copying it. However, it would be more convenient not to do this.

Cheers,
Greg Shenaut

Another file path complication

It appears that if a stimulus list file folder is actually a symbolic link, the link is not used, instead, the target of the link is used, for both the absolute and relative path. It’s apparently OK if all of the individual files within a folder are symbolic links, but the folder itself cannot be one.

This is only a minor inconvenience, and it may well be an artifact of the need to canonicalize the path to the folder as part of providing both relative and absolute paths. However, it is something to be aware of if you’re setting up a complex experimental hierarchy.

Greg Shenaut

Logfile folder and symlinked scenario files

If instead of copying the scenario file into a new hierarchy, you symlink it, the option to save the logfile in the same folder as the experiment scenario is broken–it doesn’t go in the folder where the link is, it goes into the link target’s folder. I suppose the remaining options are to use a hard link or to make a copy.

To explain, suppose you set up folder subj1 with an experiment scenario file called foo.sl4, referring to stimuli in folder subj1/stim. It is set to save the results in the same folder as the experiment file. You then set up subj[2-8] all with subfolder stim, but where the stim subfolder has different contents. To save space, you symlink the scenario file into each subj[2-8] folder, and start superlab by opening the link, for example, subj4/foo.sl4. As established above, superlab will in fact use the relative path first, and therefore, will use the local stimuli. However, it will try to put the results into the target of the link, namely, subj1.

On the other hand, if you use a hard link or copy the scenario into each of the other folders subj[2-8], then it will by default save the data in the local folder.

Personally, I think superlab should always use the symlink itself, never the symlink target, for all filesystem paths. This is the kind of thing that can really confuse a user–a copy or hard link working one way, a symbolic link working completely differently. In any case, it’s something else to be aware of.

Greg

To answer your first question: yes, the relative path is always checked first. We do this precisely for the reason you are asking.

Regarding symlinks, check out the results of the following:

$ cd /etc
$ pwd
/private/etc

The behavior you’re observing with symlinks is as expected by the Posix standard.

cd ?

So superlab uses chdir to load stimuli? This seems unnecessary (and wrong?) to me.

To me, the more relevant example would be:

$ x=/etc

$ echo $x
/etc

$ ls $x
[contents of /private/etc get printed]

My point is only that symbolic links are very useful for setting up complex, redundant hierarchies, and it seems unfortunate to me that superlab converts them all to absolute paths. However, there are workarounds for most situations, especially once the basic principle is understood.

Cheers,
Greg

P.S.
On my system, at least with ksh, bash, and csh, if you cd to /etc and run pwd, you get “/etc”, not “/private/etc”.

I ran with tcsh (on 10.5), and it gave the above results, as did csh. Bash and ksh did not. No, SuperLab doesn’t use chdir to load stimuli. That was just an example.

SuperLab uses wxWidgets for all of this stuff, and wxWidgets uses Apple’s APIs. The Navigation Dialog in OS X returns File System references (NavDialogGetReply FSRef). We want a path, so the path is retrieved using CFURLCreateFromFSRef. Since this is a file system reference, it’s the actual path of the file that is returned instead of the path chosen in the dialog through symlinks.

As shown by the differences in how the various shells handle symlinks, it seems there’s pretty clearly some debate on how things should be done. Regardless, this is how Apple is providing the information to programs, so this is the information that is used.

Remember, though, that Apple treats Aliases differently from how they treat symlinks. Try making an alias in the Finder instead–see if you get a different behavior that way.

And btw, the Posix standard would argue that bash and ksh are wrong.

If a symbolic link is encountered during pathname resolution, the behavior shall depend on whether the pathname component is at the end of the pathname and on the function being performed. If all of the following are true, then pathname resolution is complete:[LIST=1]

  • This is the last pathname component of the pathname.
  • The pathname has no trailing slash.
  • The function is required to act on the symbolic link itself, or certain arguments direct that the function act on the symbolic link itself.[/LIST]In all other cases, the system shall prefix the remaining pathname, if any, with the contents of the symbolic link. ... [T]he resolved pathname shall be the resolution of the pathname just created. If the resulting pathname does not begin with a slash, the predecessor of the first filename of the pathname is taken to be the directory containing the symbolic link.

    The argument could be made that this is supposed to be invisible to the user, but that’s not stated. This being an IEEE standard, I think that would imply that making it invisible to the user is technically incorrect.
    :cool:

  • But

    the text you cited talks about how the system resolves symbolic links, and doesn’t address whether it’s OK for programs to store them unresolved or not.

    POSIX or not, if you store a path with symbolic links in a variable and then later retrieve it, the links aren’t going to get canonicalized or changed in any other way along the way. At least, not simply as part of storing it and retrieving it.

    When you browse for a stimulus folder, it is quite possible for you (well, me) to believe that you have specified a symbolic link. That is, while you are navigating graphically, symbolic links pointing to folders are treated just like folders. However, what gets stored in the scenario is always, as we have seen, the canonicalized version of the path, never containing a symbolic link. In other words, what you see is NOT what you get.

    That was really my point. In fact, had this thread existed before I started my latest project, it would have saved me some grief so hopefully we have made the point strongly enough for people to understand: all symbolic links followed in setting up superlab scenario files, explicitly or implicitly, are converted to absolute paths before being stored in the scenario file.

    The folders can be filled with symbolic links, but they can’t be symbolic links themselves.

    Cheers,
    Greg