Index: src/sas/sascalc/file_converter/bsl_loader.py
===================================================================
--- src/sas/sascalc/file_converter/bsl_loader.py	(revision c3f01140b5e22b089b3f0629fc511a84761eda81)
+++ src/sas/sascalc/file_converter/bsl_loader.py	(revision 535e18165fb7319948e27d8876a389fd5c738129)
@@ -8,5 +8,5 @@
     # TODO: Change to __init__(self, filename, frame)
     # and parse n_(pixels/rasters) from header file
-    def __init__(self, filename, frame):
+    def __init__(self, filename):
         header_file = open(filename, 'r')
         data_info = {}
@@ -56,5 +56,5 @@
             data_info['pixels'] = 1
 
-        CLoader.__init__(self, data_info['filename'], frame,
+        CLoader.__init__(self, data_info['filename'], data_info['frames'],
             data_info['pixels'], data_info['rasters'], data_info['swap_bytes'])
 
@@ -62,4 +62,6 @@
         if name == 'filename':
             return self.set_filename(value)
+        elif name == 'n_frames':
+            return self.set_n_frames(value)
         elif name == 'frame':
             return self.set_frame(value)
@@ -75,4 +77,6 @@
         if name == 'filename':
             return self.get_filename()
+        elif name == 'n_frames':
+            return self.get_n_frames()
         elif name == 'frame':
             return self.get_frame()
@@ -84,5 +88,2 @@
             return self.get_swap_bytes()
         return CLoader.__getattr__(self, name)
-
-    def create_arr(self):
-        return np.zeros((self.n_rasters, self.n_pixels))
Index: src/sas/sascalc/file_converter/c_ext/bsl_loader.c
===================================================================
--- src/sas/sascalc/file_converter/c_ext/bsl_loader.c	(revision c3f01140b5e22b089b3f0629fc511a84761eda81)
+++ src/sas/sascalc/file_converter/c_ext/bsl_loader.c	(revision 535e18165fb7319948e27d8876a389fd5c738129)
@@ -21,5 +21,5 @@
 static PyObject *CLoader_init(CLoader *self, PyObject *args, PyObject *kwds) {
     const char *filename;
-    const int frame;
+    const int n_frames;
     const int n_pixels;
     const int n_rasters;
@@ -27,10 +27,10 @@
 
     if (self != NULL) {
-        if (!PyArg_ParseTuple(args, "siiii", &filename, &frame, &n_pixels, &n_rasters, &swap_bytes))
+        if (!PyArg_ParseTuple(args, "siiii", &filename, &n_frames, &n_pixels, &n_rasters, &swap_bytes))
             Py_RETURN_NONE;
         if (!(self->params.filename = malloc(strlen(filename) + 1)))
             Py_RETURN_NONE;
         strcpy(self->params.filename, filename);
-        self->params.frame = frame;
+        self->params.n_frames = n_frames;
         self->params.n_pixels = n_pixels;
         self->params.n_rasters = n_rasters;
@@ -49,6 +49,7 @@
     char str[100];
     sprintf(str,
-        "Filename: %s\nframe: %d\nn_pixels: %d\nn_rasters: %d\nswap_bytes: %d",
+        "Filename: %s\nn_frames: %d\nframe: %d\nn_pixels: %d\nn_rasters: %d\nswap_bytes: %d",
         self->params.filename,
+        self->params.n_frames,
         self->params.frame,
         self->params.n_pixels,
@@ -73,4 +74,17 @@
 }
 
+static PyObject *get_n_frames(CLoader *self, PyObject *args) {
+    return Py_BuildValue("i", self->params.n_frames);
+}
+
+static PyObject *set_n_frames(CLoader *self, PyObject *args) {
+    int new_frames;
+    if (!PyArg_ParseTuple(args, "i", &new_frames))
+        return NULL;
+    self->params.n_frames = new_frames;
+
+    return Py_BuildValue("i", self->params.n_frames);
+}
+
 static PyObject *get_frame(CLoader *self, PyObject *args) {
     return Py_BuildValue("i", self->params.frame);
@@ -144,12 +158,10 @@
     int pixel;
     int frame_pos;
-    int size[2] = {self->params.n_rasters, self->params.n_pixels};
+    npy_intp size[2] = {self->params.n_rasters, self->params.n_pixels};
     float cur_val;
     FILE *input_file;
     PyArrayObject *data;
 
-    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &data)) {
-        return NULL;
-    }
+    data = (PyArrayObject *)PyArray_SimpleNew(2, size, NPY_FLOAT);
 
     input_file = fopen(self->params.filename, "rb");
@@ -171,7 +183,6 @@
 
     fclose(input_file);
-    Py_DECREF(data);
-
-    return Py_BuildValue("O", data);
+
+    return Py_BuildValue("N", data);
 }
 
@@ -182,4 +193,6 @@
     { "get_filename", (PyCFunction)get_filename, METH_VARARGS, "Get the filename" },
     { "set_filename", (PyCFunction)set_filename, METH_VARARGS, "Set the filename" },
+    { "get_n_frames", (PyCFunction)get_n_frames, METH_VARARGS, "Get n_frames" },
+    { "set_n_frames", (PyCFunction)set_n_frames, METH_VARARGS, "Set n_frames" },
     { "get_frame", (PyCFunction)get_frame, METH_VARARGS, "Get the frame that will be loaded" },
     { "set_frame", (PyCFunction)set_frame, METH_VARARGS, "Set the frame that will be loaded" },
Index: src/sas/sascalc/file_converter/c_ext/bsl_loader.h
===================================================================
--- src/sas/sascalc/file_converter/c_ext/bsl_loader.h	(revision 6eaf89ea65cd8bd9989a815dfc97d309a7be25ec)
+++ src/sas/sascalc/file_converter/c_ext/bsl_loader.h	(revision 535e18165fb7319948e27d8876a389fd5c738129)
@@ -5,4 +5,6 @@
     // File to load
     char *filename;
+    // Number of frames in the file
+    int n_frames;
     // Frame to load
     int frame;
Index: src/sas/sasgui/perspectives/file_converter/converter_panel.py
===================================================================
--- src/sas/sasgui/perspectives/file_converter/converter_panel.py	(revision a3c538e1ee8fe6c2d6e50600675f8a3f43ab099b)
+++ src/sas/sasgui/perspectives/file_converter/converter_panel.py	(revision 535e18165fb7319948e27d8876a389fd5c738129)
@@ -18,7 +18,9 @@
 from sas.sasgui.guiframe.documentation_window import DocumentationWindow
 from sas.sasgui.guiframe.dataFitting import Data1D
+from sas.sascalc.dataloader.data_info import Data2D
 from sas.sasgui.guiframe.utils import check_float
 from sas.sasgui.perspectives.file_converter.cansas_writer import CansasWriter
-from sas.sasgui.perspectives.file_converter.bsl_loader import BSLLoader
+from sas.sasgui.perspectives.file_converter.bsl_loader import BSLLoader as OTOKOLoader
+from sas.sascalc.file_converter.bsl_loader import BSLLoader
 from sas.sascalc.dataloader.data_info import Detector
 from sas.sascalc.dataloader.data_info import Sample
@@ -90,5 +92,5 @@
                     sasentry_attrs=entry_attrs)
 
