Beispiel #1
0
def point_transformix(txtflnm, transformfile, dst=False):
    '''apply elastix transform to points
    
    
    Inputs
    -------------
    txtflnm = list of points that have resizingtransform
    transformfile = elastix transform file
    dst = optional folder
    
    Returns
    ---------------
    trnsfrm_out_file = pth to file containing post transformix points
    
    '''
    sys.stdout.write('\n***********Starting Transformix***********')
    from subprocess import check_output
    #set paths
    if not dst:
        trnsfrm_outpath = os.path.join(os.path.dirname(transformfile),
                                       'posttransformix')
        makedir(trnsfrm_outpath)
    if dst:
        trnsfrm_outpath = os.path.join(dst, 'posttransformix')
        makedir(trnsfrm_outpath)
    trnsfrm_out_file = os.path.join(trnsfrm_outpath, 'outputpoints.txt')

    #run transformix point transform
    call = 'transformix -def {} -out {} -tp {}'.format(txtflnm,
                                                       trnsfrm_outpath,
                                                       transformfile)
    print(check_output(call, shell=True))
    writer(trnsfrm_outpath,
           '\n   Transformix File Generated: {}'.format(trnsfrm_out_file))
    return trnsfrm_out_file
Beispiel #2
0
def detect_contours_in_3d_checker(jobid, pln_chnk=50, **kwargs):
    '''Not utilized yet
    '''
    kwargs = load_kwargs(**kwargs)
    outdr = kwargs['outputdirectory']
    vols = kwargs['volumes']
    reg_vol = [xx for xx in vols if xx.ch_type == 'regch'][0]
    ###set volume to use
    vol = [xx for xx in vols if xx.ch_type != 'regch'][jobid]
    if vol.ch_type == 'cellch':
        detect3dfld = reg_vol.celldetect3dfld
        coordinatesfld = reg_vol.cellcoordinatesfld
    elif vol.ch_type == 'injch':
        detect3dfld = reg_vol.injdetect3dfld
        coordinatesfld = reg_vol.injcoordinatesfld

    zmax = vols[0].fullsizedimensions[0]
    if len(os.listdir(detect3dfld)) != int(ceil(zmax / pln_chnk)):
        writer(
            outdr,
            '\n\n***************************STEP 4 FAILED*********************\n{} files found in {}. Should have {}.'
            .format(len(os.listdir(contourdetect3dfld)),
                    contourdetect3dfld[contourdetect3dfld.rfind('/') + 1:],
                    int(ceil(zmax / pln_chnk))))
    else:
        writer(
            outdr,
            '\n\n***************************STEP 4 SUCCESS*********************\n{} files found in {}. Should have {}.'
            .format(len(os.listdir(contourdetect3dfld)),
                    contourdetect3dfld[contourdetect3dfld.rfind('/') + 1:],
                    int(ceil(zmax / pln_chnk))))
    return
Beispiel #3
0
def inj_and_cells(elastixfld, cellch, injch, AtlasFile, threshold=0.075):
    ###assumes sagittal files
    ###set paths for
    ###generate Allen Atlas background
    allen = os.path.join(elastixfld, 'allenatlas_inj')
    makedir(allen)
    allentiff = tifffile.imread(AtlasFile[:-4] + '.tif')[:, 390:, :]
    allentiffloc = os.path.join(allen, 'allen_for_inj.tif')
    tifffile.imsave(allentiffloc, allentiff)
    depth.colorcode(allentiffloc, allen)
    grayscale = [
        os.path.join(allen, 'proj0.png'),
        os.path.join(allen, 'proj1.png'),
        os.path.join(allen, 'proj2.png')
    ]
    ####parsing out injection site
    ninjfld = os.path.join(elastixfld, 'injection_and_cells')
    makedir(ninjfld)
    injstack = tifffile.imread(injch)[:, 390:, :]  ##assumes sagittal ABA 25um
    ninjstackloc = os.path.join(ninjfld, 'injectionsite.tif')
    #normalize and threshold
    mxx = injstack.max()
    injstack = (injstack - injstack.min()) / (injstack.max() - injstack.min())
    injstack[injstack < threshold] = 0
    injstack = injstack * mxx
    tifffile.imsave(ninjstackloc, injstack.astype('uint16'))
    ####applying depth coding
    depth.colorcode(ninjstackloc, ninjfld)
    ###apply overlay
    color = [
        os.path.join(ninjfld, 'proj0.png'),
        os.path.join(ninjfld, 'proj1.png'),
        os.path.join(ninjfld, 'proj2.png')
    ]
    nametosave = [
        os.path.join(ninjfld, "proj0_overlay.png"),
        os.path.join(ninjfld, "proj1_overlay.png"),
        os.path.join(ninjfld, "proj2_overlay.png")
    ]
    for x in range(3):
        print(grayscale[x], color[x], nametosave[x])
        depth.overlay(grayscale[x], color[x], nametosave[x], alpha=0.95)
    depth.layout(nametosave[1], nametosave[0], nametosave[2], ninjfld)
    print(grayscale)
    print(color)
    print(nametosave)
    writer(elastixfld, "\nFinished inj_and_cells depth coloring overlay")
    return
Beispiel #4
0
def points_transform(src, dst, transformfile, verbose=False):
    '''Function to apply a tranform given a numpy.
    
    ***Assumes ZYX and that any orientation changes have already been done.***
    
    src: numpy array or list of np arrays of dims nx3
    dst: folder to save
    '''
    src = np.asarray(src)
    assert src.shape[-1] == 3, 'src must be a nx3 array'

    #create txt file, with elastix header, then populate points
    makedir(dst)
    pnts_fld = os.path.join(dst, 'transformedpoints_pretransformix')
    makedir(pnts_fld)
    transforminput = os.path.join(pnts_fld, 'zyx_transformedpnts.txt')

    #prevent adding to an already made file
    removedir(transforminput)
    writer(pnts_fld, 'index\n{}\n'.format(len(src)), flnm=transforminput)
    if verbose:
        sys.stdout.write(
            '\nwriting centers to transfomix input points text file: {}....'.
            format(transforminput))

    #this step converts from zyx to xyz*****
    stringtowrite = '\n'.join(
        ['\n'.join(['{} {} {}'.format(i[2], i[1], i[0])]) for i in src])
    writer(pnts_fld, stringtowrite, flnm=transforminput)
    if verbose:
        sys.stdout.write('...done writing centers.')
        sys.stdout.flush()

    #elastix for inverse transform
    trnsfrm_out_file = point_transformix(txtflnm=transforminput,
                                         dst=dst,
                                         transformfile=transformfile)
    assert os.path.exists(
        trnsfrm_out_file), 'Error Transform file does not exist: {}'.format(
            trnsfrm_out_file)
    #if verbose: sys.stdout.write('\n***Elastix Inverse Transform File: {}***'.format(transformfile))

    return trnsfrm_out_file
