#!/usr/bin/python

"""
This module takes the uploaded ASCII mess and uses stuff from the inproc RD
to turn that into halfway sane FITS binary tables.

This is tricky because the input files have a totally whacky format
(idlgrammar somewhat takes care of this) pushing way too much information
into a single file: Both disk-integrated flux and lots of little parts
are in there, which causes drastic file bloat.

So, we first parse the inputs to rows but then pick these apart to
separate files, a main one and the 20 disk parts (except for the 1d
spectra, which are one file only).

Possible improvement: Merge spectrum and associated continuum?

Of course, by actually pulling columns out of the IDL mess and using this,
all this could be made a few times faster.  Don't think that's worth it.
"""

import os

from gavo import api

from gavo.protocols import sdm

RDID = "co5boldspecs/inproc"


PARAM_LABELS = ("kind", "colat", "azimuth", "fnamepart")

META_FOR_IDLCOLS = {
"MEANFlux":   ("Integrated light", None, None, "full"),
"MEANInt1":   ("Disk center", 0.00,   0.00, "center"),
"MEANInt2":   ("Inner ring sector 0",   38.03,   0.00, "iee"),
"MEANInt3":   ("Inner ring sector 1",   38.03,  45.00, "ine"),
"MEANInt4":   ("Inner ring sector 2",   38.03,  90.00, "inn"),
"MEANInt5":   ("Inner ring sector 3",   38.03, 135.00, "inw"),
"MEANInt6":   ("Inner ring sector 4",   38.03, 180.00, "iww"),
"MEANInt7":   ("Inner ring sector 5",   38.03, 225.00, "isw"),
"MEANInt8":   ("Inner ring sector 6",   38.03, 270.00, "iss"),
"MEANInt9":   ("Inner ring sector 7",   38.03, 315.00, "ise"),
"MEANInt10":  ("Middle ring sector 0",  65.83,   0.00, "mee"),
"MEANInt11":  ("Middle ring sector 1",  65.83,  45.00, "mne"),
"MEANInt12":  ("Middle ring sector 2",  65.83,  90.00, "mnn"),
"MEANInt13":  ("Middle ring sector 3",  65.83, 135.00, "mnw"),
"MEANInt14":  ("Middle ring sector 4",  65.83, 180.00, "mww"),
"MEANInt15":  ("Middle ring sector 5",  65.83, 225.00, "msw"),
"MEANInt16":  ("Middle ring sector 6",  65.83, 270.00, "mss"),
"MEANInt17":  ("Middle ring sector 7",  65.83, 315.00, "mse"),
"MEANInt18":  ("Outer ring sector 0",  84.92,   0.00, "oee"),
"MEANInt19":  ("Outer ring sector 1",  84.92,  90.00, "onn"),
"MEANInt20":  ("Outer ring sector 2",  84.92, 180.00, "oww"),
"MEANInt21":  ("Outer ring sector 3",  84.92, 270.00, "oss"),}


from gavo.grammars.customgrammar import CustomRowIterator

class CustomIterator(CustomRowIterator):
	"""a shim for building the tables from the 3D spectra.

	Essentially, it just returns the rows and parameters it is constructed
	with.
	"""
	def __init__(self, rows, params):
		self.rows, self.params = rows, params
	
	def getParameters(self):
		return self.params
	
	def __iter__(self):
		return iter(self.rows)

	def getLocator(self):
		return "<internal>"


class Reformatter(api.FileProcessor):

	def _createAuxiliaries(self, dd):
		self.rd = dd.rd

	def import_1d(self, srcName, destName):
		# The easy case: one source file, one destination file.
		table = api.makeData(
			self.rd.getById("import_1d"),
			forceSource=srcName)
		with open(destName, "w") as f:
			f.write(sdm.formatSDMData(table, "application/fits")[1])
	
	def import_3d(self, srcName, destName):
		# the whacko case: parse the source file, then manually make
		# data out of parts of that source
		level1grammar = self.rd.getById("idlgrammar")
		rows = list(level1grammar.parse(srcName))

		for label, meta in META_FOR_IDLCOLS.iteritems():
			src = CustomIterator(
				[{"spectral": r["WaveAng100"], "flux": r[label]}
					for r in rows],
				dict(zip(PARAM_LABELS, meta)))
			

			table = api.makeData(self.rd.getById("import_3d"),
				forceSource=src)
			with open(destName[:-5]+"-"+meta[3]+".fits", "w") as f:
				f.write(sdm.formatSDMData(table, "application/fits")[1])

	def process(self, srcName):
		srcParts = api.getInputsRelativePath(srcName).split("/")
		srcParts[1] = "data"
		destName = os.path.join(api.getConfig("inputsDir"), *srcParts)
		destDir = os.path.dirname(destName)
		if not os.path.isdir(destDir):
			os.makedirs(destDir)

		if "/1D/" in srcName:
			self.import_1d(srcName, destName)
		elif "/3D/" in srcName:
			return self.import_3d(srcName, destName)
		else:
			ddt



if __name__=="__main__":
  api.procmain(Reformatter, RDID, "import_3d")