-    def extract_data(self, filename):
+    def extract_ascii_data(self, filename):
         data = np.loadtxt(filename, dtype=str)
 
@@ -114,4 +116,21 @@
 
         return np.array(data, dtype=np.float32)
+
+    def extract_otoko_data(self, filename):
+        loader = OTOKOLoader(self.q_input.GetPath(),
+            self.iq_input.GetPath())
+        bsl_data = loader.load_bsl_data()
+        qdata = bsl_data.q_axis.data
+        iqdata = bsl_data.data_axis.data
+        if len(qdata) > 1:
+            msg = ("Q-Axis file has multiple frames. Only 1 frame is "
+                "allowed for the Q-Axis")
+            wx.PostEvent(self.parent.manager.parent,
+                StatusEvent(status=msg, info="error"))
+            return
+        else:
+            qdata = qdata[0]
+
+        return qdata, iqdata
 
     def ask_frame_range(self, n_frames):
@@ -160,33 +179,33 @@
         try:
             if self.data_type == 'ascii':
-                qdata = self.extract_data(self.q_input.GetPath())
-                iqdata = self.extract_data(self.iq_input.GetPath())
+                qdata = self.extract_ascii_data(self.q_input.GetPath())
+                iqdata = np.array([self.extract_ascii_data(self.iq_input.GetPath())])
+            elif self.data_type == 'otoko':
+                qdata, iqdata = self.extract_otoko_data(self.q_input.GetPath())
             else: # self.data_type == 'bsl'
