V1_0.java [src/java/m/ann/run] Revision: default  Date:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package m.ann.run;

import utils.MongoAccess;
import com.google.common.math.Quantiles;
import csip.ModelDataService;
import csip.ServiceException;
import csip.utils.JSONUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Path;
import oms3.annotations.Description;
import oms3.annotations.Name;
import org.bson.Document;
import utils.Calc;
import utils.CSIPMLData;
import utils.Metadata;
import utils.MongoUtils.Sorting;
import utils.SurrogateModel;

/**
 *
 * @author sidereus
 */
@Name("Run the ANN")
@Description("Run the network with provided input data")
@Path("m/run/1.0")
public class V1_0 extends ModelDataService {

    @Override
    public void doProcess() throws ServiceException, IOException {
        String annName = parameter().getString("annName");

        Iterable<Document> d = MongoAccess.getSortedNormalizedData(annName, MongoAccess.NORMALIZED, MongoAccess.NAME, Sorting.ASCENDING);
        double percMinMax = MongoAccess.retrieveMinMaxPerc(annName);
        double percQuart = MongoAccess.retrieveQuartPerc(annName);

        List<Double> in = new LinkedList<>();
        Map<String, Metadata> out = new HashMap<>();
        preProcess(d, in, out);

        SurrogateModel sm = new SurrogateModel(annName);
        List<double[]> result = sm.compute(new CSIPMLData(in));

        outputProcess(out, result, percMinMax, percQuart);
    }


    private void preProcess(Iterable<Document> d, List<Double> in, Map<String, Metadata> out) throws ServiceException {
        for (Document doc : d) {
            Document meta = doc.get(MongoAccess.METADATA, Document.class);
            String type = meta.getString(MongoAccess.TYPE);
            String varName = meta.getString(MongoAccess.NAME);
            double max = meta.getDouble("max");
            double min = meta.getDouble("min");
            boolean normal = meta.getBoolean(MongoAccess.NORM);
            double norm_max = meta.getDouble(MongoAccess.NORM_MAX);
            double norm_min = meta.getDouble(MongoAccess.NORM_MIN);
            if (type.equals(IN)) {
                if (normal) {
                    in.add(parameter().getDouble(varName));
                } else {
                    in.add(Calc.normalize(parameter().getDouble(varName), min, max, norm_min, norm_max));
                }
            } else {
                out.put(varName, new Metadata(normal, min, max, norm_min, norm_max));
            }
        }
    }


    /**
     * @TODO: improve algorithm efficency
     * @param outputMetadata
     * @param output
     */
    private void outputProcess(Map<String, Metadata> outputMetadata, List<double[]> output, double percMinMax, double percQuart) {
        int index = 0;
        for (Map.Entry<String, Metadata> entry : outputMetadata.entrySet()) {
            String name = entry.getKey();
            Metadata metadata = entry.getValue();
            double min = metadata.getMin();
            double max = metadata.getMax();
            boolean norm = metadata.getNorm();
            double norm_min = metadata.getNormMin();
            double norm_max = metadata.getNormMax();

            double[] dataset = new double[output.size()];
            int nnindex = 0;
            for (double[] out : output) {
                dataset[nnindex] = norm ? out[index] : Calc.denormalize(out[index], min, max, norm_min, norm_max);
                nnindex++;
            }

            Map<Integer, Double> uncertResult = Quantiles.quartiles().indexes(0, 1, 2, 3, 4).compute(dataset);
            results().put(name, uncertResult.get(2));
            results().putMetaInfo(name, "min", uncertResult.get(0));
            results().putMetaInfo(name, "1q", uncertResult.get(1));
            results().putMetaInfo(name, "3q", uncertResult.get(3));
            results().putMetaInfo(name, "max", uncertResult.get(4));
            results().putMetaInfo(name, "percentage btw quartiles", percQuart);
            results().putMetaInfo(name, "percentage btw min-max", percMinMax);
            results().putMetaInfo(name, "vals", JSONUtils.toArray(dataset)); //NEEDS TO BE FIXED
            index++;
        }
    }
    
}