Example #1
0
    def testValidSeries(self):
        """Promts the user to enter a directory name. After one has been
        chosen, prompt for a series name. If yt can't load it, display
        an error message and try again.
        """
        directory = QW.QFileDialog.getExistingDirectory(self, "Select a directory with your series in it",
                                                        self.Param_Dict["Directory"])
        if directory != '':
            # Information on DataSetSeries object:
            # http://yt-project.org/doc/reference/api/yt.data_objects.time_series.html#yt.data_objects.time_series.DataSetSeries
            ts = self.loadSeries(directory)
            if ts is None:
                return
            try:
                GUILogger.info(f"This series includes {len(ts)} files.")
#                ts = [yt.load(filename) for filename in ts._pre_outputs]
                self.Param_Dict["DataSeries"] = ts
                self.setUpSeries()
            except TypeError:
                self.RadioDict_Dict["EvalMode"]["Single file"].setChecked(True)
                self.Param_Dict["SingleDataSet"] = ts
                GUILogger.warning("Only a single file has been selected. Changing to single file mode.")
                self.Param_Dict["Filename"] = self.Param_Dict["Seriesname"]
                self.Param_Dict["Seriesname"] = ""
                self.Status_Dict["Series"].setText(self.Param_Dict["Seriesname"])
                self.Status_Dict["File"].setText(self.Param_Dict["Seriesname"])
                self.Param_Dict["isValidFile"] = True
                self.Param_Dict["isValidSeries"] = False
                self.setUpFile()
Example #2
0
 def loadSeries(self, directory):
     """Handles loading a given series in a directory.
     Also changes the current working directory
     self.Param_Dict["Directory"]
     Parameters:
         directory: path of the series
     returns:
         ts: yt DataSetSeries object
     """
     GUILogger.info(f"{directory} is directory for series mode")
     self.Status_Dict["Dir"].setText(directory)
     self.Param_Dict["Directory"] = directory
     ok = self.askSeriesName()
     if ok:
         try:
             GUILogger.info(f"Loading series '{self.Param_Dict['Seriesname']}'...")
             ts = yt.load(directory + '/' + self.Param_Dict["Seriesname"])
             self.Param_Dict["Filename"] = ""
             self.Status_Dict["File"].setText(self.Param_Dict["Filename"])
             self.Param_Dict["isValidSeries"] = True
             self.Param_Dict["isValidFile"] = True
             return ts
         except YTOutputNotIdentified:
             sut.alertUser("Couldn't load this series. Please try again")
             # Ask the user to enter another series name.
             # If he cancels, pass.
             return self.loadSeries(directory)
     else:
         GUILogger.warning("Couldn't load series.")
         GUILogger.log(29, "Try replacing the last digits of your series with "
                       "questionmarks or import all files of the directory "
                       "by using *")
         return None
Example #3
0
def PhasePlot(Param_Dict, worker):
    """Takes a DataSet object loaded with yt and performs a phasePlot on it.
    Parameters:
        Param_Dict: to access the relevant parameters
    """
    if Param_Dict["WeightField"] is None:
        GUILogger.warning('Having <font color="DarkViolet">None</font> as the '
                          "weight field just accumulates, "
                          "so the extrema might be inaccurate.")
    ds = Param_Dict["CurrentDataSet"]
    XField, YField, ZField = Param_Dict["XAxis"], Param_Dict["YAxis"], \
        Param_Dict["ZAxis"]
    ad = ds.all_data()
    if Param_Dict["ParticlePlot"]:
        plot = yt.ParticlePhasePlot(ad, XField, YField, ZField,
                                    weight_field=Param_Dict["WeightField"],
                                    fontsize=14)
    else:
        plot = yt.PhasePlot(ad, XField, YField, ZField,
                            weight_field=Param_Dict["WeightField"],
                            fontsize=14)
    emitStatus(worker, "Setting phase plot modifications")
    # Set min, max, unit log and color scheme:
    setAxisSettings(plot, Param_Dict, "X")
    setAxisSettings(plot, Param_Dict, "Y")
    setAxisSettings(plot, Param_Dict, "Z")
    emitStatus(worker, "Annotating the phase plot")
    plot.annotate_title(Param_Dict["PlotTitle"])
    finallyDrawPlot(plot, Param_Dict, worker)
