Example #1
0
        public void configureOutputLogging(string prefix, SamplePackageFormat output)
        {
            // retrieve and prepare the logging of streams
            mLogDataStreams        = parameters.getValue <bool>("LogDataStreams");
            mLogDataStreamsRuntime = mLogDataStreams;
            if (mLogDataStreams)
            {
                // register the streams
                for (int channel = 0; channel < outputFormat.numChannels; channel++)
                {
                    Data.registerDataStream((prefix + "Output_Ch" + (channel + 1)), output.numSamples);
                }
            }

            // retrieve and prepare the visualization of streams
            mEnableDataVisualization = Globals.getValue <bool>("EnableDataVisualization");
            if (mEnableDataVisualization)
            {
                // register the streams to visualize
                for (int channel = 0; channel < outputFormat.numChannels; channel++)
                {
                    Data.registerVisualizationStream((prefix + "Output_Ch" + (channel + 1)), output);

                    // debug
                    //logger.Warn((prefix + "Output_Ch" + (channel + 1)));
                }
            }
        }
        /**
         * Configure the filter. Checks the values and application logic of the
         * parameters and, if valid, transfers the configuration parameters to local variables
         * (initialization of the filter is done later by the initialize function)
         **/
        public bool configure(ref SamplePackageFormat input, out SamplePackageFormat output)
        {
            // check sample-major ordered input
            if (input.valueOrder != SamplePackageFormat.ValueOrder.SampleMajor)
            {
                logger.Error("This filter is designed to work only with sample-major ordered input");
                output = null;
                return(false);
            }

            // retrieve the number of input channels
            if (input.numChannels <= 0)
            {
                logger.Error("Number of input channels cannot be 0");
                output = null;
                return(false);
            }

            // the output package will be in the same format as the input package
            output = new SamplePackageFormat(input.numChannels, input.numSamples, input.packageRate, input.valueOrder);

            // store a references to the input and output format
            inputFormat  = input;
            outputFormat = output;

            // check the values and application logic of the parameters
            if (!checkParameters(parameters))
            {
                return(false);
            }

            // transfer the parameters to local variables
            transferParameters(parameters);

            // configure output logging for this filter
            configureOutputLogging(filterName + "_", output);

            // print configuration
            printLocalConfiguration();

            // return success
            return(true);
        }
