| The JAIDA library is quite extensive and elaborate, so we cannot 
              provide more than a brief introduction to it here. We will walk 
              through the PolyFitJAIDAApp 
              program displayed on the previous page 
              and discuss the JAIDA code to provide a general idea as to how you 
              can use it in your own code. 
              For more information, the 
                JAIDA website offers resources like the API 
                Documentation. The AIDA 
                Manual describes both the Java and C++ versons of the libraries 
                and can act as a general tutoral for the library. Other resources 
                include a page on JAIDA 
                Fit Methods and the Release 
                Notes, which include a number of userful items such as a sample 
                program showing how to add the JAIDA plotter to an application 
                program. (We followed this approach in PolyFitJAIDAApp.) 
                The AIDA 
                Discussion Forum can help with questions you have about particular 
                difficulties with the code.  In the PolyFitJAIDAApp 
              program, several instance variables for JAIDA objects are listed 
              at the top of the class description file. At the bottom of the file, 
              the main() method creates an instance 
              of the class, which is a JPanel subclass 
              that will be added to a JFrame. The constructor 
              invokes the init() method, which does 
              the work of building the interface.  JAIDA Setup in init() 
               The init() method starts by creating 
              several object factories:     // 
              Create the JAIDA factory objectsfAnalFactory           
              = IAnalysisFactory.create ();
 ITree tree             
              = fAnalFactory.createTreeFactory ().create ();
 fDpsFactory            = 
              fAnalFactory.createDataPointSetFactory (tree);
 IHistogramFactory hf   = fAnalFactory.createHistogramFactory 
              (tree);
 IFunctionFactory funcF = fAnalFactory.createFunctionFactory 
              (tree);
 IFitFactory       
              fitF = fAnalFactory.createFitFactory ();
 
 A factory refers to a static method that returns an instance 
              of a class that you do not create directly with a constructor. This 
              can be very convenient design pattern when there are setup parameters, 
              such as those that vary with the platform, that are of no interest 
              to the user of the object. The factory takes care of all the details 
              of making the object and you simply start using the object after 
              getting it from the factory. The JAIDA framework relies completely on factories for creating 
              objects. As shown by the JAIDA 
              API, the library consists only of interfaces. So factories are 
              the only way to instantiate objects that implement these interfaces. The JAIDA software lets you organize your analysis data, plots, 
              and histograms via a directory-style tree structure. Other than 
              in the above factory object section, we don't take deal with the 
              tree capability in the demo program here. However, it can be of 
              great importance when handling the complexities of many different 
              data sets and the histograms and plots for each. The JAS3 demo program 
              shown here, for example, 
 displays the tree hierarchy of data and plots in the left frame 
              of the program. The currently selected plot is displayed in the 
              frame on the right. So getting back to PolyFitJAIDAApp, 
              we have created our factories and so in the next code lines,      // 
              Create a fitterfFitter  = fitF.createFitter ("Chi2","jminuit","noClone=true");
 fFitData = fitF.createFitData ();
 
 we create an instance of the IFitter 
              tool for doing our point and distribution fits. The arguments to 
              the factory method tell it to use the JMinuit code for the fitting 
              and to use the CHI2 minimization technique. (See the the Release 
              Notes for a list of fitting techniques available in JMinuit.) 
              The third argument is a technical detail that tells the fitter not 
              to create an internal copy of of the fitted plot. The IFitData object provides the data 
              that the fitter will actually work on. It serves as an intermediate 
              buffer that allows the fitter to work on a a standard data format 
              regardless of the type of plot or histogram the data comes from. Our own raw data points (the ones we will fit a polynomial to) 
              must be placed into a IDataPointSet object 
              for 2 dimensional data:     // 
              Create a two dimensional IDataPointSet.fDps2D = fDpsFactory.create ("dps2D","two 
              dimensional IDataPointSet",2);
 JAIDA allows for you to create a custom function to use for plotting 
              and fitting:
 //Create a 1d second order polynomial
 fP2Func =
 funcF.createFunctionFromScript 
              ("p2", 1, "a+b*x[0]+c*x[0]*x[0]",
 "a,b,c", 
              "", null);
 
 You will be able to access the three parameters of the polynomial 
              via the names - a,b, 
              and c. The function is named "p2". JAIDA also provides some pre-defined functions such as the Gaussian:      // 
              Create Gaussian function for fitting residualsfGaussFunc = funcF.createFunctionByName("Gaussian", 
              "G");
 
 which we will use to fit our residuals distribution. To hold 
              that we create a 1-D histogram:
     // 
              Create fit residuals histogramfResidualsHist = hf.createHistogram1D ("Histogram 
              1D",50,-3,3);
 
 The following code creates the plotting tool.
 
 // Create an IPlotter
 fPlotter = fAnalFactory.createPlotterFactory 
              ().create ();
 // Create a region for the points plot and 
              for the histogram.
 fPlotter.createRegions(2,1);
 
  Here we use the createRegions() 
              method to tell the plotter to create two areas where we will display 
              the plot of points to fit and the residuals histogram. The final JAIDA code in init() connects 
              the plotter component to our the JPanel 
              subclass PolyFitJAIDAApp, 
              which in turn will be added to the JFrame 
              instance:      // 
              Now embed the plotter into the application frameadd (PlotterUtilities.componentForPlotter 
              (fPlotter), BorderLayout.CENTER);
 
 The other code in init() follows that 
              in the original Chapter 8: Physics 
              : LSQ Fit to a Polynominal program. It sets up the two text 
              fields for input of the number of data points to fit and the sigma 
              of the Gaussian smearing on the data points. It also adds buttons 
              for initiating the plotting of the data, clearing the histogram, 
              and ending the program. Plotting, Histogramming 
              and Fitting with JAIDA  
 When the user clicks on the "Go" button, the code in 
              the actionPerformed() method will get 
              the values from the text fields and then starts a thread. The class 
              implements the Runnable interface and 
              the run() method holds most of the code 
              for carrying out the plot and fitting tasks. The run() method holds a loop that runs 
              over the number of plots requested in the first text field. The 
              loop begins with an invocation of the genRanCurve() 
              method that generates a quadratic polynomial with randomly selected 
              parameters. Then "y" values 
              at the given "x" positions are 
              determined for this curve. For each point a Gauassian generated 
              error factor is added to each point to emulate the smearing of real 
              data with imprecise measurements. The sigma for that Gaussian is 
              given by the value in the second text field. A random error bar 
              is also created for each point. The run() method loop then clears the 
              IDataPointSet 
              object and puts the x, y 
              and y error bar values into it:       // 
              Clear the data point setfDps2D.clear ();
 
 // Fill the data point set with 
              the generated data values.
 for (int j = 0; j < fX.length; 
              j++ ) {
 fDps2D.addPoint 
              ();
 fDps2D.point (j).coordinate 
              (0).setValue (fX[j]);
 fDps2D.point (j).coordinate 
              (1).setValue (fY[j]);
 fDps2D.point (j).coordinate 
              (1).setErrorPlus (fYErr[j]);
 }
 
 
 The data point set is connected to the fitter tool via the intermediate 
              IFitData object:        fFitData.create1DConnection 
              (fDps2D,0,1);
 The method arguments indicate that the first (0) dimension of the 
              two-dimensional data set should be used as the x 
              coordinate and the second dimension as the y 
              coordinate in a fit of y=f(x).  The subsequent code deals with the fitting of the data. For some 
              pathological cases, the fits may fail and throw run-time exceptions 
              and stop the program. So we catch those exceptions. Two boolean 
              variables        boolean 
              fit_p_ok = true;boolean fit_g_ok = true;
 
 are used to flag whether an error condition has occurred.  The first fitting task is to fit a polynomial to the points that 
              we generated:         fFittedP 
              = fFitter.fit (fFitData,fP2Func);
 where fP2Func 
              is the polynomial function object that we created in init(). 
             We then obtain the parameters of the fitted function and calculate 
              the residuals of the fit and fill the histogram:         double 
              [] fit_params = fFittedP.fittedParameters ();
 // Calculate the 
              residual and fill the histogram
 for (int j=0; j 
              < fX.length; j++) {
 double 
              y_fit = fit_params[0] + fit_params[1]*fX[j]
 + 
              fit_params[2]*fX[j]*fX[j];
 fResidualsHist.fill 
              (fY[j] - y_fit);
 
 The resulting distribution is then fit to a Gaussian           fFittedG 
              = fFitter.fit(fResidualsHist,fGaussFunc);
 The following code clears the display areas and then plots the 
              data points and overlays the fitted function in the first plot region. 
              In the second region it plots the histogram and overlays it with 
              the fitted Gaussian:        // 
              Clear the previous plot except for the very first time.if (!fFirstPlot) fPlotter.clearRegions 
              ();
 fFirstPlot = false;
 
 // Plot and show the data with 
              the fitted functions.
 fPlotter.region (0).plot (fDps2D);
 if (fit_p_ok) fPlotter.region(0).plot 
              (fFittedP.fittedFunction () );
 fPlotter.region (1).plot (fResidualsHist);
 if (fit_g_ok) fPlotter.region(1).plot 
              (fFittedG.fittedFunction () );
 fPlotter.show ();
 
 Summary The JAIDA code becomes fairly easy to follow once you understand 
              the basic framework. It is quite powerful and you can quickly begin 
              to take advantage of it for many different types of analysis work, 
              not just for high energy physics.  There are many options and additional capabilities not dealt with 
              here. See the documentation and examples on the JAIDA website for 
              further exploration.   Most recent update: Dec.16, 2005 |