Example #4
0
 def testValidFile(self):
     """Promts the user to enter a file name. If yt can't load it, display
     an error message and try again.
     returns:
         True if load was successful
         False if user cancels before successful load
     """
     filename = QW.QFileDialog.getOpenFileName(self, "Select a simulation file", 
                                               self.Param_Dict["Directory"],
                                               "All files (*)")[0]
     if filename != '':
         try:
             # SingleDataSet is there so we can go back to a single dataset
             # if the user loaded one.
             self.Param_Dict["SingleDataSet"] = self.loadFile(filename)
             self.Param_Dict["CurrentDataSet"] = self.Param_Dict["SingleDataSet"]
             self.Param_Dict["Seriesname"] = ""
             self.Param_Dict["Filename"] = filename
             self.Status_Dict["Series"].setText(self.Param_Dict["Seriesname"])
             self.Param_Dict["isValidFile"] = True
             self.Param_Dict["isValidSeries"] = False
             self.setUpFile()
             return
         except YTOutputNotIdentified:
             sut.alertUser("Couldn't load this file. Please try again")
             # Ask the user to enter another series name.
             # If he cancels, pass.
             self.testValidFile()
     else:
         GUILogger.warning("Couldn't load file. Click 'Open File' to start over.")
         return
Example #5
0
def calcExtrema(Param_Dict, ds, field, projCond):
    """Tries to calculate the extrema."""
    if projCond:
        # For a projection plot, we need to get the projected min and max
        # We also need to create new entries in the fieldMins
        minMaxArray = calcProjectionExtrema(Param_Dict, ds, field)
    else:
        try:
            minMaxArray = ds.all_data().quantities.extrema(field)
        except yt.utilities.exceptions.YTFieldNotFound:
            GUILogger.warning(f"Couldn't find {field} in the available fields")
            raise WorkingException
    return minMaxArray
Example #6
0
 def makeProfilePlot(self, Param_Dict, arr, labels, worker=None):
     """Plots the data of the array to the axes."""
     self.arr = arr
     self.labels = labels
     emitStatus(worker, "Starting the plot")
     if Param_Dict["AddProfile"]:
         self.ax.tick_params(axis='y',)
         self.twinax = self.ax.twinx()
         x_values = arr[0].to_value(Param_Dict["XUnit"])
         for i in range(len(arr)-1):
             y_values = arr[i+1].to_value(Param_Dict["YUnit"])
             label = labels[i]
             self.twinax.plot(x_values, y_values, ":", linewidth=3,
                              label=label)
         emitStatus(worker, "Setting plot modifications")
         setProfileAxisSettings(Param_Dict, "Y", self.twinax)
         self.twinax.tick_params(axis='y')
         # ask matplotlib for the plotted objects and their labels
         lines, labels = self.ax.get_legend_handles_labels()
         lines2, labels2 = self.twinax.get_legend_handles_labels()
         self.ax.legend(lines + lines2, labels + labels2)
         self.hasProfile = False  # We only want the user to be able to add a plot if there is only one profile
         Param_Dict["SignalHandler"].changeToProfile()
     else:
         self.prepareFigure()  # Clear everything before plotting
         # get x- and y-values and plot them:
         x_values = arr[0].to_value(Param_Dict["XUnit"])
         for i in range(len(arr)-1):
             y_values = arr[i+1].to_value(Param_Dict["YUnit"])
             label = labels[i]
             self.ax.plot(x_values, y_values, "-", linewidth=3, label=label)
         emitStatus(worker, "Setting plot modifications")
         setProfileAxisSettings(Param_Dict, "Y", self.ax)
         self.hasProfile = True
         Param_Dict["SignalHandler"].changeToProfile()
         if Param_Dict["Timestamp"] and Param_Dict["XAxis"] != "time":
             if len(arr) > 2:  # This can probably be done more elegantly
                 GUILogger.warning("Timestamp is not annotated for multiple"
                                   " profiles. Sorry for leaving the CheckBox there.")
             else:
                 drawTimestampBox(Param_Dict, self.ax)
         self.ax.legend()
         self.ax.grid()
     setProfileAxisSettings(Param_Dict, "X", self.ax)
     self.ax.set_title(r"{}".format(Param_Dict["PlotTitle"]))
     emitStatus(worker, "Drawing plot onto the canvas")
     self.canvas.draw()  # called twice because somehow it isn't fully sized
     self.canvas.draw()  # at first... I don't know why.
     self.copyParamDict(Param_Dict)
