<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _parse_study(self, fname, node_types):
 """Parse study or assay row oriented file around the supplied base node. """

        if not os.path.exists(os.path.join(self._dir, fname)):
            return None
        nodes = {}
        with open(os.path.join(self._dir, fname), "rU") as in_handle:
            reader = csv.reader(in_handle, dialect="excel-tab")
            header = self._swap_synonyms(next(reader))
            hgroups = self._collapse_header(header)
            htypes = self._characterize_header(header, hgroups)

            for node_type in node_types:
                try:
                    name_index = header.index(node_type)
                except ValueError:
                    name_index = None

                if name_index is None:
                    #print "Could not find standard header name: %s in %s" \
                    #                        % (node_type, header)
                    continue

                in_handle.seek(0, 0)
                for line in reader:
                    name = line[name_index]
                    #to deal with same name used for different node types (e.g. Source Name and Sample Name using the same string)
                    node_index = self._build_node_index(node_type,name)
                    #skip the header line and empty lines
                    if name in header:
                        continue
                    if (not name):
                        continue
                    try:
                        node = nodes[node_index]
                    except KeyError:
                        #print("creating node ", name, "  index", node_index)
                        node = NodeRecord(name, node_type)
                        node.metadata = collections.defaultdict(set)
                        nodes[node_index] = node
                        attrs = self._line_keyvals(line, header, hgroups, htypes, node.metadata)
                        nodes[node_index].metadata = attrs

        return dict([(k, self._finalize_metadata(v)) for k, v in nodes.items()])