Parses XML files to get scan and source information.
    Returns tuple of dicts (scan, source).
    bdfdir is optional location to look for bdfs, will try that first, then ASDMBinary subdirectory.
    bdfstr in scan dict helps find BDFs with read_bdf (with special behavior for prearchive data.
    Optional arg scan can be used to speed up parsing for single scan.

def read_metadata(sdmfile, scan=0, bdfdir=None):
    """ Parses XML files to get scan and source information.
    Returns tuple of dicts (scan, source).
    bdfdir is optional location to look for bdfs, will try that first, then ASDMBinary subdirectory.
    bdfstr in scan dict helps find BDFs with read_bdf (with special behavior for prearchive data.
    Optional arg scan can be used to speed up parsing for single scan.
    """

    sdmfile = sdmfile.rstrip('/')
    assert os.path.exists(sdmfile), 'Could not find sdmfile %s.' % sdmfile
    if bdfdir:
        if not os.path.exists(bdfdir):
            logger.info('bdfdir %s not found' % bdfdir)
            bdfdir = os.path.join(sdmfile, 'ASDMBinary')
    else:
        bdfdir = os.path.join(sdmfile, 'ASDMBinary')
    logger.info('Looking for bdfs in %s' % bdfdir)
    sdmfile = sdmfile.rstrip('/')
    scandict = {}; sourcedict = {}

    # read Scan.xml into dictionary also and make a list
    sdm = sdmpy.SDM(sdmfile)
    if len(sdm['Scan']) > 1:    # workaround: conversion from MS to SDM tends to make scans into subscans of one large scan
        for i in range(len(sdm['Scan'])):
            row  = sdm['Scan'][i]
            scannum = int(row['scanNumber'])
            if scan in [0, scannum]:
                rowkey = [k for k in row.keys if k.lower() == 'numsubscan'][0]   # need to find key but caps rule changes between ALMA/VLA
                nsubs = int(row[rowkey])
                scanintents = row['scanIntent']
                intentstr = string.join(scanintents.strip().split(' ')[2:], ' ')
                startmjd = float(row['startTime'])*1.0E-9/86400.0           # start and end times in mjd ns
                endmjd = float(row['endTime'])*1.0E-9/86400.0
                try:
                    src = str(row["sourceName"])        # source name
                except:
                    logger.warn('Scan %d has no source name' % (len(scandict)+1))
                finally:
                    scandict[scannum] = {}
                    scandict[scannum]['source'] = src
                    scandict[scannum]['startmjd'] = startmjd
                    scandict[scannum]['endmjd'] = endmjd
                    scandict[scannum]['intent'] = intentstr
                    scandict[scannum]['nsubs'] = nsubs
                    scandict[scannum]['duration'] = endmjd-startmjd
                    scandict[scannum]['nints'] = int(sdm['Main'][i]['numIntegration'])
        
                try:
                    bdfstr = sdm['Main'][i]['dataUID'].replace(':', '_').replace('/', '_')
                except KeyError:
                    bdfstr = sdm['Main'][i]['dataOid'].replace(':', '_').replace('/', '_')

                scandict[scannum]['bdfstr'] = os.path.join(bdfdir, bdfstr)

                # clear reference to nonexistent BDFs (either bad or not in standard locations)
                if (not os.path.exists(scandict[scannum]['bdfstr'])) or ('X1' in bdfstr):
                    scandict[scannum]['bdfstr'] = None
                    logger.debug('No bdf found scan %d of %s' % (scannum, sdmfile) )

                if scandict[scannum]['source'] not in [sourcedict[source]['source'] for source in sourcedict.iterkeys()]:
                    for row in sdm['Field']:
                        src = row['fieldName'].strip()
                        if src == scandict[scannum]['source']:
                            sourcenum = int(row["sourceId"])
                            direction = row["referenceDir"].strip()
                            (ra,dec) = [float(val) for val in direction.strip().split(' ')[3:]]  # skip first two values in string

                            # original version would add warning if two sources had different ra/dec. this makes one entry for every source
                            sourcedict[sourcenum] = {}
                            sourcedict[sourcenum]['source'] = src
                            sourcedict[sourcenum]['ra'] = ra
                            sourcedict[sourcenum]['dec'] = dec
                            break  # just take first instance, then escape

    elif ( (len(sdm['Scan']) == 1) and (len(sdm['Subscan']) > 1) ):
        logger.warn('Found only one scan with multiple subscans. Treating subscans as scans.')
        for row in sdm['Subscan']:
            scannum = int(row['subscanNumber'])
            if scan in [0, scannum]:
                startmjd = float(row['startTime'])*1.0E-9/86400.0           # start and end times in mjd ns
                endmjd = float(row['endTime'])*1.0E-9/86400.0
                scanintents = row['subscanIntent']
                if len(scanintents.strip().split(' ')) > 1:
                    intentstr = string.join(scanintents.strip().split(' ')[2:], ' ')
                else:
                    intentstr = scanintents

                try:
                    src = row["fieldName"].strip()        # source name
                except:
                    logger.warn('Scan %d has no source name' % (len(scandict)+1))
                finally:
                    scandict[scannum] = {}
                    scandict[scannum]['source'] = src
                    scandict[scannum]['intent'] = intentstr
                    scandict[scannum]['startmjd'] = startmjd
                    scandict[scannum]['endmjd'] = endmjd
                    scandict[scannum]['duration'] = endmjd-startmjd





            
    return [scandict, sourcedict]