Example #3
0
        public bool configure(ref SamplePackageFormat input)
        {
            // check sample-major ordered input
            if (input.valueOrder != SamplePackageFormat.ValueOrder.SampleMajor)
            {
                logger.Error("This application is designed to work only with sample-major ordered input");
                return(false);
            }

            // check if the number of input channels is higher than 0
            if (input.numChannels <= 0)
            {
                logger.Error("Number of input channels cannot be 0");
                return(false);
            }

            // store a reference to the input format
            inputFormat = input;

            // PARAMETER TRANSFER

            // transfer window settings
            windowLeft            = parameters.getValue <int>("WindowLeft");
            windowTop             = parameters.getValue <int>("WindowTop");
            windowWidth           = parameters.getValue <int>("WindowWidth");
            windowHeight          = parameters.getValue <int>("WindowHeight");
            windowRedrawFreqMax   = parameters.getValue <int>("WindowRedrawFreqMax");
            windowBackgroundColor = parameters.getValue <RGBColorFloat>("WindowBackgroundColor");

            // transfer task specific values
            stimuli             = parameters.getValue <string[][]>("Stimuli");
            stimuliSequence     = parameters.getValue <int[]>("StimuliSequence");
            numberOfRepetitions = parameters.getValue <int>("NumberOfRepetitions");
            firstSequenceWait   = parameters.getValueInSamples("FirstSequenceWait");
            betweenSequenceWait = parameters.getValueInSamples("BetweenSequenceWait");
            startText           = parameters.getValue <string>("StartText");
            waitText            = parameters.getValue <string>("WaitText");
            endText             = parameters.getValue <string>("EndText");


            // PARAMETER CHECK
            // TODO: parameters.checkminimum, checkmaximum

            // check if stimuli are defined
            if (stimuli.Length != 4)
            {
                logger.Error("Stimuli not defined (correctly).");
                return(false);
            }
            else
            {
                // if stimuli are defined, check if duration is defined for each stimulus
                for (int i = 0; i < stimuli[3].Length; i++)
                {
                    if (string.IsNullOrEmpty(stimuli[3][i]) || stimuli[3][i] == " ")
                    {
                        logger.Error("Timing of stimulus " + (i + 1).ToString() + " is not defined.");
                        return(false);
                    }
                    else
                    {
                        // if timing is defined, see if it is parsable to integer
                        int timing = 0;
                        if (!int.TryParse(stimuli[3][i], out timing))
                        {
                            logger.Error("The timing given for stimulus " + (i + 1).ToString() + " (\"" + stimuli[3][i] + "\") is not a valid value, should be a positive integer.");
                            return(false);
                        }
                        // if timing is parsable, check if larger than 0
                        else if (timing <= 0)
                        {
                            logger.Error("The timing given for stimulus " + (i + 1).ToString() + " (" + stimuli[3][i] + ") is too short. The value should be a positive integer.");
                            return(false);
                        }
                    }
                }
            }

            // check if stimulus sequence is defined
            if (stimuliSequence.Length <= 0)
            {
                logger.Error("No stimuli sequence given.");
                return(false);
            }

            // determine maximal stimulus defined in stimulus sequence
            int stimMax = 0;

            for (int i = 0; i < stimuliSequence.Length; i++)
            {
                if (stimuliSequence[i] > stimMax)
                {
                    stimMax = stimuliSequence[i];
                }
            }

            // check if there are stimuli defined that are not included in stimuli definition
            if (stimMax > stimuli[0].Length)
            {
                logger.Error("In stimuli sequence, stimulus " + stimMax + " is defined. This stimulus can not be found in stimuli definition, as there are only " + stimuli[0].Length + " stimuli defined.");
                return(false);
            }

            // check if amount of repetitions is higher than 0
            if (numberOfRepetitions <= 0)
            {
                logger.Error("Amount of repetitions should be a positive integer.");
                return(false);
            }

            // check if first sequence wait is not smaller than 0
            if (firstSequenceWait < 0)
            {
                logger.Error("The time to wait before the start of the first sequence can not be lower than 0.");
                return(false);
            }

            // check if sequence wait is not smaller than 0
            if (betweenSequenceWait < 0)
            {
                logger.Error("The time to wait before the start of the subsequent sequence can not be lower than 0.");
                return(false);
            }

            // view checks
            if (windowRedrawFreqMax < 0)
            {
                logger.Error("The maximum window redraw frequency can be no smaller then 0");
                return(false);
            }

            if (windowWidth < 1)
            {
                logger.Error("The window width can be no smaller then 1");
                return(false);
            }

            if (windowHeight < 1)
            {
                logger.Error("The window height can be no smaller then 1");
                return(false);
            }

            return(true);
        }
Example #4
0
        public bool configure(out SamplePackageFormat output)
        {
            // retrieve the number of output channels
            outputChannels = parameters.getValue <int>("Channels");
            if (outputChannels <= 0)
            {
                logger.Error("Number of output channels cannot be 0");
                output = null;
                return(false);
            }

            // retrieve the sample-package rate
            samplePackageRate = parameters.getValue <double>("PackageRate");
            if (samplePackageRate <= 0)
            {
                logger.Error("The sample-package rate cannot be 0 or lower");
                output = null;
                return(false);
            }

            // retrieve the high precision setting
            highPrecision = parameters.getValue <bool>("HighPrecision");

            // retrieve the number of output channels
            samplesPerPackage = parameters.getValue <int>("SamplesPerPackage");
            if (samplesPerPackage <= 0)
            {
                logger.Error("Number of samples per package cannot be 0");
                output = null;
                return(false);
            }
            if (samplesPerPackage > 65535)
            {
                logger.Error("Number of samples per package cannot be higher than 65535");
                output = null;
                return(false);
            }

            // retrieve the sample value order
            //sampleValueOrder = (parameters.getValue<int>("ValueOrder") == 0 ? ValueOrder.ChannelMajor : ValueOrder.SampleMajor);
            sampleValueOrder = ValueOrder.SampleMajor;

            // create a sampleformat
            output = new SamplePackageFormat(outputChannels, samplesPerPackage, samplePackageRate, sampleValueOrder);

            // calculate the sample-package interval
            samplePackageIntervalMs = (int)Math.Floor(1000.0 / samplePackageRate);

            // check if the sample-package rate is above 1000hz
            if (samplePackageRate > 1000)
            {
                // enable the high precision timing
                highPrecision = true;

                // message
                logger.Warn("Because the sample-package rate is larger than 1000hz, the high precision timer will be used");
            }

            // check if high precision timing is enabled
            if (highPrecision)
            {
                // calculate the sample-package interval for the high precision timing
                samplePackageIntervalTicks = (long)Math.Round(Stopwatch.Frequency * (1.0 / samplePackageRate));

                // message
                logger.Warn("High precision timer enabled. The majority of the Palmtree OS-process will be claimed by the source-module, this might have consequences for the pipeline performance and/or your system performance");
            }

            // TODO: debug, log as sourceinput
            //for (int i = 0; i < outputChannels; i++)
            //    Data.registerSourceInputStream(("Ch" + i), samplesPerPackage, samplePackageRate);

            // flag as configured
            configured = true;

            // return success
            return(true);
        }
