def setup(self):
        """
        Generic setup for any analysis module, can be overriden by implementing in any child class
        This sets up subscriber and publisher based on input and output feature names
        """
        # usually this module is used with incoming EEG,
        # so we'd like to know num channels, and a header is for convenience
        # hard-coded "eeg" could be a problem if the device's metric name for raw data is not "eeg"
        # currently "eeg" is a known good metric name for both OpenBCI and Muse
        if "num_channels" in self.module_settings:
            # module specific setting
            self.num_channels = self.module_settings["num_channels"]
        elif "num_channels" in self.global_settings:
            #global setting
            self.num_channels = self.global_settings["num_channels"]
        else:
            # default for the device type
            self.num_channels = get_num_channels(self.device_name,"eeg")

        self.headers = ['timestamp'] + ['channel_%s' % i for i in xrange(self.num_channels)]

        # if input, instantiate subscriber
        if len(self.inputs):
            # there is only one subscriber to handle all inputs
            self.subscriber = PikaSubscriber(device_name=self.device_name,
                                                     device_id=self.device_id,
                                                     rabbitmq_address=self.rabbitmq_address,
                                                     metrics=self.inputs)

        # if output, instantiate publishers
        if len(self.outputs):

            for output_key, output in self.outputs.iteritems():
                # each output has a specific key, assign a placeholder for it in publishers collection
                self.publishers[output_key] = {}
                self.output_buffers[output_key] = {}

                # each output has a parameter called "message_queues"
                # this can be a single value or a list, i.e. "foo" or ["foo1","foo2"]
                # most of the time, this will be a single string
                # an example of where an output might use more than one message_queue might be:
                # one output goes to visualization, while a second copy continues down the processing chain

                if 'message_queues' in output:
                    # for convenience, convert the "message_queues" parameter to list if it isn't already
                    if type(output['message_queues']) != list:
                        output['message_queues'] =  [output['message_queues']]

                    # there is one publisher per output
                    for message_queue_name in output['message_queues']:
                        self.publishers[output_key][message_queue_name] = PikaPublisher(
                                                                    device_name=self.device_name,
                                                                    device_id=self.device_id,
                                                                    rabbitmq_address=self.rabbitmq_address,
                                                                    metric_name=message_queue_name)

                        # also instantiate an output buffer for each publisher
                        self.output_buffers[output_key][message_queue_name] = []