docs: def convert_lightcurves_to_observered_frame(
          log,
          snLightCurves,
          rawLightCurveDict,
          redshiftArray,
          snTypesArray,
          peakMagnitudesArray,
          hostExtinctionArray,
          kCorrectionArray,
          galacticExtinctionArray,
          restFrameFilter,
          pathToOutputDirectory,
          pathToOutputPlotDirectory,
          polyOrder,
          plot=True):
      """
      *Given all the randomly generated parameters of the survey, generate a dictionary of lightcurves for each object (one lightcurve per filter)*
  
      **Key Arguments:**
          - ``log`` -- logger
          - ``snLightCurves`` -- the sn lightcurve dictionary (with explosion / extinction dates)
          - ``rawLightCurveDict`` -- dictionary of the raw lightcurves (all peaking at mag = 0)
          - ``redshiftArray`` -- array of random redshifts,
          - ``snTypesArray`` --  array of random sn types,
          - ``peakMagnitudesArray`` --  array of random peak mags,
          - ``kCorrectionArray`` -- array of k-corrections,
          - ``hostExtinctionArray`` --  array of random host extinctions,
          - ``galacticExtinctionArray`` --  array of random galactic extinctions,
          - ``restFrameFilter`` -- the observed frame filter with which to calculate k-corrections with
          - ``pathToOutputDirectory`` -- path to the output directory (provided by the user)
          - ``pathToOutputPlotDirectory`` -- path to the output plot directory
          - ``polyOrder`` -- order of the polynomial used to fit the lightcurve
          - ``plot`` -- generate plots?
  
      **Return:**
          - None
      """
      ################ > IMPORTS ################
      ## STANDARD LIB ##
      ## THIRD PARTY ##
      import numpy as np
      import matplotlib.pyplot as plt
      import math
      import yaml
      ## LOCAL APPLICATION ##
      import dryxPython.astrotools as da
      import dryxPython.plotting as dp
  
      ################ >ACTION(S) ################
      filters = ['g', 'r', 'i', 'z']
      fileName = pathToOutputDirectory + "/transient_light_curves.yaml"
      stream = file(fileName, 'r')
      generatedLCs = yaml.load(stream)
      models = generatedLCs.keys()
      ebvConverters = {'g': 3.793, 'r': 2.751, 'i': 2.086, 'z': 1.479}
      stepNum = 0
  
      ###########################################################
      # STEP 1 - CONVERT RAW LIGHTCURVES TO ABSOLUTE MAG CURVES #
      ###########################################################
      stepNum += 1
      stepStr = "%02d" % stepNum
      # CONVERT PEAK MAGS TO POLYNOMIALS
      peakMagPolyList = []
      for item in peakMagnitudesArray:
          thisPoly = np.poly1d([item, ])
          peakMagPolyList.append(thisPoly)
  
      # CONVERT RAW LIGHTCURVES TO ABSOLUTE MAG CURVES
      absLightCurveList = []
      exampleDictionary = {}
  
      for item in range(len(snTypesArray)):
          thisModel = snTypesArray[item]
          # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
          log.debug('thisModel, restFrameFilter: %s, %s' %
                    (thisModel, restFrameFilter,))
          explosionDay = rawLightCurveDict[thisModel][
              restFrameFilter]['Explosion Day Relative to Peak']
          endOfLightcurveDay = snLightCurves[thisModel][
              'End of lightcurve relative to peak']
          log.info(
              'explosionDay, endOfLightcurveDay for absolute Light Curve: %s, %s' %
              (explosionDay, endOfLightcurveDay))
          absLightCurve = rawLightCurveDict[thisModel][
              restFrameFilter]['poly'] + peakMagPolyList[item]
          absLightCurve = np.poly1d(absLightCurve)
          absLightCurveList.append(absLightCurve)
          exampleDictionary['SN %02d @ z = %04.3f' %
                            (item, redshiftArray[item])] = absLightCurve
      if plot:
          plot_polynomial(
              log,
              title="Absoulte Magnitude Lightcurves - random sample",
              polynomialDict=exampleDictionary,
              orginalDataDictionary=False,
              pathToOutputPlotsFolder=pathToOutputPlotDirectory,
              xRange=[explosionDay, endOfLightcurveDay],
              xlabel="Days Relative to Peak (Rest Frame)",
              ylabel="Absolute Magnitude",
              xAxisLimits=False,
              yAxisLimits=False,
              yAxisInvert=True,
              prependNum=stepNum)
  
      ################################################################
      # STEP 2 - CONVERT ABSOLUTE LIGHTCURVES TO APPARENT MAG CURVES #
      ################################################################
      stepNum += 1
      stepStr = "%02d" % stepNum
      # CONVERT DISTANCE MOD TO POLYNOMIALS
      distanceModPolyList = []
      for item in redshiftArray:
          log.debug('redshift: %s' % (item,))
          if item == 0.0:
              item = 0.01
          distanceDictionary = da.convert_redshift_to_distance(item)
          distanceMpc = distanceDictionary["dl_mpc"]
          distanceModulus = distanceDictionary["dmod"]
          # log.debug('distanceMpc %s' % (distanceMpc,))
          # log.info('redshift %s = distanceModulus %s' % (item, distanceModulus,))
          thisPoly = np.poly1d([distanceModulus, ])
          distanceModPolyList.append(thisPoly)
  
      # CONVERT ABSOLUTE LIGHTCURVES TO APPARENT MAG CURVES
      apparentLightCurveList = []
      for item in range(len(snTypesArray)):
          thisModel = snTypesArray[item]
          # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
          explosionDay = rawLightCurveDict[thisModel][
              restFrameFilter]['Explosion Day Relative to Peak']
          endOfLightcurveDay = snLightCurves[thisModel][
              'End of lightcurve relative to peak']
          log.info(
              'explosionDay, endOfLightcurveDay for apparent Light Curve: %s, %s' %
              (explosionDay, endOfLightcurveDay))
          apparentLightCurve = absLightCurveList[
              item] + distanceModPolyList[item]
          # log.debug('apparentLightCurve %s' % (apparentLightCurve,))
          apparentLightCurve = np.poly1d(apparentLightCurve)
          apparentLightCurveList.append(apparentLightCurve)
          exampleDictionary['SN %02d @ z = %04.3f' %
                            (item, redshiftArray[item])] = apparentLightCurve
          #log.info('absLightCurveDictionary %s' % (absLightCurveDictionary,))
      if plot:
          plot_polynomial(
              log,
              title="Pre-KCorrection Apparent Magnitude Lightcurves - random sample",
              polynomialDict=exampleDictionary,
              orginalDataDictionary=False,
              pathToOutputPlotsFolder=pathToOutputPlotDirectory,
              xRange=[explosionDay, endOfLightcurveDay],
              xlabel="Days Relative to Peak (Rest Frame)",
              ylabel="Apparent Magnitude",
              xAxisLimits=False,
              yAxisLimits=False,
              yAxisInvert=True,
              prependNum=stepNum)
  
      ###########################################################
      # STEP 3 - (UN) K-CORRECT THE APPARENT LIGHTCURVES        #
      ###########################################################
      stepNum += 1
      stepStr = "%02d" % stepNum
      # (UN) K-CORRECT THE APPARENT LIGHTCURVES
      kCorApparentLightCurveList = []
      for i in range(len(apparentLightCurveList)):
          thisModel = snTypesArray[i]
          # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
          explosionDay = rawLightCurveDict[thisModel][
              restFrameFilter]['Explosion Day Relative to Peak']
          endOfLightcurveDay = snLightCurves[thisModel][
              'End of lightcurve relative to peak']
          log.info(
              'explosionDay, endOfLightcurveDay for unkcor apparent Light Curve: %s, %s' %
              (explosionDay, endOfLightcurveDay))
          kCorDict = kCorrectionArray[i]
          lcDict = {}
          plotLcDict = {}
          for ffilter, poly in kCorDict.iteritems():
              if poly is None:
                  kcorLightCurve = None
              else:
                  kcorLightCurve = apparentLightCurveList[i] - poly
                  plotLcDict[ffilter] = kcorLightCurve
              lcDict[ffilter] = kcorLightCurve
              if plot:
                  plot_polynomial(
                      log,
                      title="K(un)corrected Apparent Magnitude Lightcurves - SN Number %s" % (
                          i),
                      polynomialDict=plotLcDict,
                      orginalDataDictionary=False,
                      pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                      xRange=[explosionDay, endOfLightcurveDay],
                      xlabel="Days Relative to Peak (Rest Frame)",
                      ylabel="Apparent Magnitude",
                      xAxisLimits=False,
                      yAxisLimits=False,
                      yAxisInvert=True,
                      prependNum=stepNum)
  
          kCorApparentLightCurveList.append(lcDict)
  
      ###########################################################
      # STEP 4 - INCLUDE GALACTIC EXTINCTION IN LIGHTCURVES     #
      ###########################################################
      stepNum += 1
      stepStr = "%02d" % stepNum
      # INCLUDE GALACTIC EXTINCTION
      # CONVERT EXT TO POLYNOMIALS
      galExtPolyList = []
      for ext in galacticExtinctionArray:
          extDict = {}
          for ffilter in filters:
              thisExt = ext * ebvConverters[ffilter]
              # log.info('ext %s, filter %s' % (thisExt, ffilter))
              thisPoly = np.poly1d([thisExt, ])
              extDict[ffilter] = thisPoly
          galExtPolyList.append(extDict)
  
      # INCLUDE GALAXTIC EXTINTION IN LIGHTCURVES
      galExtLightCurveList = []
      for item in range(len(kCorApparentLightCurveList)):
          thisModel = snTypesArray[item]
          # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']
          explosionDay = rawLightCurveDict[thisModel][
              restFrameFilter]['Explosion Day Relative to Peak']
          endOfLightcurveDay = snLightCurves[thisModel][
              'End of lightcurve relative to peak']
          log.info(
              'explosionDay, endOfLightcurveDay for galatic extinction corr Frame Light Curve: %s, %s' %
              (explosionDay, endOfLightcurveDay))
          lcDict = {}
          plotLcDict = {}
          for ffilter in filters:
              if kCorApparentLightCurveList[item][ffilter] is not None:
                  galExtLightCurve = kCorApparentLightCurveList[
                      item][ffilter] + galExtPolyList[item][ffilter]
                  # log.debug('apparentLightCurve %s' % (apparentLightCurve,))
                  galExtPoly = np.poly1d(galExtLightCurve)
                  plotLcDict[ffilter] = galExtPoly
              else:
                  galExtPoly = None
              lcDict[ffilter] = galExtPoly
          if plot:
              plot_polynomial(
                  log,
                  title="Galactic Extinction Corrected Lightcurves - SN Number %s" % (
                      item),
                  polynomialDict=plotLcDict,
                  orginalDataDictionary=False,
                  pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                  xRange=[explosionDay, endOfLightcurveDay],
                  xlabel="Days Relative to Peak (Rest Frame)",
                  ylabel="Apparent Magnitude",
                  xAxisLimits=False,
                  yAxisLimits=False,
                  yAxisInvert=True,
                  prependNum=stepNum)
  
          galExtLightCurveList.append(lcDict)
  
      ###########################################################
      # STEP 5 - TIME-DILATE LIGHTCURVES                        #
      ###########################################################
      stepNum += 1
      stepStr = "%02d" % stepNum
      observedFrameLightCurveInfo = []
      peakAppMagList = []
      for item in range(len(redshiftArray)):
          timeDilation = 1. + redshiftArray[item]
          thisModel = snTypesArray[item]
          # explosionDay = snLightCurves[thisModel]['Explosion Day Relative to Peak']*timeDilation
          explosionDay = rawLightCurveDict[thisModel][restFrameFilter][
              'Explosion Day Relative to Peak'] * timeDilation
          endOfLightcurveDay = snLightCurves[thisModel][
              'End of lightcurve relative to peak'] * timeDilation
          log.info(
              'explosionDay, endOfLightcurveDay for observed time dil Frame Light Curve: %s, %s' %
              (explosionDay, endOfLightcurveDay))
          polyDict = {}
          lcPolyDict = {}
          peakMagDict = {}
          floatPeakMagDict = {}
  
          for ffilter in filters:
              if galExtLightCurveList[item][ffilter] is not None:
                  xList = []
                  yList = []
                  for x in range(int(explosionDay), int(endOfLightcurveDay)):
                      xList.append(x * timeDilation)
                      y = galExtLightCurveList[item][ffilter](x)
                      yList.append(y)
  
                  x = np.array(xList)
                  y = np.array(yList)
                  thisPoly = np.polyfit(x, y, polyOrder)
                  flatPoly = np.poly1d(thisPoly)
                  peakMag = flatPoly(0)
                  floatPeakMag = float(peakMag)
                  polyDict[ffilter] = flatPoly
                  peakMagDict[ffilter] = peakMag
                  floatPeakMagDict[ffilter] = floatPeakMag
                  lcPolyDict[ffilter] = flatPoly
              else:
                  polyDict[ffilter] = None
                  peakMagDict[ffilter] = None
                  floatPeakMagDict[ffilter] = None
  
          if plot:
              plot_polynomial(
                  log,
                  title="Observed Lightcurves - SN Number %s" % (item, ),
                  polynomialDict=lcPolyDict,
                  orginalDataDictionary=False,
                  pathToOutputPlotsFolder=pathToOutputPlotDirectory,
                  xRange=[explosionDay, endOfLightcurveDay],
                  xlabel="Days Relative to Peak (Observed Frame)",
                  ylabel="Apparent Magnitude",
                  xAxisLimits=False,
                  yAxisLimits=False,
                  yAxisInvert=True,
                  prependNum=stepNum,
                  legend=True)
  
          thisData = {
              'lightCurves': polyDict,
              'peakMags': peakMagDict,
              'explosionDay': explosionDay,
              'endOfLightcurveDay': endOfLightcurveDay}
          # log.info('peakMagDict %s' % (peakMagDict,))
          observedFrameLightCurveInfo.append(thisData)
          peakAppMagList.append(floatPeakMagDict)
  
      return observedFrameLightCurveInfo, peakAppMagList