def spectra_plot(target, dataproduct=None): spectra = [] spectral_dataproducts = ReducedDatum.objects.filter(target=target, data_type='spectroscopy').order_by('-timestamp') if dataproduct: spectral_dataproducts = DataProduct.objects.get(dataproduct=dataproduct) for spectrum in spectral_dataproducts: datum = SpectrumSerializer().deserialize(spectrum.value) wavelength = datum.spectral_axis.to(SpectroscopyProcessor.DEFAULT_WAVELENGTH_UNITS).value flux = datum.new_flux_unit(SpectroscopyProcessor.DEFAULT_FLUX_CONSTANT).flux.value name = str(spectrum.timestamp).split(' ')[0] spectra.append((wavelength, flux, name)) wavelength_unit = SpectroscopyProcessor.DEFAULT_WAVELENGTH_UNITS.to_string('unicode') flux_unit = re.sub('\s*─+\s*', ' / ', SpectroscopyProcessor.DEFAULT_FLUX_CONSTANT.to_string('unicode').strip()) plot_data = [ go.Scatter( x=spectrum[0], y=spectrum[1], name=spectrum[2] ) for spectrum in spectra] layout = go.Layout( height=600, width=700, hovermode='closest', xaxis=dict( tickformat=".0f", title=f'Wavelength ({wavelength_unit})', gridcolor='#D3D3D3', showline=True, linecolor='#D3D3D3', mirror=True ), yaxis=dict( tickformat=".1eg", title=f'Flux ({flux_unit})', gridcolor='#D3D3D3', showline=True, linecolor='#D3D3D3', mirror=True ), plot_bgcolor='white' ) if plot_data: return { 'target': target, 'plot': offline.plot(go.Figure(data=plot_data, layout=layout), output_type='div', show_link=False) } else: return { 'target': target, 'plot': 'No spectra for this target yet.' }
def spectroscopy_for_target(target, dataproduct=None): """ Renders a spectroscopic plot for a ``Target``. If a ``DataProduct`` is specified, it will only render a plot with that spectrum. """ spectral_dataproducts = DataProduct.objects.filter(target=target, data_product_type=settings.DATA_PRODUCT_TYPES['spectroscopy'][0]) if dataproduct: spectral_dataproducts = DataProduct.objects.get(data_product=dataproduct) plot_data = [] for datum in ReducedDatum.objects.filter(data_product__in=spectral_dataproducts): deserialized = SpectrumSerializer().deserialize(datum.value) plot_data.append(go.Scatter( x=deserialized.wavelength.value, y=deserialized.flux.value, name=datetime.strftime(datum.timestamp, '%Y%m%d-%H:%M:%s') )) layout = go.Layout( height=600, width=700, xaxis=dict( tickformat="d" ), yaxis=dict( tickformat=".1eg" ) ) return { 'target': target, 'plot': offline.plot(go.Figure(data=plot_data, layout=layout), output_type='div', show_link=False) }
def photon_spectrum_to_energy_spectrum(apps, schema_editor): reduced_datum = apps.get_model('tom_dataproducts', 'ReducedDatum') spectrum_serializer = SpectrumSerializer() for row in reduced_datum.objects.filter(data_type='spectroscopy'): # In order to avoid a KeyError on already-corrected data or data that has no need to be corrected, we only # perform the spectroscopy correction on values that have photon_flux/photon_flux_units if all(k in row.value.keys() for k in ['photon_flux', 'photon_flux_units', 'wavelength', 'wavelength_units']): photon_counts = Quantity(value=row.value['photon_flux'], unit=row.value['photon_flux_units']) wavelength = Quantity(value=row.value['wavelength'], unit=row.value['wavelength_units']) photon_spectrum = Spectrum1D(flux=photon_counts, spectral_axis=wavelength) energy_spectrum = photon_spectrum.flux * (photon_spectrum.energy / photon) energy_spectrum_object = Spectrum1D( spectral_axis=wavelength, flux=energy_spectrum.to('erg / (s cm2 AA)', spectral_density(wavelength))) row.value = spectrum_serializer.serialize(energy_spectrum_object) row.save()
def photon_spectrum_to_energy_spectrum(apps, schema_editor): reduced_datum = apps.get_model('tom_dataproducts', 'ReducedDatum') spectrum_serializer = SpectrumSerializer() for row in reduced_datum.objects.filter(data_type='spectroscopy'): photon_counts = Quantity(value=row.value['photon_flux'], unit=row.value['photon_flux_units']) wavelength = Quantity(value=row.value['wavelength'], unit=row.value['wavelength_units']) photon_spectrum = Spectrum1D(flux=photon_counts, spectral_axis=wavelength) energy_spectrum = photon_spectrum.flux * (photon_spectrum.energy / photon) energy_spectrum_object = Spectrum1D(spectral_axis=wavelength, flux=energy_spectrum.to( 'erg / (s cm2 AA)', spectral_density(wavelength))) row.value = spectrum_serializer.serialize(energy_spectrum_object) row.save()
def process_data(self, data_product, extras): mimetype = mimetypes.guess_type(data_product.data.name)[0] if mimetype in self.FITS_MIMETYPES: spectrum, obs_date = self._process_spectrum_from_fits(data_product) elif mimetype in self.PLAINTEXT_MIMETYPES: spectrum, obs_date = self._process_spectrum_from_plaintext( data_product) else: raise InvalidFileFormatException('Unsupported file type') serialized_spectrum = SpectrumSerializer().serialize(spectrum) return [(obs_date, serialized_spectrum)]
def process_data(self, data_product): """ Routes a spectroscopy processing call to a method specific to a file-format, then serializes the returned data. :param data_product: Spectroscopic DataProduct which will be processed into the specified format for database ingestion :type data_product: DataProduct :returns: python list of 2-tuples, each with a timestamp and corresponding data :rtype: list """ mimetype = mimetypes.guess_type(data_product.data.name)[0] if mimetype in self.FITS_MIMETYPES: spectrum, obs_date = self._process_spectrum_from_fits(data_product) elif mimetype in self.PLAINTEXT_MIMETYPES: spectrum, obs_date = self._process_spectrum_from_plaintext( data_product) else: raise InvalidFileFormatException('Unsupported file type') serialized_spectrum = SpectrumSerializer().serialize(spectrum) return [(obs_date, serialized_spectrum)]
class TestDataSerializer(TestCase): def setUp(self): self.serializer = SpectrumSerializer() def test_serialize_spectrum(self): flux = np.arange(1, 200) * units.Jy wavelength = np.arange(1, 200) * units.Angstrom spectrum = Spectrum1D(spectral_axis=wavelength, flux=flux) serialized = self.serializer.serialize(spectrum) self.assertTrue(isinstance(serialized, str)) serialized = json.loads(serialized) self.assertTrue(serialized['photon_flux']) self.assertTrue(serialized['photon_flux_units']) self.assertTrue(serialized['wavelength']) self.assertTrue(serialized['wavelength_units']) def test_serialize_spectrum_invalid(self): with self.assertRaises(Exception): self.serializer.serialize({'flux': [1, 2], 'wavelength': [1, 2]}) def test_deserialize_spectrum(self): serialized_spectrum = json.dumps({ 'photon_flux': [1, 2], 'photon_flux_units': 'ph / (Angstrom cm2 s)', 'wavelength': [1, 2], 'wavelength_units': 'Angstrom' }) deserialized = self.serializer.deserialize(serialized_spectrum) self.assertTrue(type(deserialized) is Spectrum1D) self.assertEqual(deserialized.flux.mean().value, 1.5) self.assertEqual(deserialized.wavelength.mean().value, 1.5) def test_deserialize_spectrum_invalid(self): with self.assertRaises(Exception): self.serializer.deserialize(json.dumps({'invalid_key': 'value'}))
def setUp(self): self.serializer = SpectrumSerializer()