def elastix_command_line_call(fx, mv, out, parameters, fx_mask=False):
    '''Wrapper Function to call elastix using the commandline, this can be time consuming
    
    by @tpisano
    '''
    e_params = ['elastix', '-f', fx, '-m', mv, '-out', out]
    if fx_mask:
        e_params = [
            'elastix', '-f', fx, '-m', mv, '-fMask', fx_mask, '-out', out
        ]

    ###adding elastix parameter files to command line call
    for x in range(len(parameters)):
        e_params.append('-p')
        e_params.append(parameters[x])
    writer(out, 'Elastix Command:\n{}\n...'.format(e_params))

    #set paths
    TransformParameterFile = os.path.join(
        out, 'TransformParameters.{}.txt'.format((len(parameters) - 1)))
    ElastixResultFile = os.path.join(
        out, 'result.{}.tif'.format((len(parameters) - 1)))

    #run elastix:
    try:
        print('Running Elastix, this can take some time....\n')
        sp.call(e_params)  #sp_call(e_params)#
        writer(out, 'Past Elastix Commandline Call')
    except RuntimeError, e:
        writer(
            out,
            '\n***RUNTIME ERROR***: {} Elastix has failed. Most likely the two images are too dissimiliar.\n'
            .format(e.message))
        pass
Beispiel #6
0
def process_planes(job, cores, compression, volumes, verbose=True):
    '''Function for Slurm Array job to process single zplane; this could be parallelized'''
    ############################inputs
    zpln = str(job).zfill(4)
    resizefactor = 3
    bitdepth = 'uint16'  #default to uint16 unless specified
    ####################################

    for i, vol in enumerate(volumes):
        if i == 0:
            writer(vol.full_sizedatafld,
                   'Processing zpln {}...'.format(zpln),
                   flnm='process.txt',
                   verbose=verbose)
        try:
            dct = vol.zdct[zpln]  #dictionary of files for single z plane
        except KeyError:
            return 'ArrayJobID/SF exceeds number of planes'

        #handle raw vs nonraw
        if vol.raw:
            stitchdct = flatten_stitcher(cores, vol.outdr, vol.tiling_overlap,
                                         vol.xtile, vol.ytile, zpln, dct,
                                         vol.lightsheets, **kwargs)
        if not vol.raw:
            stitchdct = stitcher(cores, vol.outdr, vol.tiling_overlap,
                                 vol.xtile, vol.ytile, zpln, dct, **kwargs)

        #save for eventual compression
        saver(cores, stitchdct, vol.full_sizedatafld, vol.brainname, zpln,
              compression, bitdepth)

        #####################Cell detect ###CAN ADD A INJ CHANNEL HERE
        #resize
        resize_save(
            cores, stitchdct, vol.outdr, resizefactor, vol.brainname, zpln,
            bitdepth
        )  ##can return location of cell channel but not interested in this; if so remove [0]
        writer(vol.full_sizedatafld,
               '\n   completed zpln {}, channel {}, channel_type {}, nm {}'.
               format(zpln, vol.channel, vol.ch_type,
                      os.path.basename(vol.full_sizedatafld_vol)),
               flnm='process.txt',
               verbose=verbose)

    #log and return
    writer(vol.full_sizedatafld,
           '\n   ...completed all volumes of zpln {}\n'.format(zpln),
           flnm='process.txt',
           verbose=verbose)

    return
