original_docstring: 
          Performs a search for possible harmonically related U-lines.
          The first step loops over every possible U-line pair, and uses the
          difference to estimate an effective B value for predicting the next
          transition. If the search is successful, the U-line is added to the
          list. The search is repeated until there are no more U-lines within
          frequency range of the next predicted line.
  
          Once the possible series are identified, the frequencies are fit to
          an effective linear molecule model (B and D terms). An affinity propa-
          gation cluster model is then used to group similar progressions toge-
          ther, with either a systematic test of preference values or a user
          specified value.
  
          Parameters
          ----------
          search: float, optional
              Percentage value of the target frequency cutoff for excluding
              possible candidates in the harmonic search
          low_B, high_B: float, optional
              Minimum and maximum value of B in MHz to be considered. This
              constrains the size of the molecule you are looking for.
          refit: bool, optional
              If True, B and D are refit to the cluster frequencies.
          plot: bool, optional
              If True, creates a Plotly scatter plot of the clusters, as a funct-
              ion of the preference values.
          preferences: float or array_like of floats, optional
              A single value or an array of preference values for the AP cluster
              model. If None, the clustering will be performed on a default grid,
              where all of the results are returned.
          kwargs: optional
              Additional kwargs are passed to the AP model initialization.
  
          Returns
          -------
          fig
          
docstring: Performs a search for possible harmonically related U-lines.
  The first step loops over every possible U-line pair, and uses the
  difference to estimate an effective B value for predicting the next
  transition. If the search is successful, the U-line is added to the
  list. The search is repeated until there are no more U-lines within
  frequency range of the next predicted line.
  
  Once the possible series are identified, the frequencies are fit to
  an effective linear molecule model (B and D terms). An affinity propa
  gation cluster model is then used to group similar progressions toge
  ther, with either a systematic test of preference values or a user
  specified value.
  
  Parameters
  
  float, optional
  Percentage value of the target frequency cutoff for excluding
  possible candidates in the harmonic search
  low_B, high_B: float, optional
  Minimum and maximum value of B in MHz to be considered. This
  constrains the size of the molecule you are looking for.
  refit: bool, optional
  If True, B and D are refit to the cluster frequencies.
  plot: bool, optional
  If True, creates a Plotly scatter plot of the clusters, as a funct
  ion of the preference values.
  preferences: float or array_like of floats, optional
  A single value or an array of preference values for the AP cluster
  model. If None, the clustering will be performed on a default grid,
  where all of the results are returned.
  kwargs: optional
  Additional kwargs are passed to the AP model initialization.
  
  Returns
  
  fig
