def a_breaking_ratio(model=None, s=None, dq=None, odb=None, tau=1., z=None, r=3, full_advection=False, only_boundary=True, centre='rho', advect=False): ''' Computes the "breaking ratio" of gradient p to centripetal acceleration: (a_g-a_c)/a_c. For an ideal cylindrically symetric field rotating around a given centre, this ratio is zero. If full_advection is True, replaces a_c by advection term. ''' if not model: model=_model if dq == None: dq=bool(_parfile) if dq: tau1_level=np.array(pybold.level(model.dq.tau,tau),dtype=int) tau1=int(round(np.mean(tau1_level))) tau1min=int(round(np.min(tau1_level))) else: tau1=int(np.size(model.z.xc3)/2.) if s == None: s=snake.snake_from_box(model.z.rho,radius=r,start=tau1) if z == None or z == 'tau': pass if z == 'mintau': tau1 = tau1min if z == 'halftau': tau1 = int(round(.5*(tau1min+tau1))) tau1_sindex = int(list(s[:,2]).index(tau1)) xmean = int(s[tau1_sindex,0]) ymean = int(s[tau1_sindex,1]) if not odb: odb=snake.select_disk(model.z.rho[:,:,tau1],(xmean,ymean)) o, d, b = odb a_g = a_gradient((xmean,ymean), model,tau1) if not advect: a_c = a_centripetal((xmean,ymean),model,tau1) #a_c = (a_c[0][:,:,tau1], a_c[1][:,:,tau1]) a_c = np.sqrt(a_c[0]**2+a_c[1]**2) #a_g = (a_g[0][:,:,tau1], a_g[1][:,:,tau1]) else: a_c1 = advection(model.z.v1,model,tau1) a_c2 = advection(model.z.v1,model,tau1) a_c3 = advection(model.z.v1,model,tau1) a_c = np.sqrt(a_c1**2+a_c2**2+a_c3**2) #a_g = (a_g[0][:,:,tau1], a_g[1][:,:,tau1], a_g[2][:,:,tau1]) a_g = np.sqrt(a_g[0]**2+a_g[1]**2) if only_boundary: return np.sqrt(np.mean(((a_g[d]-a_c[d])/a_c[d])**2)),np.max(np.abs((a_g[d]-a_c[d])/a_c[d])) else: o_star = np.zeros_like(a_c,dtype=bool) o_star[o] = True o_star[xmean,ymean] = False o_star=np.where(o_star) return np.sqrt(np.mean(((a_g[o_star]-a_c[o_star])/np.mean(a_c[o_star]))**2)),np.max(np.abs((a_g[o_star]-a_c[o_star])/np.mean(a_c[o_star])))
def wilson_depression(model=None,s=None,odb=None,tau=1.,r=3): ''' Computes the Wilson depression. ''' if not model: model=_model tau1_level=np.array(pybold.level(model.dq.tau,tau),dtype=int) tau1=int(round(np.mean(tau1_level))) if s is None: s=snake.snake_from_box(model.z.rho,radius=r,start=tau1) tau1_sindex = int(list(s[:,2]).index(tau1)) xmean = int(s[tau1_sindex,0]) ymean = int(s[tau1_sindex,1]) if not odb: o,d,b=snake.select_disk(model.z.rho[:,:,tau1],(xmean,ymean)) else: o,d,b=odb min_tau1=int(np.min(tau1_level[o])) extended_b = np.ones_like(model.z.rho[:,:,0],dtype=bool) extended_b[o] = False extended_b = np.where(extended_b) mean_tau1=int(round(np.mean(tau1_level[extended_b]))) return model.z.xc3[0,0,mean_tau1]-model.z.xc3[0,0,min_tau1]
def contrast(arr,model=None,s=None,odb=None,tau=1.,r=3): ''' Computes local and global contrast of arr; (arr_i-<arr>)/<arr>. <arr> is taken in the local neighbourhood and on the whole z=cst slice, at <tau>=tau (=1 by default). ''' if not model: model=_model tau1_level=np.array(pybold.level(model.dq.tau,tau),dtype=int) tau1=int(round(np.mean(tau1_level))) if s is None: s=snake.snake_from_box(model.z.rho,radius=r,start=tau1) tau1_sindex = int(list(s[:,2]).index(tau1)) xmean = int(s[tau1_sindex,0]) ymean = int(s[tau1_sindex,1]) if not odb: o,d,b=snake.select_disk(model.z.rho[:,:,tau1],(xmean,ymean)) else: o,d,b=odb arr_mean=np.mean(arr[:,:,tau1]) arr_bmean=np.mean(arr[:,:,tau1][b]) contrast_global = (arr[xmean,ymean,tau1]-arr_mean)/arr_mean contrast_local = (arr[xmean,ymean,tau1]-arr_bmean)/arr_bmean return contrast_global, contrast_local
def report(ireport=None, model=None, s=None, dq=None, odb=None, tau=1., z=None, r=3, savefig=False, show=True): if not model: model=_model if dq == None: dq=bool(_parfile) if dq: tau1_level=np.array(pybold.level(model.dq.tau,tau),dtype=int) tau1=int(round(np.mean(tau1_level))) tau1min=int(round(np.min(tau1_level))) else: tau1=int(np.size(model.z.xc3)/2.) if s == None: s=snake.snake_from_box(model.z.rho,radius=r,start=tau1) if z == None or z == 'tau': pass if z == 'mintau': tau1 = tau1min if z == 'halftau': tau1 = int(round(.5*(tau1min+tau1))) tau1_sindex = int(list(s[:,2]).index(tau1)) xmean = int(s[tau1_sindex,0]) ymean = int(s[tau1_sindex,1]) print(str(xmean)+', '+str(ymean)) print(str(np.unravel_index(np.argmin(model.z.v1[46:56,39:50,tau1]**2+model.z.v2[46:56,39:50,tau1]**2),(10,11)))) if not odb: odb=snake.select_disk(model.z.rho[:,:,tau1],(xmean,ymean),threshold=.5) rot_index = np.argmin(model.z.v1[:,:,tau1][odb[0]]**2) xrot,yrot = odb[0][0][rot_index], odb[0][1][rot_index] print(str(xrot)+', '+str(yrot)) # #if not odb: odb=snake.select_disk(tau1_level,(xmean,ymean),mask_flag=False,threshold=.8) plt.imshow(model.z.rho[:,:,tau1],origin='bottom') oring=np.zeros_like(model.z.rho[:,:,tau1],dtype=bool) oring[odb[0]]=True plt.imshow(oring,origin='bottom',alpha=.7,interpolation='none') plt.quiver(model.z.v2[:,:,tau1],model.z.v1[:,:,tau1]) #odb2=snake.select_disk(model.z.rho[:,:,tau1],(xmean,ymean),threshold=.8) #plt.figure() #plt.imshow(model.z.rho[:,:,tau1],origin='bottom') #oring=np.zeros_like(model.z.rho[:,:,tau1],dtype=bool) #oring[odb2[0]]=True #plt.imshow(oring,origin='bottom',alpha=.7,interpolation='none') #plt.quiver(model.z.v2[:,:,tau1],model.z.v1[:,:,tau1]) #plt.figure() #plt.imshow(model.z.v2[:,:,tau1]**2+model.z.v1[:,:,tau1]**2,origin='bottom',interpolation='none',cmap=cm.gray) # fmt='{0: <20}' if _modelfile: print(fmt.format('File:')+_modelfile) else: print(fmt.format('File:')+'Unknown') wd=wilson_depression(model,s,odb,tau,r) print(fmt.format('Wilson depression:')+str(wd)) #c_rho=contrast(model.z.rho,model,s,odb,tau,r) c_rho=contrastf(model.z.rho[:,:,tau1],odb,np.min) print(fmt.format('Density contrast:')+str(c_rho)) #c_p=contrast(model.dq.P,model,s,odb,tau,r) c_p=contrastf(model.dq.P[:,:,tau1],odb,np.min) print(fmt.format('Pressure contrast:')+str(c_p)) a_ratio=a_breaking_ratio(model,s,dq,odb,tau,z,r,centre='rho') print(fmt.format('Acceleration ratio:')+str(a_ratio)) adv_ratio=a_breaking_ratio(model,s,dq,odb,tau,z,r,centre='rho',advect=True) print(fmt.format('Advection ratio::')+str(adv_ratio)) if _modelfile: title = _modelfile.split('.') title = '.'.join(title[:max(1,len(title)-1)]) if ireport and _modelfile: id_name = title.split('nMBP')[-1] with open(ireport) as f: lines = f.readlines() names = [l.split('\t')[0] for l in lines] lines = [[f.strip() for f in l.split('\t')] for l in lines[1:]] idx = int(names.index(id_name))+1 diam = float(lines[idx][1]) c_I = (float(lines[idx][2]),float(lines[idx][3])) time = float(lines[idx][4]) print(fmt.format('Diametre:')+str(diam)) print(fmt.format('Intensity contrast:')+str(c_I)) print(fmt.format('Lifetime:')+str(time)) boxtext = 'Wilson depression: '+str(int(round(wd/1.e5)))+' [km]\n' boxtext+= 'Density contrast: '+str(int(round(100*c_rho[0])))+'%, ' boxtext+= str(int(round(100*c_rho[1])))+'%\n' boxtext+= 'Pressure contrast: '+str(int(round(100*c_p[0])))+'%, ' boxtext+= str(int(round(100*c_p[1])))+'%' #boxtext+= 'Acceleration ratio: '+str(int(round(100*a_ratio[0])))+'%, ' #boxtext+= str(int(round(100*a_ratio[1])))+'%' if ireport and _modelfile: delta = model.z.xc1[1,:,:]-model.z.xc1[0,:,:] boxtext+= '\nDiametre: '+str(int(round(diam*delta/1.e5)))+' [km]' boxtext+= '\nIntensity contrast: '+str(int(round(100*c_I[0])))+'%, ' boxtext+= str(int(round(100*c_I[1])))+'%' boxtext+= '\nLifetime: '+str(int(round(time)))+' [s]' if savefig: sY,sX=plotv_slice(model.z.rho,model,s,dq,tau,r,boxtext,show=False) if savefig == True: plt.savefig(title+'.png') else: plt.savefig(savefig) if show: plt.show() plt.close() else: sY,sX=plotv_slice(model.z.rho,model,s,dq,tau,r,boxtext,show=show) plt.close()
def report(): ''' Prints a report of the current nMBP together with the corresponding plots. ''' global _model, _parameters, _rad model = _model tau = 1. r = 3 tau1_level = np.array(pybold.level(model.dq.tau, tau), dtype=int) tau1 = int(round(np.mean(tau1_level))) tau1min = int(round(np.min(tau1_level))) seed = [ _parameters[0][0] - model.z.dimension[0][0], _parameters[0][1] - model.z.dimension[0][1], tau1 ] s = snake.snake_from_box(model.z.rho, radius=r, start=tau1, periodic=False, seed=seed) tau1_sindex = int(list(s[:, 2]).index(tau1)) xmean = int(s[tau1_sindex, 0]) ymean = int(s[tau1_sindex, 1]) odb = snake.select_disk(model.z.rho[:, :, tau1], (xmean, ymean), threshold=.5) rot_index = np.argmin(model.z.v1[:, :, tau1][odb[0]]**2) xrot, yrot = odb[0][0][rot_index], odb[0][1][rot_index] xc1, xc2 = model.z.xc1.flatten() / 1.e5, model.z.xc2.flatten() / 1.e5 xb1, xb2 = model.z.xb1.flatten() / 1.e5, model.z.xb2.flatten() / 1.e5 ext = [xc1[0], xc1[-1], xc2[0], xc2[-1]] #Ttau1 = pybold.varAtLevel(model.dq.T,model.dq.tau,1.) rhotau1 = pybold.varAtLevel(model.z.rho, model.dq.tau, 1.) #plt.imshow(model.z.rho[:,:,tau1].T,origin='bottom',cmap=plt.cm.gray,extent=ext) plt.imshow(rhotau1.T, origin='bottom', extent=ext) plt.xlim(xc1[0], xc1[-1]) plt.ylim(xc2[0], xc2[-1]) plt.xlabel('Spatial horizontal position (X axis) [km]') plt.ylabel('Spatial horizontal position (Y axis) [km]') oring = np.zeros_like(model.z.rho[:, :, tau1], dtype=bool) oring[odb[0]] = True plt.imshow(oring.T, origin='bottom', alpha=.15, interpolation='none', extent=ext, cmap=plt.cm.gray_r) X, Y = np.meshgrid(xc1, xc2) arrfreq = 5 v1 = pybold.varAtLevel(model.z.v1, model.dq.tau, 1.) v2 = pybold.varAtLevel(model.z.v2, model.dq.tau, 1.) #plt.quiver(X[::arrfreq,::arrfreq], Y[::arrfreq,::arrfreq], model.z.v1[::arrfreq,::arrfreq,tau1].T,model.z.v2[::arrfreq,::arrfreq,tau1].T) plt.quiver(X[::arrfreq, ::arrfreq], Y[::arrfreq, ::arrfreq], v1[::arrfreq, ::arrfreq].T, v2[::arrfreq, ::arrfreq].T) fmt = '{0: <20}' if _modelfile: print(fmt.format('File:') + _modelfile) else: print(fmt.format('File:') + 'Unknown') wd = wilson_depression(model, s, odb, tau, r) print(fmt.format('Wilson depression:') + str(wd)) c_rho = contrast(model.z.rho, model, s, odb, tau, r) print(fmt.format('Density contrast:') + str(c_rho)) c_p = contrast(model.dq.P, model, s, odb, tau, r) print(fmt.format('Pressure contrast:') + str(c_p)) if _modelfile: title = _modelfile.split('.') title = '.'.join(title[:max(1, len(title) - 1)]) boxtext = 'Wilson depression: ' + str(int(round(wd / 1.e5))) + ' [km]\n' boxtext += 'Density contrast: ' + str(int(round(100 * c_rho[1]))) + '%, ' boxtext += str(int(round(100 * c_rho[0]))) + '%\n' boxtext += 'Pressure contrast: ' + str(int(round(100 * c_p[1]))) + '%, ' boxtext += str(int(round(100 * c_p[0]))) + '%' diam = _parameters[3] delta = model.z.xc1[1, :, :] - model.z.xc1[0, :, :] boxtext += '\nDiametre: ' + str(int(round(diam * delta / 1.e5))) + ' [km]' c_I = (_parameters[1], _parameters[2]) boxtext += '\nIntensity contrast: ' + str(int(round(100 * c_I[0]))) + '%, ' boxtext += str(int(round(100 * c_I[1]))) + '%' boxtext += '\nLifetime: ' + str(int(round(120.))) + ' [s]' fig = plt.figure() ax = fig.add_subplot(1, 1, 1) deltaX = xb1[1] - xb1[0] deltaY = xb2[1] - xb2[0] xlim_min = xc1[0] - model.z.dimension[0][0] * deltaX ylim_min = xc2[0] - model.z.dimension[0][1] * deltaY szX, szY = np.shape(_rad.T) ext = [ xlim_min, xlim_min + szX * deltaX, ylim_min, ylim_min + szY * deltaY ] ax.imshow(_rad.T, origin='bottom', cmap=plt.cm.gray, extent=ext) ax.set_xlim(xlim_min, xlim_min + szX * deltaX) ax.set_ylim(ylim_min, ylim_min + szY * deltaY) ax.set_xlabel('Spatial horizontal position (X axis) [km]') ax.set_ylabel('Spatial horizontal position (Y axis) [km]') c1_idx = _parameters[0][0] - model.z.dimension[0][0] c2_idx = _parameters[0][1] - model.z.dimension[0][1] centre = [xc1[c1_idx], xc2[c2_idx]] c_r = 50. * np.sqrt(deltaX**2 + deltaY**2) / np.sqrt(2.) circ = plt.Circle(centre, radius=c_r, color='r', fill=False) ax.add_patch(circ) sY, sX = plotv_slice(model.z.rho, model, s, dq=True, tau=tau, r=r, boxtext=boxtext, show=True, tight=False) plt.close()
def getNMBPs(indicator, intensity=None, granules=None, l=50, footprint=None): ''' Gets all nMBPs using the given indicator. If an intensity map is not provided, temperature at isosurface tau=1. is taken in place. If granules were already computed, they can be provided here to avoid a new computations. If footprint is not provided a circular footprint (or stencil) of diameter l is used. ''' global _model, _T if intensity is None: intensity = _T if granules is None and _model is None: granules = getGranules(intensity, shrink=0.) if granules is None and _model != None: v3 = varAtLevel(_model.z.v3, _model.dq.tau, 1.) granules = v3 > 0. if footprint is None: fp = circleFootprint(l) elif type(footprint) == int: fp = circleFootprint(footprint) else: fp = footprint p = find_min(-indicator) p = [(int(p0[0]), int(p0[1])) for p0 in p] p = [p0 for p0 in p if indicator[p0] > .2] zones = [] toRemove = set() #minimas = [] nmbps = [] for p00, p01 in p: nx, ny = np.shape(indicator) mgrid = np.meshgrid( np.arange(p00 - l, p00 + l + 1) % nx, np.arange(p01 - l, p01 + l + 1) % ny) mgrid = (mgrid[0].T, mgrid[1].T) q, err = nearestMin(-intensity[mgrid], (l + 1, l + 1)) if err != 0: print('Warning: nearest nMBP in intensity map to point (' + str(p00) + ', ' + str(p01) + ') is further than max_dist.') s, d, b = select_disk(-intensity[mgrid], q) zones.append(zip((s[0] + p00 - l) % nx, (s[1] + p01 - l) % ny)) nmbps.append(((q[0] + p00 - l) % nx, (q[1] + p01 - l) % ny)) for i in range(len(p)): if p[i] not in zones[i]: toRemove.add(i) continue for j in range(len(p)): if j >= i: break s = set.intersection(set(zones[i]), set(zones[j])) if len(s) == 0: continue if len(zones[j]) > len(zones[i]): toRemove.add(i) else: toRemove.add(j) if len(toRemove) > 0: toRemove = np.sort(np.array(list(toRemove))) - np.arange(len(toRemove)) for i in toRemove: p.pop(i) zones.pop(i) nmbps.pop(i) background = [] contrast_local = [] contrast_global = [] diametre = [] int_global = np.mean(intensity) for i in range(len(nmbps)): xshift = int(nmbps[i][0] - (np.size(fp, axis=0) - 1) / 2.) yshift = int(nmbps[i][1] - (np.size(fp, axis=1) - 1) / 2.) NX, NY = np.shape(intensity) n = np.count_nonzero(fp) fp_mask = np.array(np.where(fp)) + np.repeat( [[xshift], [yshift]], n, axis=1) fp_mask = (np.mod(fp_mask[0], NX), np.mod(fp_mask[1], NY)) nmbp_mask = zip(*zones[i]) mask = zip(*set.difference(set(zip(*fp_mask)), set(zip(*nmbp_mask)))) dnh = intensity[mask] * (1 - granules[mask]) # Dark neighbourhood background.append(np.sum(dnh) / np.count_nonzero(dnh)) contrast_local.append( np.mean(intensity[zip(*zones[i])]) / background[i]) contrast_global.append(np.mean(intensity[zip(*zones[i])]) / int_global) diametre.append(2. * np.sqrt(len(zones[i]) / np.pi)) return zip(p, np.array(contrast_local) - 1., np.array(contrast_global) - 1., diametre)