public ClassifierCombiner(params AbstractSequenceClassifier <IN>[] classifiers)
     : base(new Properties())
 {
     this.combinationMode   = DefaultCombinationMode;
     baseClassifiers        = new List <AbstractSequenceClassifier <IN> >(Arrays.AsList(classifiers));
     flags.backgroundSymbol = baseClassifiers[0].flags.backgroundSymbol;
     this.initProps         = new Properties();
 }
        /// <summary>
        /// Loads a series of base classifiers from the paths specified using the
        /// Properties specified.
        /// </summary>
        /// <param name="props">Properties for the classifier to use (encodings, output format, etc.)</param>
        /// <param name="combinationMode">How to handle multiple classifiers specifying the same entity type</param>
        /// <param name="loadPaths">Paths to the base classifiers</param>
        /// <exception cref="System.IO.IOException">If IO errors in loading classifier files</exception>
        public ClassifierCombiner(Properties props, ClassifierCombiner.CombinationMode combinationMode, params string[] loadPaths)
            : base(props)
        {
            this.combinationMode = combinationMode;
            IList <string> paths = new List <string>(Arrays.AsList(loadPaths));

            LoadClassifiers(props, paths);
            this.initLoadPaths = new List <string>(paths);
            this.initProps     = props;
        }
        /// <param name="p">
        /// Properties File that specifies
        /// <c>loadClassifier</c>
        /// and
        /// <c>loadAuxClassifier</c>
        /// properties or, alternatively,
        /// <c>loadClassifier[1-10]</c>
        /// properties.
        /// </param>
        /// <exception cref="Java.IO.FileNotFoundException">If classifier files not found</exception>
        /// <exception cref="System.IO.IOException"/>
        public ClassifierCombiner(Properties p)
            : base(p)
        {
            // keep track of properties used to initialize
            // keep track of paths used to load CRFs
            this.combinationMode = ExtractCombinationModeSafe(p);
            string         loadPath1;
            string         loadPath2;
            IList <string> paths = new List <string>();

            //
            // preferred configuration: specify up to 10 base classifiers using loadClassifier1 to loadClassifier10 properties
            //
            if ((loadPath1 = p.GetProperty("loadClassifier1")) != null && (loadPath2 = p.GetProperty("loadClassifier2")) != null)
            {
                paths.Add(loadPath1);
                paths.Add(loadPath2);
                for (int i = 3; i <= 10; i++)
                {
                    string path;
                    if ((path = p.GetProperty("loadClassifier" + i)) != null)
                    {
                        paths.Add(path);
                    }
                }
                LoadClassifiers(p, paths);
            }
            else
            {
                //
                // second accepted setup (backward compatible): two classifier given in loadClassifier and loadAuxClassifier
                //
                if ((loadPath1 = p.GetProperty("loadClassifier")) != null && (loadPath2 = p.GetProperty("loadAuxClassifier")) != null)
                {
                    paths.Add(loadPath1);
                    paths.Add(loadPath2);
                    LoadClassifiers(p, paths);
                }
                else
                {
                    //
                    // fall back strategy: use the two default paths on NLP machines
                    //
                    paths.Add(DefaultPaths.DefaultNerThreeclassModel);
                    paths.Add(DefaultPaths.DefaultNerMucModel);
                    LoadClassifiers(p, paths);
                }
            }
            this.initLoadPaths = new List <string>(paths);
            this.initProps     = p;
        }
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="System.TypeLoadException"/>
        /// <exception cref="System.InvalidCastException"/>
        public ClassifierCombiner(ObjectInputStream ois, Properties props)
            : base(PropertiesUtils.OverWriteProperties((Properties)ois.ReadObject(), props))
        {
            // constructor for building a ClassifierCombiner from an ObjectInputStream
            // read the initial Properties out of the ObjectInputStream so you can properly start the AbstractSequenceClassifier
            // note now we load in props from command line and overwrite any that are given for command line
            // read another copy of initProps that I have helpfully included
            // TODO: probably set initProps in AbstractSequenceClassifier to avoid this writing twice thing, its hacky
            this.initProps = PropertiesUtils.OverWriteProperties((Properties)ois.ReadObject(), props);
            // read the initLoadPaths
            this.initLoadPaths = (List <string>)ois.ReadObject();
            // read the combinationMode from the serialized version
            string cm = (string)ois.ReadObject();

            // see if there is a commandline override for the combinationMode, else set newCM to the serialized version
            ClassifierCombiner.CombinationMode newCM;
            if (props.GetProperty("ner.combinationMode") != null)
            {
                // there is a possible commandline override, have to see if its valid
                try
                {
                    // see if the commandline has a proper value
                    newCM = ClassifierCombiner.CombinationMode.ValueOf(props.GetProperty("ner.combinationMode"));
                }
                catch (ArgumentException)
                {
                    // the commandline override did not have a proper value, so just use the serialized version
                    newCM = ClassifierCombiner.CombinationMode.ValueOf(cm);
                }
            }
            else
            {
                // there was no commandline override given, so just use the serialized version
                newCM = ClassifierCombiner.CombinationMode.ValueOf(cm);
            }
            this.combinationMode = newCM;
            // read in the base classifiers
            int numClassifiers = ois.ReadInt();

            // set up the list of base classifiers
            this.baseClassifiers = new List <AbstractSequenceClassifier <IN> >();
            int i = 0;

            while (i < numClassifiers)
            {
                try
                {
                    log.Info("loading CRF...");
                    CRFClassifier <IN> newCRF = ErasureUtils.UncheckedCast(CRFClassifier.GetClassifier(ois, props));
                    baseClassifiers.Add(newCRF);
                    i++;
                }
                catch (Exception)
                {
                    try
                    {
                        log.Info("loading CMM...");
                        CMMClassifier newCMM = ErasureUtils.UncheckedCast(CMMClassifier.GetClassifier(ois, props));
                        baseClassifiers.Add(newCMM);
                        i++;
                    }
                    catch (Exception ex)
                    {
                        throw new IOException("Couldn't load classifier!", ex);
                    }
                }
            }
        }
 /// <summary>
 /// Loads a series of base classifiers from the paths specified using the
 /// Properties specified.
 /// </summary>
 /// <param name="combinationMode">How to handle multiple classifiers specifying the same entity type</param>
 /// <param name="loadPaths">Paths to the base classifiers</param>
 /// <exception cref="System.IO.IOException">If IO errors in loading classifier files</exception>
 public ClassifierCombiner(ClassifierCombiner.CombinationMode combinationMode, params string[] loadPaths)
     : this(new Properties(), combinationMode, loadPaths)
 {
 }