[RESOLVED] Question with 'join_fidl' and 'join_fidl_folder'

Hi, all

I am trying to perform activation analysis on task fMRI. But there was a problem encountered during the join_fidl and join_fidl_folder stages. In my data, one participant had two traits of task fMRI, namely bold3 in the AP direction and bold4 in the PA direction. Each trail participant is required to perform three actions (each action needs to be performed twice), which means that each trail contains six random actions.

I want to know if using join_fidl_folder is correct in this situation. I saved .conc file in the concs folder and two .fidl files in the fidls folder.

Below is my .conc and .fidl files.

STG005.conc:

number_of_files: 2
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold3_Atlas.dtseries.nii
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold4_Atlas.dtseries.nii

STG005_bold3.fidl

0.8  encoding delay
28.0  1  28
84.0  2  28
140.0  0  28
196.0  1  28
252.0  0  28
308.0  2  28

STG005_bold4.fidl

0.8  encoding delay
28.0  2  28
84.0  0  28
140.0  1  28
196.0  2  28
252.0  0  28
308.0  1  28

my code:

    join_fidl_folder)
		qunex_container join_fidl_folder\
            --concfolder="/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/concs" \
            --fidlfolder="/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/fidls" \
            --bind="${SDIR}:${SDIR}" \
            --container="${QUNEX_CONTAINER}";
		;;

Now I’m not sure whether organizing files and folders like this is correct. And after running, an error was reported.

--- Full QuNex call for command: join_fidl_folder

qunex join_fidl_folder --concfolder="/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/concs" --fidlfolder="/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/fidls"

---------------------------------------------------------
started running join_fidl_folder at 2025-08-22 11:59:20, track progress in /mnt/ssd2/qzheng/STG_all/qunex/comlogs/tmp_join_fidl_folder_2025-08-22_11.59.20.967435.log
call: gmri join_fidl_folder concfolder="/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/concs" fidlfolder="/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/fidls"
-----------------------------------------

---> reading STG005.conc
 ... 2 bolds: 005 

ERROR
Traceback (most recent call last):
  File "/opt/qunex/python/qx_utilities/general/core.py", line 735, in runWithLog
    result = function(**args)
             ^^^^^^^^^^^^^^^^
  File "/opt/qunex/python/qx_utilities/general/fidl.py", line 249, in join_fidl_folder
    join_fidl(concfile, root, outfolder, fidlname)
  File "/opt/qunex/python/qx_utilities/general/fidl.py", line 149, in join_fidl
    bolddata = readConc(concfile, TR)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/qunex/python/qx_utilities/general/fidl.py", line 94, in readConc
    length = boldInfo(boldfile).frames * TR
             ^^^^^^^^^^^^^^^^^^
  File "/opt/qunex/python/qx_utilities/general/fidl.py", line 50, in boldInfo
    hdr = gi.niftihdr(boldfile)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/qunex/python/qx_utilities/general/img.py", line 387, in __init__
    self.readHeader(filename)
  File "/opt/qunex/python/qx_utilities/general/img.py", line 571, in readHeader
    self.unpackHdr(h)
  File "/opt/qunex/python/qx_utilities/general/img.py", line 472, in unpackHdr
    e, = struct.unpack(">i", s.read(si))                        # int       - must be 348
                             ^^^^^^^^^^
  File "<frozen codecs>", line 322, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc7 in position 56: invalid continuation byte


-----------------------------------------
Finished at 2025-08-22 11:59:20
singularity exec --bind /home/qzheng,/mnt/ssd2/qzheng/STG_all:/mnt/ssd2/qzheng/STG_all --cleanenv /mnt/ssd2/qzheng/STG_all/qunex/qunexcontainer/qunex_suite-1.3.0.sif bash /home/qzheng/qunex/qunex_container_command_2025-08-22_11.59.17.288060.sh