Beispiel #7
0
def identify_structures_w_contours(jobid,
                                   cores=5,
                                   make_color_images=False,
                                   overlay_on_original_data=False,
                                   consider_only_multipln_contours=False,
                                   **kwargs):
    '''function to take 3d detected contours and apply elastix transform
    '''
    #######################inputs and setup#################################################
    ###inputs
    kwargs = load_kwargs(**kwargs)
    outdr = kwargs['outputdirectory']
    vols = kwargs['volumes']
    reg_vol = [xx for xx in vols if xx.ch_type == 'regch'][0]

    ###get rid of extra jobs
    if jobid >= len([xx for xx in vols if xx.ch_type != 'regch'
                     ]):  ###used to end jobs if too many are called
        print('jobid({}) >= volumes {}'.format(
            jobid, len([xx for xx in vols if xx.ch_type != 'regch'])))
        return

    ###volumes to process: each job represents a different contour volume
    vol_to_process = [xx for xx in vols if xx.ch_type != 'regch'][jobid]
    ch = vol_to_process.channel
    print(vol_to_process.ch_type)

    #find appropriate folders for contours
    if vol_to_process.ch_type == 'cellch':
        detect3dfld = reg_vol.celldetect3dfld
        coordinatesfld = reg_vol.cellcoordinatesfld
    elif vol_to_process.ch_type == 'injch':
        detect3dfld = reg_vol.injdetect3dfld
        coordinatesfld = reg_vol.injcoordinatesfld

    #set scale and atlas
    xscl, yscl, zscl = reg_vol.xyz_scale  ###micron/pixel
    zmx, ymx, xmx = reg_vol.fullsizedimensions
    AtlasFile = reg_vol.atlasfile
    print('Using {} CORES'.format(cores))
    try:
        p
    except NameError:
        p = mp.Pool(cores)
    resizefactor = kwargs['resizefactor']
    brainname = reg_vol.brainname

    ############################################################################################################
    #######################use regex to sort np files by ch and then by zpln####################################
    ############################################################################################################
    fl = [f for f in os.listdir(detect3dfld)
          if '.p' in f and 'ch' in f]  #sorted for raw files
    reg = re.compile(r'(.*h+)(?P<ch>\d{2})(.*)(.p)')
    matches = map(reg.match, fl)

    ##load .np files
    sys.stdout.write(
        '\njobid({}), loading ch{} .p files to extract contour_class objects....'
        .format(jobid, ch))
    contour_class_lst = []
    for fl in [
            os.path.join(detect3dfld, ''.join(xx.groups())) for xx in matches
            if xx.group('ch')[-2:] in ch
    ]:
        tmpkwargs = {}
        pckl = open(fl, 'rb')
        tmpkwargs.update(pickle.load(pckl))
        pckl.close()
        if consider_only_multipln_contours == False:
            tmplst = tmpkwargs['single']
            [tmplst.append(xx) for xx in tmpkwargs['multi']]
        elif consider_only_multipln_contours == True:
            tmplst = tmpkwargs['multi']
        [contour_class_lst.append(xx) for xx in tmplst]
    sys.stdout.write('\ndone loading contour_class objects.\n')

    #check for successful loading
    if len(contour_class_lst) == 0:
        print('Length of contours in ch{} was {}, ending process...'.format(
            jobid, len(contour_class_lst)))
        try:
            p.terminate()
        except:
            1
        return

    ############################################################################################################
    ##############################make color files##############################################################
    ############################################################################################################
    if make_color_images == True:
        sys.stdout.write('\nmaking 3d planes...')
        sys.stdout.flush()
        valid_plns = range(0, zmx + 1)
        svlc = os.path.join(outdr, 'ch{}_3dcontours'.format(ch))
        removedir(svlc)
        if overlay_on_original_data == False:
            ovly = False
        elif overlay_on_original_data == True:
            ovly = True
        iterlst = []
        [
            iterlst.append(
                (ch, svlc, contour_class_lst, valid_plns, outdr,
                 vol_to_process, resizefactor, contour_class_lst,
                 consider_only_multipln_contours, ovly, core, cores))
            for core in range(cores)
        ]
        p.starmap(ovly_3d, iterlst)
        lst = os.listdir(svlc)
        lst1 = [os.path.join(svlc, xx) for xx in lst]
        lst1.sort()
        del lst
        del iterlst
        ###load ims and return dct of keys=str(zpln), values=np.array
        sys.stdout.write(
            '\n3d planes made, saved in {},\nnow compressing into single tifffile'
            .format(svlc))
        imstack = tifffile.imread(lst1)
        del lst1
        if len(imstack.shape) > 3:
            imstack = np.squeeze(imstack)
        try:  ###check for orientation differences, i.e. from horiztonal scan to sagittal for atlas registration
            imstack = np.swapaxes(imstack, *kwargs['swapaxes'])
        except:
            pass
        tiffstackpth = os.path.join(
            outdr, '3D_contours_ch{}_{}'.format(ch, brainname))
        tifffile.imsave(tiffstackpth, imstack.astype('uint16'))
        del imstack
        gc.collect()
        shutil.rmtree(svlc)
        sys.stdout.write('\ncolor image stack made for ch{}'.format(ch))
    else:
        sys.stdout.write('\nmake_color_images=False, not creating images')
    ############################################################################################################
    ######################apply point transform and make transformix input file#################################
    ############################################################################################################
    ###find centers and add 1's to make nx4 array for affine matrix multiplication to account for downsizing
    ###everything is in PIXELS
    contourarr = np.empty((len(contour_class_lst), 3))
    for i in range(len(contour_class_lst)):
        contourarr[i, ...] = contour_class_lst[
            i].center  ###full sized dimensions: if 3x3 tiles z(~2000),y(7680),x(6480) before any rotation
    try:
        contourarr = swap_cols(
            contourarr, *kwargs['swapaxes']
        )  ###change columns to account for orientation changes between brain and atlas: if horizontal to sagittal==>x,y,z relative to horizontal; zyx relative to sagittal
        z, y, x = swap_cols(np.array([
            vol_to_process.fullsizedimensions
        ]), *kwargs['swapaxes'])[
            0]  ##convert full size cooridnates into sagittal atlas coordinates
        sys.stdout.write('\nSwapping Axes')
    except:  ###if no swapaxes then just take normal z,y,x dimensions in original scan orientation
        z, y, x = vol_to_process.fullsizedimensions
        sys.stdout.write('\nNo Swapping of Axes')
    d1, d2 = contourarr.shape
    nx4centers = np.ones((d1, d2 + 1))
    nx4centers[:, :-1] = contourarr
    ###find resampled elastix file dim

    print(os.listdir(outdr))
    print([xx.channel for xx in vols if xx.ch_type == 'regch'])
    with tifffile.TiffFile([
            os.path.join(outdr, f) for f in os.listdir(outdr)
            if 'resampledforelastix' in f and 'ch{}'.format(
                [xx.channel for xx in vols if xx.ch_type == 'regch'][0]) in f
    ][0]) as tif:
        zr = len(tif.pages)
        yr, xr = tif.pages[0].shape
        tif.close()
    ####create transformmatrix
    trnsfrmmatrix = np.identity(4) * (
        zr / z, yr / y, xr / x, 1)  ###downscale to "resampledforelastix size"
    sys.stdout.write('trnsfrmmatrix:\n{}\n'.format(trnsfrmmatrix))
    #nx4 * 4x4 to give transform
    trnsfmdpnts = nx4centers.dot(trnsfrmmatrix)  ##z,y,x
    sys.stdout.write('first three transformed pnts:\n{}\n'.format(
        trnsfmdpnts[0:3]))
    #create txt file, with elastix header, then populate points
    txtflnm = '{}_zyx_transformedpnts_ch{}.txt'.format(brainname, ch)
    pnts_fld = os.path.join(outdr, 'transformedpoints_pretransformix')
    makedir(pnts_fld)
    transforminput = os.path.join(pnts_fld, txtflnm)
    removedir(transforminput)  ###prevent adding to an already made file
    writer(pnts_fld, 'index\n{}\n'.format(len(trnsfmdpnts)), flnm=txtflnm)
    sys.stdout.write(
        '\nwriting centers to transfomix input points text file: {}....'.
        format(transforminput))
    stringtowrite = '\n'.join([
        '\n'.join(['{} {} {}'.format(i[2], i[1], i[0])]) for i in trnsfmdpnts
    ])  ####this step converts from zyx to xyz*****
    writer(pnts_fld, stringtowrite, flnm=txtflnm)
    #[writer(pnts_fld, '{} {} {}\n'.format(i[2],i[1],i[0]), flnm=txtflnm, verbose=False) for i in trnsfmdpnts] ####this step converts from zyx to xyz*****
    sys.stdout.write('...done writing centers.')
    sys.stdout.flush()
    del trnsfmdpnts, trnsfrmmatrix, nx4centers, contourarr
    gc.collect()
    ############################################################################################################
    ####################################elastix for inverse transform###########################################
    ############################################################################################################
    transformfile = make_inverse_transform(vol_to_process, cores, **kwargs)
    assert os.path.exists(transformfile)
    sys.stdout.write(
        '\n***Elastix Inverse Transform File: {}***'.format(transformfile))
    ############################################################################################################
    ####################################transformix#############################################################
    ############################################################################################################
    if make_color_images != False:
        #apply transform to 3d_tiffstack:
        transformimageinput = tiffstackpth
        elastixpth = os.path.join(outdr, 'elastix')
        trnsfrm_outpath = os.path.join(
            elastixpth, '3D_contours_ch{}_{}'.format(ch, brainname))
        makedir(trnsfrm_outpath)
        writer(trnsfrm_outpath, '\nProcessing ch{} 3D...'.format(ch))
        #transformfiles=[os.path.join(elastixpth, xx) for xx in os.listdir(os.path.join(outdr, 'elastix')) if "TransformParameters" in xx]; mxx=max([xx[-5] for xx in transformfiles])
        #transformfile=os.path.join(elastixpth, 'TransformParameters.{}.txt'.format(mxx))
        trnsfrm_out_file = os.path.join(trnsfrm_outpath,
                                        'result.tif')  #output of transformix
        transformimageinput_resized = transformimageinput[:-4] + '_resampledforelastix.tif'
        print('Resizing {}'.format(transformimageinput_resized))
        resample_par(cores,
                     transformimageinput,
                     AtlasFile,
                     svlocname=transformimageinput_resized,
                     singletifffile=True,
                     resamplefactor=1.7)
        sp.call([
            'transformix', '-in', transformimageinput_resized, '-out',
            trnsfrm_outpath, '-tp', transformfile
        ])
        writer(trnsfrm_outpath,
               '\n   Transformix File Generated: {}'.format(trnsfrm_out_file))
        writer(
            trnsfrm_outpath, '\n   Passing colorcode: {} file as {}'.format(
                ch, os.path.join(trnsfrm_outpath, 'depthcoded.png')))
        ###depth coded image of transformix result; not functional yet
        #depth.colorcode(trnsfrm_out_file, trnsfrm_outpath)
        #getvoxels(trnsfrm_out_file, os.path.join(trnsfrm_outpath, 'zyx_voxels_{}.npy'.format(ch)))
        #allen_compare(AtlasFile, svlc, trnsfrm_outpath)
        ##if successful delete contour cooridnates and maybe contourdetect3d flds
    ############################################################

    ##############apply transform to points#####################
    elastixpth = os.path.join(outdr, 'elastix_inverse_transform')
    trnsfrm_outpath = os.path.join(elastixpth, 'ch{}_3dpoints'.format(ch))
    makedir(trnsfrm_outpath)
    writer(trnsfrm_outpath,
           '\n***********Starting Transformix for: {}***********'.format(ch))
    sys.stdout.flush()
    #transformfiles=[os.path.join(elastixpth, xx) for xx in os.listdir(os.path.join(outdr, 'elastix')) if "TransformParameters" in xx]; mxx=max([xx[-5] for xx in transformfiles])
    #transformfile=os.path.join(elastixpth, 'TransformParameters.{}.txt'.format(mxx))
    trnsfrm_out_file = os.path.join(
        trnsfrm_outpath, 'outputpoints.txt')  #MIGHT NEED TO CHANGE THIS
    sp.call([
        'transformix', '-def', transforminput, '-out', trnsfrm_outpath, '-tp',
        transformfile
    ])
    #sp.call(['transformix', '-def', 'all', '-out', trnsfrm_outpath, '-tp', transformfile]) ##displacement field
    writer(trnsfrm_outpath,
           '\n   Transformix File Generated: {}'.format(trnsfrm_out_file))
    ####################################################################################
    ##############generate list and image overlaid onto allen atlas#####################
    ####################################################################################
    name = 'job{}_{}'.format(jobid, vol_to_process.ch_type)
    transformed_pnts_to_allen(trnsfrm_out_file, ch, cores, name=name, **kwargs)
    writer(outdr, '*************STEP 5*************\n Finished')
    print('end of script')
    try:
        p.terminate()
    except:
        1
    return
    ElastixResultFile = os.path.join(
        out, 'result.{}.tif'.format((len(parameters) - 1)))

    #run elastix:
    try:
        print('Running Elastix, this can take some time....\n')
        sp.call(e_params)  #sp_call(e_params)#
        writer(out, 'Past Elastix Commandline Call')
    except RuntimeError, e:
        writer(
            out,
            '\n***RUNTIME ERROR***: {} Elastix has failed. Most likely the two images are too dissimiliar.\n'
            .format(e.message))
        pass
    if os.path.exists(ElastixResultFile) == True:
        writer(out, 'Elastix Registration Successfully Completed\n')
    #check to see if it was MHD instead
    elif os.path.exists(
            os.path.join(out, 'result.{}.mhd'.format(
                (len(parameters) - 1)))) == True:
        ElastixResultFile = os.path.join(
            out, 'result.{}.mhd'.format((len(parameters) - 1)))
        writer(out, 'Elastix Registration Successfully Completed\n')
    else:
        writer(
            out, '\n***ERROR***Cannot find elastix result file\n: {}'.format(
                ElastixResultFile))
        return

    return ElastixResultFile, TransformParameterFile
