Load workflow from the database and store in memory
        :param workflow_id: The workflow id
        :return: The workflow

def load_workflow(self, workflow_id):
        """
        Load workflow from the database and store in memory
        :param workflow_id: The workflow id
        :return: The workflow
        """
        with switch_db(WorkflowDefinitionModel, db_alias='hyperstream'):
            workflow_definition = WorkflowDefinitionModel.objects.get(workflow_id=workflow_id)
            if not workflow_definition:
                logging.warn("Attempted to load workflow with id {}, but not found".format(workflow_id))

            workflow = Workflow(
                workflow_id=workflow_id,
                name=workflow_definition.name,
                description=workflow_definition.description,
                owner=workflow_definition.owner,
                online=workflow_definition.online,
                monitor=workflow_definition.monitor
            )

            for n in workflow_definition.nodes:
                workflow.create_node(
                    stream_name=n.stream_name,
                    channel=self.channel_manager.get_channel(n.channel_id),
                    plates=[self.plate_manager.plates[p] for p in n.plate_ids])

            for f in workflow_definition.factors:
                source_nodes = [workflow.nodes[node_id] for node_id in f.sources] if f.sources else []
                sink_nodes = [workflow.nodes[node_id] for node_id in f.sinks] if f.sinks else []
                alignment_node = workflow.nodes[f.alignment_node] if f.alignment_node else None
                splitting_node = workflow.nodes[f.splitting_node] if f.splitting_node else None
                output_plate = f.output_plate

                parameters = Tool.parameters_from_model(f.tool.parameters)
                # tool = dict(name=f.tool.name, parameters=parameters)
                tool = self.channel_manager.get_tool(f.tool.name, parameters, version=None)

                if f.factor_type == "Factor":
                    if len(sink_nodes) != 1:
                        raise ValueError(
                            "Standard factors should have a single sink node, received {}"
                            .format(len(sink_nodes)))

                    if splitting_node is not None:
                        raise ValueError(
                            "Standard factors do not support splitting nodes")

                    if output_plate is not None:
                        raise ValueError(
                            "Standard factors do not support output plates")

                    workflow.create_factor(
                        tool=tool,
                        sources=source_nodes,
                        sink=sink_nodes[0],
                        alignment_node=alignment_node
                    )

                elif f.factor_type == "MultiOutputFactor":
                    if len(source_nodes) > 1:
                        raise ValueError(
                            "MultiOutputFactor factors should have at most one source node, received {}"
                            .format(len(source_nodes)))

                    if len(sink_nodes) != 1:
                        raise ValueError(
                            "MultiOutputFactor factors should have a single sink node, received {}"
                            .format(len(sink_nodes)))

                    if alignment_node is not None:
                        raise ValueError(
                            "MultiOutputFactor does not support alignment nodes")

                    if output_plate is not None:
                        raise ValueError(
                            "MultiOutputFactor does not support output plates")

                    workflow.create_multi_output_factor(
                        tool=tool,
                        source=source_nodes[0] if source_nodes else None,
                        splitting_node=splitting_node,
                        sink=sink_nodes[0]
                    )

                elif f.factor_type == "NodeCreationFactor":
                    if len(source_nodes) > 1:
                        raise ValueError(
                            "NodeCreationFactor factors should no more than one source node, received {}"
                            .format(len(source_nodes)))

                    if len(sink_nodes) != 0:
                        raise ValueError(
                            "NodeCreationFactor factors should not have sink nodes"
                            .format(len(sink_nodes)))

                    if output_plate is None:
                        raise ValueError(
                            "NodeCreationFactor requires an output plate definition")

                    workflow.create_node_creation_factor(
                        tool=tool,
                        source=source_nodes[0] if source_nodes else None,
                        output_plate=output_plate.to_mongo().to_dict(),
                        plate_manager=self.plate_manager
                    )

                else:
                    raise NotImplementedError("Unsupported factor type {}".format(f.factor_type))

            self.add_workflow(workflow, False)
            return workflow