Example #5
0
        public bool configure(out SamplePackageFormat output)
        {
            #pragma warning disable 0162            // for constant checks, conscious ignore

            // retrieve whether the file should be read into memory
            readEntireFileInMemory = parameters.getValue <bool>("ReadEntireFileInMemory");

            // retrieve the input file and remove the extension
            inputFile = parameters.getValue <string>("Input");
            int extIndex = inputFile.LastIndexOf('.');
            if (extIndex != -1)
            {
                inputFile = inputFile.Substring(0, extIndex);
            }

            // check if the .dat file exists
            string inputDatFile = inputFile + ".dat";
            if (string.IsNullOrEmpty(inputDatFile) || !File.Exists(inputDatFile))
            {
                // message
                logger.Error("Could not find playback input .dat file '" + inputDatFile + "'");

                // return
                output = null;
                return(false);
            }

            // thread safety
            lock (lockInputReader) {
                lock (lockInputBuffer) {
                    // check if there is still an inputreader open, if so close
                    if (inputReader != null)
                    {
                        inputReader.close();
                        inputReader        = null;
                        inputHeader        = null;
                        inputBufferRowSize = 0;
                    }

                    // read the data header
                    DataHeader header = DataReader.readHeader(inputDatFile);
                    if (header == null)
                    {
                        // message
                        logger.Error("Could not read header data from input .dat file '" + inputDatFile + "'");

                        // return
                        output = null;
                        return(false);
                    }

                    // check version
                    if (header.version != 1)
                    {
                        // message
                        logger.Error("Currently only .dat files stored in the V1 format can be playbacked. Higher versions are not implemented yet.");

                        // return
                        output = null;
                        return(false);
                    }

                    // check if the internal code is 'dat'
                    if (string.Compare(header.code, "dat") != 0)
                    {
                        // message
                        logger.Error("The input .dat file is internally marked as '" + header.code + "', while a data stream ('dat') file is required");

                        // return
                        output = null;
                        return(false);
                    }

                    // check if the number of playback input streams in the .dat is higher than 0
                    if (header.numPlaybackStreams <= 0)
                    {
                        // message
                        logger.Error("The input .dat file has no playback input streams, these are required for playback, make sure the LogPipelineInputStream setting (data tab) is switched on while recording data for replay");

                        // return
                        output = null;
                        return(false);
                    }

                    // retrieve the redistribution of channels
                    redistributeChannels = parameters.getValue <int[]>("RedistributeChannels");
                    redistributeEnabled  = redistributeChannels.Length > 0;
                    for (int i = 0; i < redistributeChannels.Length; i++)
                    {
                        if (redistributeChannels[i] < 1 || redistributeChannels[i] % 1 != 0)
                        {
                            logger.Error("The values in the RedistributeChannels parameter should be positive integers (note that the channel numbering is 1-based)");
                            output = null;
                            return(false);
                        }
                        if (redistributeChannels[i] > header.numPlaybackStreams)
                        {
                            logger.Error("One of the values in the RedistributeChannels parameter exceeds the number of playback (input) streams in the data file (#playbackStreams: " + header.numPlaybackStreams + ")");
                            output = null;
                            return(false);
                        }

                        // lower each channel value (1-based), so it can be used immediately to point to the right value in the input stream array (0-based)
                        redistributeChannels[i]--;
                    }

                    // check if the channels are redistributed
                    if (redistributeEnabled)
                    {
                        // set the number of output channels to the number of redistributed channels
                        outputChannels = redistributeChannels.Length;
                    }
                    else
                    {
                        // set the number of output channels for this source based on the playback streams in the .dat file
                        outputChannels = header.numPlaybackStreams;
                    }

                    // set the sample rate for this source based on the .dat file
                    sampleRate = header.sampleRate;

                    // check the sample rate
                    if (sampleRate <= 0)
                    {
                        logger.Error("The sample rate in the (header of the) .dat file is 0 or lower, invalid sample rate");
                        output = null;
                        return(false);
                    }

                    // create a sampleformat
                    // (at this point we can only playback .dat files with the pipeline input streams, these always have 1 sample per package.
                    // since the number of samples is 1 per package, the given samplerate is the packagerate)
                    // TODO: support more samples per package
                    output = new SamplePackageFormat(outputChannels, 1, sampleRate, SamplePackageFormat.ValueOrder.SampleMajor);

                    // check the constants (buffer size in combination with buffer min read)
                    if (INPUT_BUFFER_MIN_READ_SECONDS < 2)
                    {
                        logger.Error("The buffer minimum-till-read should not be less than two seconds, provide a larger value for INPUT_BUFFER_MIN_READ_SECONDS");
                        return(false);
                    }
                    if (INPUT_BUFFER_MIN_READ_SECONDS > INPUT_BUFFER_SIZE_SECONDS)
                    {
                        logger.Error("The buffer minimum-till-read is larger than the buffer, either adjust INPUT_BUFFER_SIZE_SECONDS or INPUT_BUFFER_MIN_READ_SECONDS");
                        return(false);
                    }

                    // calculate the input buffer size (the size of the inputbuffer is defined as number of seconds of data to hold)
                    inputBufferSize = (long)Math.Floor(INPUT_BUFFER_SIZE_SECONDS * header.sampleRate);
                    if (inputBufferSize == 0)
                    {
                        logger.Error("The buffer size is too small when combined with the sample rate, provide a larger value for INPUT_BUFFER_SIZE_SECONDS");
                        return(false);
                    }

                    // calculate the minimum amount of rows until additional read
                    inputBufferMinTillRead = (long)Math.Floor(INPUT_BUFFER_MIN_READ_SECONDS * header.sampleRate);
                    if (inputBufferMinTillRead == 0)
                    {
                        logger.Error("The buffer minimum-till-read is too small when combined with the sample rate, provide a larger value for INPUT_BUFFER_MIN_READ_SECONDS");
                        return(false);
                    }
                    if (inputBufferMinTillRead >= inputBufferSize)
                    {
                        logger.Error("The buffer minimum-till-read should be smaller than the input buffer size, provide a smaller value for INPUT_BUFFER_MIN_READ_SECONDS");
                        return(false);
                    }

                    // calculate the number of rows to read when the minimum is reached
                    // (note: a smaller read step is also possible; current just refilling the buffer by taking the difference between the minimum-till-read and total buffer size)
                    inputBufferRowsPerRead = inputBufferSize - inputBufferMinTillRead;

                    // the entire file should be read into memory, or if the number of rows in the file are equal to or smaller than the input buffer rows,
                    // then the buffer size will be based on the file row-size
                    if (readEntireFileInMemory || header.numRows <= inputBufferSize)
                    {
                        // input buffer will be the same size as the data in the input file
                        inputBufferSize = header.numRows;

                        // not necessary as the entire file will be read in on initialize
                        inputBufferMinTillRead = 1;
                        inputBufferRowsPerRead = 1;
                    }

                    // check if the number of rows per read is not too big
                    // note: should not happen since it is calculated based on the buffer size and min-till-read, just in case)
                    if (inputBufferRowsPerRead > inputBufferSize - inputBufferMinTillRead)
                    {
                        logger.Error("Number of rows per read (" + inputBufferRowsPerRead + ") should be smaller than the space in the buffer that is open when the buffer min-till-read is reached ('" + (inputBufferSize - inputBufferMinTillRead) + ")");
                        return(false);
                    }

                    // write some playback information
                    logger.Info("Playback data file: " + inputDatFile);
                    logger.Info("Data file version: " + header.version);
                    logger.Info("Pipeline sample rate: " + sampleRate);
                    logger.Info("Number of input streams in file: " + header.numPlaybackStreams);
                    logger.Info("Number of output channels: " + outputChannels);
                    logger.Info("Number of rows: " + header.numRows);
                } // end lock
            }     // end lock

            // retrieve the timing by file setting
            timingByFile = parameters.getValue <bool>("TimingByFile");

            // retrieve the high precision setting
            highPrecision = parameters.getValue <bool>("HighPrecision");

            // calculate the sample interval
            sampleIntervalMs = (int)Math.Floor(1000.0 / sampleRate);

            // check if the samplerate is above 1000hz
            if (sampleRate > 1000)
            {
                // enable the high precision timing
                highPrecision = true;

                // message
                logger.Warn("Because the sample rate is larger than 1000hz, the high precision timer is used");
            }

            // check if high precision timing is enabled
            if (highPrecision)
            {
                // calculate the sample interval for the high precision timing
                sampleIntervalTicks = (long)Math.Round(Stopwatch.Frequency * (1.0 / sampleRate));

                // message
                logger.Warn("High precision timer enabled, as one core will be claimed entirely this might have consequences for your system performance");
            }

            // flag as configured
            configured = true;

            // return success
            return(true);
        }