Beispiel #9
0
def point_transform_due_to_resizing(array,
                                    chtype='injch',
                                    svlc=False,
                                    **kwargs):
    '''Function to take npy array, find nonzero pixels, apply point transform (due to resizing) and package them into a file for final elastix point transform
    
    
    Inputs
    -------------
    array = np array, tif, or path to numpy array from tools.objectdetection.injdetect.inj_detect_using_labels ZYX****
    chtype = 'injch' or 'cellch'
    svlc = 
        False: savesfile into (outdr, 'transformedpoints_pretransformix'). Strongly recommended to use this as it will then work with the rest of package
        True
    
    Returns
    ---------------
    txtflnm = pth to file containing transformed points BEFORE elastix transformation
    
    NOTE THIS FUNCTION ASSUMES ARRAY AND ATLAS HAVE SAME Z,Y,X (DOES NOT TAKE INTO ACCOUNT SWAPPING OF AXES)
    '''
    if type(array) == str:
        if array[-4:] == '.npy': array = np.load(array)
        if array[-4:] == '.tif': array = tifffile.imread(array)

    kwargs = load_kwargs(**kwargs)
    outdr = kwargs['outputdirectory']
    brainname = [xx for xx in kwargs['volumes']
                 if xx.ch_type == 'regch'][0].brainname
    vol = [xx for xx in kwargs['volumes'] if xx.ch_type == chtype][0]

    #array dimensions
    z, y, x = array.shape

    #compare size of array with 'resampledforelastixsize'
    with tifffile.TiffFile([
            os.path.join(outdr, f) for f in os.listdir(outdr)
            if 'resampledforelastix.tif' in f and not '3D_contours' in f
            and 'ch{}'.format([
                xx.channel for xx in kwargs['volumes'] if xx.ch_type == 'regch'
            ][0]) in f
    ][0]) as tif:
        zr = len(tif.pages)
        yr, xr = tif.pages[0].shape
        tif.close()

    nonzeropixels = np.argwhere(array > 0)
    nx4centers = np.ones(
        (len(nonzeropixels), 4))  #FIXME: the logic needs to be checked
    nx4centers[:, :-1] = nonzeropixels

    ####create transformmatrix
    trnsfrmmatrix = np.identity(4) * (
        zr / z, yr / y, xr / x, 1)  ###downscale to "resampledforelastix size"
    sys.stdout.write('\n\n Transfrom matrix:\n{}\n'.format(trnsfrmmatrix))

    #nx4 * 4x4 to give transform
    trnsfmdpnts = nx4centers.dot(trnsfrmmatrix)  ##z,y,x
    sys.stdout.write('\nfirst three transformed pnts:\n{}\n'.format(
        trnsfmdpnts[0:3]))

    #create txt file, with elastix header, then populate points
    txtflnm = '{}_zyx_transformedpnts_{}.txt'.format(brainname, vol.ch_type)

    #
    if not svlc:
        pnts_fld = os.path.join(outdr, 'transformedpoints_pretransformix')
        makedir(pnts_fld)
    if svlc:
        pnts_fld = os.path.join(svlc)
        makedir(pnts_fld)

    transforminput = os.path.join(pnts_fld, txtflnm)
    removedir(transforminput)  ###prevent adding to an already made file
    writer(pnts_fld, 'index\n{}\n'.format(len(trnsfmdpnts)), flnm=txtflnm)
    sys.stdout.write(
        '\nwriting centers to transfomix input points text file...')
    stringtowrite = '\n'.join([
        '\n'.join(['{} {} {}'.format(i[2], i[1], i[0])]) for i in trnsfmdpnts
    ])  ####this step converts from zyx to xyz*****
    writer(pnts_fld, stringtowrite, flnm=txtflnm)
    #[writer(pnts_fld, '{} {} {}\n'.format(i[2],i[1],i[0]), flnm=txtflnm, verbose=False) for i in trnsfmdpnts] ####this step converts from zyx to xyz*****
    sys.stdout.write('...done writing centers.\nSaved in {}'.format(pnts_fld))
    sys.stdout.flush()

    del trnsfmdpnts, trnsfrmmatrix, nx4centers

    return os.path.join(pnts_fld, txtflnm)