I have tried using iconv -f US-ASCII -t UTF-8 STG005.conc > STG005_utf8.conc to convert .conc and .fidl files. But the format printed using file -i STG005_utf8.conc is still ‘us-ascii’. If I use printf ‘\xEF\xBB\xBF’ | cat - STG005.fidl > STG005_utf8.fidl to force the file to be converted to UTF-8 format, I will report this error ValueError: could not convert string to float: '\ufeff0.8. So how should I solve the above problems.

Thanks a lot!

Best, Kelly

Hi Kelly,

I will get one of my colleagues who is an expert on this to help you out.

Best, Jure

Thanks so much!!

Looking forward to your and your colleagues’ reply.

Best, Kelly

Kelly, hi!

Yes, using join_fidl or join_fidl_folder would be correct in this situation. The .conc file looks ok. The two .fidl files have the correct structure, however, the content is not ok. Your header line, specifies two events, encoding and delay, the first would have index 0, the second index 1. In the following lines, however, the fidl file lists in the second column indeces 0, 1 and 2. It seems that a third event is missing in the header.

If the STG005.conc is in /mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/concs and the two .fidl files, named as indicated in /mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/fidls, then your setup is correct.

The problem, which is unfortunately not mentioned in the documentation, arises when the code tries to read the header information to extract the information about BOLD file length. Namely, it assumes that the image files are NIfTI-1 and not NIfTI-2 (CIFTI) files. We have prepared the new CIFTI reading code in a developmental feature branch but have not yet integrated it into master. While we do that, you can adjust the .conc file to point to the volume versions of the files, e.g.:

number_of_files: 2
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold3.nii.gz
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold4.nii.gz

This will enable the code to correctly read the length of the BOLD files and adjust the timing of the events for the second bold run accordingly. Of course, in the analysis you can use the resulting fidl files to work with either volume .nii.gz or cifti dtseries.nii files.

Hope this helps.

All the best,

Grega

Hi, Grega

Thanks very much for your kindly help, I have successfully completed the join_fidl_folder step using your method. But now I have a new error in preprocess_conc. Could you help me find the problem?

Here is my code. I referred to the example code provided in the documentation. But I don’t know whether my understanding of event_file is correct.

		qunex_container preprocess_conc\
            --batchfile="${WORK_DIR}/${STUDY_NAME}/processing/batch.txt" \
            --sessionsfolder="${WORK_DIR}/${STUDY_NAME}/sessions" \
            --overwrite=no \
            --parsessions=10 \
            --bolds="3,4" \
            --event_file="${WORK_DIR}/${STUDY_NAME}/sessions/inbox/fidls/STG005.fidl" \
            --glm_name=-M1 \
            --bold_actions="s,r,c" \
            --bold_nuisance=e \
            --mov_bad=none \
            --event_string="block:boynton|target:9|target:9>target_rt:1:within:z" \
            --glm_matrix=both \
            --glm_residuals=none \
            --pignore="hipass=keep|regress=keep|lopass=keep" \
            --bind="${SDIR}:${SDIR}" \
            --container="${QUNEX_CONTAINER}";
		;;

And the error is:

Session id: STG005 
[started on Wednesday, 27. August 2025 13:42:09]
Running Preprocessing conc bundles ...
Files in 'images/functional will be processed.

Conc bundle: 3,4
... ERROR: Conc data file (3,4) does not exist in the expected locations! Skipping this conc bundle.

Conc preprocessing (v2) completed on Wednesday, 27. August 2025 13:42:09
---------------------------------------------------------


---> Final report for command preprocess_conc
... STG005 ---> 
---> Not all tasks completed fully!

---> QuNex will run the command over 1 sessions. It will utilize:

    Maximum sessions run in parallel for a job: 10.
    Maximum elements run in parallel for a session: 1.
    Up to 10 processes will be utilized for a job.

    Job #1 will run sessions: STG005