-                loader = BSLLoader(self.q_input.GetPath(),
-                    self.iq_input.GetPath())
-                bsl_data = loader.load_bsl_data()
-                qdata = bsl_data.q_axis.data
-                iqdata = bsl_data.data_axis.data
-                if len(qdata) > 1:
-                    msg = ("Q-Axis file has multiple frames. Only 1 frame is "
-                        "allowed for the Q-Axis")
-                    wx.PostEvent(self.parent.manager.parent,
-                        StatusEvent(status=msg, info="error"))
-                    return
-                else:
-                    qdata = qdata[0]
-                frames = [iqdata.shape[0]]
-                increment = 1
-                single_file = True
-                # Standard file has 3 frames: SAS, calibration and WAS
-                if frames[0] > 3:
-                    # File has multiple frames
-                    params = self.ask_frame_range(frames[0])
+                loader = BSLLoader(self.iq_input.GetPath())
+                frames = [0]
+                if loader.n_frames > 1:
+                    params = self.ask_frame_range(loader.n_frames)
                     frames = params['frames']
-                    increment = params['inc']
-                    single_file = params['file']
-                    if frames == []: return
-                else: # Only interested in SAS data
-                    frames = [0]
+                data = []
+                for frame in frames:
+                    loader.frame = frame
+                    data.append(loader.load_data())
+                data = data[0]
+                data_x = []
+                data_y = range(loader.n_pixels) * loader.n_rasters
+                data_i = data.reshape((loader.n_pixels*loader.n_rasters,1))
+                for i in range(loader.n_rasters):
+                    data_x += [i] * loader.n_pixels
+                import pdb; pdb.set_trace()
+                data_info = Data2D(data=data_i, qx_data=data_x, qy_data=data_y)
+                from sas.sascalc.dataloader.readers.red2d_reader import Reader as Writer2D
+                writer = Writer2D()
+                writer.write(self.output.GetPath(), data_info)
+                wx.PostEvent(self.parent.manager.parent,
+                    StatusEvent(status="Conversion completed."))
+                return
+
         except Exception as ex:
             msg = str(ex)
@@ -194,4 +213,18 @@
                 StatusEvent(status=msg, info='error'))
             return
+
+        frames = []
+        increment = 1
+        single_file = True
+        # Standard file has 3 frames: SAS, calibration and WAS
+        if iqdata.shape[0] > 3:
+            # File has multiple frames
+            params = self.ask_frame_range(frames[0])
+            frames = params['frames']
+            increment = params['inc']
+            single_file = params['file']
+            if frames == []: return
+        else: # Only interested in SAS data
+            frames = [0]
 
         output_path = self.output.GetPath()
@@ -243,5 +276,5 @@
     def validate_inputs(self):
         msg = "You must select a"
-        if self.q_input.GetPath() == '':
+        if self.q_input.GetPath() == '' and self.data_type != 'bsl':
             msg += " Q Axis input file."
         elif self.iq_input.GetPath() == '':
@@ -299,4 +332,8 @@
         dtype = event.GetEventObject().GetName()
         self.data_type = dtype
+        if dtype == 'bsl':
+            self.q_input.Disable()
+        else:
+            self.q_input.Enable()
 
     def radiationtype_changed(self, event):
@@ -363,8 +400,11 @@
         ascii_btn.Bind(wx.EVT_RADIOBUTTON, self.datatype_changed)
         radio_sizer.Add(ascii_btn)
-        bsl_btn = wx.RadioButton(self, -1, "BSL/OTOKO", name="bsl")
+        otoko_btn = wx.RadioButton(self, -1, "OTOKO 1D", name="otoko")
+        otoko_btn.Bind(wx.EVT_RADIOBUTTON, self.datatype_changed)
+        radio_sizer.Add(otoko_btn)
+        input_grid.Add(radio_sizer, (y,1), (1,1), wx.ALL, 5)
+        bsl_btn = wx.RadioButton(self, -1, "BSL 2D", name="bsl")
         bsl_btn.Bind(wx.EVT_RADIOBUTTON, self.datatype_changed)
         radio_sizer.Add(bsl_btn)
-        input_grid.Add(radio_sizer, (y,1), (1,1), wx.ALL, 5)
         y += 1
 