Example #7
0
def calcProjectionExtrema(Param_Dict, ds, field):
    """Creates dummy projection plots to then calculate the extrema in those.
    Returns a ytArray of these extrema"""
    try:
        if Param_Dict["ParticlePlot"]:
            projPlot = yt.ParticleProjectionPlot(ds, Param_Dict["NAxis"],
                                                 field)
        else:
            projPlot = yt.ProjectionPlot(ds, Param_Dict["NAxis"], field)
    except yt.utilities.exceptions.YTFieldNotFound:
        GUILogger.warning(f"Couldn't find {field} in the available fields")
        return
    ZMin = projPlot.frb[field].min()
    ZMax = projPlot.frb[field].max()
    return yt.YTArray([ZMin, ZMax])
Example #8
0
def setUpMovieFolder(Param_Dict):
    """Creates a folder for the movie pictures to be saved in."""
    directory = QW.QFileDialog.getExistingDirectory(
        None, "Select a directory "
        "to save the pictures in", Param_Dict["Directory"])
    if directory == "":
        GUILogger.warning(
            "Evaluation stopped. Please select a valid directory.")
        return False
    date = datetime.now().strftime("%d_%m_%Y_%H_%M_%S")
    plotMode = Param_Dict["PlotMode"]  # for the fstring
    directory = f"{directory}/{plotMode}plots_{date}"
    mkdir(directory)
    GUILogger.log(29, f"The pictures are being saved to <b>{directory}</b>.")
    return directory
Example #9
0
def annotatePlot(Param_Dict, plot):
    """Annotates the plot according to the selection of the user.
    Tutorial:
        https://yt-project.org/doc/visualizing/callbacks.html"""
    plot.annotate_title(Param_Dict["PlotTitle"])
    if Param_Dict["Timestamp"]:
        plot.annotate_timestamp(corner='upper_left', draw_inset_box=True)
    if Param_Dict["Geometry"] == "cartesian":
        if Param_Dict["Scale"]:
            plot.annotate_scale(corner='upper_right')
        if Param_Dict["Contour"]:
            plot.annotate_contour(Param_Dict["ZAxis"])
        if Param_Dict["VelVectors"]:
            plot.annotate_velocity(normalize=True)
        if Param_Dict["NormVecMode"] == "Axis-Aligned":
            if Param_Dict["Grid"]:
                plot.annotate_grids()
                issueAnnoWarning(plot, "Grids")
            if Param_Dict["VelStreamlines"]:
                issueAnnoWarning(plot, "Velocity streamlines")
                if Param_Dict["NAxis"] == "x":
                    plot.annotate_streamlines("velocity_y", "velocity_z")
                elif Param_Dict["NAxis"] == "y":
                    plot.annotate_streamlines("velocity_x", "velocity_z")
                elif Param_Dict["NAxis"] == "z":
                    plot.annotate_streamlines("velocity_x", "velocity_y")
            if Param_Dict["MagVectors"]:
                plot.annotate_magnetic_field(normalize=True)
            if Param_Dict["MagStreamlines"]:
                issueAnnoWarning(plot, "Magnetic field streamlines")
                if Param_Dict["NAxis"] == "x":
                    plot.annotate_streamlines("magy", "magz")
                elif Param_Dict["NAxis"] == "y":
                    plot.annotate_streamlines("magx", "magz")
                elif Param_Dict["NAxis"] == "z":
                    plot.annotate_streamlines("magx", "magy")
        if Param_Dict["ParticleAnno"] and not Param_Dict["ParticlePlot"]:
            if Param_Dict["PSlabWidth"] == "" or float(Param_Dict["PSlabWidth"]) == 0:
                Param_Dict["PSlabWidth"] = 1
            height = abs(Param_Dict["FieldMins"]["DomainHeight"] - Param_Dict["FieldMaxs"]["DomainHeight"])
            if Param_Dict["Zoom"] == 1:
                GUILogger.warning("When annotating particles, you may need a "
                                  "zoom above 1 for proper annotations")
            plot.annotate_particles(float(Param_Dict["PSlabWidth"])*height, p_size=3.0)
    elif Param_Dict["Geometry"] == "cylindrical":
        if Param_Dict["Grid"]:
            plot.annotate_grids()
