User Tools

Site Tools


mbstring extension must be loaded in order to run mPDF
neuroimagen:bioface

Proyecto BIOFACE

Conversion DICOMs

Las imagenes contienen los siguientes protocolos,

[osotolongo@detritus bioface]$ for x in `find /nas/bioface_raw/B002/ -type f`; do dckey -k "SeriesDescription" ${x} 2>&1; done | uniq
AAhead_scout
AAhead_scout_MPR_sag
AAhead_scout_MPR_cor
AAhead_scout_MPR_tra
t1_mprage_sag_p2_iso
t2_space_dark-fluid_sag_p2_iso
pd+t2_tse_tra_p2_3mm
Mag_Images
Pha_Images
mIP_Images(SW)
SWI_Images
asl_3d_tra_iso_3.0_highres
asl_3d_tra_iso_3.0_highres_Mosaics
Perfusion_Weighted
Perfusion_Weighted_Mosaics
DTIep2d_diff_mddw_48dir_p3_AP 
DTIep2d_diff_mddw_48dir_p3_AP_Mosaics 
DTIep2d_diff_mddw_48dir_p3_AP_ADC 
DTIep2d_diff_mddw_48dir_p3_AP_TRACEW
DTIep2d_diff_mddw_48dir_p3_AP_FA
DTIep2d_diff_mddw_48dir_p3_AP_TENSOR
DTIep2d_diff_mddw_48dir_p3_AP_TENSOR_B0 
DTIep2d_diff_mddw_4b0_PA
PhoenixZIPReport
MPR sag 3mm Range 
MPR cor 3mm Range 
MPR tra 3mm Range 
MPR sag 3mm Range[2]
MPR cor 3mm Range[2]
MPR tra 3mm Range[2]

De aquí en principio nos interesan t1_mprage_sag_p2_iso para procesar las T1 con Freesurfer, DTIep2d_diff_mddw_48dir_p3_AP y DTIep2d_diff_mddw_4b0_PA para el procesamiento DTI.

Lo primero es preparar una base de datos anonimizada para el procesamiento. Los sujetos ya estan anonimizados pero es mejor tenerlos separados con los codigos de neuroimagen.

El script es simple, basado en MOPEAD

El output son tres archivos, los IDs de sujeto del proyecto y de neuroimagen,

[osotolongo@detritus bioface]$ cat ids.csv 
B002,1
B003,2
B006,3
B008,4
B009,5
...

identico pero con la cadena completa,

[osotolongo@detritus bioface]$ cat ni_names.csv 
B002,0001
B003,0002
B006,0003
B008,0004
B009,0005
...

y una lista de los directorios procesados,

[osotolongo@detritus bioface]$ cat converted_t1.csv 
B002
B003
B006
B008
B009
...

Extraccion de fechas

1,2,3.. probando