singularity exec --bind /home/qzheng,/mnt/ssd2/qzheng/STG_all:/mnt/ssd2/qzheng/STG_all --cleanenv /mnt/ssd2/qzheng/STG_all/qunex/qunexcontainer/qunex_suite-1.3.0.sif bash /mnt/ssd2/qzheng/STG_all/qunex/STG_all/processing/logs/batchlogs/qunex_container_command_2025-08-27_13.42.05.429411.sh

Thanks a lot!

Best, Kelly

Hi Kelly,

Can you please also uploade the .fidl file so we have all required information. Thanks!

Best, Jure

Hi Jure,

Here is my .conc file –– STG005.conc

number_of_files: 2
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold3.nii.gz
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold4.nii.gz

These are the two .fidl file I created —- STG005_bold3.fidl & STG005_bold4.fidl

STG005_bold3.fidl

0.8  1_dsw  2_qtkh  3_jyl
28.0  1  28
84.0  2  28
140.0  0  28
196.0  1  28
252.0  0  28
308.0  2  28

STG005_bold4.fidl

0.8  1_dsw  2_qtkh  3_jyl
28.0  2  28
84.0  0  28
140.0  1  28
196.0  2  28
252.0  0  28
308.0  1  28

After running join_fidl_folder and check_fidl, I get STG005.fidl, the content is as follows:

0.8  1_dsw  2_qtkh  3_jyl
28	1	28
84	2	28
140	0	28
196	1	28
252	0	28
308	2	28
392	2	28
448	0	28
504	1	28
560	2	28
616	0	28
672	1	28

All the best,

Kelly

Kelly, hi!

Based on your setup, it seems you are trying to process a single participant with code STG005. All QuNex functionality is set up for processing multiple participants in a single step. In the case of preprocess_conc, the function expects the .fidl and .conc files to be stored in folders <sessionsfolder>/inbox/events and <sessionsfolder>/inbox/concs folders, respectively. They need to be named as <session id>_<event_file>.fidl and <session id>_<bolds>.fidl.

Let’s say that these are event and conc files that pertain to a spatial working memory task. In this case, you would save the event and conc files for your participant STG005 in the following locations:

/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/events/STG005_SWM.fidl
/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/inbox/concs/STG005_SWM.conc

In this case, your call should be:

qunex_container preprocess_conc \
  --batchfile="${WORK_DIR}/${STUDY_NAME}/processing/batch.txt" \
  --sessionsfolder="${WORK_DIR}/${STUDY_NAME}/sessions" \
  --overwrite=no \
  --parsessions=10 \
  --bolds="SWM" \
  --event_file="SWM" \
  --glm_name="-M1" \
  --bold_actions="s,r,c" \
  --bold_nuisance=e \
  --mov_bad=none \
  --event_string="1_dsw:spm|2_qtkh:spm|3_jyl:spm" \
  --glm_matrix=both \
  --glm_residuals=none \
  --pignore="hipass=keep|regress=keep|lopass=keep" \
  --bind="${SDIR}:${SDIR}" \
  --container="${QUNEX_CONTAINER}";

QuNex will, based you the batch file, find that you want to process session STG005. Based on parameter event_file it will look for file STG005_SWM.fidl in inbox/events folder, and based on parameter bods for the STG005_SWM.conc file in inbox/concs. Importantly, it will copy these two files into sessions/STG005/images/functional/events/SWM.fidl and sessions/STG005/images/functional/concs/bold_nifti_SWM.conc. If you run the command again, if will look for these files in these locations first, and only if it does not find them, it will look for them in inbox again. I note this, because, if you change the files later on – for instance, you adjust the timing or other information in the fidl file –, you need to delete the old fidl files in individual sessions folders first.

Warning: In your fidl files, you define events: 1_dsw, 2_qtkh, and 3_jyl, however in your event_string, you refer to events block and target. The event names specified in the fidl files and event string have to match! So you either need to adjust the events in the fidl file to refer to block and target, or you need to change the event string to refer to 1_dsw, 2_qtkh, or 3_jyl. instead of block and target. Also, in your event string, you define a behavioral regresor based on the first extra column in the fidl file, that does not exist. … Ah, I see! You have copied the event_string from the example in the documentation. Ok. You need to adjust your event string. If the three events in the fidl file refer to three different blocks that you want to model separately, then an appropriate event string would be “1_dsw:boynton|2_qtkh:boynton|3_jyl:boynton", alternatively, if you would rather use SPM double gamma HRF function, you could use: “1_dsw:spm|2_qtkh:spm|3_jyl:spm". I have adjusted the example call above to reflect the corrected event string.

