def make_lightcurve(self, inclinations=None, n_gridz=None, H0=None, R0=None, H_power=None, n_angle=None, dtheta=None, theta=None, unit="deg", n_radius=None, dr=None, lcurve_show=False, lcurve_savefig=False, lcurve_savecsv=False, dprofile_show=False, dprofile_savefig=False, normalizations=["stellar"], short_title=True, outfolder=None, ): """Makes a lightcurve by calling the other methods for each orientation of the dataset. Sort of a main method. TODO: Complete docstring. """ # Default setting for theta is a full revolution: if theta is None: if unit == "rad": theta = 2*np.pi elif unit == "deg": theta = 360. elif unit == "arcmin": theta = 360. * 60 elif unit == "arcsec": theta = 360. * 3600 if inclinations is None: inclinations = self.inclinations # If the inclination is a single number, put it in a list: inclinations = func.to_list(inclinations) if H0 is None: H0 = self.H0 if R0 is None: R0 = self.R0 if H_power is None: H_power = self.H_power if n_angle is None: n_angle = int(round(float(theta) / dtheta)) elif dtheta is None: dtheta = float(theta) / n_angle angles = np.linspace(0, theta-dtheta, n_angle) lightcurve = np.zeros((len(inclinations), n_angle)) # Density profile: if dprofile_show or dprofile_savefig: fig_dprof = plt.figure(figsize=(12,6)) fig_dprof.suptitle("%s" % self.dataname) axes_dprof = [] nplots = [ int(round(np.sqrt(len(inclinations)))), # No of columns. int(np.ceil(np.sqrt(len(inclinations)))), # No of rows. len(inclinations), # Total no of density profile plots. ] radius_max = None density_min = np.inf density_max = None plotcolors = ("b", "g", "r", "c", "m", "y") plotlinestyles = ('-', '--', '-.', ':') for i, angle in enumerate(angles): print "%6.2f / %g" % (angle, theta) self.rotate( angle_z=angle, unit=unit, ) for k, star in enumerate(self.stars): sylinder = Sylinder( star=star, data=self.get_sylinder(star=star), unit=self.unit, radius_in=self.radius_in, radius_out=self.radius_out, kappa=self.kappa ) for j, inclination in enumerate(inclinations): sylinder.space_sylinder( inclination=inclination, unit=unit, H0=H0, R0=R0, H_power=H_power, n_steps=n_radius, n_gridz=n_gridz, dr=dr, ) lightcurve[j, i] += sylinder.integrate() # Density profile: if (dprofile_show or dprofile_savefig) and (k < 4): # Only do for maximum 4 stars. if (i == 0) and (k == 0): # Only initialize axes once: axes_dprof.append(fig_dprof.add_subplot( nplots[1], nplots[0], j+1, )) if k == 0: axes_dprof[j].plot( sylinder.radiuses, sylinder.densities * u.Unit( u.Unit(self.unit["mass"]) / u.Unit(self.unit["distance"])**3 ).to("gram/cm3"), "%s%s" % (plotcolors[i], plotlinestyles[k]), label="%3g" % angle, ) else: axes_dprof[j].plot( sylinder.radiuses, sylinder.densities * u.Unit( u.Unit(self.unit["mass"]) / u.Unit(self.unit["distance"])**3 ).to("gram/cm3"), "%s%s" % (plotcolors[i], plotlinestyles[k]), ) for l, density in enumerate(sylinder.densities): if density == 0: if sylinder.radiuses[l] > radius_max: radius_max = sylinder.radiuses[l] break for l, density in enumerate(sylinder.densities): if density > density_max: density_max = density if density < density_min: density_min = density axes_dprof[j].set_title("inc=%2g" % inclination) # Density profile: if density_min == 0: density_min = 1e-30 if dprofile_show or dprofile_savefig: if radius_max is None: radius_max = self.radius_out else: radius_max *= 1.01 # Small buffer. for j in range(nplots[2]): # All subplots. axes_dprof[j].set_xlim([self.radius_in, radius_max]) axes_dprof[j].set_ylim([density_min, density_max]) try: axes_dprof[j].set_yscale("log") # Does not work if all 0s. except: pass axes_dprof[j].yaxis.set_major_formatter( \ ticker.FormatStrFormatter('%.1e')) for j in range(nplots[0]): # Bottom row. axes_dprof[~j].set_xlabel("radius [a]") for j in range(nplots[2] - nplots[0]): # All except bottom row. axes_dprof[j].set_xticklabels([]) for j in range(0, nplots[2], nplots[0]): # Left coumn. axes_dprof[j].set_ylabel("density [g/cm^3]") axes_dprof[nplots[0]-1].legend( # Only top right. title="v.angle [deg]=", loc="best", ) print "%6.2f / %g" % (theta, theta) if "all" in normalizations: normalizations = ["stellar", "max", "mean"] for normalization in normalizations: if "stellar" in normalization or "unobscured" in normalization: unobscured_flux = 0. for star in self.stars: unobscured_flux += star.intensity lightcurve /= unobscured_flux elif "max" in normalization: for j, maxflux in enumerate(lightcurve.max(axis=1)): if maxflux > 0: lightcurve[j] /= maxflux # else lightcurve[j] is all zeros, so avoid dividing by 0 elif "mean" in normalization: for j, maxflux in enumerate(lightcurve.max(axis=1)): if maxflux > 0: lightcurve[j] /= maxflux # else lightcurve[j] is all zeros, so avoid dividing by 0 if lcurve_show or lcurve_savefig: fig = plt.figure(figsize=(12,6)) fig.gca().get_yaxis().get_major_formatter().set_useOffset(False) # Always use absolute labels and not offsets. plt.minorticks_on() # Turn default minorticks on for y-axis. ax = fig.add_subplot(1,1,1) ax.set_xlim([0, 360]) ax.set_xticks(range(0, 360+1, 30)) ax.xaxis.set_minor_locator(ticker.AutoMinorLocator(3)) # A major tick every 30 deg and minor tick every 10 deg. # Set a specific tick step (hardcoded switch): if False: step = 0.1 stepmin = lightcurve.min() stepmax = lightcurve.max() stepdiff = stepmax - stepmin stepmin -= stepdiff # Increase the range of the ticks just stepmax += stepdiff # to be sure. stepmin = step * round(stepmin / step) # Round off to the stepmax = step * round(stepmax / step) # nearest step. ax.set_yticks(np.linspace( stepmin, stepmax, int(round((stepmax - stepmin) / step)) + 1, )) # Set a specific label step (hardcoded switch): if True: # Automatic minor ticks between steps. ax.yaxis.set_minor_locator(ticker.AutoMinorLocator(5)) elif True: # Manual label removal of certain steps. steplabel = 2 * step ylabels = [] for ytick in ax.get_yticks(): if (int(round(ytick/step)) % int(round(steplabel/step)) == 0 ): ylabels.append(ytick) else: ylabels.append("") ax.set_yticklabels(ylabels) for j, inclination in enumerate(inclinations): starradius = "" starflux = "" for star in self.stars: starradius += "%g-" % star.radius starflux += "%g-" % star.intensity starradius = starradius.rstrip("-") starflux = starflux.rstrip("-") header = ( "%s, H=%g, kappa=%g, " "r_star=%s, flux_star=%s, r_in=%g, r_out=%g, dr=%g, " "dtheta=%g%s, inc=%g%s" % ( self.dataname, H0, self.kappa, starradius, starflux, self.radius_in, self.radius_out, (self.radius_out - self.radius_in) / n_radius, float(theta) / n_angle, unit, inclination, unit, ) ) if lcurve_savecsv: outname = ( "%s__H=%g__" "r_in=%g__r_out=%g__" "inc=%02g__%snorm" % ( self.dataname, H0, self.radius_in, self.radius_out, inclination, normalization, ) ) if outfolder is None: outfolder = self.outfolder func.make_folder(outfolder) func.make_folder(outfolder + "/csvtables") outfile = open("%s/csvtables/%s.csv" \ % (outfolder, outname), "w") outfile.write("#" + header + "\n") for angle, flux in zip(angles, lightcurve[j]): outfile.write("%f,%f\n" % (angle, flux)) outfile.close() if lcurve_show or lcurve_savefig: ax.plot( angles, lightcurve[j], label="%2g" % inclinations[j], ) if lcurve_show or lcurve_savefig: if short_title: # Only use the name of the data in the title. ax.set_title(self.dataname) ax.set_position([0.10, 0.10, 0.80, 0.83]) else: # Use all metadata in the title. ax.set_title( "\n".join(textwrap.wrap(header.split(", inc")[0], 70)) ) ax.set_position([0.10, 0.10, 0.80, 0.80]) ax.set_xlabel("viewing angle [degree]") ax.set_ylabel("flux [%s flux]" % normalization) ax.legend( bbox_to_anchor=(1.11, 0.5), title="inc [deg]=", loc="right", borderaxespad=0., ) if lcurve_savefig or dprofile_savefig: if outfolder is None: outfolder = self.outfolder func.make_folder(outfolder) func.make_folder(outfolder + "/plots") outname = ( "%s__H=%g__" "r_in=%g__r_out=%g__" % ( self.dataname, H0, self.radius_in, self.radius_out, ) ) if lcurve_savefig: fig.savefig("%s/plots/%s%snorm.png" \ % (outfolder, outname, normalization)) if dprofile_savefig: fig_dprof.savefig("%s/plots/%sdprofiles.png" \ % (outfolder, outname)) if lcurve_show or dprofile_show: raw_input("Press <enter> to view the plots: ") if lcurve_show: fig.show() if dprofile_show: fig_dprof.show() raw_input("Press <enter> to close plots and exit: ")
print "CirBinDis version %s" % __version__ sys.exit(1) try: input_ = xmltodict.parse(infile)["input"] except Exception: print ( "usage: python %s input_file.xml\n" " Specify the (path)name of an input xml file. " % sys.argv[0] ) raise infile.close() input_ = func.extract_booleans(input_) for radius_in in func.to_list(input_["radius_in"], float): if radius_in is None or np.isnan(radius_in): radius_largest = 0. for stardict in func.to_list(input_["star"]): star = Star(stardict) radius = np.linalg.norm(star.position) + star.radius if radius > radius_largest: radius_largest = radius radius_in = radius_largest for radius_out in func.to_list(input_["radius_out"], float): if radius_out is None or np.isnan(radius_out): radius_out = np.inf have_resaved = False