diff --git a/edosl0util/rdrgen.py b/edosl0util/rdrgen.py
index 420699039fe6834319bc42564de93f49d57a743e..709feb5322fef12433a5f2a6838ff415862da299 100644
--- a/edosl0util/rdrgen.py
+++ b/edosl0util/rdrgen.py
@@ -1,5 +1,6 @@
 import ctypes
 import itertools
+import os
 from collections import OrderedDict
 from datetime import datetime
 
@@ -13,8 +14,8 @@ from edosl0util.jpssrdr import (
     StaticHeader, Apid as ApidListItem, PacketTracker, decode_rdr_blob)
 
 
-def write_rdr(sat, blob,
-              distributor=None, origin=None, domain=None, orbit_number=0,
+def write_rdr(sat, blob, dir_path='.',
+              distributor=None, origin=None, domain=None, compressed=False, orbit_num=0,
               creation_time=None, gran_creation_time=None, software_ver=None):
     # TODO: write out the user block too??
     distributor = distributor or origin or default_origin
@@ -34,7 +35,9 @@ def write_rdr(sat, blob,
     gran_ver = 'A1'
     format_date = lambda t: t.strftime('%Y%m%d')
     format_time = lambda t: t.strftime('%H%M%S.%fZ')
-    with h5py.File('rdr.h5', 'w') as h5_file:
+    file_name = make_rdr_filename(rdr_type.product_id, sat, gran_time, gran_end_time,
+                                  orbit_num, creation_time, origin, domain, compressed)
+    with h5py.File(os.path.join(dir_path, file_name), 'w') as h5_file:
         set_h5_attrs(h5_file, {
             'Distributor': distributor,
             'Mission_Name': 'S-NPP/JPSS',
@@ -61,7 +64,7 @@ def write_rdr(sat, blob,
             'Beginning_Time': format_time(gran_time),
             'Ending_Date': format_date(gran_end_time),
             'Ending_Time': format_time(gran_end_time),
-            'N_Beginning_Orbit_Number': np.uint64(orbit_number),  # FIXME: detect?
+            'N_Beginning_Orbit_Number': np.uint64(orbit_num),  # FIXME: detect?
             'N_Beginning_Time_IET': np.uint64(gran_iet),
             'N_Creation_Date': format_date(gran_creation_time),
             'N_Creation_Time': format_time(gran_creation_time),
@@ -84,13 +87,14 @@ def write_rdr(sat, blob,
         set_h5_attrs(aggr_ds, {
             'AggregateBeginningDate': format_date(gran_time),
             'AggregateBeginningGranuleID': gran_id,
-            'AggregateBeginningOrbitNumber': np.uint64(orbit_number),
+            'AggregateBeginningOrbitNumber': np.uint64(orbit_num),
             'AggregateBeginningTime': format_time(gran_time),
             'AggregateEndingDate': format_date(gran_end_time),
             'AggregateEndingGranuleID': gran_id,
-            'AggregateEndingOrbitNumber': np.uint64(orbit_number),
+            'AggregateEndingOrbitNumber': np.uint64(orbit_num),
             'AggregateEndingTime': format_time(gran_end_time),
             'AggregateNumberGranules': np.uint64(1)})
+    return file_name
 
 
 def set_h5_attrs(h5_obj, attrs):
@@ -227,6 +231,7 @@ class ApidSpec(object):
 
 
 class CrisScienceRdrType(object):
+    product_id = 'RCRIS'
     short_name = 'CRIS-SCIENCE-RDR'
     gran_len = 31997000
     sensor = 'cris'
@@ -236,6 +241,7 @@ class CrisScienceRdrType(object):
 
 
 class SpacecraftDiaryRdrType(object):
+    product_id = 'RNSCA'
     short_name = 'SPACECRAFT-DIARY-RDR'
     gran_len = 20000000
     sensor = None
@@ -246,6 +252,22 @@ class SpacecraftDiaryRdrType(object):
              ApidSpec(11, 'DIARY', max_expected=21)]
 
 
+def make_rdr_filename(prod_id, sat, gran_time, gran_end_time, orbit_num, creation_time,
+                      origin, domain, compressed):
+    sat_strs = {'snpp': 'npp'}
+    def format_gran_time(t):
+        return t.strftime('%H%M%S') + str(t.microsecond / 100000)
+    def format_origin(o):
+        if o.endswith('-'):
+            return o[:-1] + ('c' if compressed else 'u')
+        else:
+            return o
+    return '{p}_{s}_d{d:%Y%m%d}_t{b}_e{e}_b{n}_c{c:%Y%m%d%H%M%S%f}_{o}_{m}.h5'.format(
+        p=prod_id, s=sat_strs[sat], d=gran_time, b=format_gran_time(gran_time),
+        e=format_gran_time(gran_end_time), n=orbit_num, c=creation_time,
+        o=format_origin(origin), m=domain)
+
+
 def timecode_to_iet(timecode):
     # FIXME: move to timecode.py
     ccsds_epoch = Time('1958-01-01', scale='tai')
diff --git a/tests/test_rdrgen.py b/tests/test_rdrgen.py
index 7d79e2e8e54f09c9d6f45a9f85bed97783ddd1af..2cd701edcb38e184a6d64fe1a0568c038b23fee1 100644
--- a/tests/test_rdrgen.py
+++ b/tests/test_rdrgen.py
@@ -50,14 +50,21 @@ def test_can_reproduce_rdr_from_class():
 
     # generate new RDR from packets, injecting matching metadata from CLASS file
     blob = m.build_rdr_blob('snpp', jpss_packet_stream(StringIO(pkt_buf.tobytes())))
-    m.write_rdr('snpp', blob, distributor='arch', origin='nob-', domain='ops',
-                creation_time=datetime(2017, 9, 13, 22, 3, 40, 173580),
-                gran_creation_time=datetime(2017, 9, 12, 1, 37, 43, 474383),
-                orbit_number=30441, software_ver='I2.0.03.00')
+    tmp_dir = '/tmp'
+    file_name = m.write_rdr(
+        'snpp', blob, tmp_dir,
+        distributor='arch', origin='nob-', domain='ops',
+        creation_time=datetime(2017, 9, 13, 22, 3, 40, 173580),
+        gran_creation_time=datetime(2017, 9, 12, 1, 37, 43, 474383),
+        orbit_num=30441, software_ver='I2.0.03.00')
+
+    # file names should be identical
+    assert file_name == class_rdr_file
 
     # use h5diff to verify files match. -p option is needed to allow some slop
     # in comparing N_Percent_Missing_Data
-    p = subprocess.Popen(['h5diff', '-c', '-p', '1e-6', class_rdr_path, 'rdr.h5'],
-                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    p = subprocess.Popen(
+        ['h5diff', '-c', '-p', '1e-6', class_rdr_path, os.path.join(tmp_dir, file_name)],
+        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     assert p.communicate()[0] == ''
     assert p.returncode == 0