Beispiel #10
0
def make_inverse_transform(vol_to_process, cores=5, **kwargs):
    '''Script to perform inverse transform and return path to elastix inverse parameter file
    
    Returns:
    ---------------
    transformfile
    '''

    sys.stdout.write('starting make_inverse_transform, this will take time...')
    ############inputs
    kwargs = load_kwargs(kwargs['outputdirectory'])
    outdr = kwargs['outputdirectory']
    vols = kwargs['volumes']
    reg_vol = [xx for xx in vols if xx.ch_type == 'regch'][0]
    AtlasFile = reg_vol.atlasfile
    parameterfolder = reg_vol.parameterfolder

    ###############
    ###images need to have been stitched, resized, and saved into single tiff stack ###
    ###resize to ~220% total size of atlas (1.3x/dim) ###
    reg_vol.add_resampled_for_elastix_vol(reg_vol.downsized_vol +
                                          '_resampledforelastix.tif')
    #resample_par(cores, reg_vol, AtlasFile, svlocname=reg_vol_resampled, singletifffile=True, resamplefactor=1.2)
    if not os.path.exists(reg_vol.resampled_for_elastix_vol):
        print('Resizing')
        #resample(reg_vol, AtlasFile, svlocname=reg_vol_resampled, singletifffile=True, resamplefactor=1.3)
        resample_par(cores,
                     reg_vol.downsized_vol + '.tif',
                     AtlasFile,
                     svlocname=reg_vol.resampled_for_elastix_vol,
                     singletifffile=True,
                     resamplefactor=1.3)
        print('Past Resizing')

    vol_to_process.add_resampled_for_elastix_vol(vol_to_process.downsized_vol +
                                                 '_resampledforelastix.tif')

    if not os.path.exists(vol_to_process.resampled_for_elastix_vol):
        print('Resizing')
        resample_par(cores,
                     vol_to_process.downsized_vol + '.tif',
                     AtlasFile,
                     svlocname=vol_to_process.resampled_for_elastix_vol,
                     singletifffile=True,
                     resamplefactor=1.3)
        print('Past Resizing')

    ####setup
    parameters = []
    [
        parameters.append(os.path.join(parameterfolder, files))
        for files in os.listdir(parameterfolder)
        if files[0] != '.' and files[-1] != '~'
    ]
    parameters.sort()

    ###set up save locations
    svlc = os.path.join(outdr, 'elastix_inverse_transform')
    makedir(svlc)
    svlc = os.path.join(
        svlc, '{}_{}'.format(vol_to_process.ch_type, vol_to_process.brainname))
    makedir(svlc)

    ###Creating LogFile
    #writer(svlc, 'Starting elastix...AtlasFile: {}\n   parameterfolder: {}\n   svlc: {}\n'.format(AtlasFile, parameterfolder, svlc))
    writer(
        svlc,
        'Order of parameters used in Elastix:{}\n...\n\n'.format(parameters))

    ##register: 1) atlas->reg 2) reg->sig NOTE these are intentionally backwards so applying point transform can be accomplished
    #atlas(mv)->reg (fx)
    atlas2reg = os.path.join(
        svlc,
        reg_vol.resampled_for_elastix_vol[reg_vol.resampled_for_elastix_vol.
                                          rfind('/') + 1:-4] + '_atlas2reg')
    makedir(atlas2reg)
    e_out_file, e_transform_file = elastix_command_line_call(
        fx=reg_vol.resampled_for_elastix_vol,
        mv=AtlasFile,
        out=atlas2reg,
        parameters=parameters)

    #reg(mv)->sig(fx)
    reg2sig = os.path.join(
        svlc, vol_to_process.resampled_for_elastix_vol[
            vol_to_process.resampled_for_elastix_vol.rfind('/') + 1:-4] +
        '_reg2sig')
    makedir(reg2sig)
    e_out_file, e_transform_file = elastix_command_line_call(
        fx=vol_to_process.resampled_for_elastix_vol,
        mv=reg_vol.resampled_for_elastix_vol,
        out=reg2sig,
        parameters=parameters)

    ##set up transform series:
    atlas2reg2sig = os.path.join(
        svlc, vol_to_process.resampled_for_elastix_vol[
            vol_to_process.resampled_for_elastix_vol.rfind('/') + 1:-4] +
        '_atlas2reg2sig')
    makedir(atlas2reg2sig)
    #copy transform paramters
    [
        shutil.copy(os.path.join(reg2sig, xx),
                    os.path.join(atlas2reg2sig, 'reg2sig_' + xx))
        for xx in os.listdir(reg2sig) if 'TransformParameters' in xx
    ]
    [
        shutil.copy(os.path.join(atlas2reg, xx),
                    os.path.join(atlas2reg2sig, 'atlas2reg_' + xx))
        for xx in os.listdir(atlas2reg) if 'TransformParameters' in xx
    ]

    #connect transforms by setting regtoatlas TP0's initial transform to sig->reg transform
    tps = [
        os.path.join(atlas2reg2sig, xx) for xx in os.listdir(atlas2reg2sig)
        if 'TransformParameters' in xx
    ]
    tps.sort(
        reverse=True
    )  #they are now in order recent to first, thus first is regtoatlas_TransformParameters.1.txt
    for x in range(len(tps)):
        if not x == len(tps) - 1:
            change_transform_parameter_initial_transform(tps[x], tps[x + 1])

    assert os.path.exists(tps[0])
    writer(svlc, '***Elastix Registration Successfully Completed***\n')
    writer(svlc, '\ne_transform_file is {}'.format(tps[0]))
    ####################
    sys.stdout.write('complted make_inverse_transform')
    return tps[0]
