@@ -83,7 +83,9 @@ def resample_reference_to_sections(
8383 if not os .path .exists (iso_output_fn ) or not os .path .exists (output_fn ) or clobber :
8484 # Apply 3d transformation to the reference volume
8585 rand = tempfile .NamedTemporaryFile ().name
86+
8687 rand_fn = f"{ rand } .nii.gz"
88+
8789 utils .simple_ants_apply_tfm (input_fn , ref_fn , tfm_inv_fn , rand_fn , ndim = 3 )
8890
8991 img = nib .load (rand_fn )
@@ -384,6 +386,7 @@ def align_2d_parallel(
384386 nib .load (row ["2d_align_cls" ]).get_fdata (), cmap = "nipy_spectral" , alpha = 0.4
385387 )
386388 plt .savefig (f"{ prefix } _qc.png" )
389+ plt .close ()
387390
388391 # assert np.sum(nib.load(prefix+'_cls_rsl.nii.gz').dataobj) > 0, 'Error: 2d affine transfromation failed'
389392 assert os .path .exists (
@@ -397,7 +400,9 @@ def apply_transforms_parallel(
397400 tfm_dir : str ,
398401 resolution : float ,
399402 row : pd .Series ,
403+ tissue_str :str = '' ,
400404 file_str : str = "img" ,
405+ interpolation : str = "Linear" ,
401406 verbose : bool = False ,
402407) -> int :
403408 """Apply transforms to 2d sections.
@@ -410,14 +415,20 @@ def apply_transforms_parallel(
410415 :param row: row
411416 :return: 0
412417 """
418+
419+ out_fn = row ["2d_align" + tissue_str ]
420+
421+ if os .path .exists (out_fn ):
422+ return out_fn
423+
413424 y = int (row ["sample" ])
425+
414426 base = row ["base" ]
415427
416428 prefix = f"{ tfm_dir } /{ base } _y-{ y } "
417- img_rsl_fn = f"{ prefix } _{ resolution } mm.nii.gz"
418- out_fn = prefix + "_rsl.nii.gz"
419- fx_fn = gen_2d_fn (prefix , "_fx" )
420429
430+ img_rsl_fn = f"{ prefix } _{ resolution } mm{ tissue_str } .nii.gz"
431+
421432 img_fn = row [file_str ]
422433
423434 try :
@@ -428,34 +439,58 @@ def apply_transforms_parallel(
428439
429440 img_res = np .array ([img .affine [0 , 0 ], img .affine [1 , 1 ]])
430441
442+ print (img_fn )
443+ print (img_res );
444+
431445 # if we're not at the final resolution, we need to downsample the image
432- if resolution != img_res [0 ] and resolution != img_res [1 ]:
433- sigma = utils .calculate_sigma_for_downsampling (resolution / img_res )
446+ if resolution != img_res [0 ] or resolution != img_res [1 ]:
434447
435- vol = img .get_fdata ()
448+ #sigma = utils.calculate_sigma_for_downsampling(resolution / img_res)
449+ #vol = img.get_fdata()
450+ #vol = gaussian_filter(vol, sigma)
436451
437- vol = gaussian_filter (vol , sigma )
452+ resample_to_resolution (
453+ img_fn ,
454+ [float (resolution ), float (resolution )],
455+ order = 2 ,
456+ output_filename = img_rsl_fn ,
457+ )
438458
439- nib .Nifti1Image (vol , img .affine , direction_order = "lpi" ).to_filename (img_rsl_fn )
459+ # nib.Nifti1Image(vol, img.affine, direction_order="lpi").to_filename(img_rsl_fn)
440460 else :
441461 # if we're at the final resolution, we need to symlink the image
442- # check if the symlink exists
443462
444463 # Check if the symlink exists and points to the correct file
445464 if os .path .islink (img_rsl_fn ):
465+
446466 if os .readlink (img_rsl_fn ) != img_fn :
447467 os .remove (img_rsl_fn )
448468 os .symlink (img_fn , img_rsl_fn )
469+
449470 elif not os .path .exists (img_rsl_fn ):
450471 os .symlink (img_fn , img_rsl_fn )
472+
451473 # the symlink is just created to help qc if the user needs to check the moving image before alignment
452474 # however ITK does not support symlinks so we rename img_rsl_fn to the actual file name
453475 img_rsl_fn = img_fn
454476
455- cmd = f"antsApplyTransforms -v { int (verbose )} -d 2 -n BSpline -i { img_rsl_fn } -r { fx_fn } -t { prefix } _Composite.h5 -o { out_fn } "
477+
478+ #fx_fn = gen_2d_fn(prefix, "_fx")
479+ fx_fn = img_rsl_fn
480+
481+ #tfm_fn ={prefix}_Composite.h5
482+ tfm_fn = row ["2d_tfm" ]
483+
484+ #out_fn = prefix + "_rsl.nii.gz"
485+
486+
487+ print (out_fn )
488+ cmd = f"antsApplyTransforms -v { int (verbose )} -d 2 -n { interpolation } -i { img_rsl_fn } -r { fx_fn } -t { tfm_fn } -o { out_fn } "
456489
457490 shell (cmd , True )
491+
458492 assert os .path .exists (f"{ out_fn } " ), "Error apply nl 2d tfm to img autoradiograph"
493+
459494 return out_fn
460495
461496
@@ -471,7 +506,7 @@ def get_align_2d_to_do(sect_info: pd.DataFrame, clobber: bool = False) -> tuple:
471506 to_do_sect_info = []
472507 to_do_resample_sect_info = []
473508
474- for idx , (i , row ) in enumerate (sect_info .iterrows ()):
509+ for idx , (_ , row ) in enumerate (sect_info .iterrows ()):
475510 cls_fn = row ["2d_align_cls" ]
476511 tfm_fn = row ["2d_tfm" ]
477512 out_fn = row ["2d_align" ]
@@ -502,7 +537,7 @@ def get_align_filenames(
502537 sect_info ["2d_align" ] = ["" ] * sect_info .shape [0 ]
503538 sect_info ["2d_align_cls" ] = ["" ] * sect_info .shape [0 ]
504539
505- for idx , (i , row ) in enumerate (sect_info .iterrows ()):
540+ for idx , (_ , row ) in enumerate (sect_info .iterrows ()):
506541 y = int (row ["sample" ])
507542 base = row ["base" ]
508543 prefix = f"{ tfm_dir } /{ base } _y-{ y } "
@@ -522,7 +557,6 @@ def get_align_filenames(
522557
523558def align_sections (
524559 sect_info : pd .DataFrame ,
525- mv_dir : str ,
526560 output_dir : str ,
527561 resolution : float ,
528562 resolution_list : list ,
@@ -531,6 +565,7 @@ def align_sections(
531565 file_to_align : str = "seg" ,
532566 use_syn : bool = True ,
533567 num_cores : int = 0 ,
568+ interpolation : str = "Linear" ,
534569 verbose : bool = False ,
535570) -> None :
536571 """Align sections to sections from reference volume using ANTs.
@@ -566,28 +601,26 @@ def align_sections(
566601 # get lists of files that need to be aligned and resampled
567602 to_do_sect_info , to_do_resample_sect_info = get_align_2d_to_do (sect_info )
568603
569- last_resolution = resolution == resolution_list [- 1 ]
570-
571604 if len (to_do_sect_info ) > 0 :
572605 Parallel (n_jobs = num_cores , backend = "multiprocessing" )(
573606 delayed (align_2d_parallel )(
574607 tfm_dir ,
575608 resolution ,
576609 resolution_list ,
577610 row ,
578- base_lin_itr = base_lin_itr ,
579- base_nl_itr = base_nl_itr ,
580- file_to_align = file_to_align ,
581- use_syn = use_syn ,
582- verbose = verbose ,
611+ base_lin_itr = base_lin_itr ,
612+ base_nl_itr = base_nl_itr ,
613+ file_to_align = file_to_align ,
614+ use_syn = use_syn ,
615+ verbose = verbose ,
583616 )
584617 for row in to_do_sect_info
585618 )
586619
587620 if len (to_do_resample_sect_info ) > 0 :
588621 Parallel (n_jobs = num_cores , backend = "multiprocessing" )(
589622 delayed (apply_transforms_parallel )(
590- tfm_dir , resolution , row , verbose = verbose
623+ tfm_dir , resolution , row , interpolation = interpolation , verbose = verbose
591624 )
592625 for row in to_do_resample_sect_info
593626 )
@@ -600,7 +633,7 @@ def concatenate_tfm_sections_to_volume(
600633 rec_fn : str ,
601634 output_dir : str ,
602635 out_fn : str ,
603- target_str : str = "rsl " ,
636+ target_str : str = "" ,
604637) -> pd .DataFrame :
605638 """Concatenate 2D sections into output volume.
606639
@@ -616,16 +649,16 @@ def concatenate_tfm_sections_to_volume(
616649 tfm_dir = output_dir + os .sep + "tfm"
617650
618651 hires_img = nib .load (rec_fn )
619- target_name = "nl_2d_ " + target_str
652+ target_name = "2d_align " + target_str
620653
621- sect_info [target_name ] = ["" ] * sect_info .shape [0 ]
654+ # sect_info[target_name] = [""] * sect_info.shape[0]
622655
623- def set_target_name (base , y ):
624- return f"{ tfm_dir } /{ base } _y-{ y } _{ target_str } .nii.gz"
656+ # def set_target_name(base, y):
657+ # return f"{tfm_dir}/{base}_y-{y}_{target_str}.nii.gz"
625658
626- sect_info [target_name ] = sect_info .apply (
627- lambda row : set_target_name (row ["base" ], int (row ["sample" ])), axis = 1
628- )
659+ # sect_info[target_name] = sect_info.apply(
660+ # lambda row: set_target_name(row["base"], int(row["sample"])), axis=1
661+ # )
629662
630663 concatenate_sections_to_volume (
631664 sect_info , target_name , out_fn , hires_img .shape , hires_img .affine
@@ -652,6 +685,7 @@ def align_2d(
652685 use_syn : bool = True ,
653686 file_to_align : str = "seg" ,
654687 num_cores : int = 1 ,
688+ interpolation : str = "Linear" ,
655689 clobber : bool = False ,
656690) -> pd .DataFrame :
657691 """Align 2D sections to sections from reference volume using ANTs.
@@ -679,6 +713,8 @@ def align_2d(
679713 """
680714 ymax = sect_info ["sample" ].max ()
681715
716+ # Apply 3D transformation to reference volume and resample to the resolution
717+ # of the reconstruction and to the section thickness along the y-axis
682718 _ , ref_space_nat_fn = resample_reference_to_sections (
683719 float (resolution ),
684720 ref_rsl_fn ,
@@ -689,6 +725,7 @@ def align_2d(
689725 ymax = ymax ,
690726 )
691727
728+ # Create 2D sections from the resampled reference volume
692729 utils .create_2d_sections (
693730 sect_info , ref_space_nat_fn , float (resolution ), nl_2d_dir , dtype = np .uint8
694731 )
@@ -698,16 +735,17 @@ def align_2d(
698735 lambda x : os .path .basename (x ).split ("." )[0 ]
699736 )
700737
738+ # Align 2D sections to sections from reference volume using ANTs
701739 sect_info = align_sections (
702740 sect_info ,
703- seg_dir + "/2d/" ,
704741 nl_2d_dir ,
705742 resolution ,
706743 resolution_list ,
707744 use_syn = use_syn ,
708745 base_lin_itr = base_lin_itr ,
709746 base_nl_itr = base_nl_itr ,
710747 num_cores = num_cores ,
748+ interpolation = interpolation ,
711749 file_to_align = file_to_align ,
712750 )
713751
@@ -718,7 +756,7 @@ def align_2d(
718756
719757 # Concatenate 2D nonlinear aligned cls sections into an output volume
720758 sect_info = concatenate_tfm_sections_to_volume (
721- sect_info , ref_space_nat_fn , nl_2d_dir , nl_2d_cls_fn , target_str = "cls_rsl "
759+ sect_info , ref_space_nat_fn , nl_2d_dir , nl_2d_cls_fn , target_str = "_cls "
722760 )
723761
724762 return sect_info , ref_space_nat_fn
0 commit comments