docstring_tokens: Performs a search for possible harmonically related U - lines . The first step loops over every possible U - line pair and uses the difference to estimate an effective B value for predicting the next transition . If the search is successful the U - line is added to the list . The search is repeated until there are no more U - lines within frequency range of the next predicted line . Once the possible series are identified the frequencies are fit to an effective linear molecule model ( B and D terms ) . An affinity propa gation cluster model is then used to group similar progressions toge ther with either a systematic test of preference values or a user specified value . Parameters float optional Percentage value of the target frequency cutoff for excluding possible candidates in the harmonic search low_B high_B : float optional Minimum and maximum value of B in MHz to be considered . This constrains the size of the molecule you are looking for . refit : bool optional If True B and D are refit to the cluster frequencies . plot : bool optional If True creates a Plotly scatter plot of the clusters as a funct ion of the preference values . preferences : float or array_like of floats optional A single value or an array of preference values for the AP cluster model . If None the clustering will be performed on a default grid where all of the results are returned . kwargs : optional Additional kwargs are passed to the AP model initialization . Returns fig
code: def find_progressions(
          self,
          search=0.001,
          low_B=400.0,
          high_B=9000.0,
          refit=False,
          plot=True,
          preferences=None,
          **kwargs,
      ):
          """
          Performs a search for possible harmonically related U-lines.
          The first step loops over every possible U-line pair, and uses the
          difference to estimate an effective B value for predicting the next
          transition. If the search is successful, the U-line is added to the
          list. The search is repeated until there are no more U-lines within
          frequency range of the next predicted line.
  
          Once the possible series are identified, the frequencies are fit to
          an effective linear molecule model (B and D terms). An affinity propa-
          gation cluster model is then used to group similar progressions toge-
          ther, with either a systematic test of preference values or a user
          specified value.
  
          Parameters
          ----------
          search: float, optional
              Percentage value of the target frequency cutoff for excluding
              possible candidates in the harmonic search
          low_B, high_B: float, optional
              Minimum and maximum value of B in MHz to be considered. This
              constrains the size of the molecule you are looking for.
          refit: bool, optional
              If True, B and D are refit to the cluster frequencies.
          plot: bool, optional
              If True, creates a Plotly scatter plot of the clusters, as a funct-
              ion of the preference values.
          preferences: float or array_like of floats, optional
              A single value or an array of preference values for the AP cluster
              model. If None, the clustering will be performed on a default grid,
              where all of the results are returned.
          kwargs: optional
              Additional kwargs are passed to the AP model initialization.
  
          Returns
          -------
          fig
          """
          ulines = self.line_lists["Peaks"].get_ulines()
          uline_frequencies = [uline.frequency for uline in ulines]
          self.logger.info("Performing harmonic progression search")
          progressions = analysis.harmonic_finder(
              uline_frequencies, search=search, low_B=low_B, high_B=high_B
          )
          self.logger.info("Fitting progressions.")
          fit_df, _ = fitting.harmonic_fitter(progressions, J_thres=search)
          self.logger.info(f"Found {len(fit_df)} possible progressions.")
          pref_test_data = dict()
          # Run cluster analysis on the results
          if preferences is None:
              preferences = np.array(
                  [-8e4, -4e4, -2e4, -1e4, -5e3, -3e3, -1.5e3, -500.0, -100.0]
              )
          # Perform the AP cluster modelling
          if type(preferences) == list or type(preferences) == np.ndarray:
              self.logger.info(f"Evaluating AP over grid values {preferences}.")
              for preference in preferences:
                  try:
                      ap_settings = {"preference": preference}
                      ap_settings.update(**kwargs)
                      cluster_dict, progressions, _ = analysis.cluster_AP_analysis(
                          fit_df, sil_calc=True, refit=refit, **ap_settings
                      )
                      npoor = (progressions.loc[progressions["Silhouette"] < 0.0].size,)
                      if type(npoor) == tuple:
                          npoor = npoor[0]
                      nclusters = len(cluster_dict)
                      pref_test_data[preference] = {
                          "cluster_data": cluster_dict,
                          "nclusters": nclusters,
                          "npoor": npoor,
                          "avg_silh": np.average(progressions["Silhouette"]),
                          "progression_df": progressions,
                      }
                      self.logger.info(
                          f"{preference} has {npoor} poor fits "
                          f"out of {nclusters} clusters ({npoor / nclusters})."
                      )
                  except ValueError:
                      pass
          else:
              # Perform the AP clustering with a single preference value
              cluster_dict, progressions, _ = analysis.cluster_AP_analysis(
                  fit_df, sil_calc=True, refit=refit, **{"preference": preferences}
              )
              npoor = (progressions.loc[progressions["Silhouette"] < 0.0].size,)
              if type(npoor) == tuple:
                  npoor = npoor[0]
              nclusters = len(cluster_dict)
              pref_test_data[preferences] = {
                  "cluster_data": cluster_dict,
                  "nclusters": nclusters,
                  "npoor": npoor,
                  "avg_silh": np.average(progressions["Silhouette"]),
                  "progression_df": progressions,
              }
              self.logger.info(
                  f"{preferences} has {npoor} poor fits "
                  f"out of {nclusters} clusters ({npoor / nclusters})."
              )
          # Make a plotly figure of how the clustering goes (with frequency)
          # as a function of preference
          if plot is True:
              fig = go.FigureWidget()
              fig.layout["xaxis"]["title"] = "Frequency (MHz)"
              fig.layout["yaxis"]["title"] = "Preference"
              fig.layout["xaxis"]["tickformat"] = ".,"
              # Loop over the preference values
              for preference, contents in pref_test_data.items():
                  # Create the colors for the unique clusters
                  colors = figurefactory.generate_colors(
                      len(contents["cluster_data"]), hex=True, cmap=plt.cm.Spectral
                  )
                  # Assign a color to each cluster
                  cmap = {
                      index: color
                      for index, color in zip(
                          np.arange(len(contents["cluster_data"])), colors
                      )
                  }
                  for index, data in contents["cluster_data"].items():
                      frequencies = data["Frequencies"]
                      fig.add_scattergl(
                          x=frequencies,
                          y=[preference + index] * len(frequencies),
                          mode="markers",
                          marker={"color": cmap.get(index, "#ffffff")},
                          opacity=0.7,
                          name=f"{preference}-{index}",
                      )
              return fig, pref_test_data
          else:
              return None, pref_test_data