Beispiel #11
0
def elastix_registration(jobid, cores=5, **kwargs):
    '''Function to take brainvolumes and register them to AtlasFiles using elastix parameters in parameterfolder.
    Inputs
    ---------------
    cores = for parallelization
    
    optional kwargs:
    secondary_registration (optional): False (default) - apply transform determined from regch->atlas to other channels
                                       True - register other channel(s) to regch then apply transform determined from regch->atlas 
                                       (useful if imaging conditions were different between channel and regch, i.e. added horizontal foci, sheet na...etc)
                                       kwargs overrides explicit 'secondary_registration' input to function
    
    
    Required inputs via kwargs:
            brainname='AnimalID'
            brainpath= pathtofolder
            AtlasFile=pathtoatlas ###atlas is a tif stack
            parameterfolder ##contains parameter files: Order1_filename.txt, Order2_filename.txt,....
            svlc=pathtosavedirectory
            maskfile(optional)=creates a nested folder inside svlc and runs registration with mask
    To run in parallel use: parallel_elastixlooper 
  '''

    ###inputs
    outdr = kwargs['outputdirectory']
    kwargs = load_kwargs(outdr)
    #check to see if masking, cropping or normal atlas
    if 'maskatlas' in kwargs:
        AtlasFile = generate_masked_atlas(**kwargs)
    elif 'cropatlas' in kwargs:
        AtlasFile = generate_cropped_atlas(**kwargs)
    else:
        AtlasFile = kwargs['AtlasFile']

    ###make variables for volumes:
    vols = kwargs['volumes']
    reg_vol = [xx for xx in vols if xx.ch_type == 'regch'][0]

    #images need to have been stitched, resized, and saved into single tiff stack
    #resize to ~220% total size of atlas (1.3x/dim)
    sys.stdout.write('Beginning registration on {}'.format(reg_vol.brainname))
    sys.stdout.flush()
    reg_vol.add_resampled_for_elastix_vol(reg_vol.downsized_vol +
                                          '_resampledforelastix.tif')
    if not os.path.exists(reg_vol.resampled_for_elastix_vol):
        sys.stdout.write('\n   Resizing {}'.format(reg_vol.downsized_vol))
        sys.stdout.flush()
        resample_par(cores,
                     reg_vol.downsized_vol + '.tif',
                     AtlasFile,
                     svlocname=reg_vol.resampled_for_elastix_vol,
                     singletifffile=True,
                     resamplefactor=1.3)
        [
            vol.add_registration_volume(reg_vol.resampled_for_elastix_vol)
            for vol in vols
        ]
        sys.stdout.write('...completed resizing\n')
        sys.stdout.flush()

    ###find elastix parameters files and sort, set up parameters and logfiles
    parameters = []
    [
        parameters.append(os.path.join(reg_vol.parameterfolder, files))
        for files in os.listdir(reg_vol.parameterfolder)
        if files[0] != '.' and files[-1] != '~'
    ]
    parameters.sort()
    svlc = os.path.join(outdr, 'elastix')
    makedir(svlc)
    writer(
        svlc,
        'Starting elastix...AtlasFile: {}\n   parameterfolder: {}\n   svlc: {}\n'
        .format(AtlasFile, reg_vol.parameterfolder, svlc))
    writer(
        svlc,
        'Order of parameters used in Elastix:{}\n...\n\n'.format(parameters))

    #optionally generate MHD file for better scaling in elastix (make both mhds if present since one tiff and one mhd doesn't work well)
    resampled_zyx_dims = False
    if False and 'atlas_scale' in kwargs:
        atlasfilecopy = AtlasFile
        AtlasFile = convert_to_mhd(
            AtlasFile,
            dims=kwargs['atlas_scale'],
            dst=os.path.join(
                kwargs['outputdirectory'],
                os.path.splitext(os.path.basename(kwargs['AtlasFile']))[0]) +
            '.mhd')
        #copy reg vol and calculate effective distance/pixel scale
        reg_volcopy = reg_vol.resampled_for_elastix_vol
        resampled_zyx_dims = [
            cc * dd for cc, dd in zip(kwargs['xyz_scale'][::-1], [
                float(bb) / float(aa) for aa, bb in zip(
                    tifffile.imread(reg_vol.resampled_for_elastix_vol).shape,
                    reg_vol.fullsizedimensions)
            ])
        ]
        #note convert_to_mhd dims are in XYZ
        reg_vol.add_resampled_for_elastix_vol(
            convert_to_mhd(
                reg_vol.resampled_for_elastix_vol,
                dims=resampled_zyx_dims[::-1],
                dst=os.path.join(
                    kwargs['outputdirectory'],
                    os.path.splitext(
                        os.path.basename(
                            reg_vol.resampled_for_elastix_vol))[0]) + '.mhd'))

    #ELASTIX
    e_out_file, transformfile = elastix_command_line_call(
        AtlasFile, reg_vol.resampled_for_elastix_vol, svlc, parameters)

    #optionally generate MHD file for better scaling in elastix
    if False and 'atlas_scale' in kwargs:
        removedir(AtlasFile)
        removedir(AtlasFile[-3:] + '.raw')
        AtlasFile = atlasfilecopy
        removedir(reg_vol.resampled_for_elastix_vol)
        removedir(reg_vol.resampled_for_elastix_vol + '.raw')
        reg_vol.add_resampled_for_elastix_vol(reg_volcopy)

    #RG movie for visual inspection of image registration
    color_movie_merger(AtlasFile, e_out_file, svlc, reg_vol.brainname)

    #RGB movie with blue channel=pre-registered stack
    bluechannel = os.path.join(svlc, 'combinedmovies',
                               reg_vol.brainname + '_resized_bluechannel.tif')
    resample(
        reg_vol.downsized_vol + '.tif',
        AtlasFile,
        svlocname=bluechannel,
        singletifffile=True
    )  ##needs to be resample(not resample_par) as you need EXTACT dimensions
    color_movie_merger(AtlasFile,
                       e_out_file,
                       svlc,
                       reg_vol.brainname + '_bluechanneloriginal',
                       movie5=bluechannel)

    #Make gridline transform file
    gridfld, tmpgridline = gridcompare(svlc, reg_vol)
    sp.call([
        'transformix', '-in', tmpgridline, '-out', gridfld, '-tp',
        transformfile
    ])
    combine_images(str(reg_vol.resampled_for_elastix_vol), AtlasFile,
                   os.path.join(gridfld, 'result.tif'), e_out_file, svlc,
                   reg_vol.brainname)
    shutil.rmtree(gridfld)

    #Apply transforms to other channels
    writer(
        svlc,
        '\n...\nStarting Transformix on channel files...\n\nChannels to process are {}\n*****\n\n'
        .format([x.downsized_vol for x in vols]))

    #type of transform and channels to apply transform to
    secondary_registration = kwargs[
        'secondary_registration'] if 'secondary_registration' in kwargs else True
    transform_function = apply_transformix_and_register if secondary_registration else apply_transformix
    vols_to_register = [xx for xx in vols if xx.ch_type != 'regch']

    #appy transform
    [
        transform_function(vol, reg_vol, svlc, cores, AtlasFile, parameters,
                           transformfile, resampled_zyx_dims)
        for vol in vols_to_register
    ]
    writer(svlc, '\nPast transformix step')

    ###make final output image if a cellch and injch exist
    if any([True
            for vol in vols_to_register if vol.ch_type == 'cellch']) and any(
                [True for vol in vols_to_register if vol.ch_type == 'injch']):
        injch = [
            vol.registration_volume for vol in vols_to_register
            if vol.ch_type == 'injch'
        ][0]
        cellch = [
            vol.registration_volume for vol in vols_to_register
            if vol.ch_type == 'cellch'
        ][0]
        inj_and_cells(svlc, cellch, injch, AtlasFile)

    ####### check to see if script finished due to an error
    if os.path.exists(e_out_file) == False:
        writer(
            svlc,
            '****ERROR****GOTTEN TO END OF SCRIPT,\nTHIS ELASTIX OUTPUT FILE DOES NOT EXIST: {0} \n'
            .format(e_out_file))

    ######write out logfile describing parameters input into function
    writer(
        svlc,
        "\nelastixlooper has finished using:\nbrainname: {}\nAtlasFile: {}\nparameterfolder: {}\nparameter files {}\nsvlc: {}"
        .format(reg_vol.brainname, AtlasFile, reg_vol.parameterfolder,
                parameters, svlc))

    ###update volumes in kwargs and pickle
    vols_to_register.append(reg_vol)
    kwargs.update(dict([('volumes', vols_to_register)]))
    pckloc = os.path.join(outdr, 'param_dict.p')
    pckfl = open(pckloc, 'wb')
    pickle.dump(kwargs, pckfl)
    pckfl.close()
    writer(
        outdr,
        "\n\n*************STEP 3************************\nelastix has completed using:\nbrainname: {}\nAtlasFile: {}\nparameterfolder: {}\nparameter files {}\nsvlc: {}\n****************\n"
        .format(reg_vol.brainname, AtlasFile, reg_vol.parameterfolder,
                parameters, svlc))

    return