[osotolongo@detritus bioface]$ for x in /nas/bioface_raw/*; do d=$(for y in ${x}/*; do dckey -k "SeriesDate" ${y} 2>&1; done | head -n 1); n=$(echo ${x} | awk -F"/" '{print $4}'); echo ${n},${d}; done
B001,20180719
B002,20180907
.....

Es lento pero seguro,

[osotolongo@detritus bioface]$ for x in /nas/bioface_raw/*; do d=$(for y in ${x}/*; do dckey -k "SeriesDate" ${y} 2>&1; done | head -n 1); n=$(echo ${x} | awk -F"/" '{print $4}'); echo ${n},${d}; done > dcm_dates.csv

bien hecho, solo pregunto al primer file,

[osotolongo@detritus bioface]$ for x in /nas/bioface_raw/*; do d=$(for y in `ls ${x}/* | head -n 1`; do dckey -k "SeriesDate" ${y} 2>&1; done | head -n 1); n=$(echo ${x} | awk -F"/" '{print $4}'); echo ${n},${d}; done > dcm_dates.csv

Conversion

NIfTI

Igual que en MOPEAD. Convertimos todo primero. Lo almacenamos y despues escogemos los archivos necesarios para el procesamiento.

Codigo aqui

T1

Aqui almacenamos en la carpeta mri las imagenes con etiqueta t1_mprage_sag_p2_iso. Voy a utilizar el mismo archivo update_t1.pl que su uso para el proyecto MOPEAD.

solo hay que retocarlo un poco

Aqui tambien se genera el archivo converted_t1.csv que almacena los T1 que ya se han convertido. De esta manera las imagenes que ya se han copiado no se reprocesan de nuevo y se ahorra mucho tiempo.

El output son las T1 en el directorio mri del proyecto, listas para el procesamiento,

[osotolongo@detritus bioface]$ ls mri
bfa0001s0012.json    bfa0004s0012.json    bfa0007s0012.json    bfa0010s0012.json    bfa0013s0012.json    bfa0016s0012.json    bfa0019s0012.json    bfa0022s0012.json
bfa0001s0012.nii.gz  bfa0004s0012.nii.gz  bfa0007s0012.nii.gz  bfa0010s0012.nii.gz  bfa0013s0012.nii.gz  bfa0016s0012.nii.gz  bfa0019s0012.nii.gz  bfa0022s0012.nii.gz
bfa0002s0012.json    bfa0005s0012.json    bfa0008s0012.json    bfa0011s0012.json    bfa0014s0012.json    bfa0017s0012.json    bfa0020s0012.json    bfa0023s0012.json
bfa0002s0012.nii.gz  bfa0005s0012.nii.gz  bfa0008s0012.nii.gz  bfa0011s0012.nii.gz  bfa0014s0012.nii.gz  bfa0017s0012.nii.gz  bfa0020s0012.nii.gz  bfa0023s0012.nii.gz
bfa0003s0012.json    bfa0006s0012.json    bfa0009s0012.json    bfa0012s0012.json    bfa0015s0012.json    bfa0018s0012.json    bfa0021s0012.json    bfa0024s0012.json
bfa0003s0012.nii.gz  bfa0006s0012.nii.gz  bfa0009s0012.nii.gz  bfa0012s0012.nii.gz  bfa0015s0012.nii.gz  bfa0018s0012.nii.gz  bfa0021s0012.nii.gz  bfa0024s0012.nii.gz

DTI

La conversion es similar.

Se usa un script parecido,

Los DTI que se obtienen no son correctos. De los 22 obtenidos hay solo 5 que tienen los bval y bvec. Algun problema hay con el protocolo. Esto era un problema del dcm2niiix. He actualizado el dcm2niix y ahora todo procesa OK.

Para futuras actualizaciones:

$ git clone -b development https://github.com/rordenlab/dcm2niix.git
$ cd dcm2niix
$ mkdir build
$ cd build/
$ cmake
$ cp dcm2niix /nas/software/bin/
$ cp /nas/software/bin/dcm2niix /usr/local/mricron/
$ dcm2niix 
Chris Rorden's dcm2niiX version v1.0.20191031  GCC4.4.7 (64-bit Linux)
usage: dcm2niix [options] <in_folder>
......

ASL

Para convertir los ASL.

Ver https://asl-docs.readthedocs.io/en/latest/oxasl_userguide.html

Informes

Tengo los informes de las MRI en pdf asi que voy a intentar sacar los datos de atrofia de ahi.

Primero a convertir los PDF en algo util,

[osotolongo@brick03 informes]$ pwd
/nas/data/bioface/informes
[osotolongo@brick03 informes]$ mkdir txts
[osotolongo@brick03 informes]$ for x in *.pdf; do pdftotext ${x} txts/${x%.pdf}.txt; done

Ahora quiero sacar las atrofias que estan informadas estructuradamente,

[osotolongo@brick03 informes]$ grep "^Atrofia" txts/B001-20180611.txt 
Atrofia global grado 1    
Atrofia parietal grado (D/I) 1/1    
Atrofia temporal medial grado (D/I) 0/0    

Me hare un parser en Perl entonces,

parse0.pl
#!/usr/bin/perl
 
use strict;
use warnings;
use File::Find::Rule;
use File::Basename qw(basename);
use Data::Dump qw(dump);
 
my %rois = ('global' => 'AG',
	('parietal' => 'AP'),
	('tempo' => 'ATM') 
);
my $parse_dir = shift;
my @txts = find(file => 'name' => "*.txt", in => $parse_dir);
my %info;
foreach my $report (sort @txts){
	my $name = basename $report;
	$name =~ s/\.txt$//;
	foreach my $roi (sort keys %rois){
		unless($rois{$roi} eq 'AG'){
			$info{$name}{$rois{$roi}.'_I'} = "NA";
			$info{$name}{$rois{$roi}.'_D'} = "NA";
		}else{
			$info{$name}{$rois{$roi}} = "NA";
		}
	}
	open IDF, "<$report";
	my $this_line;
	while(<IDF>) {
	if (/^Atrofia/){
		foreach my $roi (sort keys %rois){
			if (/$roi/){
				if (/\(D\/I\)/){
					my ($gd,$gi) = /\(D\/I\).*(\d)\/(\d)/;
					$info{$name}{$rois{$roi}.'_I'} = $gi if defined $gi;
					$info{$name}{$rois{$roi}.'_D'} = $gd if defined $gd;
				}else{
					(my $gb) = /grado.*\d*-*(\d)/;
					$info{$name}{$rois{$roi}} = $gb if defined $gb;
 				}
			}
		}
	}	
	}
	close IDF;
}
 
print "Subject";
foreach my $roi (sort keys %rois){
	my $ch;
	unless ($rois{$roi} eq 'AG'){
		$ch = ','.$rois{$roi}.'_I,'.$rois{$roi}.'_D';
	}else{
		$ch = ','.$rois{$roi};
	}
	print "$ch";
}
print "\n";
foreach my $subject (sort keys %info){
	print "$subject";
	foreach my $roi (sort keys %rois){
		unless ($rois{$roi} eq 'AG'){
			my $ad = exists($info{$subject}{$rois{$roi}.'_D'})?$info{$subject}{$rois{$roi}.'_D'}:"NA";
			my $ai = exists($info{$subject}{$rois{$roi}.'_I'})?$info{$subject}{$rois{$roi}.'_I'}:"NA";
			print ",$ai,$ad";
		}else{
			my $ag = exists($info{$subject}{$rois{$roi}})?$info{$subject}{$rois{$roi}}:"NA";
			print ",$ag";
		}
 
	}
	print "\n";
}

y le digo que me haga el spider donde estan los txt,

[osotolongo@brick03 informes]$ ./parse0.pl txts/ > parsed_reports.csv
[osotolongo@brick03 informes]$ head parsed_reports.csv
Subject,AG,AP_I,AP_D,ATM_I,ATM_D
B001-20180611,1,1,1,0,0
B002-20170581,1,1,1,0,0
B003-20180364,NA,1,0,1,0
B004-20141541,0,NA,NA,NA,NA
B005-20180246,1,1,1,0,0
B006-20131186,0,NA,NA,NA,NA
B007-20161829,1,1,0,0,0
B008-20180298,0,0,0,0,0
B009-20171174,1,0,1,0,0

No saca todos pero si bastantes. 8-)

Recepcion V2

Aqui tenemos las imagenes nuevas,

[root@brick03 corachan]# ls BIOFACE_V2
B014  B035  B038  B048  B053  B056  B058  B060  B063  B069  B072  B076  B084  B106
B030  B037  B039  B050  B054  B057  B059  B061  B068  B070  B074  B078  B105

Asi que las subimos al XNAT,

[osotolongo@brick03 bioface]$ for x in $(ls /nas/corachan/BIOFACE_V2); do xnatapic upload_dicom --project_id bioface21 --subject_id ${x} --pipelines /nas/corachan/BIOFACE_V2/${x}; done

sacamos la lista de experimentos y los enviamos al pipeline,

[osotolongo@brick03 bioface]$ for x in $(ls /nas/corachan/BIOFACE_V2); do xnatapic list_experiments --project_id bioface21 --subject_id ${x} --modality MRI; done >> experiments.list
[osotolongo@brick03 bioface]$ for x in $(cat experiments.list); do xnatapic run_pipeline --project_id bioface21 --pipeline RunFreesurfer --experiment_id ${x}; done
[osotolongo@brick03 bioface]$ queue | grep XNAT
  163807      fast           RunFreesurfer.XNAT5_E01331     xnat PD       0:00      1 (Resources)
  163808      fast           RunFreesurfer.XNAT5_E01332     xnat PD       0:00      1 (Priority)
  163809      fast           RunFreesurfer.XNAT5_E01333     xnat PD       0:00      1 (Priority)
  163810      fast           RunFreesurfer.XNAT5_E01334     xnat PD       0:00      1 (Priority)
  163811      fast           RunFreesurfer.XNAT5_E01335     xnat PD       0:00      1 (Priority)
  163812      fast           RunFreesurfer.XNAT5_E01336     xnat PD       0:00      1 (Priority)
  163786      fast           RunFreesurfer.XNAT5_E01310     xnat  R       1:41      1 brick02
  163787      fast           RunFreesurfer.XNAT5_E01311     xnat  R       1:41      1 brick02
  163788      fast           RunFreesurfer.XNAT5_E01312     xnat  R       1:41      1 brick05
  163789      fast           RunFreesurfer.XNAT5_E01313     xnat  R       1:41      1 brick05
  163790      fast           RunFreesurfer.XNAT5_E01314     xnat  R       1:38      1 brick05
  163791      fast           RunFreesurfer.XNAT5_E01315     xnat  R       1:38      1 brick05
  163792      fast           RunFreesurfer.XNAT5_E01316     xnat  R       1:38      1 brick05
  163793      fast           RunFreesurfer.XNAT5_E01317     xnat  R       1:38      1 brick05
  163794      fast           RunFreesurfer.XNAT5_E01318     xnat  R       1:38      1 brick04
  163795      fast           RunFreesurfer.XNAT5_E01319     xnat  R       1:38      1 brick04
  163796      fast           RunFreesurfer.XNAT5_E01320     xnat  R       1:38      1 brick04
  163797      fast           RunFreesurfer.XNAT5_E01321     xnat  R       1:38      1 brick04
  163798      fast           RunFreesurfer.XNAT5_E01322     xnat  R       1:38      1 brick04
  163799      fast           RunFreesurfer.XNAT5_E01323     xnat  R       1:38      1 brick04
  163800      fast           RunFreesurfer.XNAT5_E01324     xnat  R       1:35      1 brick04
  163801      fast           RunFreesurfer.XNAT5_E01325     xnat  R       1:35      1 brick04
  163802      fast           RunFreesurfer.XNAT5_E01326     xnat  R       1:35      1 brick03
  163803      fast           RunFreesurfer.XNAT5_E01327     xnat  R       1:35      1 brick03
  163804      fast           RunFreesurfer.XNAT5_E01328     xnat  R       1:35      1 brick03
  163805      fast           RunFreesurfer.XNAT5_E01329     xnat  R       1:35      1 brick03
  163806      fast           RunFreesurfer.XNAT5_E01330     xnat  R       1:35      1 brick03

comprobando las MRI

Saco la columna de fecha de las mri y el codigo del sujeto del excel y lo savlo, luego lo convierto a algo potable,

[osotolongo@brick03 bioface]$ ./xls2csv.pl v2_mris.xlsx | grep -iv "no\|dropout\|ensayo" | awk -F"," '{if($1 && $2) print}' | sed 's/,$//' > citados.csv

y lo filtro segun la lista de los subidos,

[osotolongo@brick03 bioface]$ grep -v "`ls /nas/corachan/BIOFACE_V2/`" citados.csv
Sujeto ,RM
B009,2021-06-18
B021,2021-06-15
B055,2021-07-14
B094,2021-07-23
neuroimagen/bioface.txt · Last modified: 2021/07/19 14:53 by osotolongo