All the best,

Grega

Hi, Grega

Thank you so much for your help!! I am now able to complete the preprocess_conc step.
I want to observe the brain activation of actions 1_dsw, 2_qtkh, and 3_jyl, so I ran generalize_extract_roi_glm_values after the preprocess_conc according to the “visual schematic of QuNex steps”.

I don’t quite understand what file should be written into -- roif. According to the example, it is --roif='CCN.names' \. Does the. name file need to be handwritten or how should it be obtained?

my task.list file:

# Generated by QuNex 1.3.0 [QIO] on 2025-09-01_14.13.26.826489
#
session id: STG005
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold3_s_res-e-M1.nii.gz
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold4_s_res-e-M1.nii.gz
    roi:/mnt/ssd2/qzheng/STG_all/qunex/Schaefer2018_400Parcels_Kong2022_17Networks_order_FSLMNI152_2mm.nii.gz
    glm:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold_conc_MT_s_res-e-M1_Bcoeff.nii.gz
    conc:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/concs/bold_nifti_MT_s_res-e-M1.conc
    fidl:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/events/MT.fidl

my bold_nifti_MT_s_res-e-M1.conc file

number_of_files: 2
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold3_s_res-e-M1.nii.gz
    file:/mnt/ssd2/qzheng/STG_all/qunex/STG_all/sessions/STG005/images/functional/bold4_s_res-e-M1.nii.gz

my MT.fidl file

0.8  1_dsw  2_qtkh  3_jyl
28	1	28
84	2	28
140	0	28
196	1	28
252	0	28
308	2	28
392	2	28
448	0	28
504	1	28
560	2	28
616	0	28
672	1	28

code:

    general_extract_roi_glm_values)
        qunex_container general_extract_roi_glm_values \
            --sessionsfolder="${WORK_DIR}/${STUDY_NAME}/sessions" \
            --sessions="${SUBJ}" \
            --flist="lists/task.list" \
            --roif="/mnt/ssd2/qzheng/STG_all/qunex/Schaefer2018_400Parcels_Kong2022_17Networks_order_FSLMNI152_2mm.nii.gz" \
            --outf='' \
            --effects='1_dsw,2_qtkh,3_jyl' \
            --frames='' \
            --values='psc' \
            --tformat='long' \
            --bind="${SDIR}:${SDIR}" \
            --container="${QUNEX_CONTAINER}";
        ;;

Even though I used roif="/mnt/ssd2/qzheng/STG_all/qunex/Schaefer2018_400Parcels_Kong2022_17Networks_order_FSLMNI152_2mm.nii.gz, it ran successfully and I obtained the task.list_psc_long.tsv. I would like to know if what I’m doing is correct, and figure out how to use .name file.

Also, could you tell me how to visualize after obtaining the tsv file? I didn’t find any relevant information in the tutorial.

Thank you from the bottom of my heart. Your generosity with your time and knowledge was absolutely above and beyond. I’m so sorry for the trouble, and I am so thankful for your help!

Best, Kelly

Kelly, hi!

The roif refers to a roi definition file, which are described in more detail in the documentation. Besides the .names file, the parameter also accepts an image file. In this case, it assumes that the image codes the grayordinates that correspond to a region with the same integer, e.g., 1, 2, 3 .. 17 … The .names file would usually be constructed manually. It may refer to a parcellation, it could refer to results of general_find_peaks, and so on.