code_tokens: def find_progressions ( self , search = 0.001 , low_B = 400.0 , high_B = 9000.0 , refit = False , plot = True , preferences = None , ** kwargs , ) : ulines = self . line_lists [ "Peaks" ] . get_ulines ( ) uline_frequencies = [ uline . frequency for uline in ulines ] self . logger . info ( "Performing harmonic progression search" ) progressions = analysis . harmonic_finder ( uline_frequencies , search = search , low_B = low_B , high_B = high_B ) self . logger . info ( "Fitting progressions." ) fit_df , _ = fitting . harmonic_fitter ( progressions , J_thres = search ) self . logger . info ( f"Found {len(fit_df)} possible progressions." ) pref_test_data = dict ( ) if preferences is None : preferences = np . array ( [ - 8e4 , - 4e4 , - 2e4 , - 1e4 , - 5e3 , - 3e3 , - 1.5e3 , - 500.0 , - 100.0 ] ) if type ( preferences ) == list or type ( preferences ) == np . ndarray : self . logger . info ( f"Evaluating AP over grid values {preferences}." ) for preference in preferences : try : ap_settings = { "preference" : preference } ap_settings . update ( ** kwargs ) cluster_dict , progressions , _ = analysis . cluster_AP_analysis ( fit_df , sil_calc = True , refit = refit , ** ap_settings ) npoor = ( progressions . loc [ progressions [ "Silhouette" ] < 0.0 ] . size , ) if type ( npoor ) == tuple : npoor = npoor [ 0 ] nclusters = len ( cluster_dict ) pref_test_data [ preference ] = { "cluster_data" : cluster_dict , "nclusters" : nclusters , "npoor" : npoor , "avg_silh" : np . average ( progressions [ "Silhouette" ] ) , "progression_df" : progressions , } self . logger . info ( f"{preference} has {npoor} poor fits " f"out of {nclusters} clusters ({npoor / nclusters})." ) except ValueError : pass else : cluster_dict , progressions , _ = analysis . cluster_AP_analysis ( fit_df , sil_calc = True , refit = refit , ** { "preference" : preferences } ) npoor = ( progressions . loc [ progressions [ "Silhouette" ] < 0.0 ] . size , ) if type ( npoor ) == tuple : npoor = npoor [ 0 ] nclusters = len ( cluster_dict ) pref_test_data [ preferences ] = { "cluster_data" : cluster_dict , "nclusters" : nclusters , "npoor" : npoor , "avg_silh" : np . average ( progressions [ "Silhouette" ] ) , "progression_df" : progressions , } self . logger . info ( f"{preferences} has {npoor} poor fits " f"out of {nclusters} clusters ({npoor / nclusters})." ) if plot is True : fig = go . FigureWidget ( ) fig . layout [ "xaxis" ] [ "title" ] = "Frequency (MHz)" fig . layout [ "yaxis" ] [ "title" ] = "Preference" fig . layout [ "xaxis" ] [ "tickformat" ] = ".," for preference , contents in pref_test_data . items ( ) : colors = figurefactory . generate_colors ( len ( contents [ "cluster_data" ] ) , hex = True , cmap = plt . cm . Spectral ) cmap = { index : color for index , color in zip ( np . arange ( len ( contents [ "cluster_data" ] ) ) , colors ) } for index , data in contents [ "cluster_data" ] . items ( ) : frequencies = data [ "Frequencies" ] fig . add_scattergl ( x = frequencies , y = [ preference + index ] * len ( frequencies ) , mode = "markers" , marker = { "color" : cmap . get ( index , "#ffffff" ) } , opacity = 0.7 , name = f"{preference}-{index}" , ) return fig , pref_test_data else : return None , pref_test_data
short_docstring: Performs a search for possible harmonically related U-lines.
short_docstring_tokens: Performs a search for possible harmonically related U - lines .
comment: """
          Performs a search for possible harmonically related U-lines.
          The first step loops over every possible U-line pair, and uses the
          difference to estimate an effective B value for predicting the next
          transition. If the search is successful, the U-line is added to the
          list. The search is repeated until there are no more U-lines within
          frequency range of the next predicted line.
  
          Once the possible series are identified, the frequencies are fit to
          an effective linear molecule model (B and D terms). An affinity propa-
          gation cluster model is then used to group similar progressions toge-
          ther, with either a systematic test of preference values or a user
          specified value.
  
          Parameters
          ----------
          search: float, optional
              Percentage value of the target frequency cutoff for excluding
              possible candidates in the harmonic search
          low_B, high_B: float, optional
              Minimum and maximum value of B in MHz to be considered. This
              constrains the size of the molecule you are looking for.
          refit: bool, optional
              If True, B and D are refit to the cluster frequencies.
          plot: bool, optional
              If True, creates a Plotly scatter plot of the clusters, as a funct-
              ion of the preference values.
          preferences: float or array_like of floats, optional
              A single value or an array of preference values for the AP cluster
              model. If None, the clustering will be performed on a default grid,
              where all of the results are returned.
          kwargs: optional
              Additional kwargs are passed to the AP model initialization.
  
          Returns
          -------
          fig
          """$SEP$# Run cluster analysis on the results$SEP$# Perform the AP cluster modelling$SEP$# Perform the AP clustering with a single preference value$SEP$# Make a plotly figure of how the clustering goes (with frequency)$SEP$# as a function of preference$SEP$# Loop over the preference values$SEP$# Create the colors for the unique clusters$SEP$# Assign a color to each cluster