Example #10
0
def ProfilePlot(Param_Dict, worker):
    """Takes a DataSet object loaded with yt and performs a ProfilePlot with
    fields on it.
    Parameters:
        Param_Dict: Dict with Parameters
    """
    if Param_Dict["XAxis"] == "time":
        arr, labels = createProfWithTimeForX(Param_Dict, worker)
    elif Param_Dict["TimeSeriesProf"]:
        arr, labels = createMultipleProfiles(Param_Dict, worker)
    else:
        arr, labels = createNormalProfile(Param_Dict)
    if Param_Dict["WeightField"] is None and Param_Dict["XAxis"] != "time":
        GUILogger.warning('Having <b><font color="DarkViolet">None</font></b> '
                          "as the weight field just accumulates, "
                          "so the extrema might be inaccurate.")
    Canvas = Param_Dict["CurrentPlotWindow"]
    Canvas.makeProfilePlot(Param_Dict, arr, labels, worker)
Example #11
0
 def readOutExtrema(self):
     """Reads out the current constraints of x- and y-axis and stores them
     before restoring them to the gui"""
     mode = self.Param_Dict["PlotMode"]
     xmin, xmax = self.ax.get_xlim()
     ymin, ymax = self.ax.get_ylim()
     if mode in ["Profile", "Phase"]:
         self.Param_Dict["XMin"] = xmin
         self.Param_Dict["XMax"] = xmax
     if mode in ["Profile", "Phase", "Line"]:
         self.Param_Dict["YMin"] = ymin
         self.Param_Dict["YMax"] = ymax
     if mode in ["Slice", "Projection"]:
         self.Param_Dict["HorWidth"] = abs(xmin-xmax)
         self.Param_Dict["VerWidth"] = abs(ymin-ymax)
         self.Param_Dict["Zoom"] = 1.0
         aligned = self.Param_Dict["NormVecMode"] == "Axis-Aligned"
         cart = self.Param_Dict["Geometry"] == "cartesian"
         if cart or self.Param_Dict["NAxis"] == "theta" and aligned:
             horCen = mean([xmin, xmax])
             verCen = mean([ymin, ymax])
             if self.Param_Dict["NAxis"] == "theta":
                 n = 2
             else:
                 n = ["x", "y", "z"].index(self.Param_Dict["NAxis"])
             horAxis = ["X", "Y", "Z"][convertToLessThanThree(n+1)]
             verAxis = ["X", "Y", "Z"][convertToLessThanThree(n+2)]
             self.Param_Dict[horAxis + "Center"] = horCen
             self.Param_Dict[verAxis + "Center"] = verCen
         elif not aligned:
             GUILogger.warning("For off-axis plots, setting the center "
                               "coordinates is not supported.")
         else:
             GUILogger.warning("Reading out the center coordinates is not "
                               "supported for having "
                               f"{self.Param_Dict['NAxis']} as normal axis."
                               "This may produce weird behaviour.")