In your case, the results should be fine. The .tsv file generated should hold basic statistic for each parcel defined in Schaefer2018_400Parcels_Kong2022_17Networks_order_FSLMNI152_2mm.nii.gz, for each participant. QuNex does not provide any further tools for visualizing these results. We would usually import the data into R and visualize using ggplot2.

If you would like to visualize the whole brain results, you can just load the resulting glm file in any software that enables visualizing neuroimaging data. The file contains a volume for each estimated parameter including baseline, linear drift, mean and SD images. The order of volumes correspond to the design matrix that is present in the <session>/images/functional/glm. You can also extract volumes for specific parameters using the general_extract_glm_volumes command.

The exact pathway to visualization is really dependent on what you would like to show.

If you have specific idea, what you would like to show, let us know.

All the best,

Grega

Hi, Grega

Sorry, I’m here to trouble you again.

I would like to visualize the brain activation results for the three actions mentioned above separately. I used the glm file you mentioned, bold_conc_MT_s_res-e-M1_Bcoeff.nii.gz in , for visualization. When I opened it with Workbench, I saw a total of 9 maps in the ‘Map’ position. I don’t understand what these 9 maps represent. Bold3 and Bold4 contain a total of 3 actions, each action 4 times, for a total of 12 actions.

the result of bold_conc_MT_s_res-e-M1_Bcoeff.nii.gz is as below (all the voxels are almost red, but i want to see that only several regions are activated (if possible), like following second picture from “workbench tutorial data”

I referred to the tutorial on “Workbench Scene 7: tfMRI on surfaces and volume montage”. I want to know how I should organize the files to obtain the sufaces and volume activation result graph after processing with Qunex. I couldn’t find the *. 32k_fs.LR.scene file loaded in the tutorial in my process file. The example files include surface and volume. Currently, my processing method can only display the results of volume. What should I do if I want to add the results of surfaces?
I am currently very confused about how to achieve the desired results (each action corresponds to a brain activation map). I sincerely request your help to explain it.

Thank you very much!

Best, Kelly

Kelly, hi!

Sorry for the late response. I am a bit overwhelmed with obligations at the moment. Briefly, to know what each volume corresponds to, open the .txt file located at <session id>/images/functional/glm. There will be a line starting with # effects. The effects listed there name the volumes in the glm file. You only need this, if you are working with with volume files. When you are working with CIFTI files, the names will be indicated in the “Map” field in the Workbench.

To run the analysis on the CIFTI (combined surface/volume) representation, you need to adjust your preprocess_conc call:

qunex_container preprocess_conc \
  --batchfile="${WORK_DIR}/${STUDY_NAME}/processing/batch.txt" \
  --sessionsfolder="${WORK_DIR}/${STUDY_NAME}/sessions" \
  --overwrite=no \
  --parsessions=10 \
  --bolds="SWM" \
  --event_file="SWM" \
  --glm_name="-M1" \
  --bold_actions="s,r,c" \
  --bold_nuisance=e \
  --mov_bad=none \
  --event_string="1_dsw:spm|2_qtkh:spm|3_jyl:spm" \
  --glm_matrix=both \
  --glm_residuals=none \
  --pignore="hipass=keep|regress=keep|lopass=keep" \
  --bind="${SDIR}:${SDIR}" \
  --image_target="dtseries" \
  --container="${QUNEX_CONTAINER}";

The addition of --image_target="dtseries" informs QuNex to work with dtseries CIFTI files instead of NIFTI volume images. When this is run, you will have GLM images in dtseries format.

I do need to warn you, that your results will be a beta estimates map, not a statistical significance map. To obtain those, you would usually run a second-level analysis using PALM over a number of participants. It is possible to compute a p-value for a single GLM, however, as this is such a rare case, QuNex currently does not offer a function to compute that. It is possible to do it in matlab using QuNex matlab library. If you need that, let me know and we can prepare an example script.

All the best,

Grega

Hi, Grega

I see! Thank you very much for your help, I have completely understood. I will try using PALM to run a secondary analysis on a number of participants next.
Thanks a lot again!

Best, Kelly