All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.actelion.research.orbit.imageAnalysis.cp.CpParser Maven / Gradle / Ivy

Go to download

Orbit, a versatile image analysis software for biological image-based quantification

There is a newer version: 3.15
Show newest version
/*
 *     Orbit, a versatile image analysis software for biological image-based quantification.
 *     Copyright (C) 2009 - 2017 Actelion Pharmaceuticals Ltd., Gewerbestrasse 16, CH-4123 Allschwil, Switzerland.
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see .
 *
 */

package com.actelion.research.orbit.imageAnalysis.cp;

import com.actelion.research.orbit.beans.RawDataFile;
import com.actelion.research.orbit.imageAnalysis.components.RecognitionFrame;
import com.actelion.research.orbit.imageAnalysis.dal.DALConfig;
import com.actelion.research.orbit.imageAnalysis.models.*;
import com.actelion.research.orbit.imageAnalysis.tasks.ExclusionMapGen;
import com.actelion.research.orbit.imageAnalysis.utils.OrbitUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class CpParser {

    private static final Logger log = LoggerFactory.getLogger(CpParser.class);
    public final static String imageName = "Image";
    public final static String ending = ".csv";
    public final static String sep = ",";
    public final static String Data_OUT_IDENTIFIER = "Data to export:";
    private final static int MAX_CNT_WRITEDB = 2000;

    private Map imageMap;
    public final Map> objectCountMap = new ConcurrentHashMap<>();
    public final Map orbitDataMap = new ConcurrentHashMap<>();
    private final Random random = new Random();
    private String path;
    private OrbitModel model;
    private String pipeline;
    private String orbitUser = "";

    public CpParser(String orbitUser) {
        this.orbitUser = orbitUser;
    }

    private Map parseImages() throws Exception {
        Map imageMap = new ConcurrentHashMap<>();
        //File file = new File(path + File.separator + imageName + ending);
        File file = null;
        for (File f : new File(path).listFiles()) {
            if (f.getName().toLowerCase().endsWith("image.csv")) {
                file = f;
                break;
            }
        }
        if (file == null) {
            throw new Exception("no *Image.csv found. Please configure your CP pipeline so that CP produces an *Image.csv file.");
        }
        try (
                FileReader fr = new FileReader(file);
                BufferedReader reader = new BufferedReader(fr);
        ) {
            imageMap.clear();
            String line;
            reader.readLine(); // header
            while ((line = reader.readLine()) != null) {
                String[] split = line.split(sep);
                int id = Integer.parseInt(split[0]);
                CpImage img = new CpImage(id, Integer.parseInt(split[1]), Integer.parseInt(split[2]), Integer.parseInt(split[3]));
                imageMap.put(id, img);
                //System.out.println("img: "+img);
            }
        }
        return imageMap;
    }


    private void parseObject(String objName, boolean writeDB, List objectNames) throws Exception {
        log.info("parseObj " + objName + " start");
        Map objNameMap = new HashMap<>();
        for (int i = 0; i < objectNames.size(); i++) {
            objNameMap.put(objectNames.get(i), i);
        }
        //if (model.getExclusionModel() == null) throw new Exception("no exclusion model available");
        File file = new File(path + File.separator + objName + ending);
        try (
                FileReader fr = new FileReader(file);
                BufferedReader reader = new BufferedReader(fr);
        ) {
            String line;
            reader.readLine(); // header
            int lastImageId = -1;
            int lastOrbitId = -1;
            CpImage img = null;
            OrbitData orbitData = null;
            int cnt = 0;
            while ((line = reader.readLine()) != null) {
                cnt++;
                String[] split = line.split(sep);
                int imgId = Integer.parseInt(split[0]);
                if (imgId != lastImageId) {
                    if (!imageMap.containsKey(imgId))
                        throw new IllegalArgumentException("Image with id " + imgId + " not found in image map");
                    img = imageMap.get(imgId);
                    lastImageId = imgId;
                    if (img.getOrbitId() != lastOrbitId) {
                        if (!orbitDataMap.containsKey(img.getOrbitId())) {
                            RawDataFile rdf = DALConfig.getImageProvider().LoadRawDataFile(img.getOrbitId());
                            RecognitionFrame rf = new RecognitionFrame(rdf);
                            Shape roi = OrbitUtils.loadAnnotationROI(img.getOrbitId(),/*model.getAnnotationGroup()*/0);
                            ExclusionMapGen exMapGen = ExclusionMapGen.constructExclusionMap(rdf, rf, model, (IScaleableShape) roi);
                            if (exMapGen != null)
                                exMapGen.generateMap();
                            OrbitData od = new OrbitData(img.getOrbitId(), exMapGen, rdf, roi, rf.bimg.getTileWidth(), rf.bimg.getTileHeight());
                            orbitDataMap.put(img.getOrbitId(), od);
                        }
                        orbitData = orbitDataMap.get(img.getOrbitId());
                        lastOrbitId = img.getOrbitId();
                        log.trace("cpImgId:" + imgId + ", orbitId:" + img.getOrbitId());
                    }
                }
                double centerX = Double.parseDouble(split[2]);
                double centerY = Double.parseDouble(split[3]);
                int x = (int) (img.getTileX() * orbitData.getTileWidth() + centerX);
                int y = (int) (img.getTileY() * orbitData.getTileHeight() + centerY);
                if (OrbitUtils.isInROI(x, y, orbitData.getRoi(), orbitData.getExMapGen())) {
                    if (!objectCountMap.containsKey(img.orbitId)) {
                        objectCountMap.put(img.getOrbitId(), new ConcurrentHashMap());
                    }
                    Map counts = objectCountMap.get(img.getOrbitId());
                    if (!counts.containsKey(objName)) {
                        counts.put(objName, 0);
                    }
                    int objCnt = counts.get(objName);
                    objCnt++;
                    counts.put(objName, objCnt);

                    // save as special annotation  (but not nuclei - too many...)
                    if (writeDB /*&& !objName.equals("Nuclei")*/ && cnt <= MAX_CNT_WRITEDB) {
                        Color col = Color.yellow;
                        int classNum = 0;

                        // different colors per class
//                        switch (objName) {
//							case "FilteredCD4": col=Color.red; classNum=0; break;
//							case "FilteredFoxp3": col=Color.green; classNum=1; break;
//							case "CD4_FOXP3": col=Color.yellow; classNum=2; break;
//						}
                        classNum = objNameMap.get(objName);
                        col = RecognitionFrame.getColorByNum(classNum);

                        final double w = 10d;
                        final double h = 10d;
                        double xj = x + ((random.nextDouble() - 0.5d) * 3d);
                        double yj = y + ((random.nextDouble() - 0.5d) * 3d);
                        ClassShape cs = new ClassShape(objName, col, ClassShape.SHAPETYPE_ARC);
                        cs.getShapeList().add(new Arc2DExt(xj - (w / 2d), yj - (h / 2d), 10, 10, 0, 360, Arc2DFixed.CHORD));
                        CellDetectionAnnotation anno = new CellDetectionAnnotation(objName, cs);
                        anno.setRawDataFileId(img.getOrbitId());
                        anno.setUserId(orbitUser);
                        anno.setClassNum(classNum);
                        DALConfig.getImageProvider().InsertRawAnnotation(anno);
                    }


                }


            }

        }
        log.info("parseObj " + objName + " end");
    }


    public Map> processObjects(String path, String pipeline, String exclModelFilename, boolean writeDB) throws Exception {
        final OrbitModel model = exclModelFilename == null ? null : OrbitModel.LoadFromFile(exclModelFilename);
        return processObjects(path, pipeline, model, writeDB);
    }

    public Map> processObjects(String path, String pipeline, final OrbitModel exclModel, boolean writeDB) throws Exception {
        this.path = path;
        this.model = exclModel;
        this.imageMap = parseImages();
        this.pipeline = pipeline;

        List objectNames = parseOutputObjects(pipeline);
        for (String objectName : objectNames) {
            parseObject(objectName, writeDB, objectNames);
        }

        StringBuilder sb = new StringBuilder();
        sb.append("OrbitId,ImageName");
        for (String objName : objectNames) sb.append("," + objName);
        sb.append("\n");

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(path + File.separator + "objectcounts.csv"))) {
            writer.write(sb.toString());
            for (int orbitId : objectCountMap.keySet()) {
                RawDataFile rdf = DALConfig.getImageProvider().LoadRawDataFile(orbitId);
                String s = orbitId + sep + "\"" + rdf.getFileName() + "\"";
                for (String objName : objectNames) {
                    s += sep + objectCountMap.get(orbitId).get(objName);
                }
                s += "\n";
                sb.append(s);
                writer.write(s);
            }
            writer.flush();
        }

        System.out.println("\n" + sb.toString());

        return objectCountMap;
    }


    public List parseOutputObjects(String pipeline) throws IOException {
        List objectNames = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(pipeline))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.trim().startsWith(Data_OUT_IDENTIFIER)) {
                    String objectName = line.replaceAll(Data_OUT_IDENTIFIER, "").trim();
                    if (!objectName.equals(imageName)) {
                        log.debug("object name found in pipeline: " + objectName);
                        objectNames.add(objectName);
                    }
                }
            }
        }
        return objectNames;
    }


    class OrbitData {
        private int orbitId;
        private RawDataFile rdf;
        private ExclusionMapGen exMapGen;
        private Shape roi;
        private int tileWidth;
        private int tileHeight;

        public OrbitData(int orbitId, ExclusionMapGen exMapGen, RawDataFile rdf, Shape roi, int tileWidth, int tileHeight) {
            this.orbitId = orbitId;
            this.exMapGen = exMapGen;
            this.rdf = rdf;
            this.roi = roi;
            this.tileWidth = tileWidth;
            this.tileHeight = tileHeight;
        }

        public int getTileHeight() {
            return tileHeight;
        }

        public void setTileHeight(int tileHeight) {
            this.tileHeight = tileHeight;
        }

        public int getTileWidth() {
            return tileWidth;
        }

        public void setTileWidth(int tileWidth) {
            this.tileWidth = tileWidth;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            OrbitData orbitData = (OrbitData) o;

            return orbitId == orbitData.orbitId;

        }

        @Override
        public int hashCode() {
            return orbitId;
        }

        @Override
        public String toString() {
            return "OrbitData{" +
                    "orbitId=" + orbitId +
                    ", rdf=" + rdf +
                    ", roi=" + roi +
                    '}';
        }

        public ExclusionMapGen getExMapGen() {
            return exMapGen;
        }

        public void setExMapGen(ExclusionMapGen exMapGen) {
            this.exMapGen = exMapGen;
        }

        public int getOrbitId() {
            return orbitId;
        }

        public void setOrbitId(int orbitId) {
            this.orbitId = orbitId;
        }

        public RawDataFile getRdf() {
            return rdf;
        }

        public void setRdf(RawDataFile rdf) {
            this.rdf = rdf;
        }

        public Shape getRoi() {
            return roi;
        }

        public void setRoi(Shape roi) {
            this.roi = roi;
        }

    }


    class CpImage implements Serializable {
        private int id;
        private int orbitId;
        private int tileX;
        private int tileY;

        public CpImage(int id, int orbitId, int tileX, int tileY) {
            this.id = id;
            this.orbitId = orbitId;
            this.tileX = tileX;
            this.tileY = tileY;
        }

        @Override
        public String toString() {
            return "CpImage{" +
                    "id=" + id +
                    ", orbitId=" + orbitId +
                    ", tileX=" + tileX +
                    ", tileY=" + tileY +
                    '}';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            CpImage cpImage = (CpImage) o;

            if (id != cpImage.id) return false;
            if (orbitId != cpImage.orbitId) return false;
            if (tileX != cpImage.tileX) return false;
            return tileY == cpImage.tileY;

        }

        @Override
        public int hashCode() {
            int result = id;
            result = 31 * result + orbitId;
            result = 31 * result + tileX;
            result = 31 * result + tileY;
            return result;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getOrbitId() {
            return orbitId;
        }

        public void setOrbitId(int orbitId) {
            this.orbitId = orbitId;
        }

        public int getTileX() {
            return tileX;
        }

        public void setTileX(int tileX) {
            this.tileX = tileX;
        }

        public int getTileY() {
            return tileY;
        }

        public void setTileY(int tileY) {
            this.tileY = tileY;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy