package de.lmu.ifi.dbs.algorithm.result.outlier;


import de.lmu.ifi.dbs.algorithm.result.AbstractResult;
import de.lmu.ifi.dbs.data.ClassLabel;
import de.lmu.ifi.dbs.data.DatabaseObject;
import de.lmu.ifi.dbs.database.AssociationID;
import de.lmu.ifi.dbs.database.Database;
import de.lmu.ifi.dbs.normalization.NonNumericFeaturesException;
import de.lmu.ifi.dbs.normalization.Normalization;
import de.lmu.ifi.dbs.utilities.UnableToComplyException;
import de.lmu.ifi.dbs.utilities.optionhandling.AttributeSettings;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;

/**
 * Provides the result of the LOF algorithm.
 *
 * @author Arthur Zimek
 */

public class GeneralizedLOFResult<O extends DatabaseObject> extends AbstractResult<O>
{

    /**
     * Marker for a file name containing lofs.
     */
    public static final String LOF_MARKER = "lof";

    /**
     * A new LOFResult set for a database.
     * 
     * The database needs to contain associations for the computed lofs
     * with <code>AssociationID</code> {@link de.lmu.ifi.dbs.database.AssociationID#LOF LOF}.
     *
     * @param db       the database containing the LOFs as association
     */
    public GeneralizedLOFResult(Database<O> db)
    {
        super(db);
        this.db = db;
    }

    /**
     * @see AbstractResult#output(java.io.File, de.lmu.ifi.dbs.normalization.Normalization, java.util.List)
     */
    @Override
    public void output(File out, Normalization<O> normalization, List<AttributeSettings> settings) throws UnableToComplyException
    {
        PrintStream outStream;
        try
        {
            File lofFile = new File(out.getAbsolutePath() + File.separator + LOF_MARKER + FILE_EXTENSION);
            lofFile.getParentFile().mkdirs();
            PrintStream lofOut = new PrintStream(new FileOutputStream(lofFile));
            outputLOF(lofOut, normalization, settings);
            lofOut.flush();

        }
        catch(Exception e)
        {
            outStream = new PrintStream(new FileOutputStream(FileDescriptor.out));
            output(outStream, normalization, settings);
        }
    }

    /**
     * @see AbstractResult#output(java.io.PrintStream, de.lmu.ifi.dbs.normalization.Normalization, java.util.List)
     */
    public void output(PrintStream outStream, Normalization<O> normalization, List<AttributeSettings> settings) throws UnableToComplyException
    {

        outputLOF(outStream, normalization, settings);
        outStream.flush();
    }

    /**
     * Writes the lofs to output.
     *
     * @param outStream     the stream to write to
     * @param normalization Normalization to restore original values according to, if this action is supported
     *                      - may remain null.
     * @param settings      the settings to be written into the header, if this parameter is <code>null</code>,
     *                      no header will be written
     */
    private void outputLOF(PrintStream outStream, Normalization<O> normalization, List<AttributeSettings> settings) throws UnableToComplyException
    {

        writeHeader(outStream, settings, null);

        try
        {
            

            // write lofs
            for(Iterator<Integer> it = db.iterator(); it.hasNext();)
            {
                Integer id = it.next();

                outStream.print(id);
                outStream.print(" ");

                O object = db.get(id);
                if(normalization != null)
                {
                    O restored = normalization.restore(object);
                    outStream.print(restored.toString());
                }
                else
                {
                    outStream.print(object.toString());
                }
                outStream.print(" ");

                String label = db.getAssociation(AssociationID.LABEL, id);
                if(label != null)
                {
                    outStream.print(label);
                    outStream.print(" ");
                }

                ClassLabel<?> classLabel = db.getAssociation(AssociationID.CLASS, id);
                if(classLabel != null)
                {
                    outStream.print(classLabel);
                    outStream.print(" ");
                }

                outStream.println(db.getAssociation(AssociationID.LOF, id));
            }
        }
        catch(NonNumericFeaturesException e)
        {
            throw new UnableToComplyException(e);
        }

        outStream.flush();
    }

}

@@ -380,24 +380,70 @@
 malization;%0A
+import de.lmu.ifi.dbs.utilities.IDDoublePair;%0A
 import de.lm
@@ -659,32 +659,90 @@
 io.PrintStream;%0A
+import java.util.ArrayList;%0Aimport java.util.Collections;%0A
 import java.util
@@ -3364,40 +3364,74 @@
     
-  %0A%0A            // write lofs%0A  
+List%3CIDDoublePair%3E lofs = new ArrayList%3CIDDoublePair%3E(db.size());%0A
     
@@ -3507,53 +3507,329 @@
     
-  %7B%0A                Integer id = it.next(
+%7B%0A            Integer id = it.next();%0A              lofs.add(new IDDoublePair(id,db.getAssociation(AssociationID.LOF, id)));%0A          %7D%0A          Collections.sort(lofs);%0A%0A            // write lofs%0A            for(IDDoublePair pair : lofs)%7B%0A              Integer id = pair.getID();%0A%0A              outStream.print(%22ID=%22
 );%0A
-%0A
     
@@ -4812,50 +4812,66 @@
 rint
-ln(db.getAssociation(AssociationID.LOF, id
+(%22LOF=%22);%0A                outStream.println(pair.getValue(
 ));%0A

output gestaltung