Example #6
0
 public bool configure(ref SamplePackageFormat input)
 {
     return(true);
 }
Example #7
0
        public bool configure(out SamplePackageFormat output)
        {
            // retrieve the number of output channels
            outputChannels = parameters.getValue <int>("Channels");
            if (outputChannels <= 0)
            {
                logger.Error("Number of output channels cannot be 0");
                output = null;
                return(false);
            }

            // retrieve the sample-package rate
            samplePackageRate = parameters.getValue <double>("SamplePackageRate");
            if (samplePackageRate <= 0)
            {
                logger.Error("The sample-package rate cannot be 0 or lower");
                output = null;
                return(false);
            }

            // retrieve the high precision setting
            highPrecision = parameters.getValue <bool>("HighPrecision");

            // retrieve the number of output channels
            samplesPerPackage = parameters.getValue <int>("SamplesPerPackage");
            if (samplesPerPackage <= 0)
            {
                logger.Error("Number of samples per package cannot be 0");
                output = null;
                return(false);
            }
            if (samplesPerPackage > 65535)
            {
                logger.Error("Number of samples per package cannot be higher than 65535");
                output = null;
                return(false);
            }

            // retrieve the sample value order
            //sampleValueOrder = (parameters.getValue<int>("ValueOrder") == 0 ? ValueOrder.ChannelMajor : ValueOrder.SampleMajor);
            sampleValueOrder = ValueOrder.SampleMajor;

            // create a sampleformat
            output = new SamplePackageFormat(outputChannels, samplesPerPackage, samplePackageRate, sampleValueOrder);

            // calculate the sample-package interval
            samplePackageIntervalMs = (int)Math.Floor(1000.0 / samplePackageRate);

            // check if the sample-package rate is above 1000hz
            if (samplePackageRate > 1000)
            {
                // enable the high precision timing
                highPrecision = true;

                // message
                logger.Warn("Because the sample-package rate is larger than 1000hz, the high precision timer will be used");
            }

            // check if high precision timing is enabled
            if (highPrecision)
            {
                // calculate the sample-package interval for the high precision timing
                samplePackageIntervalTicks = (long)Math.Round(Stopwatch.Frequency * (1.0 / samplePackageRate));

                // message
                logger.Warn("High precision timer enabled. The majority of the Palmtree OS-process will be claimed by the source-module, this might have consequences for the pipeline performance and/or your system performance");
            }

            // retrieve key settings
            string[][] keys = parameters.getValue <string[][]>("Keys");
            if (keys == null || keys.Length == 0)
            {
                // no keys specified

                mConfigKeys           = new Keys[0];
                mConfigOutputChannels = new int[0];
                mConfigPressed        = new double[0];
                mConfigNotPressed     = new double[0];
            }
            else
            {
                // keys present

                if (keys.Length != 4)
                {
                    logger.Error("Keys parameter must have 4 columns (Key, Output channel, Pressed, Not-pressed)");
                    return(false);
                }

                // resize the variables
                mConfigKeys           = new Keys[keys[0].Length];         // char converted to virtual key
                mConfigOutputChannels = new int[keys[0].Length];          // for the values stored in this array: value 0 = channel 1
                mConfigPressed        = new double[keys[0].Length];
                mConfigNotPressed     = new double[keys[0].Length];

                // loop through the rows
                for (int row = 0; row < keys[0].Length; ++row)
                {
                    // try to convert the key character to an int
                    string key = keys[0][row].ToUpper();
                    if (key.Length != 1 || !(new Regex(@"^[A-Z0-9]*$")).IsMatch(key))
                    {
                        logger.Error("The key value '" + key + "' is not a valid key (should be a single character, a-z or 0-9)");
                        return(false);
                    }
                    mConfigKeys[row] = (Keys)key[0];     // capital characters A-Z and numbers can be directly saved as int (directly used/emulated as virtual keys)

                    // try to parse the channel number
                    int channel = 0;
                    if (!int.TryParse(keys[1][row], out channel))
                    {
                        logger.Error("The value '" + keys[1][row] + "' is not a valid output channel value (should be a positive integer)");
                        return(false);
                    }
                    if (channel < 1)
                    {
                        logger.Error("Output channels must be positive integers");
                        return(false);
                    }
                    if (channel > outputChannels)
                    {
                        logger.Error("The output channel value '" + keys[1][row] + "' exceeds the number of channels coming out of the filter (#outputChannels: " + outputChannels + ")");
                        return(false);
                    }
                    mConfigOutputChannels[row] = channel - 1;   // -1 since the user input the channel 1-based and we use a 0-based array

                    // try to parse the pressed value
                    double doubleValue = 0;
                    if (!double.TryParse(keys[2][row], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Parameters.NumberCulture, out doubleValue))
                    {
                        logger.Error("The value '" + keys[2][row] + "' is not a valid double value");
                        return(false);
                    }
                    mConfigPressed[row] = doubleValue;

                    // try to parse the not-pressed value
                    doubleValue = 0;
                    if (!double.TryParse(keys[3][row], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Parameters.NumberCulture, out doubleValue))
                    {
                        logger.Error("The value '" + keys[3][row] + "' is not a valid double value");
                        return(false);
                    }
                    mConfigNotPressed[row] = doubleValue;
                }
            }

            // flag as configured
            configured = true;

            // return success
            return(true);
        }
        /**
         * Configure the filter. Checks the values and application logic of the
         * parameters and, if valid, transfers the configuration parameters to local variables
         * (initialization of the filter is done later by the initialize function)
         **/
        public bool configure(ref SamplePackageFormat input, out SamplePackageFormat output)
        {
            // check sample-major ordered input
            if (input.valueOrder != SamplePackageFormat.ValueOrder.SampleMajor)
            {
                logger.Error("This filter is designed to work only with sample-major ordered input");
                output = null;
                return(false);
            }

            // retrieve and check the number of input channels
            if (input.numChannels <= 0)
            {
                logger.Error("Number of input channels cannot be 0");
                output = null;
                return(false);
            }

            // store a references to the input format (here so checkParameters can use it)
            inputFormat = input;

            // check the values and application logic of the parameters
            if (!checkParameters(parameters))
            {
                output = null;
                return(false);
            }

            // transfer the parameters to local variables
            transferParameters(parameters);

            // determine the number of output channels
            int outputChannels;

            if (mEnableFilter)
            {
                // determine the highest output channel from the configuration and set this as the number of output channels
                int highestOutputChannel = 0;
                for (int row = 0; row < mConfigOutputChannels.Length; ++row)
                {
                    if (mConfigOutputChannels[row] > highestOutputChannel)
                    {
                        highestOutputChannel = mConfigOutputChannels[row];
                    }
                }
                outputChannels = highestOutputChannel;
            }
            else
            {
                // filter will pass the input straight through, so same number of channels as output
                outputChannels = inputFormat.numChannels;
            }

            // create an output sampleformat and store a references to the output format
            output       = new SamplePackageFormat(outputChannels, input.numSamples, input.packageRate, input.valueOrder);
            outputFormat = output;

            // configure output logging for this filter
            configureOutputLogging(filterName + "_", output);

            // print configuration
            printLocalConfiguration();

            // return success
            return(true);
        }