Beispiel #12
0
def allen_compare(AtlasFile,
                  svlc,
                  trnsfrm_out_file,
                  verbose=False,
                  outline=False):
    '''Function to make a 3 axis depth color overlay between the allen atlas (will be greyscale), and the inputpth (will be color representing depth)
    AtlasFile=pth to atlas
    svlc=pth to save files
    trnsfrm_out_file=file to transform
    outline = generates an outline of the nonzero label, useful for interacting with allen structures rather than injeciton sites
    '''
    trnsfrm_outpath = trnsfrm_out_file[:trnsfrm_out_file.rfind('/')]
    depth.colorcode(trnsfrm_out_file, trnsfrm_outpath)
    ###using Allen Atlas as background
    allen = os.path.join(svlc, 'allenatlas')
    makedir(allen)
    allentiff = AtlasFile[:-4] + '.tif'
    depth.colorcode(allentiff, allen)
    grayscale = [
        os.path.join(allen, 'proj0.png'),
        os.path.join(allen, 'proj1.png'),
        os.path.join(allen, 'proj2.png')
    ]
    color = [
        os.path.join(trnsfrm_outpath, 'proj0.png'),
        os.path.join(trnsfrm_outpath, 'proj1.png'),
        os.path.join(trnsfrm_outpath, 'proj2.png')
    ]
    nametosave = [
        os.path.join(trnsfrm_outpath, "proj0_overlay.png"),
        os.path.join(trnsfrm_outpath, "proj1_overlay.png"),
        os.path.join(trnsfrm_outpath, "proj2_overlay.png")
    ]
    ###
    if outline:
        import pylab as pl
        #cntlst = [];
        tick = 0
        for xx in color:
            im = cv2.imread(xx, 1)
            im_gray = cv2.imread(xx, 0)
            #disp, center, cnt = detect_inj_site(im_gray.astype('uint8'), kernelsize = 2, threshold = 0.1, minimumarea=1); cntlst.append(cnt)
            disp = find_site(im_gray)
            nim = np.zeros((im.shape[0], im.shape[1], 4))
            for i in range(3):
                if tick == 2: nim[..., i] = im[..., i] * disp.astype('bool')
                if tick == 0 or tick == 1:
                    nim[..., i] = im[..., i] * disp.astype('bool')
                    nim[..., i] = nim[..., i] + im[..., i] * np.fliplr(
                        disp.astype('bool'))
            nim[..., 3] = 1
            #cv2.imwrite(xx, nim)
            pl.imsave(xx, nim)
            tick += 1
    ##
    for x in range(3):
        depth.overlay(grayscale[x], color[x], nametosave[x], alpha=0.95)
    depth.layout(nametosave[0], nametosave[1], nametosave[2],
                 trnsfrm_outpath)  ###might need 1,0,2 for some files
    if verbose != False: writer(svlc, "\nFinished depth coloring overlay")
    #if outline: return cntlst
    return
Beispiel #13
0
def apply_transformix_and_register(vol, reg_vol, svlc, cores, AtlasFile,
                                   parameters, transformfile,
                                   resampled_zyx_dims):
    '''Function to
        1) register a sig/inj channel to the autofluro (registration) channel
        2) apply sig/inj -> auto then registration->atlas transform
        3) generate depth coded images
    
    Contrast this with apply_transformix.
        
    (vol, reg_vol, svlc, cores, AtlasFile, parameters, transformfile)    

    Inputs
    ----------------
    vol = volume object to apply transform
    reg_vol = volume initially used to register to atlas
    svlc = path to 'elastix' folder, where files will be written
    cores = int # of cores
    AtlasFile = path to ABA atlas
    parameters = list in order of application of parameter file paths
    transformfile = output of elastix's transform from reg chan to atlas

    '''

    writer(
        svlc,
        '\n\nStarting transform AND REGISTRATION to regch for: {}...\n   to change to transform only add "secondary_registration": False to params in run tracing\n'
        .format(vol.downsized_vol))

    #set up folder/inputs
    sig_ch_resized = vol.downsized_vol + '.tif'
    sig_out = os.path.join(svlc, os.path.basename(vol.downsized_vol))
    makedir(sig_out)
    sig_to_reg_out = os.path.join(sig_out, 'sig_to_reg')
    makedir(sig_to_reg_out)
    reg_ch_resampledforelastix = reg_vol.resampled_for_elastix_vol
    sig_ch_resampledforelastix = sig_ch_resized[:-4] + '_resampledforelastix.tif'

    #run elastix on sig/inj channel -> reg channel (but don't register reg to itself)
    if not vol.ch_type == 'regch':
        writer(svlc, 'Resizing transforminput: {}'.format(sig_ch_resized))
        resample(sig_ch_resized,
                 AtlasFile,
                 svlocname=sig_ch_resampledforelastix,
                 singletifffile=True,
                 resamplefactor=1.3)
        #cannot be resample_par because that be a pool inside of pool
        #resample_par(cores, sig_ch_resized, AtlasFile, svlocname=sig_ch_resampledforelastix, singletifffile=True, resamplefactor=1.3)

        ElastixResultFile, TransformParameterFile = elastix_command_line_call(
            reg_ch_resampledforelastix, sig_ch_resampledforelastix,
            sig_to_reg_out, parameters)

    #copy transform paramters to set up transform series:
    [
        shutil.copy(os.path.join(svlc, xx),
                    os.path.join(sig_to_reg_out, 'regtoatlas_' + xx))
        for xx in os.listdir(svlc) if 'TransformParameters' in xx
    ]

    #connect transforms by setting regtoatlas TP0's initial transform to sig->reg transform
    #might need to go backwards...
    reg_to_atlas_tps = [
        os.path.join(sig_to_reg_out, xx) for xx in os.listdir(sig_to_reg_out)
        if 'TransformParameters' in xx and 'regtoatlas' in xx
    ]
    reg_to_atlas_tps.sort()
    sig_to_reg_tps = [
        os.path.join(sig_to_reg_out, xx) for xx in os.listdir(sig_to_reg_out)
        if 'TransformParameters' in xx and 'regtoatlas' not in xx
    ]
    sig_to_reg_tps.sort()

    #account for moving the reg_to_atlas_tps:
    [
        change_transform_parameter_initial_transform(reg_to_atlas_tps[xx + 1],
                                                     reg_to_atlas_tps[xx])
        for xx in range(len(reg_to_atlas_tps) - 1)
    ]

    #now make the initialtransform of the first(0) sig_to_reg be the last's reg_to_atlas transform
    change_transform_parameter_initial_transform(reg_to_atlas_tps[0],
                                                 sig_to_reg_tps[-1])

    #optionally convert to mhd, note convert_to_mhd dims are in XYZ
    if resampled_zyx_dims:
        sig_ch_resampledforelastix = convert_to_mhd(
            vol.resampled_for_elastix_vol, dims=resampled_zyx_dims[::-1])

    #run transformix
    sp.call([
        'transformix', '-in', sig_ch_resampledforelastix, '-out', sig_out,
        '-tp', reg_to_atlas_tps[-1]
    ])

    if resampled_zyx_dims:
        removedir(sig_ch_resampledforelastix)
        removedir(sig_ch_resampledforelastix + '.raw')

    writer(svlc, '\n   Transformix File Generated: {}'.format(sig_out))

    return vol
