Changeset 7694


Ignore:
Timestamp:
04/12/11 20:28:53 (9 years ago)
Author:
aivar
Message:

Enable the old System.loadLibrary JNA version as well as the new NativeLibraryUtility version. If there is a shared library on the library path, use it. Intent is to allow quick testing of native libraries without having to rebuild the entire SLIMPlugin jar with dependencies.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/projects/curve-fitter/src/main/java/loci/curvefitter/SLIMCurveFitter.java

    r7692 r7694  
    4646 
    4747/** 
    48  * TODO 
     48 * This class is a Java wrapper around the SLIMCurve fitting C code. 
    4949 * 
    5050 * <dl><dt><b>Source code:</b></dt> 
     
    5555 */ 
    5656public class SLIMCurveFitter extends AbstractCurveFitter { 
    57     //TODO old style: 
    58     static CLibrary s_library; 
    59     boolean m_oldStyle = false; 
    60     //TODO 
    61     static boolean s_loaded = false; 
    6257    public enum AlgorithmType { RLD, LMA, RLD_LMA }; 
     58 
     59    private static boolean s_libraryLoaded = false; 
     60    private static boolean s_libraryOnPath = false; 
     61    private static CLibrary s_library; 
     62 
    6363    private AlgorithmType m_algorithmType; 
    6464 
    65     //TODO old style 
     65    /** 
     66     * This interface supports loading the library using JNA. 
     67     */ 
    6668    public interface CLibrary extends Library { 
    6769 
     
    102104                           double chiSquareTarget 
    103105                           ); 
    104  
    105  
    106         /* public int nr_GCI_triple_integral_fitting_engine(float xincr, float y[], int fitStart, int fitEnd, 
    107                                                                            float instr[], int nInstr, int noise, float sig[], 
    108                                                                            FloatByReference z, FloatByReference a, FloatByReference tau, 
    109                                                                            float fitted[], float residuals[], 
    110                                                                            FloatByReference chiSq, float chiSqTarget); 
    111  
    112            public int nr_GCI_marquardt_fitting_engine(float xincr, float y[], int nData, int fitStart, int fitEnd, 
    113                                                                            float instr[], int nInstr, int noise, float sig[], 
    114                                                                            float param[], int paramFree[], int nParam, 
    115                                                                            int restrainType, int fitType, 
    116                                                                            float fitted[], float residuals[], 
    117                                                                            FloatByReference chiSq);*/ 
    118         //, 
    119         //                                                                   float covar[], float alpha[], float errAxes[], 
    120         //                                                                   float chiSqTarget, int chiSqPercent); 
    121  
    122  
    123         /*public int nr_GCI_marquardt_fitting_engine(float xincr, float *trans, int ndata, int fit_start, int fit_end, 
    124                                                                  float prompt[], int nprompt, //TODO ARG is this actually instr[] & ninstr? 
    125                                                                  noise_type noise, float sig[], 
    126                                                                  float param[], int paramfree[], 
    127                                                                  int nparam, restrain_type restrain, 
    128                                                                  fit_type fit, //TODO ARG void (*fitfunc)(float, float [], float *, float [], int), 
    129                                                                  float *fitted, float *residuals, float *chisq, 
    130                                                                  float **covar, float **alpha, float **erraxes, 
    131                                                                         float chisq_target, int chisq_percent) {*/ 
    132     } 
    133     //TODO 
     106    } 
     107 
     108 
     109    /** 
     110     * This supports calling the libray using JNI. 
     111     * 
     112     * @param xInc 
     113     * @param y 
     114     * @param fitStart 
     115     * @param fitEnd 
     116     * @param instr 
     117     * @param nInstr 
     118     * @param sig 
     119     * @param z 
     120     * @param a 
     121     * @param tau 
     122     * @param fitted 
     123     * @param chiSquare 
     124     * @param chiSquareTarget 
     125     * @return 
     126     */ 
    134127 
    135128 
     
    152145                           ); 
    153146 
     147    /** 
     148     * This supports calling the library using JNI. 
     149     * 
     150     * @param xInc 
     151     * @param y 
     152     * @param fitStart 
     153     * @param fitEnd 
     154     * @param instr 
     155     * @param n_instr 
     156     * @param sig 
     157     * @param param 
     158     * @param paramFree 
     159     * @param nParam 
     160     * @param fitted 
     161     * @param chiSquare 
     162     * @param chiSquareTarget 
     163     * @return 
     164     */ 
    154165    //TODO I'm omitted noise, see above and restrainType and fitType, for now 
    155166    //TODO also covar, alpha, errAxes and chiSqPercent 
     
    171182                           ); 
    172183 
     184    /** 
     185     * Create a curve fitter for a given algorithm type. 
     186     * 
     187     * @param algorithmType 
     188     */ 
    173189    public SLIMCurveFitter(AlgorithmType algorithmType) { 
    174190        m_algorithmType = algorithmType; 
    175191    } 
    176192 
     193    /** 
     194     * Create the default curve fitter, which uses RLD. 
     195     * 
     196     */ 
    177197    public SLIMCurveFitter() { 
    178198        m_algorithmType = AlgorithmType.RLD; 
     
    183203    public int fitData(ICurveFitData[] dataArray, int start, int stop) { 
    184204        int returnValue = 0; 
    185         IJ.log("SLIMCurveFitter.fitData " + m_algorithmType + " s_loaded " + s_loaded + " dataArray.length " + dataArray.length); 
    186  
    187         //TODO old style: 
    188         if (m_oldStyle) { 
    189              
    190        if (null == s_library) { 
     205        IJ.log("SLIMCurveFitter.fitData " + m_algorithmType + " s_loaded " + s_libraryLoaded + " dataArray.length " + dataArray.length); 
     206 
     207        // load the native library, if not already loaded 
     208        if (!s_libraryLoaded) { 
     209 
     210            // look for library on path 
    191211            try { 
    192                 // extract to library path 
    193                 //TODO sort out the nameSystem.out.println("extract native library returns " + NativeLibraryUtil.extractNativeLibraryToPath(this.getClass(), "SLIMCurve-2.0-SNAPSHOT")); 
    194                 //System.out.println("extract native library returns " + NativeLibraryUtil.extractNativeLibraryToPath(this.getClass(), "slim-curve-1.0-SNAPSHOT")); 
    195                 System.out.println("loadNativeLibrary returns " + NativeLibraryUtil.loadNativeLibrary(this.getClass(), "slim-curve")); 
    196  
    197                 IJ.log("before System load library"); 
    198                ////// System.loadLibrary("slim-curve-1.0-SNAPSHOT"); 
    199                 IJ.log("after System load library"); 
    200  
    201                 // load once, on-demand 
    202                 //TODO sort out the name s_library = (CLibrary) Native.loadLibrary("SLIMCurve", CLibrary.class); 
    203                //TODO test with old code instead: s_library = (CLibrary) Native.loadLibrary("slim-curve-1.0-SNAPSHOT", CLibrary.class); 
    204                 //TODO this was yet another version s_library = (CLibrary) Native.loadLibrary("SLIMCurve_trimmed_down", CLibrary.class); 
     212                // use JNA 
    205213                s_library = (CLibrary) Native.loadLibrary("slim-curve-1.0-SNAPSHOT", CLibrary.class); 
    206  
    207                 System.out.println("s_library is " + s_library); 
     214                s_libraryLoaded = true; 
     215                s_libraryOnPath = true; 
     216 
     217                IJ.log("load library from library path, use JNA"); 
    208218            } 
    209219            catch (UnsatisfiedLinkError e) { 
    210                 IJ.log("unable to load dynamic library " + e.getMessage()); 
    211                 System.out.println("unable to load dynamic library " + e.getMessage()); 
     220                System.out.println("Library not on path " + e.getMessage()); 
     221            } 
     222 
     223            if (!s_libraryLoaded) { 
     224                // look for library in jar, using JNI 
     225                s_libraryLoaded = NativeLibraryUtil.loadNativeLibrary(this.getClass(), "slim-curve"); 
     226 
     227                if (s_libraryLoaded) { 
     228                    IJ.log("load library from jar, use JNI"); 
     229                } 
     230            } 
     231 
     232            if (!s_libraryLoaded) { 
     233                IJ.log("Unable to do fit."); 
    212234                return 0; 
    213235            } 
     
    230252        } 
    231253 
    232         DoubleByReference chiSquare = new DoubleByReference(); 
    233         double chiSquareTarget = 1.0; //TODO s/b specified incoming 
    234  
    235         if (AlgorithmType.RLD.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
    236             // RLD or triple integral fit 
    237             DoubleByReference z = new DoubleByReference(); 
    238             DoubleByReference a = new DoubleByReference(); 
    239             DoubleByReference tau = new DoubleByReference(); 
    240  
    241             for (ICurveFitData data: dataArray) { 
    242                 // grab incoming parameters 
    243                 a.setValue(  data.getParams()[2]); 
    244                 tau.setValue(data.getParams()[3]); 
    245                 z.setValue(  data.getParams()[1]); 
    246  
    247                 // get IRF curve, if any 
    248                 double[] instrumentResponse = getInstrumentResponse(data.getPixels()); 
    249                 int nInstrumentResponse = 0; 
    250                 if (null != instrumentResponse) { 
    251                     nInstrumentResponse = instrumentResponse.length; 
     254        if (s_libraryOnPath) { 
     255            // JNA version 
     256            DoubleByReference chiSquare = new DoubleByReference(); 
     257            double chiSquareTarget = 1.0; //TODO s/b specified incoming 
     258 
     259            if (AlgorithmType.RLD.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
     260                // RLD or triple integral fit 
     261                DoubleByReference z = new DoubleByReference(); 
     262                DoubleByReference a = new DoubleByReference(); 
     263                DoubleByReference tau = new DoubleByReference(); 
     264 
     265                for (ICurveFitData data: dataArray) { 
     266                    // grab incoming parameters 
     267                    a.setValue(  data.getParams()[2]); 
     268                    tau.setValue(data.getParams()[3]); 
     269                    z.setValue(  data.getParams()[1]); 
     270 
     271                    // get IRF curve, if any 
     272                    double[] instrumentResponse = getInstrumentResponse(data.getPixels()); 
     273                    int nInstrumentResponse = 0; 
     274                    if (null != instrumentResponse) { 
     275                        nInstrumentResponse = instrumentResponse.length; 
     276                    } 
     277 
     278                    returnValue = s_library.RLD_fit( 
     279                            m_xInc, 
     280                            data.getYCount(), 
     281                            start, 
     282                            stop, 
     283                            instrumentResponse, 
     284                            nInstrumentResponse, 
     285                            data.getSig(), 
     286                            z, 
     287                            a, 
     288                            tau, 
     289                            data.getYFitted(), 
     290                            chiSquare, 
     291                            chiSquareTarget 
     292                            ); 
     293                    // set outgoing parameters, unless they are fixed 
     294                    data.getParams()[0] = chiSquare.getValue(); 
     295                    if (free[0]) { 
     296                        data.getParams()[1] = z.getValue(); 
     297                    } 
     298                    if (free[1]) { 
     299                        data.getParams()[2] = a.getValue(); 
     300                    } 
     301                    if (free[2]) { 
     302                        data.getParams()[3] = tau.getValue(); 
     303                    } 
    252304                } 
    253  
    254                 returnValue = s_library.RLD_fit( 
    255                         m_xInc, 
    256                         data.getYCount(), 
    257                         start, 
    258                         stop, 
    259                         instrumentResponse, 
    260                         nInstrumentResponse, 
    261                         data.getSig(), 
    262                         z, 
    263                         a, 
    264                         tau, 
    265                         data.getYFitted(), 
    266                         chiSquare, 
    267                         chiSquareTarget 
    268                         ); 
    269                 // set outgoing parameters, unless they are fixed 
    270                 data.getParams()[0] = chiSquare.getValue(); 
    271                 if (free[0]) { 
    272                     data.getParams()[1] = z.getValue(); 
     305            } 
     306 
     307            if (AlgorithmType.LMA.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
     308                // LMA fit 
     309                for (ICurveFitData data: dataArray) { 
     310                    int nInstrumentResponse = 0; 
     311                    if (null != m_instrumentResponse) { 
     312                        nInstrumentResponse = m_instrumentResponse.length; 
     313                    } 
     314                    returnValue = s_library.LMA_fit( 
     315                            m_xInc, 
     316                            data.getYCount(), 
     317                            start, 
     318                            stop, 
     319                            m_instrumentResponse, 
     320                            nInstrumentResponse, 
     321                            data.getSig(), 
     322                            data.getParams(), 
     323                            toIntArray(m_free), 
     324                            data.getParams().length - 1, 
     325                            data.getYFitted(), 
     326                            chiSquare, 
     327                            chiSquareTarget 
     328                            ); 
    273329                } 
    274                 if (free[1]) { 
    275                     data.getParams()[2] = a.getValue(); 
     330            } 
     331        } 
     332        else { 
     333            // JNI version 
     334 
     335            // use array to pass double by reference 
     336            double[] chiSquare = new double[1]; 
     337            double chiSquareTarget = 1.0; //TODO s/b specified incoming 
     338 
     339            if (AlgorithmType.RLD.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
     340                // RLD or triple integral fit 
     341 
     342                // use arrays to pass double by reference 
     343                double[] z = new double[1]; 
     344                double[] a = new double[1]; 
     345                double[] tau = new double[1]; 
     346 
     347                for (ICurveFitData data: dataArray) { 
     348                    // grab incoming parameters 
     349                    a[0] = data.getParams()[2]; 
     350                    tau[0] = data.getParams()[3]; 
     351                    z[0] = data.getParams()[1]; 
     352 
     353                    // get IRF curve, if any 
     354                    double[] instrumentResponse = getInstrumentResponse(data.getPixels()); 
     355                    int nInstrumentResponse = 0; 
     356                    if (null != instrumentResponse) { 
     357                        nInstrumentResponse = instrumentResponse.length; 
     358                    } 
     359 
     360                    returnValue = RLD_fit(m_xInc, 
     361                            data.getYCount(), 
     362                            start, 
     363                            stop, 
     364                            instrumentResponse, 
     365                            nInstrumentResponse, 
     366                            data.getSig(), 
     367                            z, 
     368                            a, 
     369                            tau, 
     370                            data.getYFitted(), 
     371                            chiSquare, 
     372                            chiSquareTarget 
     373                            ); 
     374 
     375                    // set outgoing parameters, unless they are fixed 
     376                    data.getParams()[0] = chiSquare[0]; 
     377                    if (free[0]) { 
     378                        data.getParams()[1] = z[0]; 
     379                    } 
     380                    if (free[1]) { 
     381                        data.getParams()[2] = a[0]; 
     382                    } 
     383                    if (free[2]) { 
     384                        data.getParams()[3] = tau[0]; 
     385                    } 
    276386                } 
    277                 if (free[2]) { 
    278                     data.getParams()[3] = tau.getValue(); 
     387            } 
     388 
     389            if (AlgorithmType.LMA.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
     390                // LMA fit 
     391                for (ICurveFitData data: dataArray) { 
     392                    int nInstrumentResponse = 0; 
     393                    if (null != m_instrumentResponse) { 
     394                        nInstrumentResponse = m_instrumentResponse.length; 
     395                    } 
     396                    returnValue = LMA_fit( 
     397                            m_xInc, 
     398                            data.getYCount(), 
     399                            start, 
     400                            stop, 
     401                            m_instrumentResponse, 
     402                            nInstrumentResponse, 
     403                            data.getSig(), 
     404                            data.getParams(), 
     405                            toIntArray(m_free), 
     406                            data.getParams().length - 1, 
     407                            data.getYFitted(), 
     408                            chiSquare, 
     409                            chiSquareTarget 
     410                            ); 
    279411                } 
    280412            } 
    281413        } 
    282414 
    283         if (AlgorithmType.LMA.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
    284             // LMA fit 
    285             for (ICurveFitData data: dataArray) { 
    286                 int nInstrumentResponse = 0; 
    287                 if (null != m_instrumentResponse) { 
    288                     nInstrumentResponse = m_instrumentResponse.length; 
    289                 } 
    290                 returnValue = s_library.LMA_fit( 
    291                         m_xInc, 
    292                         data.getYCount(), 
    293                         start, 
    294                         stop, 
    295                         m_instrumentResponse, 
    296                         nInstrumentResponse, 
    297                         data.getSig(), 
    298                         data.getParams(), 
    299                         toIntArray(m_free), 
    300                         data.getParams().length - 1, 
    301                         data.getYFitted(), 
    302                         chiSquare, 
    303                         chiSquareTarget 
    304                         ); 
    305             } 
    306         } 
    307415        //TODO error return deserves much more thought!!  Just returning the last value here!! 
    308416        return returnValue; 
    309417 
    310         } 
    311         else { 
    312         //TODO 
    313         if (!s_loaded) { 
    314             try { 
    315                 // extract to library path 
    316                 //TODO sort out the nameSystem.out.println("extract native library returns " + NativeLibraryUtil.extractNativeLibraryToPath(this.getClass(), "SLIMCurve-2.0-SNAPSHOT")); 
    317                 //System.out.println("extract native library returns " + NativeLibraryUtil.extractNativeLibraryToPath(this.getClass(), "slim-curve-1.0-SNAPSHOT")); 
    318  
    319                 //System.out.println("loadNativeLibrary returns " + NativeLibraryUtil.loadNativeLibrary(this.getClass(), "slim-curve")); 
    320  
    321                 boolean inNetBeans = false; //TODO useful for debugging when running NetBeans, requires dylib to be in slim-plugin directory // true; 
    322                 if (inNetBeans) { 
    323                     System.loadLibrary("slim-curve-1.0-SNAPSHOT"); 
    324                     s_loaded = true; 
    325                 } 
    326                 else { 
    327                     s_loaded = NativeLibraryUtil.loadNativeLibrary(this.getClass(), "slim-curve"); 
    328                 } 
    329  
    330                 //IJ.log("before System load library"); 
    331                ////// System.loadLibrary("slim-curve-1.0-SNAPSHOT"); 
    332                 //IJ.log("after System load library"); 
    333  
    334                 // load once, on-demand 
    335                 //TODO sort out the name s_library = (CLibrary) Native.loadLibrary("SLIMCurve", CLibrary.class); 
    336                //TODO test with old code instead: s_library = (CLibrary) Native.loadLibrary("slim-curve-1.0-SNAPSHOT", CLibrary.class); 
    337                 //TODO this was yet another version s_library = (CLibrary) Native.loadLibrary("SLIMCurve_trimmed_down", CLibrary.class); 
    338                 //s_library = (CLibrary) Native.loadLibrary("slim-curve-1.0-SNAPSHOT", CLibrary.class); 
    339  
    340                 //System.out.println("s_library is " + s_library); 
    341                 System.out.println("s_loaded is " + s_loaded); 
    342                 IJ.log("s_loaded is " + s_loaded); 
    343             } 
    344             catch (UnsatisfiedLinkError e) { 
    345                 IJ.log("unable to load dynamic library " + e.getMessage()); 
    346                 System.out.println("unable to load dynamic library " + e.getMessage()); 
    347                 return 0; 
    348             } 
    349         } 
    350         IJ.log("test"); 
    351  
    352         //TODO ARG 9/3/10 these issues still need to be addressed: 
    353  
    354         //TODO ARG since initial x = fit_start * xincr we have to supply the unused portion of y[] before fit_start. 
    355         // if this data were already premassaged it might be better to get rid of fit_start & _end, just give the 
    356         // portion to be fitted and specify an initial x. 
    357         //TODO ARG August use initial X of 0. 
    358  
    359         boolean[] free = m_free.clone(); 
    360         if (AlgorithmType.RLD.equals(m_algorithmType)) { 
    361             // pure RLD (versus RLD followed by LMA) has no way to fix 
    362             // parameters 
    363             for (int i = 0; i < free.length; ++i) { 
    364                 free[i] = true; 
    365             } 
    366         } 
    367  
    368         // use array to pass double by reference 
    369         double[] chiSquare = new double[1]; 
    370         double chiSquareTarget = 1.0; //TODO s/b specified incoming 
    371  
    372         if (AlgorithmType.RLD.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
    373             // RLD or triple integral fit 
    374  
    375             // use arrays to pass double by reference 
    376             double[] z = new double[1]; 
    377             double[] a = new double[1]; 
    378             double[] tau = new double[1]; 
    379  
    380             for (ICurveFitData data: dataArray) { 
    381                 // grab incoming parameters 
    382                 a[0] = data.getParams()[2]; 
    383                 tau[0] = data.getParams()[3]; 
    384                 z[0] = data.getParams()[1]; 
    385  
    386                 // get IRF curve, if any 
    387                 double[] instrumentResponse = getInstrumentResponse(data.getPixels()); 
    388                 int nInstrumentResponse = 0; 
    389                 if (null != instrumentResponse) { 
    390                     nInstrumentResponse = instrumentResponse.length; 
    391                 } 
    392  
    393           IJ.log("about to do RLD_fit"); 
    394                 returnValue = RLD_fit(m_xInc, 
    395                         data.getYCount(), 
    396                         start, 
    397                         stop, 
    398                         instrumentResponse, 
    399                         nInstrumentResponse, 
    400                         data.getSig(), 
    401                         z, 
    402                         a, 
    403                         tau, 
    404                         data.getYFitted(), 
    405                         chiSquare, 
    406                         chiSquareTarget 
    407                         ); 
    408            IJ.log("did RLD_fit"); 
    409                 // set outgoing parameters, unless they are fixed 
    410                 data.getParams()[0] = chiSquare[0]; 
    411                 if (free[0]) { 
    412                     data.getParams()[1] = z[0]; 
    413                 } 
    414                 if (free[1]) { 
    415                     data.getParams()[2] = a[0]; 
    416                 } 
    417                 if (free[2]) { 
    418                     data.getParams()[3] = tau[0]; 
    419                 } 
    420             } 
    421         } 
    422  
    423         if (AlgorithmType.LMA.equals(m_algorithmType) || AlgorithmType.RLD_LMA.equals(m_algorithmType)) { 
    424             // LMA fit 
    425             for (ICurveFitData data: dataArray) { 
    426                 int nInstrumentResponse = 0; 
    427                 if (null != m_instrumentResponse) { 
    428                     nInstrumentResponse = m_instrumentResponse.length; 
    429                 } 
    430                 returnValue = LMA_fit( 
    431                         m_xInc, 
    432                         data.getYCount(), 
    433                         start, 
    434                         stop, 
    435                         m_instrumentResponse, 
    436                         nInstrumentResponse, 
    437                         data.getSig(), 
    438                         data.getParams(), 
    439                         toIntArray(m_free), 
    440                         data.getParams().length - 1, 
    441                         data.getYFitted(), 
    442                         chiSquare, 
    443                         chiSquareTarget 
    444                         ); 
    445             } 
    446         } 
    447         //TODO error return deserves much more thought!!  Just returning the last value here!! 
    448         IJ.log("SLIMCurveFitter.fitData returns " + returnValue); 
    449         return returnValue; 
    450         //TODO old style: 
    451         } 
    452         //TODO 
    453418    } 
    454419 
Note: See TracChangeset for help on using the changeset viewer.