/* * Copyright (c) 2012 Patrick Meyer * * 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 <http://www.gnu.org/licenses/>. */ package com.itemanalysis.jmetrik.graph.itemmap; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Iterator; import javax.swing.SwingWorker; import com.itemanalysis.jmetrik.dao.DatabaseAccessObject; import com.itemanalysis.jmetrik.graph.histogram.HistogramChartDataset; import com.itemanalysis.jmetrik.sql.DataTableName; import com.itemanalysis.jmetrik.sql.VariableTableName; import com.itemanalysis.jmetrik.workspace.VariableChangeEvent; import com.itemanalysis.jmetrik.workspace.VariableChangeListener; import com.itemanalysis.psychometrics.data.VariableAttributes; import com.itemanalysis.psychometrics.data.VariableName; import com.itemanalysis.psychometrics.histogram.BinCalculationType; import com.itemanalysis.psychometrics.histogram.Histogram; import com.itemanalysis.psychometrics.histogram.HistogramType; import com.itemanalysis.psychometrics.tools.StopWatch; import com.itemanalysis.squiggle.base.SelectQuery; import com.itemanalysis.squiggle.base.Table; import org.apache.log4j.Logger; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; public class ItemMapAnalysis extends SwingWorker<ItemMapPanel, Void> { private ItemMapCommand command = null; private ItemMapPanel itemMapPanel = null; private Connection conn = null; private StopWatch sw = null; private DataTableName tableName = null; private DataTableName itemTableName = null; private ArrayList<VariableAttributes> variable = null; static Logger logger = Logger.getLogger("jmetrik-logger"); static Logger scriptLogger = Logger.getLogger("jmetrik-script-logger"); private int progressValue = 0; private int lineNumber = 0; private double maxProgress = 100.0; private Throwable theException = null; private DatabaseAccessObject dao = null; private ArrayList<VariableChangeListener> variableChangeListeners = null; public ItemMapAnalysis(Connection conn, DatabaseAccessObject dao, ItemMapCommand command, ItemMapPanel itemMapPanel){ this.command = command; this.itemMapPanel = itemMapPanel; this.conn = conn; this.dao = dao; variableChangeListeners = new ArrayList<VariableChangeListener>(); } private void initializeProgress()throws SQLException { int nrow = dao.getRowCount(conn, tableName); maxProgress = ((double)nrow)*2.0;//once for bin calculation and noce for filling bin nrow = dao.getRowCount(conn, itemTableName); maxProgress += ((double)nrow)*2.0;//once for bin calculation and noce for filling bin } private void updateProgress(){ progressValue=(int)((100*((double)lineNumber+1.0))/maxProgress); setProgress(Math.max(0,Math.min(100,progressValue))); lineNumber++; } private HistogramChartDataset summarizePersons()throws SQLException{ HistogramChartDataset data = new HistogramChartDataset(); Statement stmt = null; ResultSet rs=null; try{ Table sqlTable = new Table(tableName.getNameForDatabase()); SelectQuery select = new SelectQuery(); for(VariableAttributes v : variable){ select.addColumn(sqlTable, v.getName().nameForDatabase()); } stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs=stmt.executeQuery(select.toString()); Histogram histogram = new Histogram(HistogramType.DENSITY, BinCalculationType.STURGES, true); String dbVarName = variable.get(0).getName().nameForDatabase(); rs=stmt.executeQuery(select.toString()); while(rs.next()){ Double value = (Double)rs.getObject(dbVarName); if(value!=null){ histogram.increment(value.doubleValue()); } updateProgress(); } histogram.evaluate();//compute histogram data.addHistogram("Theta", histogram); return data; }catch(SQLException ex){ logger.fatal(ex.getMessage(), ex); throw new SQLException(ex); }finally{ if(rs!=null) rs.close(); if(stmt!=null) stmt.close(); } } private XYSeriesCollection summarizeItemSteps()throws SQLException{ Statement stmt = null; ResultSet rs=null; XYSeriesCollection seriesCollection = new XYSeriesCollection(); try{ Table sqlTable = new Table(itemTableName.getNameForDatabase()); SelectQuery select = new SelectQuery(); select.addColumn(sqlTable, "*"); stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs=stmt.executeQuery(select.toString()); VariableName itemName = new VariableName("name"); VariableName nCatName = new VariableName("ncat"); VariableName deltaName = new VariableName("bparam"); VariableName tauName = null; int numCat = 2; String gName = "difficulty"; rs=stmt.executeQuery(select.toString()); //Each item has its own series XYSeries series = null; Double itemPosition = 1.0; //Create points while(rs.next()){ String itemNameText = (String)rs.getObject(itemName.nameForDatabase()); Double nCat = (Double)rs.getObject(nCatName.nameForDatabase()); Double delta = (Double)rs.getObject(deltaName.nameForDatabase()); Double tau = 0.0; Double step = 0.0; series = new XYSeries(itemNameText); if(nCat!=null && delta!=null){ numCat = nCat.intValue(); if(numCat>2){ for(int i=1;i<numCat;i++){ gName = "step" + i; //compute step difficulties and frequency of occurrence tauName = new VariableName(gName); tau = delta + (Double)rs.getObject(tauName.nameForDatabase()); step = delta + tau; series.add(step, itemPosition); } }else{ series.add(delta, itemPosition); } } seriesCollection.addSeries(series); updateProgress(); itemPosition++; } return seriesCollection; }catch(SQLException ex){ throw(ex); }finally{ if(rs!=null) rs.close(); if(stmt!=null) stmt.close(); } } private HistogramChartDataset summarizeItems()throws SQLException{ Statement stmt = null; ResultSet rs=null; HistogramChartDataset data = new HistogramChartDataset(); try{ Table sqlTable = new Table(itemTableName.getNameForDatabase()); SelectQuery select = new SelectQuery(); select.addColumn(sqlTable, "*"); stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); rs=stmt.executeQuery(select.toString()); VariableName nCatName = new VariableName("ncat"); VariableName deltaName = new VariableName("bparam"); VariableName tauName = null; int numCat = 2; String gName = "difficulty"; rs=stmt.executeQuery(select.toString()); //fill bins while(rs.next()){ Double nCat = (Double)rs.getObject(nCatName.nameForDatabase()); Double delta = (Double)rs.getObject(deltaName.nameForDatabase()); Double tau = 0.0; Double step = 0.0; if(nCat!=null && delta!=null){ numCat = nCat.intValue(); if(numCat>2){ for(int i=1;i<numCat;i++){ gName = "step" + i; //compute step difficulties and frequency of occurrence tauName = new VariableName(gName); tau = delta + (Double)rs.getObject(tauName.nameForDatabase()); step = delta + tau; Histogram h = data.getHistogram(gName); if(h==null){ h = new Histogram(HistogramType.FREQUENCY, BinCalculationType.STURGES, true); data.addHistogram(gName, h); } h.increment(step); } }else{ Histogram h = data.getHistogram(gName); if(h==null){ h = new Histogram(HistogramType.FREQUENCY, BinCalculationType.STURGES, true); data.addHistogram(gName, h); } h.increment(delta); } } updateProgress(); } //Compute histogram Iterator<Comparable> iter = data.iterator(); Histogram h = null; while(iter.hasNext()){ data.getHistogram(iter.next()).evaluate(); } return data; }catch(SQLException ex){ throw(ex); }finally{ if(rs!=null) rs.close(); if(stmt!=null) stmt.close(); } } protected ItemMapPanel doInBackground(){ sw = new StopWatch(); this.firePropertyChange("status", "", "Running Item Map..."); this.firePropertyChange("progress-on", null, null); try{ logger.info(command.paste()); //get variable info from db tableName = new DataTableName(command.getPairedOptionList("data").getStringAt("table")); itemTableName = new DataTableName(command.getPairedOptionList("itemdata").getStringAt("table")); ArrayList<String> selectedVariables = new ArrayList<String>(); selectedVariables.add(command.getFreeOption("variables").getString()); VariableTableName varTable = new VariableTableName(tableName.toString()); variable = dao.getSelectedVariables(conn, varTable, selectedVariables); initializeProgress(); itemMapPanel.updatePersonDataset(summarizePersons()); // itemMapPanel.updateItemDataSet(summarizeItems()); itemMapPanel.updateItemDataSet2(summarizeItemSteps()); firePropertyChange("status", "", "Done: " + sw.getElapsedTime()); firePropertyChange("progress-off", null, null); //make statusbar progress not visible }catch(Throwable t){ logger.fatal(t.getMessage(), t); theException=t; } return itemMapPanel; } //=============================================================================================================== //Handle variable changes here //=============================================================================================================== public synchronized void addVariableChangeListener(VariableChangeListener l){ variableChangeListeners.add(l); } public synchronized void removeVariableChangeListener(VariableChangeListener l){ variableChangeListeners.remove(l); } public synchronized void removeAllVariableChangeListeners(){ variableChangeListeners.clear(); } public void fireVariableChanged(VariableChangeEvent event){ System.out.println("TestSclingAnalysis: firing variable changed=" + event.getVariable().getName().toString()); for(VariableChangeListener l : variableChangeListeners){ l.variableChanged(event); } } //=============================================================================================================== @Override protected void done(){ try{ if(theException!=null){ logger.fatal(theException.getMessage(), theException); firePropertyChange("error", "", "Error - Check log for details."); } scriptLogger.info(command.paste()); }catch(Exception ex){ logger.fatal(theException.getMessage(), theException); firePropertyChange("error", "", "Error - Check log for details."); } } }