Beispiel #14
0
def apply_transformix(vol, reg_vol, svlc, cores, AtlasFile, parameters,
                      transformfile, resampled_zyx_dims):
    '''
    Signature: (vol, svlc, cores, AtlasFile, parameters, transformfile)
    
    Function to
        1) apply sig/inj -> auto then registration->atlas transform
        2) generate depth coded images
        
    Contrast this with apply_transformix_and_register: which also includes: registration of a sig/inj channel to the autofluro (registration) channel

    (vol, reg_vol, svlc, cores, AtlasFile, parameters, transformfile)    

    Inputs
    ----------------
    vol = volume object to apply transform
    reg_vol (unused but needed to keep input the same with apply_transformix_and_register)
    svlc = path to 'elastix' folder, where files will be written
    cores = int # of cores
    AtlasFile = path to ABA atlas
    parameters = list in order of application of parameter file paths
    transformfile = output of elastix's transform from reg chan to atlas

    '''

    writer(
        svlc,
        '\n\nStarting transform ONLY for: {}...\n\n   to change to transform and registration of channel to regch add "secondary_registration": True to params in run tracing'
        .format(vol.downsized_vol))

    #set up folder/inputs
    sig_ch_resized = vol.downsized_vol + '.tif'
    trnsfrm_outpath = os.path.join(svlc, os.path.basename(vol.downsized_vol))
    makedir(trnsfrm_outpath)
    sig_ch_resampledforelastix = sig_ch_resized[:-4] + '_resampledforelastix.tif'

    #resample if necessary
    writer(svlc, 'Resizing channel: {}'.format(sig_ch_resized))
    if not vol.ch_type == 'regch':
        resample(sig_ch_resized,
                 AtlasFile,
                 svlocname=sig_ch_resampledforelastix,
                 singletifffile=True,
                 resamplefactor=1.3)
    #cannot be resample_par because that be a pool inside of pool
    #resample_par(cores, transforminput, AtlasFile, svlocname=transforminput_resized, singletifffile=True, resamplefactor=1.3)

    #optionally convert to mhd, note convert_to_mhd dims are in XYZ
    if resampled_zyx_dims:
        sig_ch_resampledforelastix = convert_to_mhd(
            vol.resampled_for_elastix_vol, dims=resampled_zyx_dims[::-1])

    #run transformix
    sp.call([
        'transformix', '-in', sig_ch_resampledforelastix, '-out',
        trnsfrm_outpath, '-tp', transformfile
    ])
    writer(svlc, '\n   Transformix File Generated: {}'.format(trnsfrm_outpath))

    if resampled_zyx_dims:
        removedir(sig_ch_resampledforelastix)
        removedir(sig_ch_resampledforelastix + '.raw')

    return vol
Beispiel #15
0
def elastix_command_line_call(fx, mv, out, parameters, fx_mask=False):
    '''Wrapper Function to call elastix using the commandline, this can be time consuming
    
    Inputs
    -------------------
    fx = fixed path (usually Atlas for 'normal' noninverse transforms)
    mv = moving path (usually volume to register for 'normal' noninverse transforms)
    out = folder to save file
    parameters = list of paths to parameter files IN ORDER THEY SHOULD BE APPLIED
    fx_mask= (optional) mask path if desired
    
    Outputs
    --------------
    ElastixResultFile = '.tif' or '.mhd' result file
    TransformParameterFile = file storing transform parameters
    
    '''
    e_params = ['elastix', '-f', fx, '-m', mv, '-out', out]
    if fx_mask:
        e_params = [
            'elastix', '-f', fx, '-m', mv, '-fMask', fx_mask, '-out', out
        ]

    ###adding elastix parameter files to command line call
    for x in range(len(parameters)):
        e_params.append('-p')
        e_params.append(parameters[x])
    writer(out, 'Elastix Command:\n{}\n...'.format(e_params))

    #set paths
    TransformParameterFile = os.path.join(
        out, 'TransformParameters.{}.txt'.format((len(parameters) - 1)))
    ElastixResultFile = os.path.join(
        out, 'result.{}.tif'.format((len(parameters) - 1)))

    #run elastix:
    try:
        print('Running Elastix, this can take some time....\n')
        sp.call(e_params)  #sp_call(e_params)#
        writer(out, 'Past Elastix Commandline Call')
    except RuntimeError as e:
        writer(
            out,
            '\n***RUNTIME ERROR***: {} Elastix has failed. Most likely the two images are too dissimiliar.\n'
            .format(e.message))
        pass
    if os.path.exists(ElastixResultFile) == True:
        writer(out, 'Elastix Registration Successfully Completed\n')
    #check to see if it was MHD instead
    elif os.path.exists(
            os.path.join(out, 'result.{}.mhd'.format(
                (len(parameters) - 1)))) == True:
        ElastixResultFile = os.path.join(
            out, 'result.{}.mhd'.format((len(parameters) - 1)))
        writer(out, 'Elastix Registration Successfully Completed\n')
    else:
        writer(
            out, '\n***ERROR***Cannot find elastix result file\n: {}'.format(
                ElastixResultFile))
        return

    return ElastixResultFile, TransformParameterFile