class DistanceMoment {

    public static float[] generateMoments(IAtomContainer atomContainer) throws CDKException {
        // lets check if we have 3D coordinates
        Iterator<IAtom> atoms;

        int natom = atomContainer.getAtomCount();

        Point3d ctd = getGeometricCenter(atomContainer);
        Point3d cst = new Point3d();
        Point3d fct = new Point3d();
        Point3d ftf = new Point3d();

        double[] distCtd = new double[natom];
        double[] distCst = new double[natom];
        double[] distFct = new double[natom];
        double[] distFtf = new double[natom];

        atoms = atomContainer.atoms().iterator();
        int counter = 0;
        double min = Double.MAX_VALUE;
        double max = Double.MIN_VALUE;

        // eval dist to centroid
        while (atoms.hasNext()) {
            IAtom atom = atoms.next();
            Point3d p = atom.getPoint3d();
            double d = p.distance(ctd);
            distCtd[counter++] = d;

            if (d < min) {
                cst.x = p.x;
                cst.y = p.y;
                cst.z = p.z;
                min = d;
            }
            if (d > max) {
                fct.x = p.x;
                fct.y = p.y;
                fct.z = p.z;
                max = d;
            }
        }

        // eval dist to cst
        atoms = atomContainer.atoms().iterator();
        counter = 0;
        while (atoms.hasNext()) {
            IAtom atom = atoms.next();
            Point3d p = atom.getPoint3d();
            double d = p.distance(cst);
            distCst[counter++] = d;
        }

        // eval dist to fct
        atoms = atomContainer.atoms().iterator();
        counter = 0;
        max = Double.MIN_VALUE;
        while (atoms.hasNext()) {
            IAtom atom = atoms.next();
            Point3d p = atom.getPoint3d();
            double d = p.distance(fct);
            distFct[counter++] = d;

            if (d > max) {
                ftf.x = p.x;
                ftf.y = p.y;
                ftf.z = p.z;
                max = d;
            }
        }

        // eval dist to ftf
        atoms = atomContainer.atoms().iterator();
        counter = 0;
        while (atoms.hasNext()) {
            IAtom atom = atoms.next();
            Point3d p = atom.getPoint3d();
            double d = p.distance(ftf);
            distFtf[counter++] = d;
        }

        float[] moments = new float[12];

        float mean = mu1(distCtd);
        float sigma2 = mu2(distCtd, mean);
        float skewness = mu3(distCtd, mean, Math.sqrt(sigma2));
        moments[0] = mean;
        moments[1] = sigma2;
        moments[2] = skewness;

        mean = mu1(distCst);
        sigma2 = mu2(distCst, mean);
        skewness = mu3(distCst, mean, Math.sqrt(sigma2));
        moments[3] = mean;
        moments[4] = sigma2;
        moments[5] = skewness;

        mean = mu1(distFct);
        sigma2 = mu2(distFct, mean);
        skewness = mu3(distFct, mean, Math.sqrt(sigma2));
        moments[6] = mean;
        moments[7] = sigma2;
        moments[8] = skewness;

        mean = mu1(distFtf);
        sigma2 = mu2(distFtf, mean);
        skewness = mu3(distFtf, mean, Math.sqrt(sigma2));
        moments[9] = mean;
        moments[10] = sigma2;
        moments[11] = skewness;

        return moments;
    }

}