|
| 1 | +import renderapi |
| 2 | +import matplotlib as mpl |
| 3 | +mpl.use('Agg') |
| 4 | +from renderapps.module.render_module import RenderParameters, RenderModule |
| 5 | +import argschema |
| 6 | +from renderapps.TrakEM2.AnnotationJsonSchema import AnnotationFile |
| 7 | +import matplotlib.pyplot as plt |
| 8 | +#%matplotlib notebook |
| 9 | +import numpy as np |
| 10 | +import os |
| 11 | +import pandas as pd |
| 12 | +from multiprocessing import pool |
| 13 | +from functools import partial |
| 14 | +import json |
| 15 | + |
| 16 | + |
| 17 | +############## this is modified from notebook: http://ibs-forrestc-ux1:8888/notebooks/MakeSynaptogramsFromAnnotations.ipynb ##### |
| 18 | + |
| 19 | + |
| 20 | +example_parameters = { |
| 21 | + "render":{ |
| 22 | + "host": "ibs-forrestc-ux1", |
| 23 | + "port": 80, |
| 24 | + "owner": "Forrest", |
| 25 | + "project": "M246930_Scnn1a_4_f1", |
| 26 | + "client_scripts": "/pipeline/render/render-ws-java-client/src/main/scripts" |
| 27 | + }, |
| 28 | + |
| 29 | + "global_annotation_file":"/nas/data/M246930_Scnn1a_4_f1/annotation/m246930_site5_annotation_MN_adjustZ_bb_Take2Site5_EMA_global.json", |
| 30 | + "annotation_metadata_json":"/nas/data/M246930_Scnn1a_4_f1/SEMdata/processed/Synaptograms/annotationMetadata/m246930_Take2Site5_synaptogram_metadata.json", |
| 31 | + "fig_directory":"/nas/data/M246930_Scnn1a_4_f1/SEMdata/processed/Synaptograms/Take2Site5_TdTeSyn", |
| 32 | + "synapses_to_make":['1226','1326','1416','2171','2299','668','2707','2709','2711'], |
| 33 | + "channel_stacks":[ |
| 34 | + { |
| 35 | + |
| 36 | + "stack":"EMSite5_take2_EMA" |
| 37 | + }, |
| 38 | + { |
| 39 | + |
| 40 | + "stack":"EMSite5_take2_EMA" |
| 41 | + }, |
| 42 | + { |
| 43 | + "channel":"TdTomato", |
| 44 | + "stack":"Take2Site5_EMA_STI_DCV_FF_allSession_2", |
| 45 | + "maxIntensity":10000 |
| 46 | + }, |
| 47 | + { |
| 48 | + "channel":"synapsin", |
| 49 | + "stack":"Take2Site5_manReg_EMA_STI_DCV_FF_allSession_3", |
| 50 | + "maxIntensity":16000 |
| 51 | + } |
| 52 | + ] |
| 53 | +} |
| 54 | + |
| 55 | + |
| 56 | + |
| 57 | +class ChannelStack(argschema.schemas.DefaultSchema): |
| 58 | + channel = argschema.fields.Str(required=False, |
| 59 | + description="Channel of stack to render (if needed)") |
| 60 | + stack = argschema.fields.Str(required=True, |
| 61 | + description="render stack to render") |
| 62 | + maxIntensity = argschema.fields.Int(required=False, |
| 63 | + description="Max intensity to render this channel") |
| 64 | + |
| 65 | +class MakeAnnotationSynaptogramParameters(RenderParameters): |
| 66 | + global_annotation_file = argschema.fields.InputFile(required=True, |
| 67 | + description = "global annotation file") |
| 68 | + fig_directory = argschema.fields.OutputDir(required=True, |
| 69 | + description = "directory to store figures") |
| 70 | + annotation_metadata_json = argschema.fields.OutputFile(required=True, |
| 71 | + description = "where to save metadata") |
| 72 | + channel_stacks = argschema.fields.Nested(ChannelStack, |
| 73 | + many=True, |
| 74 | + required=True, |
| 75 | + description="list of Channel Stacks to render") |
| 76 | + synapses_to_make=argschema.fields.List(argschema.fields.Str, |
| 77 | + required=False, |
| 78 | + description="list of oid's to make synapses from") |
| 79 | + |
| 80 | + |
| 81 | + |
| 82 | +def load_annotation_file(annotation_path): |
| 83 | + with open(annotation_path,'r') as fp: |
| 84 | + annotation_d = json.load(fp) |
| 85 | + schema = AnnotationFile() |
| 86 | + annotations,errors = schema.load(annotation_d) |
| 87 | + assert(len(errors)==0) |
| 88 | + return annotations |
| 89 | + |
| 90 | +def make_synaptogram(render,channel_stacks,savedir,al,border=400/3,borderz=2): |
| 91 | + oid = al['oid'] |
| 92 | + zvalues = [] |
| 93 | + Nareas = len(al['areas']) |
| 94 | + mins = np.zeros((Nareas,2)) |
| 95 | + maxs = np.zeros((Nareas,2)) |
| 96 | + for i,area in enumerate(al['areas']): |
| 97 | + zvalues.append(area['z']) |
| 98 | + gp = area['global_path'] |
| 99 | + mins[i,:] = np.min(gp,axis=0) |
| 100 | + maxs[i,:] = np.max(gp,axis=0) |
| 101 | + gmins = np.min(mins,axis=0)-border |
| 102 | + gmaxs = np.max(maxs,axis=0)+border |
| 103 | + minX = gmins[0] |
| 104 | + minY = gmins[1] |
| 105 | + maxX = gmaxs[0] |
| 106 | + maxY = gmaxs[1] |
| 107 | + width = maxX-minX+1 |
| 108 | + height = maxY-minY+1 |
| 109 | + zvalues=sorted(zvalues) |
| 110 | + zvals = np.arange(np.min(zvalues)-1,np.max(zvalues)+1+1) |
| 111 | + Nz = len(zvals) |
| 112 | + Nc = len(channel_stacks) |
| 113 | + minZ = int(min(zvals)) |
| 114 | + ratio = ((Nc)*(height)*1.05)/((Nz)*(width)*1.0) |
| 115 | + fig_width=.5*(width*Nz)/100.0 |
| 116 | + print width,height,Nz |
| 117 | + d={ |
| 118 | + 'oid':oid, |
| 119 | + 'id':al['id'], |
| 120 | + 'minX':minX, |
| 121 | + 'maxX':maxX, |
| 122 | + 'minY':minY, |
| 123 | + 'maxY':maxY, |
| 124 | + 'Nz':Nz, |
| 125 | + 'minZ':minZ, |
| 126 | + 'maxZ':minZ+Nz, |
| 127 | + 'width':width, |
| 128 | + 'height':height |
| 129 | + } |
| 130 | + if width>1000: |
| 131 | + return d |
| 132 | + if height>1000: |
| 133 | + return d |
| 134 | + if len(zvals)>16: |
| 135 | + return d |
| 136 | + plt.rcParams['axes.facecolor'] = 'black' |
| 137 | + f,ax=plt.subplots(Nc,Nz, |
| 138 | + figsize=(fig_width,int(fig_width*ratio)), |
| 139 | + gridspec_kw = {'wspace':0, 'hspace':0}, |
| 140 | + facecolor='black') |
| 141 | + plt.subplots_adjust(left=0.0, right=1.0, top=1.0, bottom=0.0) |
| 142 | + for c,chstack in enumerate(channel_stacks): |
| 143 | + for zi,z in enumerate(zvals): |
| 144 | + a=ax[c,zi] |
| 145 | + a.set_xlim([minX,maxX]) |
| 146 | + a.set_ylim([minY,maxY]) |
| 147 | + a.set_xticks([]) |
| 148 | + a.set_yticks([]) |
| 149 | + a.set_aspect('equal') |
| 150 | + chname = chstack.get('channel',None) |
| 151 | + maxIntensity = chstack.get('maxIntensity',None) |
| 152 | + img = renderapi.image.get_bb_image(chstack['stack'], |
| 153 | + z, |
| 154 | + minX, |
| 155 | + minY, |
| 156 | + width, |
| 157 | + height, |
| 158 | + channel=chname, |
| 159 | + maxIntensity=maxIntensity, |
| 160 | + render=render) |
| 161 | + a.imshow(img,vmin=0,vmax=255,extent=[minX,maxX,maxY,minY]) |
| 162 | + for i,area in enumerate(al['areas']): |
| 163 | + zi = int(area['z']-minZ) |
| 164 | + for c in range(1,len(channel_stacks)): |
| 165 | + a = ax[c,zi] |
| 166 | + a.plot(area['global_path'][:,0],area['global_path'][:,1],c='Teal',linewidth=2) |
| 167 | + for c,chstack in enumerate(channel_stacks): |
| 168 | + chname = chstack.get('channel',chstack['stack']) |
| 169 | + |
| 170 | + ax[c,0].text(minX,minY,chname[0:4],fontdict={'color':'SLATEGRAY','weight':'bold'},fontsize=14) |
| 171 | + #f.tight_layout(True) |
| 172 | + fname = os.path.join(savedir,'{}.png'.format(oid)) |
| 173 | + f.savefig(fname) |
| 174 | + d['figure']=fname |
| 175 | + plt.clf() |
| 176 | + plt.close() |
| 177 | + del(f) |
| 178 | + return d |
| 179 | + |
| 180 | + |
| 181 | +class MakeAnnotationSynaptograms(RenderModule): |
| 182 | + default_schema = MakeAnnotationSynaptogramParameters |
| 183 | + |
| 184 | + def run(self): |
| 185 | + print self.args |
| 186 | + annotations = load_annotation_file(self.args['global_annotation_file']) |
| 187 | + |
| 188 | + if not os.path.isdir(self.args['fig_directory']): |
| 189 | + os.makedirs(self.args['fig_directory']) |
| 190 | + |
| 191 | + |
| 192 | + myp = partial(make_synaptogram, |
| 193 | + self.render, |
| 194 | + self.args['channel_stacks'], |
| 195 | + self.args['fig_directory']) |
| 196 | + |
| 197 | + #print disagree_oids |
| 198 | + proc_pool= pool.Pool(6) |
| 199 | + good_oids = self.args.get('synapses_to_make',None) |
| 200 | + if good_oids is not None: |
| 201 | + good_ann =[al for al in annotations['area_lists'] if al['oid'] in good_oids] |
| 202 | + ds = proc_pool.map(myp,good_ann) |
| 203 | + else: |
| 204 | + ds=proc_pool.map(myp,annotations['area_lists']) |
| 205 | + print(len(ds)) |
| 206 | + with open(self.args['annotation_metadata_json'],'w') as fp: |
| 207 | + json.dump(ds,fp) |
| 208 | + |
| 209 | + |
| 210 | +if __name__ == '__main__': |
| 211 | + mod = MakeAnnotationSynaptograms(input_data = example_parameters) |
| 212 | + mod.run() |
0 commit comments